/* This program written by Alastair GW0AJU. The code presented here for an all HF tri-band digital vfo. The program code is set in this listing as the lower ham band 160m, 80m, and the 40m band, with either CW or LSB. The program code to be easily adjusted for the mid-bands of 30m, 20, and 17m, adjusting the "void setup()" code accordingly. The "void carrier_mode()" and "void tx_rx()" would need altered to represent the new hamd band requirements. Subsequently for the higher ham bands of 15m, 12m, and 10m bands, the same alterations would be required. An extended band radio of LF, MF and 60m could also be constructed by adjusting the same code routines. In all cases, the code uses a 9MHz intermediate frequency for reception, and also for SSB exciter. However for CW transmissions, the digital VFO is placed directly onto the dial frequency as the digital vfo is used as the carrier oscillator for TX mode, thus CW keying the digital vfo for CW tx onto the output dial frequency setting, then the digital vfo adjusted for reception onto a 9MHz intermediate frequency setting. An i/o bus expander of the pcf8754 type is used to access to an output LED panel indicator, while also giving a logic output for ham band antenna switching on three of the i/o bus pins, P0, P1 and P2. The carrier mode switching is also present on the i/o bus, on pins P3 for CW and P4 for SSB, used also for switching between CW and SSB Tx/Rx circuits such as the BFO frequency selection for CW and SSB and band pass filtering. The morse key and PTT line is also imaged on i/o pin P5. It is suggested that in order to accurately use the twi display and i/o bus expander, use a twi searching program to find the network address of each unit. Ardunio board used = Ardiuno Uno original date 8th Feb 2016 */ //********** liquid display setup ********* #include #include #include #define I2C_ADDR 0x27 // <<- Add your address here. #define Rs_pin 0 #define Rw_pin 1 #define En_pin 2 #define BACKLIGHT_PIN 3 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); int PCF = 32; // TWI bus location for the pcf8754 i/o 8bit bus expander chip ( 32 = 0x20 ) //*********** arduino uno eeprom setup ************* #include long start_freq; long address; //*********** rotary encoder dial setup ************** int clk_location = 2; int dt_location = 3; //******************** morse key and tx_rx relay ************** int cw_key_ptt = 4; // pin 4 for cw key connection int test_cw_key_ptt; int check_cw_key_ptt = HIGH; int test_key = LOW; //********* logic switch for vfo step change ***************** int vfo_step_DA = 5; // logic pin d0 for vfo step change int vfo_step_DB = 6; // logic pin d1 for vfo step change int DA; int DB; int HDA; int HDB; //********** LF, 600m, 60m band select switch ************** int band_change_DA = 7; int band_change_DB = 8; int BDA = HIGH; int BDB = HIGH; int BDC = HIGH; int BDD = HIGH; //*********** dds vfo setup ************** #define DDS_CLOCK 125E6 #define CLOCK 9 // W_CLK = Pin 9 - connect to AD9850 module word load clock pin (CLK) #define LOAD 10 // FQ_UD = Pin 10 - connect to freq update pin (FQ_UD) #define DATA 11 // DATA = Pin 11 - connect to serial data load pin (AD9850 D7 = DATA) #define RESET 12 // RESET = Pin 12 - connect to DDS reset line //***************** carier mode selection **************** int carrier_mode_sense = 13; // sense CW or LSB, CW over-ride switch input int CW_LSB; int test_CW_LSB = HIGH; int check_CW_LSB = LOW; // ******************************************************* int run_once = 1; float result = 0; unsigned long IF_LO; unsigned long freq; long dial_step; long carrier_centre; float dial_post = 0; long last_Set = 0; int move_dial = 0; int dial_delay_clk = 0; int dial_delay_anti_clk = 0; int dial_delay_movement = 0; int start_line = 0; //********** start of arduino DDS VFO control program ********* //This function will write a 4 byte (32bit) long to the eeprom at //the specified address to address + 3. void EEPROMWritelong(int address, long value) { //Decomposition from a long to 4 bytes by using bitshift. //One = Most significant -> Four = Least significant byte byte four = (value & 0xFF); byte three = ((value >> 8) & 0xFF); byte two = ((value >> 16) & 0xFF); byte one = ((value >> 24) & 0xFF); //Write the 4 bytes into the eeprom memory. EEPROM.write(address, four); EEPROM.write(address + 1, three); EEPROM.write(address + 2, two); EEPROM.write(address + 3, one); } //This function will return a 4 byte (32bit) long from the eeprom //at the specified address to address + 3. long EEPROMReadlong(long address) { //Read the 4 bytes from the eeprom memory. long four = EEPROM.read(address); long three = EEPROM.read(address + 1); long two = EEPROM.read(address + 2); long one = EEPROM.read(address + 3); //Return the recomposed long by using bitshift. return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF); } void setup() { Serial.begin(9600); // error correction in program code use only pinMode(clk_location, INPUT); // pin 2 rotary encoder pinMode(dt_location, INPUT); // pin 3 rotary encoder pinMode(cw_key_ptt, INPUT); // pin 4 morse key pinMode(vfo_step_DA, INPUT); // pin 5 logic pin d0 for vfo step change pinMode(vfo_step_DB, INPUT); // pin 6 logic pin d1 for vfo step change pinMode(band_change_DA, INPUT); // pin 7 logic pin d0 for band change pinMode(band_change_DB, INPUT); // pin 8 logic pin d1 for band change pinMode(CLOCK, OUTPUT); // pin 9 W_CLK = connect to AD9850 module word load clock pin (CLK) pinMode(LOAD, OUTPUT); // pin 10 FQ_UD = connect to freq update pin (FQ_UD) pinMode(DATA, OUTPUT); // pin 11 DATA = connect to serial data load pin (AD9850 D7 = DATA) pinMode(RESET, OUTPUT); // pin 12 RESET = connect to DDS reset line pinMode(carrier_mode_sense, INPUT); // pin 13 CW over-ride switch on low active AD9850_reset(); AD9850_init(); // ********* start up display messages ************ Wire.begin(); lcd.begin (16,2); // <<-- our LCD is a 20x4, change for your LCD if needed // LCD Backlight ON lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); lcd.home(); // go home on LCD lcd.setCursor(0,0); // first line of display lcd.print("HF added band"); lcd.setCursor(0,1); lcd.print("Digital VFO"); delay(1500); lcd.clear(); lcd.home(); lcd.setCursor(0,0); // first line of display lcd.print("program code by"); lcd.setCursor(0,1); lcd.print("Alastair GW0AJU"); delay(1500); lcd.clear(); lcd.home(); //*************** initialise the memory on first time boot up ***************** address = 0; long pwr_up_LF_metres = 136500; //Starting at the first byte on the eeprom. start_freq = EEPROMReadlong(address); if (start_freq > 135700 && start_freq < 137800) { carrier_centre = EEPROMReadlong(address); } else { EEPROMWritelong(address, pwr_up_LF_metres); address = 0; carrier_centre = EEPROMReadlong(address); } address = 4; long pwr_up_MF_metre = 476000; //Starting at the first byte on the eeprom. start_freq = EEPROMReadlong(address); if (start_freq > 472000 && start_freq < 479000) { carrier_centre = EEPROMReadlong(address); } else { EEPROMWritelong(address, pwr_up_MF_metre); address = 4; carrier_centre = EEPROMReadlong(address); } address = 8; long pwr_up_sixty_metre = 5262000; //Starting at the first byte on the eeprom. start_freq = EEPROMReadlong(address); if (start_freq > 5258500 && start_freq < 5406500) { carrier_centre = EEPROMReadlong(address); } else { EEPROMWritelong(address, pwr_up_sixty_metre); address = 8; carrier_centre = EEPROMReadlong(address); } //***************** last used memory recall and carrier mode starup ****************** CW_LSB = digitalRead(carrier_mode_sense); BDA = digitalRead(band_change_DA); BDB = digitalRead(band_change_DB); if (BDA == HIGH && BDB == LOW && CW_LSB == LOW) // 30metres band { address = 0; carrier_centre = EEPROMReadlong(address); lcd.home(); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("LF "); // set message for band operation lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("CW"); Wire.beginTransmission(PCF); Wire.write(B00110110); // LF , CW Wire.endTransmission(); } else if (BDA == HIGH && BDB == LOW && CW_LSB == HIGH) { address = 0; carrier_centre = EEPROMReadlong(address); lcd.home(); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("LF "); // set message for band operation lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("USB"); Wire.beginTransmission(PCF); Wire.write(B00101110); // LF , USB Wire.endTransmission(); } if (BDA == HIGH && BDB == HIGH && CW_LSB == LOW) // 20metre band { address = 4; carrier_centre = EEPROMReadlong(address); lcd.home(); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("600m"); // set message for band operation lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("CW"); Wire.beginTransmission(PCF); Wire.write(B00110101); // 600m , CW Wire.endTransmission(); } else if (BDA == HIGH && BDB == HIGH && CW_LSB == HIGH) { address = 4; carrier_centre = EEPROMReadlong(address); lcd.home(); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("600m "); // set message for band operation lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("USB"); Wire.beginTransmission(PCF); Wire.write(B00101101); // 600m , USB Wire.endTransmission(); } if (BDA == LOW && BDB == HIGH && CW_LSB == LOW) // 17metre band { address = 8; carrier_centre = EEPROMReadlong(address); lcd.home(); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("60m "); // set message for band operation lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("CW"); Wire.beginTransmission(PCF); Wire.write(B00110011); // 60m , CW Wire.endTransmission(); } else if (BDA == LOW && BDB == HIGH && CW_LSB == HIGH) { address = 8; carrier_centre = EEPROMReadlong(address); lcd.home(); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("60m "); // set message for band operation lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("USB"); Wire.beginTransmission(PCF); Wire.write(B00101011); // 60m , USB Wire.endTransmission(); } vfo_step_change(); // routine for change the vfo step 10Hz, 100Hz, or 1KHz dial_post = carrier_centre; // display show centre channel frequency of Radio set operation lcd.home(); lcd.setCursor(0,0); lcd.print("vfo="); lcd.setCursor(5,0); lcd.print(" "); lcd.setCursor(5,0); lcd.print(dial_post/1E3,3); lcd.setCursor(13,0); lcd.print("KHz"); band_change(); // start up check of band in use at stsrt up point of arduino dial_frequency(); } //************* void loop *********************** void loop() { radio_panel_change(); // detect vahnge in ham band or carrier mode getEncoderTurn(); // rotary encoder sub-routine for rotary movement of dial setting } //*************** start of program code sub-routines **************** //***************** radio panel change ************** void radio_panel_change() { HDA = digitalRead(vfo_step_DA); HDB = digitalRead(vfo_step_DB); BDC = digitalRead(band_change_DA); // old state of switch BDD = digitalRead(band_change_DB); // old state of switch test_cw_key_ptt = digitalRead(cw_key_ptt); // old state of cw_key_ptt check_cw_key_ptt = test_cw_key_ptt; CW_LSB = digitalRead(carrier_mode_sense); check_CW_LSB = CW_LSB; if ( BDC != BDA || BDD != BDB ) // ham band change { BDA = BDC; BDB = BDD; band_change(); panel_display(); } if ( HDA != DA || HDB != DB ) // vfo step change { DA = HDA; DB = HDB; vfo_step_change(); } if ( check_cw_key_ptt == LOW ) // ptt and morse key change { tx(); panel_display(); } if ( check_cw_key_ptt == HIGH ) // ptt and morse key change { rx(); panel_display(); } if ( check_CW_LSB != test_CW_LSB ) // carrier mode change { test_CW_LSB = check_CW_LSB; carrier_mode(); panel_display(); } } // *************** LED front panel of radio indication routine ******************* void panel_display() { //**************************** LF indication ************************* if ( BDA == HIGH && BDB == LOW && check_cw_key_ptt == HIGH && CW_LSB == HIGH) // 30m, Rx, USB { Wire.beginTransmission(PCF); Wire.write(B00101110); // LF, Rx, USB Wire.endTransmission(); } if ( BDA == HIGH && BDB == LOW && check_cw_key_ptt == LOW && CW_LSB == HIGH) //300m, Tx, USB { Wire.beginTransmission(PCF); Wire.write(B00001110); //LF, Tx, USB Wire.endTransmission(); } if ( BDA == HIGH && BDB == LOW && check_cw_key_ptt == HIGH && CW_LSB == LOW) // 30m, Rx, CW { Wire.beginTransmission(PCF); Wire.write(B00110110); // LF, Rx, CW Wire.endTransmission(); } if ( BDA == HIGH && BDB == LOW && check_cw_key_ptt == LOW && CW_LSB == LOW) // 30m, Rx, CW { Wire.beginTransmission(PCF); Wire.write(B00010110); // LF, Tx, CW Wire.endTransmission(); } //*********************** 600m indication ******************************** if ( BDA == HIGH && BDB == HIGH && check_cw_key_ptt == HIGH && CW_LSB == HIGH) // 20m, Rx, USB { Wire.beginTransmission(PCF); Wire.write(B00101101); // 600m, Rx, USB Wire.endTransmission(); } if ( BDA == HIGH && BDB == HIGH && check_cw_key_ptt == LOW && CW_LSB == HIGH) // 20m, Tx, USB { Wire.beginTransmission(PCF); Wire.write(B00001101); // 600m, Tx, USB Wire.endTransmission(); } if ( BDA == HIGH && BDB == HIGH && check_cw_key_ptt == HIGH && CW_LSB == LOW) // 20m, Rx, CW { Wire.beginTransmission(PCF); Wire.write(B00110101); // 600m, Rx, CW Wire.endTransmission(); } if ( BDA == HIGH && BDB == HIGH && check_cw_key_ptt == LOW && CW_LSB == LOW) // 20m, Rx, CW { Wire.beginTransmission(PCF); Wire.write(B00010101); // 600m, Tx, CW Wire.endTransmission(); } //*************************** 60m indication *************************************** if ( BDA == LOW && BDB == HIGH && check_cw_key_ptt == HIGH && CW_LSB == HIGH) // 17m, Rx, USB { Wire.beginTransmission(PCF); Wire.write(B00101011); // 60m, Rx, USB Wire.endTransmission(); } if ( BDA == LOW && BDB == HIGH && check_cw_key_ptt == LOW && CW_LSB == HIGH) // 17m, Tx, USB { Wire.beginTransmission(PCF); Wire.write(B00001011); // 60m, Tx, USB Wire.endTransmission(); } if ( BDA == LOW && BDB == HIGH && check_cw_key_ptt == HIGH && CW_LSB == LOW) // 17m, Rx, CW { Wire.beginTransmission(PCF); Wire.write(B00110011); // 60m, Rx, CW Wire.endTransmission(); } if ( BDA == LOW && BDB == HIGH && check_cw_key_ptt == LOW && CW_LSB == LOW) // 17m, Rx, CW { Wire.beginTransmission(PCF); Wire.write(B00010011); // 60m, Tx, CW Wire.endTransmission(); } } //*************** receive and transmit control routines ********* void rx() { check_cw_key_ptt = digitalRead(cw_key_ptt); // old state of cw_key_ptt CW_LSB = digitalRead(carrier_mode_sense); if ( check_cw_key_ptt == HIGH && CW_LSB == HIGH ) { IF_LO = (9E6 + (carrier_centre)); // Rx high L.O. output for 9MHz I.F. USB if (last_Set != IF_LO) { sendFrequency(IF_LO); last_Set = IF_LO; } } if ( check_cw_key_ptt == HIGH && CW_LSB == LOW ) { IF_LO = 9E6 + (carrier_centre); // Rx high L.O. output for 9MHz I.F. CW if (last_Set != IF_LO) { sendFrequency(IF_LO); last_Set = IF_LO; } } } void tx() { if ( check_cw_key_ptt == LOW && CW_LSB == HIGH ) { IF_LO = (9E6 + (carrier_centre)); // Rx high L.O. output for 9MHz I.F. USB if (last_Set != IF_LO) { sendFrequency(IF_LO); last_Set = IF_LO; } } if ( check_cw_key_ptt == LOW && CW_LSB == LOW ) { IF_LO = (carrier_centre); // Rx L.O. output for 9MHz I.F. CW if (last_Set != IF_LO) { sendFrequency(IF_LO); last_Set = IF_LO; } } } //***************************** carrier mode change **************************** void carrier_mode() { if (CW_LSB == HIGH )// usb { IF_LO = (9E6 - (carrier_centre)); // Rx L.O. output for 9MHz I.F. USB sendFrequency(IF_LO); lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("USB"); } else // cw { IF_LO = (9E6 - (carrier_centre)); // Rx L.O. output for 9MHz I.F. CW sendFrequency(IF_LO); lcd.setCursor(6,1); lcd.print(" "); lcd.setCursor(6,1); lcd.print("CW"); } dial_post = carrier_centre; // display show centre channel frequency of Radio set operation lcd.home(); lcd.setCursor(0,0); lcd.print("vfo="); lcd.setCursor(5,0); lcd.print(" "); lcd.setCursor(5,0); lcd.print(dial_post/1E3,3); lcd.setCursor(13,0); lcd.print("KHz"); } //*********************** band cahnge ********************************* void band_change() { // ********************** LF ham band ******************** if (BDA == HIGH && BDB == LOW ) //LF band { address = 0; carrier_centre = EEPROMReadlong(address); sendFrequency(carrier_centre); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("LF "); } //********************** MF ham band ************************** if (BDA == HIGH && BDB == HIGH ) // MF / 600metre band { address = 4; carrier_centre = EEPROMReadlong(address); sendFrequency(carrier_centre); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("600m"); } //************************ 60metre ham band *********************** if (BDA == LOW && BDB == HIGH ) // 60metre band { address = 8; carrier_centre = EEPROMReadlong(address); sendFrequency(carrier_centre); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print("60m "); } dial_frequency(); } //************** dial vfo step change ****************** void vfo_step_change() { if (DA == HIGH && DB == LOW) { dial_step = 1000; // 1KHz vfo increment dial_delay_movement = 5; lcd.setCursor(10,1); lcd.print(" "); lcd.setCursor(12,1); lcd.print("1KHz"); } else if (DA == HIGH && DB == HIGH) { dial_step = 100; // 100Hz vfo increment dial_delay_movement = 4; lcd.setCursor(10,1); lcd.print(" "); lcd.setCursor(11,1); lcd.print("100Hz"); } else if (DA == LOW && DB == HIGH) { dial_step = 10; // 10Hz vfo increment dial_delay_movement = 3; lcd.setCursor(10,1); lcd.print(" "); lcd.setCursor(12,1); lcd.print("10Hz"); } } //******** detection of rotary dial movement and change of carrier frequency ************ void getEncoderTurn() // rotary encoder sub-routine for rotary movement { if (digitalRead(clk_location) == HIGH) // anti clock wise direction { dial_delay_clk = 0; delay(3); if (digitalRead(clk_location) == LOW) { dial_delay_anti_clk = dial_delay_anti_clk + 1; if ( dial_delay_anti_clk == dial_delay_movement ) // change the number 18 to a higher value for smoother operation { result = -1; // down band movement carrier_centre = carrier_centre + (result * dial_step); dial_post = carrier_centre; lcd.setCursor(5,0); lcd.print(" "); lcd.setCursor(5,0); lcd.print(dial_post/1E3,3); lcd.setCursor(13,0); lcd.print("KHz"); dial_delay_anti_clk = 0; } } } else if (digitalRead(dt_location) == HIGH) // clock wise direction { dial_delay_anti_clk = 0; delay(3); if (digitalRead(dt_location) == LOW) { dial_delay_clk = dial_delay_clk + 1; if ( dial_delay_clk == dial_delay_movement ) // change the number 18 to a higher value for smoother operation { result = 1; // up band movement carrier_centre = carrier_centre + (result * dial_step); dial_post = carrier_centre; lcd.setCursor(5,0); lcd.print(" "); lcd.setCursor(5,0); lcd.print(dial_post/1E3,3); lcd.setCursor(13,0); lcd.print("KHz"); dial_delay_clk = 0; } } } if (BDA == HIGH && BDB == LOW) // LF { address = 0; EEPROMWritelong(address, carrier_centre); } else if (BDA == HIGH && BDB == HIGH) // 600m { address = 4; EEPROMWritelong(address, carrier_centre); } else if (BDA == LOW && BDB == HIGH) // 60m { address = 8; EEPROMWritelong(address, carrier_centre); } } //********************* display dial frequency ************* void dial_frequency() { dial_post = carrier_centre; // display show centre channel frequency of Radio set operation lcd.home(); lcd.setCursor(0,0); lcd.print("vfo="); lcd.setCursor(5,0); lcd.print(" "); lcd.setCursor(5,0); lcd.print(dial_post/1E3,3); lcd.setCursor(13,0); lcd.print("KHz"); } // **************************************************************************************** // ************* frequency VFO control from dial change ***************** void AD9850_reset() { //reset sequence is: // CLOCK & LOAD = LOW // Pulse RESET high for a few uS (use 5 uS here) // Pulse CLOCK high for a few uS (use 5 uS here) // Set DATA to ZERO and pulse LOAD for a few uS (use 5 uS here) // data sheet diagrams show only RESET and CLOCK being used to reset the device, but I see no output unless I also // toggle the LOAD line here. digitalWrite(CLOCK, LOW); digitalWrite(LOAD, LOW); digitalWrite(RESET, LOW); delayMicroseconds(5); digitalWrite(RESET, HIGH); //pulse RESET delayMicroseconds(5); digitalWrite(RESET, LOW); delayMicroseconds(5); digitalWrite(CLOCK, LOW); delayMicroseconds(5); digitalWrite(CLOCK, HIGH); //pulse CLOCK delayMicroseconds(5); digitalWrite(CLOCK, LOW); delayMicroseconds(5); digitalWrite(DATA, LOW); //make sure DATA pin is LOW digitalWrite(LOAD, LOW); delayMicroseconds(5); digitalWrite(LOAD, HIGH); //pulse LOAD delayMicroseconds(5); digitalWrite(LOAD, LOW); // Chip is RESET now } void AD9850_init() { digitalWrite(RESET, LOW); digitalWrite(CLOCK, LOW); digitalWrite(LOAD, LOW); digitalWrite(DATA, LOW); } // *********** frequency control of the AD9850 DDS device for TX / Rx vfo ********* void sendFrequency(unsigned long frequency) { unsigned long tuning_word = (frequency * pow(2, 32)) / DDS_CLOCK; digitalWrite (LOAD, LOW); shiftOut(DATA, CLOCK, LSBFIRST, tuning_word); shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 8); shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 16); shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 24); shiftOut(DATA, CLOCK, LSBFIRST, 0x00); digitalWrite(LOAD, HIGH); } //************************************************************************** //************ hardware test for the panel mechanical switching gear ******** // put the " button_test() " in the "void loop()" as the only sub-routine to test the switches. void button_test() { BDA = digitalRead(band_change_DA); BDB = digitalRead(band_change_DB); if (BDA == HIGH) { lcd.setCursor(0,0); lcd.print("BDA=1"); } else { lcd.setCursor(0,0); lcd.print("BDA=0"); } if (BDB == HIGH) { lcd.setCursor(0,1); lcd.print("BDB=1"); } else { lcd.setCursor(0,1); lcd.print("BDB=0"); } DA = digitalRead(vfo_step_DA); DB = digitalRead(vfo_step_DB); if (DA == HIGH) { lcd.setCursor(6,0); lcd.print("DA=1"); } else { lcd.setCursor(6,0); lcd.print("DA=0"); } if (DB == HIGH) { lcd.setCursor(6,1); lcd.print("DB=1"); } else { lcd.setCursor(6,1); lcd.print("DB=0"); } int CC = digitalRead(carrier_mode_sense); if (CC == HIGH) { lcd.setCursor(11,0); lcd.print("CC=1"); } else { lcd.setCursor(11,0); lcd.print("CC=0"); } } //**************************** end of program code ****************************