int ditlen = 120; // dot length mS
bool mode_tx = 0; // true in transmitting
bool mode_cmd = 0; // command mode, currently used to change keyer speed
bool mode_msg = 0; // play canned CW message
#define HANG_MS 1200 // T/R drop-out delay
#define LONG_PRESS 500 // long press in mS
unsigned long last_mS;
#define PDL_DIT 0
#define PDL_DAH 2
#define SDTN 1
#define PTT_LINE PB3
#define CW_LINE 4
#define CMD_A A0 // PB5 (A0) used as analogue input for CMD button
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(CW_LINE, OUTPUT);
pinMode(PDL_DIT, INPUT_PULLUP);
pinMode(PDL_DAH, INPUT_PULLUP);
pinMode(SDTN, OUTPUT);
pinMode(PTT_LINE, OUTPUT);
digitalWrite(PTT_LINE, 0);
pinMode(CMD_A, INPUT);
last_mS = millis();
//Serial.begin(9600);
// test buzzer
tone(SDTN, 700); delay(300);
noTone(SDTN); delay (1000);
digitalWrite(SDTN, HIGH);
delay(300);
digitalWrite(SDTN, LOW);
delay(300);
}
void didah(bool dit){
int durn = ditlen;
if(!dit) durn = 3*ditlen;
digitalWrite(CW_LINE, HIGH); // turn the LED on (HIGH is the voltage level)
tone(SDTN, 700);
delay(durn); // wait for a second
digitalWrite(CW_LINE, LOW); // turn the LED off by making the voltage LOW
noTone(SDTN);
delay(ditlen);
};
void Rx2Tx(){
mode_tx = 1;
digitalWrite(PTT_LINE, HIGH);
delay(300);
}
void Tx2Rx(){
mode_tx = 0;
digitalWrite(PTT_LINE, LOW);
delay(300);
}
void play_msg(){
// play a canned CW message
if(!mode_tx) Rx2Tx();
char msg[] = {'.', '.', '.', '-', ' ', // V
// '-', '.', '-', ' ', // K
// '.', '.', '.', '-', '-', ' ', // 3
// '.', '.', '.', '.', ' ', // H
// '-', '.', // N
'\n'
};
int i=0;
while(msg[i] != '\n'){
if(msg[i] == '.') didah(1);
else if(msg[i] == '-') didah(0);
else if(msg[i] == ' ') delay(ditlen*3);
i++;
};
delay(HANG_MS);
Tx2Rx();
mode_msg = 0;
}
void loop() {
// read CMD button
int val = analogRead(CMD_A);
int cntr = 0;
if((val > 1022)) {
// button is pressed, so spin for bit to see if it is a long press
while(val > 1022){
delay(100);
cntr += 100;
val = analogRead(CMD_A);
}
if(cntr >= LONG_PRESS) mode_msg = 1;
else mode_cmd = 1; // short press enters command mode
// flash the PTT line to acknowledge button press
/*digitalWrite(CW_LINE, HIGH);
delay(200);
digitalWrite(CW_LINE,LOW);
delay(200);*/
//mode_msg = 1; // temp!
}
// if requested, playcanned message
if(mode_msg) play_msg();
// read the paddle
bool dit_b=0, dah_b=0;
if(!digitalRead(PDL_DIT)) dit_b = true; // putton pressed returns LOW
if(!digitalRead(PDL_DAH)) dah_b = true;
//if((dit_b or dah_b) && !mode_tx) Rx2Tx();
if(dit_b || dah_b){
// a dit, dah or both are pressed
if(!mode_tx) Rx2Tx();
if(mode_tx){
if(dit_b && dah_b) ; // handle squeeze
if(dit_b) didah(1);
if(dah_b) didah(0);
last_mS = millis();
}
if(mode_cmd){
if(dit_b) ditlen -= 20;
if(dah_b) ditlen += 20;
delay(100);
last_mS = millis();
}
}
dit_b = 0;
dah_b = 0;
if(mode_tx && abs((millis()-last_mS)) > HANG_MS)
{
if(mode_tx) Tx2Rx();
if(mode_cmd) mode_cmd = 0;
last_mS = millis();
}
}
DIT ... DAH
CW
PTT
SIDETONE
CMD