PE4302 Attentuator einstellen vom PC & Rotary Encoder, Ausgabe auf LCD Display

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

2 Gedanken zu „PE4302 Attentuator einstellen vom PC & Rotary Encoder, Ausgabe auf LCD Display

  1. Christian Petersen

    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

    Antworten
  2. Sigi Jetzlsperger

    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.

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.