An ideal tool for connecting your IC-706 or IC-7000 to more than one antenna and having them switched automatically. You could as well use it to drive a 5 bands BPF ... or develop an antenna tuning unit, a magnetic loop variable condenser stepper motor drive etc ...
This sketch will readout on a 2x 16 characters LCD display the frequency of any ICOM transceiver by reading the CAT line (the device acting as a listener only, the transceiver is set to 'CAT TRANSCEIVE' mode to broadcast data) and switch 5 + 1 antenna's (or band pass filters... ) according to band.
Up to five digital outputs are to be interfaced with relays, the sixth position is 'no relay energized'. CAT activity will be displayed in the top row, on the right side (a small 'c' will show up when valid CAT data is received). I used 9k6 as my SPE power amplifier runs at 9k6 as well. The ARDUINO board is simply put in parallel with it.
The matrix can be programmed with 2 push-buttons (scroll left or right), the values are permanently stored in EEPROM after a small delay, once the choice is definitive (this to avoid too many write cycles to EEPROM). When the new setting is memorized, a small 'M' will briefly show up on the second line at right. The switching combination can be different for RX and TX (reading the PTT line, it will select the right antenna). In program mode, you have to depress a push button which indicates this is the 'TX' antenna. In TX mode, no antenna can be changed / programmed with the scroll buttons.
All the settings programmed in the matrix can be cleared if you depress button scroll buttons at startup / reboot.
Read More for arduino code or visit http://www.qsl.net/on7eq/projects/arduino_ant_matrix.htm
Reference: ( http://www.qsl.net/on7eq/projects/arduino_ant_matrix.htm )
Read More for arduino code or visit http://www.qsl.net/on7eq/projects/arduino_ant_matrix.htm
Reference: ( http://www.qsl.net/on7eq/projects/arduino_ant_matrix.htm )
// This sketch will decode ICOM CAT frequency information
// and switch antenna's according to preset (memorized)
// values. RX and TX antenna's can be different.
// Instead of antennas, bandfilters band be selected
// by ON7EQ November 2011
// With thx to Jeff Smith VE1ZAC from which some code was inspired.
// include EEPROM write - required to memorize antenna / band config.
#include <EEPROM.h>
// Serial NewSoftSerial is required, as standard Serial is conflicting with LCD
#include <NewSoftSerial.h>
// Use pins 2 and 3 to talk to the CAT. 2 is the RX pin, 0 is the TX pin
// this is a dummy pin, as no TX is performed
// Connect the RX pin to the CAT output through a 4k7 resistor.
// IMPORTANT : select on the rig in the menu
// CAT 'TRANSCEIVE' (ON)
// to implement broadcast of displayed frequency!
NewSoftSerial mySerial = NewSoftSerial(2, 0);
// Pin Variables
#define A1Pin (13) // Pin for Antenna 1
#define A2Pin (6) // Pin for Antenna 2
#define A3Pin (5) // Pin for Antenna 3
#define A4Pin (4) // Pin for Antenna 4
#define A5Pin (3) // Pin for Antenna 5
#define LeftPin (A0) // Pin for 'left scroll select' - +5v with 4k7 pullup, GND when depressed
#define RightPin (A1) // Pin for 'right scroll select' - idem
#define TXsimPin (A2) // Pin for 'TX simulator' - idem
#define PTTPin (A5) // PTT input pin. 0 = TX, 1 = RX
#define TonePin (1) // Pin for Beeper out
// Define band edges, some out of band allowed for antenna SWR curves
#define High6 (52025)
#define Low6 (49975)
#define High10 (29750)
#define Low10 (27975)
#define High12 (25040)
#define Low12 (24840)
#define High15 (21475)
#define Low15 (20975)
#define High17 (18200)
#define Low17 (18018)
#define High20 (14375)
#define Low20 (13975)
#define High30 (10175)
#define Low30 (10075)
#define High40 (7450)
#define Low40 (6975)
#define High80 (3850)
#define Low80 (3475)
#define High160 (2050)
#define Low160 (1760)
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
/*
* LCD RS pin to digital pin 7
* LCD Enable pin to digital pin 8
* LCD D4 pin to digital pin 9
* LCD D5 pin to digital pin 10
* LCD D6 pin to digital pin 11
* LCD D7 pin to digital pin 12
* LCD R/W pin to ground
* GND to LCD VO pin (pin 3) (contrast)
*/
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int buffget[10] ; // the receive buffer
int unsigned long MHZ = 0;
int unsigned long KHZ = 0;
int unsigned long HZ = 0;
int unsigned long QRG = 0;
int unsigned long QRGcomp = 0;
int unsigned memotime = (1000); // delay (ms) before selected antenna is memorized. Must be > 300 !
byte BAND =(0); // the actual band we are on
byte oldBAND = (0);
byte RXantenna = (1); // the default RX antenna for the band
byte TXantenna = (1); // the default RX antenna for the band
byte TXstatus = (0); // 0 = RX mode, 1 = TX mode
byte oldTXstatus = (0); // 0 = RX mode, 1 = TX mode
byte buttonpressed = (0); // 0 = no button pressed
byte simbuttonpressed = (0);
// LCD specific characters 'C' for CAT activity indication
byte cat [8] = {
B00000,
B00000,
B01110,
B01000,
B01110,
B00000,
B00000,
};
// Antenna indicator Style 1
byte accoright [8] = {
B00000,
B11000,
B01100,
B01100,
B01100,
B11000,
B00000,
};
byte accoleft [8] = {
B00000,
B00011,
B00110,
B00110,
B00110,
B00011,
B00000,
};
byte memory [8] = {
B00000,
B00000,
B11011,
B10101,
B10001,
B00000,
B00000,
};
// some control variables
int i;
int incoming;
int unsigned long DisplayTime = 0; // timer display refresh
int unsigned long ButtonTime = 0; // Timer button depressed
byte memorize = (0); // if = 1, them position to be memorzied
////////////// This loop run once on start up /////////////////
void setup() {
//set up output pins antenna control & beeper
pinMode(A1Pin, OUTPUT);
pinMode(A2Pin, OUTPUT);
pinMode(A3Pin, OUTPUT);
pinMode(A4Pin, OUTPUT);
pinMode(A5Pin, OUTPUT);
pinMode(TonePin, OUTPUT);
digitalWrite(A1Pin,0) ;
digitalWrite(A2Pin,0) ;
digitalWrite(A3Pin,0) ;
digitalWrite(A4Pin,0) ;
digitalWrite(A5Pin,0) ;
digitalWrite(TonePin,0) ;
// create LCD characters
lcd.createChar(0, cat);
lcd.createChar(1, accoleft);
lcd.createChar(2, accoright);
lcd.createChar(3, memory);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.clear();
// Print a message to the LCD.
lcd.setCursor(0, 0);
lcd.print(" ON7EQ Icom CAT");
lcd.setCursor(0, 1);
lcd.print(" v1.08 Nov2011");
delay (1000);
// RESET if SCROLL left & right buttons depressed at startup !
if ((analogRead(LeftPin)<512) and (analogRead(RightPin)<512)) Reset ();
// Startup Beep
tone(TonePin,1200);
delay(150);
tone(TonePin,1600);
delay (150);
tone(TonePin,2000);
delay (150);
noTone (TonePin);
delay (1000);
// print screen template
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("QRG --.---- MHz ");
lcd.setCursor(0, 1);
lcd.print("Bnd ");
clearindicator ();
// RXindicator ();
mySerial.begin(9600); // CAT running at 9k6
}
////////////////////////// MAIN LOOP ////////////////////////////////////
void loop() {
listen:
delay(1); // reduced from 50 !
next:
// detect if TX simulation switch depressed
if ((analogRead(TXsimPin)<512) and (simbuttonpressed ==0) and (TXstatus == 0)) { // TX simulation depressed while in RX
simbuttonpressed = 1;
lcd.setCursor(0, 1);
lcd.print("TX ");
clearindicator (); // always to do, before RX and TX change
TXindicator (); // We are displaying TX condition
}
if ((analogRead(TXsimPin)>512) and (simbuttonpressed ==1) ) { // TX simulation released
simbuttonpressed = 0;
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
if (BAND == 0) lcd.print("Man");
clearindicator (); // always to do, before RX and TX change
RXindicator (); // We are displaying RX condition
}
// detect if PTT low (Transmit status)
if ((analogRead(PTTPin)<128) and (TXstatus == 0)) { // We go into TX mode
TXstatus = 1;
lcd.setCursor(0, 1);
lcd.print("TX ");
clearindicator (); // always to do, before RX and TX change
TXindicator (); // We are displaying & setting TX condition
}
if ((analogRead(PTTPin)>256) and (TXstatus ==1 )) { // We go into RX with some hysterisis
TXstatus = 0;
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
if (BAND == 0) lcd.print("Man");
clearindicator (); // always to do, before RX and TX change
RXindicator (); // We are displaying & setting RX condition
}
/* DEBUG : test update cycle
tone(TonePin,2000);
delay (5);
noTone (TonePin);
*/
if (TXstatus == 0) ReadButtons (); // no reprogramming when really in TX mode !
if ((millis() - DisplayTime) > 350) { // refresh CAT indicator
lcd.setCursor(15, 0);
lcd.print(" ");
}
if (mySerial.available() > 0) {
incoming = mySerial.read();
if (incoming == 254) { // 1st byte is an FE look for an FE to start
goto start;
}
goto next;
}
start:
buffget[0] = 0;
// delay(1);
for ( i=0;i<10;i++) { // get next 10 bytes
if(mySerial.available() > 0) {
buffget[i]=mySerial.read(); // load buffget with next 10 characters
delay(2); //delay 1 ms if true, time for buffer fill
}
}
delay (10); // delay is required to process buffer, do not remove !
if (buffget[0] == 254) { // again FE , as 2nd character ?
goto next1;
} // yes, now do '00' test
goto listen; // wrong array, get another
next1:
if ((buffget[3] == 0) or (buffget[3] == 3) or (buffget[3] == 5) ){ // check to see if 4th char is 00 or 03 or 05 (=frequency)
goto next2;
} // detected, goto next2
/*
if ((buffget[3] == 28) and (buffget[4] == 0)) TXstatus = 0; // RX mode detect, if set by CAT
if ((buffget[3] == 28) and (buffget[4] == 1)) TXstatus = 1; // TX mode detect, if set by CAT
*/
goto listen; // wrong array, get another
next2:
// Check for last byte
if(buffget[9] == 253 ){ // look for FD at end of array
goto frequency;
} // if FD detected, goto frequency
goto listen; // wrong command
frequency: // we have frequency array on hand
MHZ = (buffget[7]);
MHZ = MHZ - (((MHZ/16) * 6)); // Transform bytes ICOM CAT
if (MHZ >= 100) goto listen; // wrong byte
KHZ = buffget[6];
KHZ = KHZ - (((KHZ/16) * 6)); // Transform bytes ICOM CAT
if (KHZ >= 100) goto listen; // wrong byte
HZ = buffget[5];
HZ = HZ - (((HZ/16) * 6)); // Transform bytes ICOM CAT
if (HZ >= 100) goto listen; // wrong byte
QRG = ((MHZ * 10000) + (KHZ * 100) + (HZ * 1)); // QRG variable stores frequency in MMkkkH format
// Print frequency
lcd.setCursor(4, 0);
if (QRG < 100000) lcd.print(" ");
lcd.print(QRG/10000,DEC);
lcd.print(".");
if (QRG%10000 < 1000 ) lcd.print("0");
if (QRG%10000 < 100 ) lcd.print("0");
if (QRG%10000 < 10 ) lcd.print("0");
lcd.print(QRG%10000,DEC);
lcd.print(" MHz");
lcd.write(0); // print the CAT activity indicator
// set display timer
DisplayTime = millis();
// Which band ?
QRGcomp = QRG / 10;
BAND = 0; // default band = will generate error
if ((QRGcomp < High6) and (QRGcomp > Low6)) BAND = 6;
if ((QRGcomp < High10) and (QRGcomp > Low10)) BAND = 10;
if ((QRGcomp < High12) and (QRGcomp > Low12)) BAND = 12;
if ((QRGcomp < High15) and (QRGcomp > Low15)) BAND = 15;
if ((QRGcomp < High17) and (QRGcomp > Low17)) BAND = 17;
if ((QRGcomp < High20) and (QRGcomp > Low20)) BAND = 20;
if ((QRGcomp < High30) and (QRGcomp > Low30)) BAND = 30;
if ((QRGcomp < High40) and (QRGcomp > Low40)) BAND = 40;
if ((QRGcomp < High80) and (QRGcomp > Low80)) BAND = 80;
if ((QRGcomp < High160) and (QRGcomp > Low160)) BAND = 160;
if (BAND == 0) {
clearindicator (); // We are not on standard band, clear antenna's
}
if (memorize == 1) goto finish; // antenna position must be memorized, do not read what is now in memory
// Check band changed
if (BAND == oldBAND) goto finish; // no bandchange
///// Band is changed ! /////
oldBAND = BAND;
// now process antenna change
// read value from EEPROM
if (BAND == 0) {
lcd.setCursor(0, 1);
lcd.print(" ");
goto finish; // no need to read
}
// display band
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
ReadEEPROMvalues ();
//Show in display
clearindicator (); // always to do, before RX and TX change
RXindicator (); // We are assuming in RX mode while changing band
// Music Maestro
tone(TonePin,1600);
delay(150);
tone(TonePin,1200);
delay (150);
noTone (TonePin);
goto finish;
// end process antenna change //
finish:
delay(0);
goto listen;
}
///////////////// SUBROUTINES ///////////////////
void clearindicator () { // Clear all antenna
lcd.setCursor(4, 1);
lcd.print(" 1 2 3 4 5 ");
digitalWrite(A1Pin,0) ;
digitalWrite(A2Pin,0) ;
digitalWrite(A3Pin,0) ;
digitalWrite(A4Pin,0) ;
digitalWrite(A5Pin,0) ;
}
/////////////////////////////////////////////////////////////////////
void RXindicator () { // Process selected RX antenna
if (RXantenna == 1) {
digitalWrite(A1Pin,1) ;
lcd.setCursor(4, 1);
lcd.write(1);
lcd.setCursor(6, 1);
lcd.write(2);
}
if (RXantenna == 2) {
digitalWrite(A2Pin,1) ;
lcd.setCursor(6, 1);
lcd.write(1);
lcd.setCursor(8, 1);
lcd.write(2);
}
if (RXantenna == 3) {
digitalWrite(A3Pin,1) ;
lcd.setCursor(8, 1);
lcd.write(1);
lcd.setCursor(10, 1);
lcd.write(2);
}
if (RXantenna == 4) {
digitalWrite(A4Pin,1) ;
lcd.setCursor(10, 1);
lcd.write(1);
lcd.setCursor(12, 1);
lcd.write(2);
}
if (RXantenna == 5) {
digitalWrite(A5Pin,1) ;
lcd.setCursor(12, 1);
lcd.write(1);
lcd.setCursor(14, 1);
lcd.write(2);
}
/* / Check if TX = RX ant
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
if (TXantenna = RXantenna) lcd.print("="); // same RX as TX antenna
*/
}
/////////////////////////////////////////////////////////////////////
void TXindicator () { // Process selected TX antenna
if (TXantenna == 1) {
digitalWrite(A1Pin,1) ;
lcd.setCursor(4, 1);
lcd.write(1);
lcd.setCursor(6, 1);
lcd.write(2);
}
if (TXantenna == 2) {
digitalWrite(A2Pin,1) ;
lcd.setCursor(6, 1);
lcd.write(1);
lcd.setCursor(8, 1);
lcd.write(2);
}
if (TXantenna == 3) {
digitalWrite(A3Pin,1) ;
lcd.setCursor(8, 1);
lcd.write(1);
lcd.setCursor(10, 1);
lcd.write(2);
}
if (TXantenna == 4) {
digitalWrite(A4Pin,1) ;
lcd.setCursor(10, 1);
lcd.write(1);
lcd.setCursor(12, 1);
lcd.write(2);
}
if (TXantenna == 5) {
digitalWrite(A5Pin,1) ;
lcd.setCursor(12, 1);
lcd.write(1);
lcd.setCursor(14, 1);
lcd.write(2);
}
/* Check if TX = RX ant
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
if (TXantenna = RXantenna) lcd.print("="); // same RX as TX antenna
*/
}
/////////////////////////////////////////////////////////////////////
void ReadEEPROMvalues () { // Read Antenna's stored in EEPROM
if (BAND == 6) RXantenna = EEPROM.read(6);
if (BAND == 6) TXantenna = EEPROM.read(7);
if (BAND == 10) RXantenna = EEPROM.read(10);
if (BAND == 10) TXantenna = EEPROM.read(11);
if (BAND == 12) RXantenna = EEPROM.read(12);
if (BAND == 12) TXantenna = EEPROM.read(13);
if (BAND == 15) RXantenna = EEPROM.read(15);
if (BAND == 15) TXantenna = EEPROM.read(16);
if (BAND == 17) RXantenna = EEPROM.read(17);
if (BAND == 17) TXantenna = EEPROM.read(18);
if (BAND == 20) RXantenna = EEPROM.read(20);
if (BAND == 20) TXantenna = EEPROM.read(21);
if (BAND == 30) RXantenna = EEPROM.read(30);
if (BAND == 30) TXantenna = EEPROM.read(31);
if (BAND == 40) RXantenna = EEPROM.read(40);
if (BAND == 40) TXantenna = EEPROM.read(41);
if (BAND == 80) RXantenna = EEPROM.read(80);
if (BAND == 80) TXantenna = EEPROM.read(81);
if (BAND == 160) RXantenna = EEPROM.read(160);
if (BAND == 160) TXantenna = EEPROM.read(161);
}
/////////////////////////////////////////////////////////////////////
void WriteEEPROMvalues () { // Write Antenna's in EEPROM
if (BAND == 6) EEPROM.write(6, RXantenna);
if (BAND == 6) EEPROM.write(7, TXantenna);
if (BAND == 10) EEPROM.write(10, RXantenna);
if (BAND == 10) EEPROM.write(11, TXantenna);
if (BAND == 12) EEPROM.write(12, RXantenna);
if (BAND == 12) EEPROM.write(13, TXantenna);
if (BAND == 15) EEPROM.write(15, RXantenna);
if (BAND == 15) EEPROM.write(16, TXantenna);
if (BAND == 17) EEPROM.write(17, RXantenna);
if (BAND == 17) EEPROM.write(18, TXantenna);
if (BAND == 20) EEPROM.write(20, RXantenna);
if (BAND == 20) EEPROM.write(21, TXantenna);
if (BAND == 30) EEPROM.write(30, RXantenna);
if (BAND == 30) EEPROM.write(31, TXantenna);
if (BAND == 40) EEPROM.write(40, RXantenna);
if (BAND == 40) EEPROM.write(41, TXantenna);
if (BAND == 80) EEPROM.write(80, RXantenna);
if (BAND == 80) EEPROM.write(81, TXantenna);
if (BAND == 160) EEPROM.write(160, RXantenna);
if (BAND == 160) EEPROM.write(161, TXantenna);
}
/////////////////////////////////////////////////////////////////////
void Reset() { // RESET memory in EEPROM
lcd.setCursor(0, 1);
lcd.print(" HOLD TO RESET");
// erase all EEPROM contents TODO !!!
delay(2000);
if ((analogRead(LeftPin)<512) and (analogRead(RightPin)<512)) { // Yes, we have a reset !
lcd.setCursor(0, 1);
lcd.print(" RESETTING ... ");
delay(1000);
EEPROM.write(6, 0);
EEPROM.write(7, 0);
EEPROM.write(10, 0);
EEPROM.write(11, 0);
EEPROM.write(12, 0);
EEPROM.write(13, 0);
EEPROM.write(15, 0);
EEPROM.write(16, 0);
EEPROM.write(17, 0);
EEPROM.write(18, 0);
EEPROM.write(20, 0);
EEPROM.write(21, 0);
EEPROM.write(30, 0);
EEPROM.write(31, 0);
EEPROM.write(40, 0);
EEPROM.write(41, 0);
EEPROM.write(80, 0);
EEPROM.write(81, 0);
EEPROM.write(160, 0);
EEPROM.write(161, 0);
lcd.setCursor(0, 1);
lcd.print(" RESTARTING ... ");
delay(1000);
}
}
/////////////////////////////////////////////////////////////////////
void ReadButtons () { // Detect antenna select buttons depressed
if ((analogRead(LeftPin)<512) and (analogRead(TXsimPin)>512) and (buttonpressed == 0)) { // Left button depressed in RX mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
RXantenna = RXantenna -- ;
if ((RXantenna == 0) or (RXantenna > 5 ))RXantenna = (6);
RXindicator ();
}
if ((analogRead(RightPin)<512) and (analogRead(TXsimPin)>512) and (buttonpressed == 0) ) { // Right button depressed in RX mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
RXantenna = RXantenna ++ ;
if (RXantenna >= 7) RXantenna = (1);
RXindicator ();
}
if ((analogRead(LeftPin)<512) and (analogRead(TXsimPin)<512) and (buttonpressed == 0)) { // Left button depressed in TX sim mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
TXantenna = TXantenna -- ;
if ((TXantenna == 0) or (TXantenna > 5 ))TXantenna = (6);
TXindicator ();
}
if ((analogRead(RightPin)<512) and (analogRead(TXsimPin)<512) and (buttonpressed == 0) ) { // Right button depressed in TX sim mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
TXantenna = TXantenna ++ ;
if (TXantenna >= 7) TXantenna = (1);
TXindicator ();
}
// Timers check
if (millis () - ButtonTime > 300) { // Button press detect
buttonpressed = (0);
}
// Memorize antenna
if ((millis () - ButtonTime > memotime) and (memorize == 1)){ // Now memorize antenna after xxx ms
memorize = 0;
lcd.setCursor(15, 1); // print MEMORY indicator
lcd.write(3);
if (TXantenna == 0) TXantenna = RXantenna; // if TX antenna undefined, set TX antenna same as RX antenna
WriteEEPROMvalues ();
tone(TonePin,2000);
delay (150);
noTone (TonePin);
delay (50);
tone(TonePin,2000);
delay (150);
noTone (TonePin);
lcd.setCursor(15, 1); // erase M indicator
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
if (BAND == 0) lcd.print("Man");
}
}
// and switch antenna's according to preset (memorized)
// values. RX and TX antenna's can be different.
// Instead of antennas, bandfilters band be selected
// by ON7EQ November 2011
// With thx to Jeff Smith VE1ZAC from which some code was inspired.
// include EEPROM write - required to memorize antenna / band config.
#include <EEPROM.h>
// Serial NewSoftSerial is required, as standard Serial is conflicting with LCD
#include <NewSoftSerial.h>
// Use pins 2 and 3 to talk to the CAT. 2 is the RX pin, 0 is the TX pin
// this is a dummy pin, as no TX is performed
// Connect the RX pin to the CAT output through a 4k7 resistor.
// IMPORTANT : select on the rig in the menu
// CAT 'TRANSCEIVE' (ON)
// to implement broadcast of displayed frequency!
NewSoftSerial mySerial = NewSoftSerial(2, 0);
// Pin Variables
#define A1Pin (13) // Pin for Antenna 1
#define A2Pin (6) // Pin for Antenna 2
#define A3Pin (5) // Pin for Antenna 3
#define A4Pin (4) // Pin for Antenna 4
#define A5Pin (3) // Pin for Antenna 5
#define LeftPin (A0) // Pin for 'left scroll select' - +5v with 4k7 pullup, GND when depressed
#define RightPin (A1) // Pin for 'right scroll select' - idem
#define TXsimPin (A2) // Pin for 'TX simulator' - idem
#define PTTPin (A5) // PTT input pin. 0 = TX, 1 = RX
#define TonePin (1) // Pin for Beeper out
// Define band edges, some out of band allowed for antenna SWR curves
#define High6 (52025)
#define Low6 (49975)
#define High10 (29750)
#define Low10 (27975)
#define High12 (25040)
#define Low12 (24840)
#define High15 (21475)
#define Low15 (20975)
#define High17 (18200)
#define Low17 (18018)
#define High20 (14375)
#define Low20 (13975)
#define High30 (10175)
#define Low30 (10075)
#define High40 (7450)
#define Low40 (6975)
#define High80 (3850)
#define Low80 (3475)
#define High160 (2050)
#define Low160 (1760)
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
/*
* LCD RS pin to digital pin 7
* LCD Enable pin to digital pin 8
* LCD D4 pin to digital pin 9
* LCD D5 pin to digital pin 10
* LCD D6 pin to digital pin 11
* LCD D7 pin to digital pin 12
* LCD R/W pin to ground
* GND to LCD VO pin (pin 3) (contrast)
*/
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int buffget[10] ; // the receive buffer
int unsigned long MHZ = 0;
int unsigned long KHZ = 0;
int unsigned long HZ = 0;
int unsigned long QRG = 0;
int unsigned long QRGcomp = 0;
int unsigned memotime = (1000); // delay (ms) before selected antenna is memorized. Must be > 300 !
byte BAND =(0); // the actual band we are on
byte oldBAND = (0);
byte RXantenna = (1); // the default RX antenna for the band
byte TXantenna = (1); // the default RX antenna for the band
byte TXstatus = (0); // 0 = RX mode, 1 = TX mode
byte oldTXstatus = (0); // 0 = RX mode, 1 = TX mode
byte buttonpressed = (0); // 0 = no button pressed
byte simbuttonpressed = (0);
// LCD specific characters 'C' for CAT activity indication
byte cat [8] = {
B00000,
B00000,
B01110,
B01000,
B01110,
B00000,
B00000,
};
// Antenna indicator Style 1
byte accoright [8] = {
B00000,
B11000,
B01100,
B01100,
B01100,
B11000,
B00000,
};
byte accoleft [8] = {
B00000,
B00011,
B00110,
B00110,
B00110,
B00011,
B00000,
};
byte memory [8] = {
B00000,
B00000,
B11011,
B10101,
B10001,
B00000,
B00000,
};
// some control variables
int i;
int incoming;
int unsigned long DisplayTime = 0; // timer display refresh
int unsigned long ButtonTime = 0; // Timer button depressed
byte memorize = (0); // if = 1, them position to be memorzied
////////////// This loop run once on start up /////////////////
void setup() {
//set up output pins antenna control & beeper
pinMode(A1Pin, OUTPUT);
pinMode(A2Pin, OUTPUT);
pinMode(A3Pin, OUTPUT);
pinMode(A4Pin, OUTPUT);
pinMode(A5Pin, OUTPUT);
pinMode(TonePin, OUTPUT);
digitalWrite(A1Pin,0) ;
digitalWrite(A2Pin,0) ;
digitalWrite(A3Pin,0) ;
digitalWrite(A4Pin,0) ;
digitalWrite(A5Pin,0) ;
digitalWrite(TonePin,0) ;
// create LCD characters
lcd.createChar(0, cat);
lcd.createChar(1, accoleft);
lcd.createChar(2, accoright);
lcd.createChar(3, memory);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.clear();
// Print a message to the LCD.
lcd.setCursor(0, 0);
lcd.print(" ON7EQ Icom CAT");
lcd.setCursor(0, 1);
lcd.print(" v1.08 Nov2011");
delay (1000);
// RESET if SCROLL left & right buttons depressed at startup !
if ((analogRead(LeftPin)<512) and (analogRead(RightPin)<512)) Reset ();
// Startup Beep
tone(TonePin,1200);
delay(150);
tone(TonePin,1600);
delay (150);
tone(TonePin,2000);
delay (150);
noTone (TonePin);
delay (1000);
// print screen template
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("QRG --.---- MHz ");
lcd.setCursor(0, 1);
lcd.print("Bnd ");
clearindicator ();
// RXindicator ();
mySerial.begin(9600); // CAT running at 9k6
}
////////////////////////// MAIN LOOP ////////////////////////////////////
void loop() {
listen:
delay(1); // reduced from 50 !
next:
// detect if TX simulation switch depressed
if ((analogRead(TXsimPin)<512) and (simbuttonpressed ==0) and (TXstatus == 0)) { // TX simulation depressed while in RX
simbuttonpressed = 1;
lcd.setCursor(0, 1);
lcd.print("TX ");
clearindicator (); // always to do, before RX and TX change
TXindicator (); // We are displaying TX condition
}
if ((analogRead(TXsimPin)>512) and (simbuttonpressed ==1) ) { // TX simulation released
simbuttonpressed = 0;
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
if (BAND == 0) lcd.print("Man");
clearindicator (); // always to do, before RX and TX change
RXindicator (); // We are displaying RX condition
}
// detect if PTT low (Transmit status)
if ((analogRead(PTTPin)<128) and (TXstatus == 0)) { // We go into TX mode
TXstatus = 1;
lcd.setCursor(0, 1);
lcd.print("TX ");
clearindicator (); // always to do, before RX and TX change
TXindicator (); // We are displaying & setting TX condition
}
if ((analogRead(PTTPin)>256) and (TXstatus ==1 )) { // We go into RX with some hysterisis
TXstatus = 0;
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
if (BAND == 0) lcd.print("Man");
clearindicator (); // always to do, before RX and TX change
RXindicator (); // We are displaying & setting RX condition
}
/* DEBUG : test update cycle
tone(TonePin,2000);
delay (5);
noTone (TonePin);
*/
if (TXstatus == 0) ReadButtons (); // no reprogramming when really in TX mode !
if ((millis() - DisplayTime) > 350) { // refresh CAT indicator
lcd.setCursor(15, 0);
lcd.print(" ");
}
if (mySerial.available() > 0) {
incoming = mySerial.read();
if (incoming == 254) { // 1st byte is an FE look for an FE to start
goto start;
}
goto next;
}
start:
buffget[0] = 0;
// delay(1);
for ( i=0;i<10;i++) { // get next 10 bytes
if(mySerial.available() > 0) {
buffget[i]=mySerial.read(); // load buffget with next 10 characters
delay(2); //delay 1 ms if true, time for buffer fill
}
}
delay (10); // delay is required to process buffer, do not remove !
if (buffget[0] == 254) { // again FE , as 2nd character ?
goto next1;
} // yes, now do '00' test
goto listen; // wrong array, get another
next1:
if ((buffget[3] == 0) or (buffget[3] == 3) or (buffget[3] == 5) ){ // check to see if 4th char is 00 or 03 or 05 (=frequency)
goto next2;
} // detected, goto next2
/*
if ((buffget[3] == 28) and (buffget[4] == 0)) TXstatus = 0; // RX mode detect, if set by CAT
if ((buffget[3] == 28) and (buffget[4] == 1)) TXstatus = 1; // TX mode detect, if set by CAT
*/
goto listen; // wrong array, get another
next2:
// Check for last byte
if(buffget[9] == 253 ){ // look for FD at end of array
goto frequency;
} // if FD detected, goto frequency
goto listen; // wrong command
frequency: // we have frequency array on hand
MHZ = (buffget[7]);
MHZ = MHZ - (((MHZ/16) * 6)); // Transform bytes ICOM CAT
if (MHZ >= 100) goto listen; // wrong byte
KHZ = buffget[6];
KHZ = KHZ - (((KHZ/16) * 6)); // Transform bytes ICOM CAT
if (KHZ >= 100) goto listen; // wrong byte
HZ = buffget[5];
HZ = HZ - (((HZ/16) * 6)); // Transform bytes ICOM CAT
if (HZ >= 100) goto listen; // wrong byte
QRG = ((MHZ * 10000) + (KHZ * 100) + (HZ * 1)); // QRG variable stores frequency in MMkkkH format
// Print frequency
lcd.setCursor(4, 0);
if (QRG < 100000) lcd.print(" ");
lcd.print(QRG/10000,DEC);
lcd.print(".");
if (QRG%10000 < 1000 ) lcd.print("0");
if (QRG%10000 < 100 ) lcd.print("0");
if (QRG%10000 < 10 ) lcd.print("0");
lcd.print(QRG%10000,DEC);
lcd.print(" MHz");
lcd.write(0); // print the CAT activity indicator
// set display timer
DisplayTime = millis();
// Which band ?
QRGcomp = QRG / 10;
BAND = 0; // default band = will generate error
if ((QRGcomp < High6) and (QRGcomp > Low6)) BAND = 6;
if ((QRGcomp < High10) and (QRGcomp > Low10)) BAND = 10;
if ((QRGcomp < High12) and (QRGcomp > Low12)) BAND = 12;
if ((QRGcomp < High15) and (QRGcomp > Low15)) BAND = 15;
if ((QRGcomp < High17) and (QRGcomp > Low17)) BAND = 17;
if ((QRGcomp < High20) and (QRGcomp > Low20)) BAND = 20;
if ((QRGcomp < High30) and (QRGcomp > Low30)) BAND = 30;
if ((QRGcomp < High40) and (QRGcomp > Low40)) BAND = 40;
if ((QRGcomp < High80) and (QRGcomp > Low80)) BAND = 80;
if ((QRGcomp < High160) and (QRGcomp > Low160)) BAND = 160;
if (BAND == 0) {
clearindicator (); // We are not on standard band, clear antenna's
}
if (memorize == 1) goto finish; // antenna position must be memorized, do not read what is now in memory
// Check band changed
if (BAND == oldBAND) goto finish; // no bandchange
///// Band is changed ! /////
oldBAND = BAND;
// now process antenna change
// read value from EEPROM
if (BAND == 0) {
lcd.setCursor(0, 1);
lcd.print(" ");
goto finish; // no need to read
}
// display band
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
ReadEEPROMvalues ();
//Show in display
clearindicator (); // always to do, before RX and TX change
RXindicator (); // We are assuming in RX mode while changing band
// Music Maestro
tone(TonePin,1600);
delay(150);
tone(TonePin,1200);
delay (150);
noTone (TonePin);
goto finish;
// end process antenna change //
finish:
delay(0);
goto listen;
}
///////////////// SUBROUTINES ///////////////////
void clearindicator () { // Clear all antenna
lcd.setCursor(4, 1);
lcd.print(" 1 2 3 4 5 ");
digitalWrite(A1Pin,0) ;
digitalWrite(A2Pin,0) ;
digitalWrite(A3Pin,0) ;
digitalWrite(A4Pin,0) ;
digitalWrite(A5Pin,0) ;
}
/////////////////////////////////////////////////////////////////////
void RXindicator () { // Process selected RX antenna
if (RXantenna == 1) {
digitalWrite(A1Pin,1) ;
lcd.setCursor(4, 1);
lcd.write(1);
lcd.setCursor(6, 1);
lcd.write(2);
}
if (RXantenna == 2) {
digitalWrite(A2Pin,1) ;
lcd.setCursor(6, 1);
lcd.write(1);
lcd.setCursor(8, 1);
lcd.write(2);
}
if (RXantenna == 3) {
digitalWrite(A3Pin,1) ;
lcd.setCursor(8, 1);
lcd.write(1);
lcd.setCursor(10, 1);
lcd.write(2);
}
if (RXantenna == 4) {
digitalWrite(A4Pin,1) ;
lcd.setCursor(10, 1);
lcd.write(1);
lcd.setCursor(12, 1);
lcd.write(2);
}
if (RXantenna == 5) {
digitalWrite(A5Pin,1) ;
lcd.setCursor(12, 1);
lcd.write(1);
lcd.setCursor(14, 1);
lcd.write(2);
}
/* / Check if TX = RX ant
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
if (TXantenna = RXantenna) lcd.print("="); // same RX as TX antenna
*/
}
/////////////////////////////////////////////////////////////////////
void TXindicator () { // Process selected TX antenna
if (TXantenna == 1) {
digitalWrite(A1Pin,1) ;
lcd.setCursor(4, 1);
lcd.write(1);
lcd.setCursor(6, 1);
lcd.write(2);
}
if (TXantenna == 2) {
digitalWrite(A2Pin,1) ;
lcd.setCursor(6, 1);
lcd.write(1);
lcd.setCursor(8, 1);
lcd.write(2);
}
if (TXantenna == 3) {
digitalWrite(A3Pin,1) ;
lcd.setCursor(8, 1);
lcd.write(1);
lcd.setCursor(10, 1);
lcd.write(2);
}
if (TXantenna == 4) {
digitalWrite(A4Pin,1) ;
lcd.setCursor(10, 1);
lcd.write(1);
lcd.setCursor(12, 1);
lcd.write(2);
}
if (TXantenna == 5) {
digitalWrite(A5Pin,1) ;
lcd.setCursor(12, 1);
lcd.write(1);
lcd.setCursor(14, 1);
lcd.write(2);
}
/* Check if TX = RX ant
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
if (TXantenna = RXantenna) lcd.print("="); // same RX as TX antenna
*/
}
/////////////////////////////////////////////////////////////////////
void ReadEEPROMvalues () { // Read Antenna's stored in EEPROM
if (BAND == 6) RXantenna = EEPROM.read(6);
if (BAND == 6) TXantenna = EEPROM.read(7);
if (BAND == 10) RXantenna = EEPROM.read(10);
if (BAND == 10) TXantenna = EEPROM.read(11);
if (BAND == 12) RXantenna = EEPROM.read(12);
if (BAND == 12) TXantenna = EEPROM.read(13);
if (BAND == 15) RXantenna = EEPROM.read(15);
if (BAND == 15) TXantenna = EEPROM.read(16);
if (BAND == 17) RXantenna = EEPROM.read(17);
if (BAND == 17) TXantenna = EEPROM.read(18);
if (BAND == 20) RXantenna = EEPROM.read(20);
if (BAND == 20) TXantenna = EEPROM.read(21);
if (BAND == 30) RXantenna = EEPROM.read(30);
if (BAND == 30) TXantenna = EEPROM.read(31);
if (BAND == 40) RXantenna = EEPROM.read(40);
if (BAND == 40) TXantenna = EEPROM.read(41);
if (BAND == 80) RXantenna = EEPROM.read(80);
if (BAND == 80) TXantenna = EEPROM.read(81);
if (BAND == 160) RXantenna = EEPROM.read(160);
if (BAND == 160) TXantenna = EEPROM.read(161);
}
/////////////////////////////////////////////////////////////////////
void WriteEEPROMvalues () { // Write Antenna's in EEPROM
if (BAND == 6) EEPROM.write(6, RXantenna);
if (BAND == 6) EEPROM.write(7, TXantenna);
if (BAND == 10) EEPROM.write(10, RXantenna);
if (BAND == 10) EEPROM.write(11, TXantenna);
if (BAND == 12) EEPROM.write(12, RXantenna);
if (BAND == 12) EEPROM.write(13, TXantenna);
if (BAND == 15) EEPROM.write(15, RXantenna);
if (BAND == 15) EEPROM.write(16, TXantenna);
if (BAND == 17) EEPROM.write(17, RXantenna);
if (BAND == 17) EEPROM.write(18, TXantenna);
if (BAND == 20) EEPROM.write(20, RXantenna);
if (BAND == 20) EEPROM.write(21, TXantenna);
if (BAND == 30) EEPROM.write(30, RXantenna);
if (BAND == 30) EEPROM.write(31, TXantenna);
if (BAND == 40) EEPROM.write(40, RXantenna);
if (BAND == 40) EEPROM.write(41, TXantenna);
if (BAND == 80) EEPROM.write(80, RXantenna);
if (BAND == 80) EEPROM.write(81, TXantenna);
if (BAND == 160) EEPROM.write(160, RXantenna);
if (BAND == 160) EEPROM.write(161, TXantenna);
}
/////////////////////////////////////////////////////////////////////
void Reset() { // RESET memory in EEPROM
lcd.setCursor(0, 1);
lcd.print(" HOLD TO RESET");
// erase all EEPROM contents TODO !!!
delay(2000);
if ((analogRead(LeftPin)<512) and (analogRead(RightPin)<512)) { // Yes, we have a reset !
lcd.setCursor(0, 1);
lcd.print(" RESETTING ... ");
delay(1000);
EEPROM.write(6, 0);
EEPROM.write(7, 0);
EEPROM.write(10, 0);
EEPROM.write(11, 0);
EEPROM.write(12, 0);
EEPROM.write(13, 0);
EEPROM.write(15, 0);
EEPROM.write(16, 0);
EEPROM.write(17, 0);
EEPROM.write(18, 0);
EEPROM.write(20, 0);
EEPROM.write(21, 0);
EEPROM.write(30, 0);
EEPROM.write(31, 0);
EEPROM.write(40, 0);
EEPROM.write(41, 0);
EEPROM.write(80, 0);
EEPROM.write(81, 0);
EEPROM.write(160, 0);
EEPROM.write(161, 0);
lcd.setCursor(0, 1);
lcd.print(" RESTARTING ... ");
delay(1000);
}
}
/////////////////////////////////////////////////////////////////////
void ReadButtons () { // Detect antenna select buttons depressed
if ((analogRead(LeftPin)<512) and (analogRead(TXsimPin)>512) and (buttonpressed == 0)) { // Left button depressed in RX mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
RXantenna = RXantenna -- ;
if ((RXantenna == 0) or (RXantenna > 5 ))RXantenna = (6);
RXindicator ();
}
if ((analogRead(RightPin)<512) and (analogRead(TXsimPin)>512) and (buttonpressed == 0) ) { // Right button depressed in RX mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
RXantenna = RXantenna ++ ;
if (RXantenna >= 7) RXantenna = (1);
RXindicator ();
}
if ((analogRead(LeftPin)<512) and (analogRead(TXsimPin)<512) and (buttonpressed == 0)) { // Left button depressed in TX sim mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
TXantenna = TXantenna -- ;
if ((TXantenna == 0) or (TXantenna > 5 ))TXantenna = (6);
TXindicator ();
}
if ((analogRead(RightPin)<512) and (analogRead(TXsimPin)<512) and (buttonpressed == 0) ) { // Right button depressed in TX sim mode
tone(TonePin,2000);
delay (20);
noTone (TonePin);
ButtonTime = millis ();
buttonpressed = 1;
if (BAND != 0) memorize = 1;
clearindicator ();
TXantenna = TXantenna ++ ;
if (TXantenna >= 7) TXantenna = (1);
TXindicator ();
}
// Timers check
if (millis () - ButtonTime > 300) { // Button press detect
buttonpressed = (0);
}
// Memorize antenna
if ((millis () - ButtonTime > memotime) and (memorize == 1)){ // Now memorize antenna after xxx ms
memorize = 0;
lcd.setCursor(15, 1); // print MEMORY indicator
lcd.write(3);
if (TXantenna == 0) TXantenna = RXantenna; // if TX antenna undefined, set TX antenna same as RX antenna
WriteEEPROMvalues ();
tone(TonePin,2000);
delay (150);
noTone (TonePin);
delay (50);
tone(TonePin,2000);
delay (150);
noTone (TonePin);
lcd.setCursor(15, 1); // erase M indicator
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
if (BAND != 0) lcd.print(BAND,DEC);
if (BAND == 0) lcd.print("Man");
}
}
No comments:
Post a Comment