Tiefpass 1.1 GHz simuliert, aufgebaut und vermessen.

Ich habe einen Tiefpass 5. Ordnung für eine Grenzfrequenz von 1,1 GHz entworfen

und simuliert mit dem Ansoft Designer.

Auf der CPWG 2.0 Platine mit diesen Werten in SMD aufgebaut Weiterlesen

Arduino als Frequenzteiler

Der Arduino kann als Frequenzteiler verwendet werden. Mich hat dabei interessiert bis zu welcher Frequenz das möglich ist.

Der Eingang : Dazu muß an einem Eingang das Signal als TTL Pegel anliegen (0/5V beim UNO, NANO, MEGA oder 0/3V beim DUE…) Ich habe hier den Eingang Pin 7 verwendet.

Das Programm: Der Arduino erkennt mit pulsIn(inPin, HIGH) eine steigende Flanke des Eingangssignals.

Der Ausgang: Als schnellen Ausgang habe ich den PORT B genommen und mit dem Assembler Befehl PORTB^=B11111111 umgeschaltet. Weiterlesen

RX String mit serialEvent einlesen und als Integer oder Float ausgeben

Mit serialEvent() können Zeichen von RX oder der USB Schnittstelle in den Arduino eingelesen werden. serialEvent() wird außerhalb von loop() ausgeführt und liest hier den Seriellen Buffer mit standardmäßig bis zu 64 Zeichen aus.

Das Programm basiert auf der Erklärung hier.

Sollten 64 Zeichen nicht reichen kann man den Buffer vergrößern, siehe hier.

Die Zeichen werden in einem String abgelegt. Das Zeilenende wird mit \n erkannt und dann wird stringComplete auf true gesetzt.

Im Hauptprogramm wird bei stringComplete==true der String ausgegeben. Zusätzlich wird der String in Integer und Float umgewandelt und ausgegeben.

Hier das Programm

// Seriell auf RX ( oder USB ) reinkommende Daten per event auslesen und das Zeilenende erkennen
// serialEvent() ist nicht kompatible mit Arduino Esplora, Leonardo oder Micro
//
// Matthias Busse 17.12.2018 Version 1.0

String inputString="";            // Eingabe String Daten
bool stringComplete=false;        // String abgeschlossen

void setup() {
  Serial.begin(38400);            // Baud
  inputString.reserve(64);        // 64 Byte Platz für den Seriellen Text
  Serial.println("Bitte Text eingeben und mit Enter bestaetigen:");
}

void loop() {
  if(stringComplete) {
    stringComplete=false;
    Serial.print("String : ");      // String ausgeben
    Serial.println(inputString);  
    Serial.print("Integer: ");      // Integer ausgeben
    Serial.println(inputString.toInt());
    Serial.print("Float  : ");      // Float ausgeben
    Serial.println(inputString.toFloat());
    inputString="";
  }
}

void serialEvent() {
// Wird aufgerufen wenn an RX Daten angekommen sind, ausserhalb von loop().
// Ein delay() in loop() kann die Datenübernahme verzögern.
// Der Arduino RX Buffer ist standardmässig 64 Zeichen groß, kann aber ggf. vergrößert werden.
  while(Serial.available()) {        // bis alle Zeichen im RX Buffer ausgelesen sind
    char inChar=(char)Serial.read(); // ein Zeichen im RX Buffer auslesen
    if(inChar == '\n') {             // String Ende erkennen
      stringComplete=true; 
    }
    else {                            // Zeichen anhängen
      inputString+=inChar; 
    }
  }
}

Verwendet wurden :
Arduino Uno
Arduino Programm Version 1.8.0

von Matthias Busse

Arduino Funktionen zur Vektor Rechnung

Für die Vektorrechnung habe ich die Funktionen in einem Unterprogramm vektor.c zusammengefasst.

// Funktionen für die Vektor Rechnung 
//
// Matthias Busse 1.10.2018 Version 1.0

// Inhalt:
// vAdd(v1, v2, v3)           : v1+v2=v3
// vSub(v1, v2, v3)           : v1-v2=v3
// vMultF(v1, f, v2)          : v1*f=v2
// f=vBetrag(v1)              : |v1|=f
// f=vSkalarprodukt(v1, v2)   : v1 * v2=f
// f=vWinkelGrad(v1, v2)      : Winkel zwischen v1 und v2 in Grad
// vVektorprodukt(v1, v2, v3) : v1 x v2 = v3
// vEinheitsvektor(v1, v2)    : v1 / |v1| = v2, Länge=1
// vRichtungscosinusX(v1)     : v1 Winkel zur X-Achse in Grad
// vRichtungscosinusY(v1)     : v1 Winkel zur Y-Achse in Grad
// vRichtungscosinusZ(v1)     : v1 Winkel zur Z-Achse in Grad

//      z |
//        |
//        |
//        ---------- y
//       /
//    x /


void vAdd(float v1[3], float v2[3], float v3[3]) {
// Vektoren Addieren v1+v2=v3 
// Matthias Busse Version 1.0 vom 30.9.2018
  v3[0]=v1[0]+v2[0];
  v3[1]=v1[1]+v2[1];
  v3[2]=v1[2]+v2[2];
}

void vSub(float v1[3], float v2[3], float v3[3]) {
// Vektoren Subtrahieren v1-v2=v3 
// Matthias Busse Version 1.0 vom 30.9.2018
  v3[0]=v1[0]-v2[0];
  v3[1]=v1[1]-v2[1];
  v3[2]=v1[2]-v2[2];
}

void vMultF(float v1[3], float z, float v2[3]) {
// Vektor multiplizieren mit Zahl v1*z=v2 
// Matthias Busse Version 1.0 vom 30.9.2018
  v2[0]=v1[0]*z;
  v2[1]=v1[1]*z;
  v2[2]=v1[2]*z;
}

float vBetrag(float v1[3]) {
// Vektor Betrag (Länge) von v1 oder |v1|=z 
// Matthias Busse Version 1.0 vom 30.9.2018
  float z;
  z=sqrt(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]);
  return z;
}

float vSkalarprodukt(float v1[], float v2[]) {
// Vektoren Skalar multiplizieren v1 * v2 = z 
// |V1| * |V2| * cos winkel_dawischen = z
// Wenn das Ergebis 0 ist, dann sind die Vektoren senkrecht zueinander
// Matthias Busse Version 1.0 vom 30.9.2018
  float z;
  z= (v1[0]*v2[0]) + (v1[1]*v2[1]) + (v1[2]*v2[2]);
  return z;
}

float vWinkelGrad(float v1[], float v2[]) {
// Den Winkel in Grad zwischen zwei Vektoren berechnen  
// Matthias Busse Version 1.0 vom 30.9.2018
  float z, w;
  z=vSkalarprodukt(v1, v2);
  w = z / vBetrag(v1) / vBetrag(v2);
  return acos(w)*57.296; // Rad zu Grad
}

void vVektorprodukt(float v1[3], float v2[3], float v3[3]) {
// Vektorprodukt v1 x v2 = v3
// v3 steht senkrecht auf v1 und v2
// v3 Betrag |v3| ist die Fläche vom v1 und v2 Parallelogramm
// Winkel zwischen v1 und v2 ist 
// |v1 x v2| = |v3| = |A| * |B| * sin winkel_dawischen
// Matthias Busse Version 1.0 vom 30.9.2018
  v3[0]= (v1[1]*v2[2]) - (v1[2]*v2[1]);
  v3[2]= (v1[0]*v2[1]) - (v1[1]*v2[0]);
  v3[1]= -1.0 * ((v1[0]*v2[2]) - (v1[2]*v2[0]));
}

void vEinheitsvektor(float v1[3], float v2[3]) {
// Einheitsvektor v1 / |v1| = v2
// Ergibt den Vektor mit der Länge 1
// Matthias Busse Version 0.1 vom 01.10.2018
  float betrag;
  betrag=vBetrag(v1);
  v2[0]=v1[0]/betrag;
  v2[1]=v1[1]/betrag;
  v2[2]=v1[2]/betrag;
}

float vRichtungscosinusX(float v1[3]) {
// Der RichtungskosinusX bildet den Winkel zwischen dem Vektor und der X Achse
// cos(w) = vx / |v|
// Matthias Busse Version 1.0 vom 01.10.2018
  float winkel;
  winkel=acos(v1[0]/vBetrag(v1));
  return winkel*57.296; // Rad zu Grad
}

float vRichtungscosinusY(float v1[3]) {
// Der RichtungskosinusY bildet den Winkel zwischen dem Vektor und der Y Achse
// cos(w) = vy / |v|
// Matthias Busse Version 1.0 vom 01.10.2018
  float winkel;
  winkel=acos(v1[1]/vBetrag(v1));
  return winkel*57.296; // Rad zu Grad
}

float vRichtungscosinusZ(float v1[3]) {
// Der RichtungskosinusZ bildet den Winkel zwischen dem Vektor und der Z Achse
// cos(w) = vz / |v|
// Matthias Busse Version 1.0 vom 01.10.2018
  float winkel;
  winkel=acos(v1[2]/vBetrag(v1));
  return winkel*57.296; // Rad zu Grad
}

Hier das Programm um die Vektor Funktionen zu testen.
Weiterlesen

Der I2C Bus Scanner. Die Adressen von Geräten am I2C Bus ausgeben.

Der I2C Bus ist ein 2-Draht Bus mit den Leitungen SCL (clock) und SDA (data). Er wird auf Platinen zwischen zwei Geräten / ICs verwendet. Die Hersteller der ICs geben die I2C Bus Adresse vor, manchmal können die unteren Bits angepasst werden, da theoretisch nur 128 Adressen zu Verfügung stehen und zwei ICs auf der selben Adresse liegen könnten.
Der Bus hat einen Master (hier der Arduino) und bis zu 112 Slaves (verschiedene ICs mit unterschiedlichen Adressen).

Hier die I2C Beschreibung bei Wikipedia.
Beim Arduino wird die Library Wire.h für die I2C Befehle eingebunden.
Der TWI Bus ist identisch mit dem standard I2C Bus.

Ein einfaches Arduino Programm scannt alle Adressen im I2C Bus und gibt die verwendeten Adressen aus.

// I²C Scanner aus dem Arduino.cc forum
// Netzfund, unbekannter Autor.
// Sucht I2C Geräte an den Adressen 0...127 und gibt bei gefundenen Geräten die Adresse aus.
//
// Matthias Busse 22.9.2018 Version 1.0

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(38400);
  while (!Serial);
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;
     
  Serial.println("scannen...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) {
    // Der i2c Scanner nimmt den Rückgabewert von Write.endTransmisstion um zu schauen ob ein Gerät auf dieser Adresse antwortet.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C Geraet gefunden an Adresse 0x");
      if (address<16) Serial.print("0");
      Serial.println(address,HEX);
      nDevices++;
    }
    else if (error==4) {
      Serial.print("Unbekannter Fehler an Addresse 0x");
      if (address<16) Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0) Serial.println("Kein I2C Geraet gefunden\n");
  else Serial.println("fertig\n");
  delay(5000);           // 5 Sekunden warten bis zum nächsten durchlauf
}

Und hier die Ausgabe

I2C Scanner
scannen...
I2C Geraet gefunden an Adresse 0x68
fertig

von Matthias Busse

Platinen abzugeben aus meinen Projekten

Von meinen Projekten habe ich hier noch einige Platinen.

Ich habe immer ein paar Platinen mehr machen lassen. Wenn also jemand die Schaltungen nachbauen möchte oder eigene Ideen hat kann ich die Platinen im Brief in Deutschland für 2 Euro verschicken. Ich verschicke nicht ins Ausland.

Die Platinen sind unbestückt und neu, ohne Stecker und andere Bauteile, nur die Platinen.

1. Platine CPWG 1.1
50 Ohm Leitung durchgehend, Masse Fläche durchkontaktiert daneben,
SMA Anschluß an beiden Seiten.
Material FR4, Dicke 1 mm, Außenmaß 14 x 50 mm
Aus dem Beitrag:
Tiefpass 5. Ordnung für 190 MHz simuliert und aufgebaut

Preis pro Platine: 5,00 €
Anzahl verfügbar: 3 Stück Weiterlesen

Ich habe meine China Dämpfungsglieder vermessen

Nach den ernüchternden Messergebnissen vom Abschlußwiderstand habe ich heute meine verschiedenen Dämpfungsglieder vermessen. Es sind welche von Mini Circuits und einfache China Versionen dabei. Hier nun meine Messergebnisse. Bei 1,3 GHz ist ein Messfehler im System nach der Kalibrierung des NWT4000, den vernachlässige ich hier.

Fangen wir mit dem Mini Circuits VAT-3 an mit 3dB Dämpfung
Bis auf zwei kleine Ausreißer von 2.5dB bei 3,8 GHz und 4,4 GHz ist es für den vollen Messbereich geeignet. Weiterlesen

Tiefpass 5. Ordnung für 190 MHz simuliert und aufgebaut

Ich habe eine Chebychev Tiefpaß 5. Ordnung entworfen mit diskreten L / C Elementen.
Chebychev Filter haben die größte Flankensteilheit.
Bei Kapazitäten habe ich hier eine größere Auswahl, deshalb wurde die 3 C und 2 L Struktur gewählt und simuliert.

Das Ergebnis der Simulation im Ansoft Designer.

Die 9,4pF wurden mit 8pF und 1,5pF aufgebaut und die 30pF mit 2 x 15pF.
Hier der fertige Aufbau im Gehäuse. Weiterlesen

Ein HF Verstärker von 100MHz bis 4400MHz aufgebaut

Ich habe einen breitbandigen HF Verstärker aufgebaut für den Frequenzbereich von 100 MHz bis 4,4 GHz.

Dazu habe ich ein ERA1-SM MMIC verwendet, wie in diesem Artikel.
Im HF 50Ohm Eingang und im Ausgang sind jeweils 10nF Kondensatoren in die Microstrip Leitung eingesetzt um die Gleichspannung nach außen abzublocken.

Auf der Rückseite ist ein Spannungsregler 7808 für 8V aufgelötet. Die zwei 100nF Kondensatoren für die Glättung und zum Verhindern von Schwingungen sind direkt an die Beine gelötet. Hier der Aufbau:

Die ERA1 MMIC Schaltung benötigt ca. 42mA über einen Vorwiderstand von 113 Ohm lt. Datenblatt bei 8V Spannung. Weiterlesen

Ein Bias Tee von 20MHz bis 2,1 GHz mit 2 SMA Steckern aufgebaut

Ein Bias Tee ist ein DC Block, wie im vorherigen Beitrag, plus eine Gleichspannungszuführung auf einer Seite um z.B. einem Verstärker die Versorgungsspannung zu geben.

Die Gleichspannung wird seitlich über eine Induktivität zugeführt um die HF nicht abfließen zu lassen. Etwas wird aber immer durch kommen, sodass man dahinter einen Kondensator an Masse legt um die HF abzuleiten. Die Gleichspannung wird zwischen Induktivität und Kondensator angeschlossen.

Hier das Blockschaltbild. Statt der Induktivität ist hier ein 1800 Ohm Widerstand eingezeichnet, dazu später mehr.

Am Port2 rechts liegt jetzt die DC Gleichspannung auf der 50 Ohm Leitung. An Port 1 kann sie über den Kondensator nicht kommen, für die HF-Welle stellt der Kondensator aber keine Sperre dar. Wenn die HF über die Induktivität seitlich abfließen sollte, wird sie mit dem 100nF Kondensator gegen Masse abgeleitet und erscheint nicht auf der Gleichspannungsleitung DC. Weiterlesen