/* ////////////////////////////////////////////////////////////////// ARDUINO/Genuino Project "ATTAMOD", a 100 dB Step Attenuator https://www.changpuak.ch/electronics/Arduino-Attamod.php Software Version 3.0 - 28.10.2023 by ALEXANDER SSE FRANK, The Serial Parser is from here : Easy_Diseqc V1.2, Monstein ETH Zurich, 20.06.2018 ////////////////////////////////////////////////////////////////// */ #include #include #include #define OLED_RESET A0 // ANYTHING UNUSED Adafruit_SSD1306 display(OLED_RESET); #if (SSD1306_LCDHEIGHT != 32) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif // THE VARIABLES / MIN + MAX VALUES const float ATTmax = 90.0 ; const float ATTmin = 0.0 ; float ATTcurr = 0.0 ; int Status = 0x0F ; // 0x0F = WAIT // THE ARDUINO I/O PINS const int PlusTen = A2 ; const int PlusOne = A3 ; const int MinusTen = A7 ; const int MinusOne = A6 ; const int DAT1 = 4 ; const int CLK1 = 3 ; const int ENB1 = 2 ; const int DAT2 = 7 ; const int CLK2 = 6 ; const int ENB2 = 5 ; const int DAT3 = 10 ; const int CLK3 = 9 ; const int ENB3 = 8 ; // DEBUG bool debug = true ; char tempbuf[80]; // keeps the command temporary until CRLF String buffer; void SetAttenuator() { float ATT1 = Runden(ATTcurr / 3.0) ; float ATT2 = Runden(ATTcurr / 3.0) ; float ATT3 = ATTcurr - ATT1 - ATT2 ; byte TRUEATT1 = 4*ATT1 ; byte TRUEATT2 = 4*ATT2 ; byte TRUEATT3 = 4*ATT3 ; // ATTENUATOR 1 digitalWrite(ENB1, LOW) ; shiftOut(DAT1, CLK1, LSBFIRST, TRUEATT1) ; digitalWrite(ENB1, HIGH) ; // ATTENUATOR 2 digitalWrite(ENB2, LOW) ; shiftOut(DAT2, CLK2, LSBFIRST, TRUEATT2) ; digitalWrite(ENB2, HIGH) ; // ATTENUATOR 3 digitalWrite(ENB3, LOW) ; shiftOut(DAT3, CLK3, LSBFIRST, TRUEATT3) ; digitalWrite(ENB3, HIGH) ; if(debug) { Serial.print("Attenuator 1 : ") ; Serial.print(ATT1,2) ; Serial.println(" dB") ; Serial.print("Attenuator 2 : ") ; Serial.print(ATT2,2) ; Serial.println(" dB") ; Serial.print("Attenuator 3 : ") ; Serial.print(ATT3,2) ; Serial.println(" dB") ; Serial.println("--------------------------") ; } } void UpdateDisplay() { display.clearDisplay() ; display.setTextSize(3) ; display.setTextColor(WHITE) ; display.setCursor(0,10) ; if(ATTcurr < 10.0) display.print(" "); int GANZ = (int)ATTcurr ; display.print(GANZ, DEC) ; display.setCursor(32,10) ; display.print(".") ; int DECIMAL = 100 * (ATTcurr - GANZ) ; display.setCursor(49,10) ; if(DECIMAL == 0) display.print("00") ; if(DECIMAL == 25) display.print("25") ; if(DECIMAL == 50) display.print("50") ; if(DECIMAL == 75) display.print("75") ; display.setCursor(74,10) ; display.print(" dB"); display.display(); } float Runden(float WERT) { float Inter = round( WERT * 4 ) ; Inter /= 4.0 ; return Inter ; } void setup() { Serial.begin(115200) ; Serial.println("Attamod V3.0 by www.changpuak.ch (C) 28.10.2023") ; Wire.begin() ; display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay() ; display.setTextSize(3); display.setTextColor(WHITE); display.setCursor(0,10); display.print("ATTAMOD"); display.display(); delay(2000); pinMode(PlusTen, INPUT) ; pinMode(PlusOne, INPUT) ; pinMode(MinusTen, INPUT) ; pinMode(MinusOne, INPUT) ; pinMode(DAT1, OUTPUT) ; pinMode(CLK1, OUTPUT) ; pinMode(ENB1, OUTPUT) ; pinMode(DAT2, OUTPUT) ; pinMode(CLK2, OUTPUT) ; pinMode(ENB2, OUTPUT) ; pinMode(DAT3, OUTPUT) ; pinMode(CLK3, OUTPUT) ; pinMode(ENB3, OUTPUT) ; SetAttenuator() ; } void loop() { UpdateDisplay() ; do { delay(20); // SCAN KEYBOARD Status = digitalRead(PlusTen) * 8 ; Status += digitalRead(PlusOne) * 4 ; Status += digitalRead(MinusTen) * 2 ; Status += digitalRead(MinusOne) * 1 ; // CHECK SERIAL INPUT if(Serial.available() > 0) Status = 0x9F ; } while(Status == 0x0F) ; switch(Status) { case 0x0F : // DO NOTHING, ALL PINS ARE HIGH delay(2) ; break ; case 0x0E : // MINUS ONE ATTcurr -= 1 ; if(ATTcurr < ATTmin) ATTcurr = ATTmin ; SetAttenuator() ; while (digitalRead(MinusOne) == 0) delay(1) ; break ; case 0x0D : // MINUS TEN ATTcurr -= 10 ; if(ATTcurr < ATTmin) ATTcurr = ATTmin ; SetAttenuator() ; while (digitalRead(MinusTen) == 0) delay(10) ; break ; case 0x0B : // PLUS ONE ATTcurr += 1 ; if(ATTcurr > ATTmax) ATTcurr = ATTmax ; SetAttenuator() ; while (digitalRead(PlusOne) == 0) delay(1) ; break ; case 0x07 : // PLUS TEN ATTcurr += 10 ; if(ATTcurr > ATTmax) ATTcurr = ATTmax ; SetAttenuator() ; while (digitalRead(PlusTen) == 0) delay(1) ; break ; case 0x9F : // WE GOT SOME SERIAL INPUT while (Serial.available() > 0) { int tmp; char st[20]; char rx = Serial.read(); // read a single character buffer += rx; //add character to the string buffer if ((rx == '\n') || (rx == '\r')) { buffer.toCharArray(tempbuf, 40); if (buffer.startsWith("Att:")) { sscanf(tempbuf,"Att:%s",&st); // extract attenuation as floating point number ATTcurr = Runden(strtod(st,NULL)) ; if(ATTcurr < ATTmin) ATTcurr = ATTmin ; if(ATTcurr > ATTmax) ATTcurr = ATTmax ; SetAttenuator() ; Serial.print("New attenuation : ") ; Serial.print(ATTcurr,2) ; Serial.println(" dB") ; } if (buffer.startsWith("Att?")) { Serial.print("Attenuation : ") ; Serial.print(ATTcurr,2) ; Serial.println(" dB") ; } if (buffer.startsWith("*IDN?")) { Serial.println("Attamod V3.0 by www.changpuak.ch (C) 28.10.2023") ; } buffer = "" ; //erase buffer for next command } } break ; } }