// Attenuator control by Tony G3PTD. // For Arduino UNO, but several others should do. // This is intended to work with a PE4302 module // wired for immediate parallel operation, and is // intended for control by rotary encoder. // No integral switch action is needed. // NOTE this will not run (for me anyway) if compiled in // Arduino 1.8.3 (There are no error messages, but the // display does not work properly)! // No problem if version 1.0.6 is used. #include #include #include // PCF85741A I2C interfaces use 3Fh // PCF85741 Interfaces use 27h // The LCD I used has only one 16 character display line, // but it is formatted as 2 lines of eight characters. // So // LiquidCrystal_IC2 lcd(0x3f,8,2) // or LiquidCrystal_I2C lcd(0x27,8,2); // Enable which ever line is needed. Encoder enc(2,3); // Assignments: float LCDdata = 0; // 0 to 31.5 Data for LCD int AttenData = 0; // 0 to 63 data for the attenuator int bypass = 4; // Bypass switch on D4 int Relaydrive = 5; // Bypass relay on D5 int changerate =4; long lastPos = 0; // End of assignments void setup() { lcd.init(); //Initialise the LCD using the above data pinMode (bypass, INPUT); digitalWrite (bypass, HIGH); //not needed if external pullup pinMode (Relaydrive, OUTPUT); } //end of Setup // The following subroutine sends data to the LCD void printToLCD(float) { lcd.clear(); lcd.setCursor(0,0); //cursor to LCD left lcd.print("Atten = "); lcd.setCursor(0,1); // 8 by 2 display so this is the // start of "line 2" if (LCDdata < 10.0) lcd.print(" "); //to keep the position stable lcd.print(LCDdata, 1); //to one decimal place lcd.print(" dB"); } // end of print to LCD // And now the story really starts void loop() { // Send the attenuator value to Port B. (Bit 0 is for // 0.5dB steps, so six bits are needed.) // D8 to 13 go to attenuator V1 to V6 DDRB = B00111111; PORTB = AttenData; // Send the state of the bypass switch to Relaydrive // Bypass is active low. Debounce is not needed int state = digitalRead (bypass); digitalWrite (Relaydrive, !state); // Now enter a loop until the bypass switch is released while (state) { lcd.clear(); //if the bypass switch is "low" lcd.print (" BY-PA"); //clear the LCD and print "BYPASSED" lcd.setCursor (0,1); lcd.print ("SSED! "); state = digitalRead (bypass); delay (250); // if this is not used the display becomes // fainter the further right we go! } // ENCODER SECTION //read encoder // AttenData is limited to between 0 and 63 long newPos = enc.read() /changerate; if (newPos != lastPos) // then encoder has moved { if (newPos < lastPos) { if (AttenData > 0) AttenData--; } else { if (AttenData < 63) AttenData++; } lastPos = newPos; } // AttenData (0 to 63) is divided by two // to get the 0 to 31.5 for the LCD. LCDdata = AttenData / 2.0; // Attendata is an int. the decimal 2.0 forces // a floating point calculation. // Now add 2dB offset to allow for the insertion loss // of about 1.2dB, which I have padded up to 2dB. LCDdata = LCDdata + 2.0; //and display it. printToLCD(AttenData); delay (100); //For the display again }