/////////////////////////////////////////////////////// // // // ICOM AUTO KEYER // // by ON7EQ 03/2016 // // // /////////////////////////////////////////////////////// // compiled with IDE v 1.0.6 #define input1 (2) // pushbutton 1 input pin (pushbutton depressed = LOW) #define input2 (3) // pushbutton 2 input pin #define input3 (4) // pushbutton 3 input pin #define input4 (5) // pushbutton 4 input pin #define output1 (6) // output 1 pin - to open collector NPN - output active = HIGH #define output2 (7) // output 2 pin - to open collector NPN #define output3 (8) // output 3 pin - to open collector NPN #define output4 (9) // output 4 pin - to open collector NPN #define LED_output (13) // output pin - to LED - if only one LED #define LED_output1 (A2) // output pin - to LED corresponding with button 1 (optional) #define LED_output2 (A3) // output pin - to LED corresponding with button 2 (optional) #define LED_output3 (A4) // output pin - to LED corresponding with button 3 (optional) #define LED_output4 (A5) // output pin - to LED corresponding with button 4 (optional) #define PTT_read (A1) // input for reading PTT (to define RX/TX status) #define Delay_pot_pin (A0) // input for reading potentiometer for delay byte mode = 0; byte button = 0; byte longpress = 0; byte OneShot = 0; // one shot flag byte Repeat = 0; byte arm = 0; // arm for repress detect in repeat mode byte stop_by_PTT = 0; byte EOM_flag = 0; // end of message flag byte button_pressed = 0; int unsigned long RX_time = 0; int unsigned long RepeatInterval = 0; int unsigned long Button_time_pressed = 0; int unsigned long EOM_time = 0; //////////////////////////////////////////////////////////// //////////////////// S E T U P ////////////////////////// //////////////////////////////////////////////////////////// void setup() { pinMode (input1, INPUT); pinMode (input2, INPUT); pinMode (input3, INPUT); pinMode (input4, INPUT); //Activate pull-ups digitalWrite(input1, HIGH); digitalWrite(input2, HIGH); digitalWrite(input3, HIGH); digitalWrite(input4, HIGH); digitalWrite(PTT_read, HIGH); pinMode (output1, OUTPUT); pinMode (output2, OUTPUT); pinMode (output3, OUTPUT); pinMode (output4, OUTPUT); digitalWrite(output1, LOW); digitalWrite(output2, LOW); digitalWrite(output3, LOW); digitalWrite(output4, LOW); pinMode (LED_output, OUTPUT); pinMode (LED_output1, OUTPUT); pinMode (LED_output2, OUTPUT); pinMode (LED_output3, OUTPUT); pinMode (LED_output4, OUTPUT); digitalWrite(LED_output, LOW); digitalWrite(LED_output1, LOW); digitalWrite(LED_output2, LOW); digitalWrite(LED_output3, LOW); digitalWrite(LED_output4, LOW); } /////////////////////////////////////////// //////////// L O O P /////////////// /////////////////////////////////////////// void loop() { if (Repeat == 0) { // single shot mode button actions // check if any button depressed, and define mode if (digitalRead(input1) == LOW) button = 1; // any of 4 buttons pressed else if (digitalRead(input2) == LOW) button = 1; else if (digitalRead(input3) == LOW) button = 1; else if (digitalRead(input4) == LOW) button = 1; else { // no button pressed button = 0; // no button pressed if (button_pressed == 1) button_pressed = 0; // button was released OneShot = 0; // be ready for new pulse longpress = 0; // long press released } if ((button == 1) and (mode < 20)) { // if ((button == 1)) { delay (30); //Crude debounce if (digitalRead(input1) == LOW) button = 11; // Button 1 effectively pressed else if (digitalRead(input2) == LOW) button = 12; // Button 1 effectively pressed else if (digitalRead(input3) == LOW) button = 13; // Button 1 effectively pressed else if (digitalRead(input4) == LOW) button = 14; // Button 1 effectively pressed else { button = 0; // it was bounce or button was released button_pressed = 0; longpress = 0; OneShot = 0; // be ready for new pulse } if ((button_pressed == 0) and (button > 10) and (button < 20)) { button_pressed = 1; // a button was depressed ! Button_time_pressed = millis(); // time stamp a button pressed } } if ((button_pressed == 1) and (millis() - Button_time_pressed > 300) ) { // check if long press on button > 0.5 sec if (longpress == 0) { // going into repeat mode longpress = 1; // button pressed for repeat mode ! if (digitalRead(input1) == LOW) mode = 21; // Button 1 else if (digitalRead(input2) == LOW) mode = 22; // Button 2 else if (digitalRead(input3) == LOW) mode = 23; // Button 3 else if (digitalRead(input4) == LOW) mode = 24; // Button 4 digitalWrite(LED_output, HIGH); // Repeat mode RX_time = millis () + 60000; // set repeat timer } } } // end single shot mode if (Repeat == 1) { // repeat mode button actions // Wait for button released = arm condition ! if ((digitalRead(input1) == LOW) // any of 4 buttons pressed ? or (digitalRead(input2) == LOW) or (digitalRead(input3) == LOW) or (digitalRead(input4) == LOW)) { delay (0) ; // do nothing } else (arm = 1); // button released, arm for repress => force stop // Wait for button pressed = exit mode ! if (((digitalRead(input1) == LOW) // any of 4 buttons pressed ? or (digitalRead(input2) == LOW) or (digitalRead(input3) == LOW) or (digitalRead(input4) == LOW)) and (arm == 1)) { arm =0; mode = 99; // Exit repeat mode } } // end repeat mode button actions //////////////////////////////////////////////////////////// /////////////// Take actions according to mode /////////// //////////////////////////////////////////////////////////// /////////////////// Single press //////////////// if ((button_pressed == 1) and (OneShot == 0) ) { digitalWrite(LED_output, HIGH); if (button == 11) { digitalWrite(output1, HIGH); digitalWrite(LED_output1, HIGH); } if (button == 12) { digitalWrite(output2, HIGH); digitalWrite(LED_output2, HIGH); } if (button == 13) { digitalWrite(output3, HIGH); digitalWrite(LED_output3, HIGH); } if (button == 14) { digitalWrite(output4, HIGH); digitalWrite(LED_output4, HIGH); } delay (100); // pulse keyer digitalWrite(output1, LOW); digitalWrite(output2, LOW); digitalWrite(output3, LOW); digitalWrite(output4, LOW); digitalWrite(LED_output, LOW); digitalWrite(LED_output1, LOW); digitalWrite(LED_output2, LOW); digitalWrite(LED_output3, LOW); digitalWrite(LED_output4, LOW); OneShot = 1; } ///////////////// Long press ////////////// if ((mode > 20) and (mode < 30)) { Repeat = 1; RepeatInterval = map(analogRead(Delay_pot_pin), 0, 1023, 1000, 20000); // 1 to 20 sec interval // Generate repeat pulse after interval, only in in RX if ((millis() - RX_time > RepeatInterval) and (EOM_flag == 1) and (analogRead(PTT_read) > 500)) { RX_time = millis (); EOM_flag = 0; if (mode == 21) digitalWrite(output1, HIGH); if (mode == 22) digitalWrite(output2, HIGH); if (mode == 23) digitalWrite(output3, HIGH); if (mode == 24) digitalWrite(output4, HIGH); digitalWrite(LED_output, LOW); digitalWrite(LED_output1, LOW); digitalWrite(LED_output2, LOW); digitalWrite(LED_output3, LOW); digitalWrite(LED_output4, LOW); delay (100); // Pulse output digitalWrite(LED_output, HIGH); if (mode == 21) digitalWrite(LED_output1, HIGH); if (mode == 22) digitalWrite(LED_output2, HIGH); if (mode == 23) digitalWrite(LED_output3, HIGH); if (mode == 24) digitalWrite(LED_output4, HIGH); digitalWrite(output1, LOW); digitalWrite(output2, LOW); digitalWrite(output3, LOW); digitalWrite(output4, LOW); } delay(50); // extra delay - allow TRX to go into TX mode and bring PTT line down if (analogRead(PTT_read) < 500) RX_time = millis () ; if ((analogRead(PTT_read) < 500) and (EOM_flag == 0)) { // Higher than 2,5 V on PTT line = RX // // RX_time = millis (); // timestamp going into RX mode. as long as in TX, RX_time is reset to millis() EOM_time = millis(); // timestamp end of message } if (analogRead(PTT_read) > 500) EOM_flag = 1; // PTT line becomes HIGH, message has been played. Required to detect subsequent stop by PTT /// STOP BY PTT during pause interval if (((millis( )- EOM_time > 50)) and (millis() < (EOM_time + RepeatInterval - 50)) and (analogRead(PTT_read) < 500) and (arm == 1)) { // PTT depressed during pause between messages --> stop keyer! stop_by_PTT = 1; arm = 0; mode = 99; EOM_flag = 0; } } // end of repeat mode // EXIT REPEAT MODE if (mode == 99) { Repeat = 0; digitalWrite(LED_output, LOW); digitalWrite(LED_output1, LOW); digitalWrite(LED_output2, LOW); digitalWrite(LED_output3, LOW); digitalWrite(LED_output4, LOW); mode = 0; // check if message playing, issue a pulse to stop if ((analogRead(PTT_read) < 500) and (stop_by_PTT == 0)) { // Yes, PTT is low, and was not forced stop by keying digitalWrite(output1, HIGH); delay (100); // Pulse output digitalWrite(output1, LOW); } stop_by_PTT = 0; //wait till buttons released before looping again while ((digitalRead(input1) == LOW) // if any of 4 buttons pressed, wait till released ! or (digitalRead(input2) == LOW) or (digitalRead(input3) == LOW) or (digitalRead(input4) == LOW)) {} delay (100); } } // End of loop