Das Dämpfungsglied PE4302 mit dem Arduino vom vorherigen Beitrag wurde erweitert um einen Rotary Encoder aus diesem Beitrag und ein LCD Display 16×2 wie in diesem Beitrag verwendet.
Der Rotary Encoder kann die Dämpfung in 0,5 dB Schritten verändern. Durch drücken der Taste wird der aktuelle Wert in das EEPROM abgelegt und beim nächsten Einschalten verwendet.
Die PC Steuerung wurde erweitert um die EEPROM Befehle:
e – speichern in EEPROM
r – auslesen aus EEPROM
Die Anschlüsse des 16×2 LCD Displays sind im Programm angegeben. Es wurde die LiquidCrystal.h Library verwendet. Die neue displayupdate Variable wird gesetzt wenn das LCD-Display geschrieben werden soll.
Hier die Schaltung auf den Steckbrettern.
Und das Programm dazu
// PE4302 Digital Step Attentuator // 1 MHz - 4 GHz Dämpfungsglied 0-31,5dB in 0,5dB Schritten // // Seriell vom PC aus einstellbar und auslesbar. // Rotary Encoder KY-040 kann den Wert einstellen und speichern. // 16x2 LCD Ausgabe // // Matthias Busse 11.2017 Version 2.2 #include <EEPROM.h> // standard Arduino Library // LCD Display Anschlüsse und Einstellungen // VSS und RW > GND // VDD und A > 5V // K > 1kOhm > GND // V0 Spannung über Poti 10k einstellbar GND ... 5V // RS > 12, E > 13 // D4 > 11, D5 > 10, D6 > 9, D7 > 8 #include <LiquidCrystal.h> const int rs = 12, e = 13, d4 = 11, d5 = 10, d6 = 9, d7 = 8; LiquidCrystal lcd(rs, e, d4, d5, d6, d7); bool displayupdate=1; // PE4302 Einstellungen int DATA=2; // Pin zu PE4302 Data int CLOCK=3; // Pin zu PE4302 CL int LE=4; // Pin zu PE4302 LE float att=0.0, attmax=31.5, attmin=0.0; // aktuelle Dämpfung und Grenzwerte // Rotary Encoder Einstellungen int ra = 5; // Pin zu CLK am KY-040 int rb = 6; // Pin zu DT am KY-040 int sw = 7; // Pin zu SW am KY-040 int alast, aval; int eeadr=10; // Speicheradresse wird hier gewählt void setup() { lcd.begin(16,2); lcd.setCursor(0,0); // Cursor Zeile 0 setzen lcd.print("Attentuator 4GHz"); // Text ausgeben lcd.setCursor(0,1); // Cusor Zeile 1 lcd.print("M.Busse Ver. 2.2"); // delay(3000); Serial.begin(38400); pinMode(DATA, OUTPUT); // PE4302 sins Ausgänge pinMode(CLOCK, OUTPUT); pinMode(LE, OUTPUT); pinMode(ra,INPUT); // Rotary Encoder A & B ist in pinMode(rb,INPUT); pinMode(sw, INPUT); // Schalter ist in digitalWrite(sw, HIGH); // interner Pull up Widerstand für Taster EEPROM.get(eeadr, att); if(isnan(att)) att=0.0; // wird zu 0 gesetzt bis ein erster Wert im EEPROM liegt. Serial.println(att); alast = digitalRead(ra); if(att > attmax) att=attmax; if(att < attmin) att=attmin; setAttenuator(att); Serial.print("attentuation: "); Serial.println(att); delay(3000); } void loop() { int ser, len; char buf[10]; float attinput; if(displayupdate) { // neue LCD Ausgabe lcd.setCursor(0,1); // Cusor Zeile 1 lcd.print(" Att: "); lcd.setCursor(7,1); if(att < 10.0) lcd.setCursor(8,1); lcd.print(att); lcd.setCursor(11,1); lcd.print(" dB "); displayupdate=0; } if(digitalRead(sw) == 0) { // Speicher Taste gedrückt? EEPROM.put(eeadr, att); Serial.print("saved: "); Serial.println(att); while (digitalRead(sw) == 0); // warten bis die Taste losgelassen wird lcd.setCursor(0,1); // Cusor Zeile 1 lcd.print(" - saved - "); delay(1000); displayupdate=1; } aval = digitalRead(ra); // Encoder gedreht? if (aval != alast){ // wenn gedreht if (digitalRead(rb) != aval) { if(att < attmax) att+=0.5; } // rechts rum else { if(att > attmin) att-=0.5; } // sonst links setAttenuator(att); Serial.print("attentuation: "); Serial.println(att); } alast = aval; if (Serial.available() > 0) { // serielle Eingaben ? ser = Serial.read(); if(ser == 'h') { Serial.println("help"); Serial.println(" sx.x: set attentuator. Examples: s1.5 | s0 | s 22.5 | s 31 | s 0.0 "); Serial.println(" g: get actual attentuator value"); Serial.println(" e: write to EEPROM"); Serial.println(" r: read from EEPROM"); Serial.println(" d: device class"); Serial.println(" w: who"); Serial.println(" v: version"); Serial.println(" 1: min. frequency"); Serial.println(" 2: max. frequency"); Serial.println(" 3: min. attentuation"); Serial.println(" 4: max. attentuation"); Serial.println(" 5: attentuator step width"); } if(ser == 'd') Serial.println("attentuator"); // device ? if(ser == 'w') Serial.println("PE4302"); // who ? if(ser == 'v') Serial.println("Version 2.2"); // version ? if(ser == 'e') { EEPROM.put(eeadr, att); // in das EEPROM schreiben ? Serial.print("saved: "); Serial.println(att); lcd.setCursor(0,1); // Cusor Zeile 1 lcd.print(" - saved - "); delay(1000); displayupdate=1; } if(ser == 'r') { EEPROM.get(eeadr, att); // aus dem EEPROM lesen ? Serial.print("read: "); Serial.println(att); displayupdate=1; } if(ser == '1') Serial.println("1000000"); // 1MHz fmin if(ser == '2') Serial.println("4000000000"); // 4GHz fmax if(ser == '3') Serial.println("0.0"); // 0dB att. min if(ser == '4') Serial.println("31.5"); // 31.5dB att. max if(ser == '5') Serial.println("0.5"); // att. step if(ser == 'g') Serial.println(att); // get attentuation if(ser == 's') { // set attentuation s1.5 | s0 | s 22.5 | s 31 | s 0.0 Serial.setTimeout(15); len = Serial.readBytes(buf,10); if((len>2) && (len<8)) { // s und was dahinter ? attinput = atof (buf); attinput = (round(attinput * 2.0)) /2.0; // auf .0 und .5 runden if((attinput >= 0.0) && (attinput <= 31.51)) { att=attinput; setAttenuator(att); } } } Serial.setTimeout(500); } } void setAttenuator(float attent){ // Einstellung an den PE4302 übergeben // MSB (C16) ... LSB (C0.5) werden an den PE4302 seriell übergeben // max. 25kHz oder alle 0,05 ms aufrufen. // // Matthias Busse 10.2017 Version 1.0 int i; // das Datenbit int attent2 = (int) attent*2.0; if ((attent2 < 0) || (attent2 > 63)) // Wert im Bereich ? return; digitalWrite(LE, LOW); // Daten in das Latch eingeben digitalWrite(CLOCK,LOW); for (int b = 6; b > 0; b--) { // die 6 Bits i=((attent2 << 1) >> b) & 0x01; digitalWrite(DATA, i); // ein Bit schreiben digitalWrite(CLOCK, HIGH); // und Bit übernehmen digitalWrite(CLOCK, LOW); } digitalWrite(LE, HIGH); // Serielle Daten an den Chip übergeben digitalWrite(LE, LOW); // Auf neue Daten warten. displayupdate=1; // Das LCD Display soll neu geschrieben werden. }
Verwendet wurden:
Arduino Nano
Arduino Software 1.8.0
Attentuator PE4302
16×2 LCD Display
Rotary Encoder KY-040
von Matthias Busse
Hallo lieber Matthias, deine Aufbaugeschichte mit dem Abschwächer gefäfft mir ganz gut, ich habe hier ebenfalls schon so etwas realisiert. Eigendlich wäre es doch toll, wenn man 2 stk dieser Abschwächer hintereinander schaltet und dann als gesammtdämpfung einen Wert bis 64 db bekommt.Auch wenn die Durchgangsdämpfung bei den Bausteinen recht hoch ist und auch der Frequenzgang recht mies ist.
Man müßte oberhalb von 32 Bit nur den 2. auf 32 db setzen und den ersten noch eimal zählen lassen von 0 bis 32 Bit und den Wert in der Anzeige plus dem Grundwert von 32 db zur Anzeige bringen. Der Zähler kann ja den gesammten wertebereich von 0 bis 128 Schritte laufen, wenn > 32 db oder 64 Schritte, bringe den 2 mit ins spiel und wenns runter geht unter 32 zähle den wieder ab. Was häst du davon, Kannst ja mal ne mail nach NF in der Nähe von Husum schicken wenn du magst
Christian DD7LP OVV DARC Husum M04
Hallo,
habe versucht diese Projekt mit einem Sparkfun Pro Micro und einem I2C 16 x 2 LCD nachzubauen,
kann aber an den Anschlüssen des PE4302 Moduls keine Pegeländerungen beim Drehen des Encoders
feststellen. Sollte man an den Anschlüssen nicht irgendwann 3 V messen können? Weiter macht der Encoder bei mir von einer Rastung zur nächsten immer 1db, nur wenn ich sachte zwischen zwei Rastungen drehe bekomme ich einen 0,5 db Schritt.
Hoffentlich kannst du mir weiterhelfen, denn ich stehe irgendwie auf dem Schlauch.