re-factor analog button functions to support multiple button lines. (#71)

* initial port

* Fix command_mode

* Remove analogbuttonpressed
pull/77/head
w6ipa 2019-10-23 16:40:53 -07:00 zatwierdzone przez Anthony Good
rodzic bdd4882cff
commit 4535e3a0ed
6 zmienionych plików z 536 dodań i 419 usunięć

Wyświetl plik

@ -1243,6 +1243,10 @@ Recent Update History
#include "keyer_settings.h"
#endif
#if defined(FEATURE_COMMAND_BUTTONS)
#include "src/buttonarray/buttonarray.h"
#endif
#if defined(FEATURE_SLEEP)
#include <avr/sleep.h> // It should be different library for ARM sp5iou
#endif
@ -1618,6 +1622,13 @@ byte send_buffer_status = SERIAL_SEND_BUFFER_NORMAL;
byte dah_counter = 0;
#endif //FEATURE_DEAD_OP_WATCHDOG
#ifdef FEATURE_COMMAND_BUTTONS
#ifdef OPTION_REVERSE_BUTTON_ORDER
ButtonArray button_array(analog_buttons_pin, analog_buttons_number_of_buttons, true);
#else
ButtonArray button_array(analog_buttons_pin, analog_buttons_number_of_buttons, false);
#endif
#endif //FEATURE_COMMAND_BUTTONS
#ifdef FEATURE_ROTARY_ENCODER // Rotary Encoder State Tables
#ifdef OPTION_ENCODER_HALF_STEP_MODE // Use the half-step state table (emits a code at 00 and 11)
@ -6739,6 +6750,7 @@ void command_mode()
looping = 1;
while (looping) {
int8_t button_temp = button_array.Pressed();
#ifdef FEATURE_DISPLAY
service_display();
@ -6778,13 +6790,12 @@ void command_mode()
#endif
looping = 0;
}
if (analogbuttonpressed() < analog_buttons_number_of_buttons){ // check for a button press
if (button_temp >=0 ){ // check for a button press
looping = 0;
cw_char = 9;
delay(50);
button_that_was_pressed = analogbuttonpressed();
while (analogbuttonpressed() < analog_buttons_number_of_buttons) {}
button_that_was_pressed = button_temp;
while (button_array.Held(button_that_was_pressed)) {}
}
#if defined(FEATURE_SERIAL)
@ -7187,6 +7198,9 @@ void command_mode()
case 9: // button was hit
Serial.print("Button - ");
Serial.println(button_that_was_pressed);
#if defined(FEATURE_MEMORIES)
if (button_that_was_pressed == 0){ // button 0 was hit - exit
stay_in_command_mode = 0;
@ -8070,7 +8084,7 @@ void switch_to_tx(byte tx)
void check_the_memory_buttons()
{
byte analogbuttontemp = analogbuttonpressed();
byte analogbuttontemp = button_array.Pressed();
if ((analogbuttontemp > 0) && (analogbuttontemp < (number_of_memories + 1)) && ((millis() - button_last_add_to_send_buffer_time) > 400)) {
add_to_send_buffer(SERIAL_SEND_BUFFER_MEMORY_NUMBER);
add_to_send_buffer(analogbuttontemp - 1);
@ -8081,305 +8095,47 @@ void check_the_memory_buttons()
//------------------------------------------------------------------
#if defined(FEATURE_COMMAND_BUTTONS) && defined(FEATURE_DL2SBA_BANKSWITCH)
void setOneButton(int button, int index) {
// sp5iou 20180328 to be compatible with either stm32 and avr arduinos
int button_value = int(1023 * (float(button * analog_buttons_r2)/float((button * analog_buttons_r2) + analog_buttons_r1)));
int lower_button_value = int(1023 * (float((button-1) * analog_buttons_r2)/float(((button-1) * analog_buttons_r2) + analog_buttons_r1)));
int higher_button_value = int(1023 * (float((button+1) * analog_buttons_r2)/float(((button+1) * analog_buttons_r2) + analog_buttons_r1)));
button_array_low_limit[index] = (button_value - ((button_value - lower_button_value)/2));
button_array_high_limit[index] = (button_value + ((higher_button_value - button_value)/2));
}
#endif
//------------------------------------------------------------------
void initialize_analog_button_array() {
#ifdef FEATURE_COMMAND_BUTTONS
/*
typical button values:
0: -56 - 46
1: 47 - 131
2: 132 - 203
3: 203 - 264
*/
#ifdef DEBUG_BUTTONS
debug_serial_port->print("initialize_analog_button_array: ");
#endif
#ifndef FEATURE_DL2SBA_BANKSWITCH
int button_value;
int lower_button_value;
int higher_button_value;
#if defined(FEATURE_DL2SBA_BANKSWITCH)
button_array.Add(0,0);
button_array.Add(1,3);
button_array.Add(2,2);
button_array.Add(3,1);
button_array.Add(4,9);
button_array.Add(5,8);
button_array.Add(6,7);
button_array.Add(7,6);
button_array.Add(8,5);
button_array.Add(9,4);
#ifdef OPTION_REVERSE_BUTTON_ORDER
byte y = analog_buttons_number_of_buttons - 1;
#endif
for (int x = 0;x < analog_buttons_number_of_buttons;x++) {
button_value = int(button_value_factor * (float(x * analog_buttons_r2)/float((x * analog_buttons_r2) + analog_buttons_r1)));
lower_button_value = int(button_value_factor * (float((x-1) * analog_buttons_r2)/float(((x-1) * analog_buttons_r2) + analog_buttons_r1)));
higher_button_value = int(button_value_factor * (float((x+1) * analog_buttons_r2)/float(((x+1) * analog_buttons_r2) + analog_buttons_r1)));
// button_value = int(1023 * (float(x * analog_buttons_r2)/float((x * analog_buttons_r2) + analog_buttons_r1)));
// lower_button_value = int(1023 * (float((x-1) * analog_buttons_r2)/float(((x-1) * analog_buttons_r2) + analog_buttons_r1)));
// higher_button_value = int(1023 * (float((x+1) * analog_buttons_r2)/float(((x+1) * analog_buttons_r2) + analog_buttons_r1)));
#ifndef OPTION_REVERSE_BUTTON_ORDER
button_array_low_limit[x] = (button_value - ((button_value - lower_button_value)/2));
button_array_high_limit[x] = (button_value + ((higher_button_value - button_value)/2));
#else
button_array_low_limit[y] = (button_value - ((button_value - lower_button_value)/2));
button_array_high_limit[y] = (button_value + ((higher_button_value - button_value)/2));
y--;
#endif
#ifdef DEBUG_BUTTON_ARRAY
debug_serial_port->print("initialize_analog_button_array: ");
debug_serial_port->print(x);
debug_serial_port->print(": ");
debug_serial_port->print(button_array_low_limit[x]);
debug_serial_port->print(" - ");
debug_serial_port->println(button_array_high_limit[x]);
#endif //DEBUG_BUTTON_ARRAY
}
#elseif defined(OPTION_DFROBOT_LCD_COMMAND_BUTTONS)
button_array.Add(0,dfrobot_btnSELECT, dfrobot_btnLEFT_analog, dfrobot_btnSELECT_analog);
button_array.Add(1,dfrobot_btnLEFT, dfrobot_btnDOWN_analog, dfrobot_btnLEFT_analog);
button_array.Add(2,dfrobot_btnDOWN, dfrobot_btnUP_analog, dfrobot_btnDOWN_analog);
button_array.Add(3,dfrobot_btnUP, dfrobot_btnRIGHT_analog, dfrobot_btnUP_analog);
button_array.Add(4,dfrobot_btnRIGHT, 0, dfrobot_btnRIGHT_analog);
#else //FEATURE_DL2SBA_BANKSWITCH
setOneButton(0,0);
setOneButton(1,3);
setOneButton(2,2);
setOneButton(3,1);
setOneButton(4,9);
setOneButton(5,8);
setOneButton(6,7);
setOneButton(7,6);
setOneButton(8,5);
setOneButton(9,4);
button_array.AddAll();
#endif //FEATURE_DL2SBA_BANKSWITCH
#endif //FEATURE_COMMAND_BUTTONS
}
//------------------------------------------------------------------
#ifdef FEATURE_COMMAND_BUTTONS
byte analogbuttonpressed() {
int analog_line_read_average = 0;
int analog_read_temp = 0;
#if defined(OPTION_DFROBOT_LCD_COMMAND_BUTTONS)
// based on code from: https://www.dfrobot.com/wiki/index.php/Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)#Pin_Allocation
for (byte x = 0;x < 19;x++){
analog_read_temp = analogRead(analog_buttons_pin);
if (analog_read_temp <= button_array_high_limit[analog_buttons_number_of_buttons-1]){
analog_line_read_average = (analog_line_read_average + analog_read_temp) / 2;
}
}
if (analog_line_read_average > 1000){
return dfrobot_btnNONE;
}
if (analog_line_read_average < dfrobot_btnRIGHT_analog){
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F(" analogbuttonpressed: dfrobot_btnRIGHT"));
#endif
return dfrobot_btnRIGHT;
}
if (analog_line_read_average < dfrobot_btnUP_analog){
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F(" analogbuttonpressed: dfrobot_btnUP"));
#endif
return dfrobot_btnUP;
}
if (analog_line_read_average < dfrobot_btnDOWN_analog){
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F(" analogbuttonpressed: dfrobot_btnDOWN"));
#endif
return dfrobot_btnDOWN;
}
if (analog_line_read_average < dfrobot_btnLEFT_analog){
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F(" analogbuttonpressed: dfrobot_btnLEFT"));
#endif
return dfrobot_btnLEFT;
}
if (analog_line_read_average < dfrobot_btnSELECT_analog){
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F(" analogbuttonpressed: dfrobot_btnSELECT"));
#endif
return dfrobot_btnSELECT;
}
#else // OPTION_DFROBOT_LCD_COMMAND_BUTTONS
#if !defined(OPTION_REVERSE_BUTTON_ORDER)
if (analogRead(analog_buttons_pin) <= button_array_high_limit[analog_buttons_number_of_buttons-1]) {
for (byte x = 0;x < 19;x++){
analog_read_temp = analogRead(analog_buttons_pin);
if (analog_read_temp <= button_array_high_limit[analog_buttons_number_of_buttons-1]){
analog_line_read_average = (analog_line_read_average + analog_read_temp) / 2;
}
}
for (int x = 0;x < analog_buttons_number_of_buttons;x++) {
if ((analog_line_read_average > button_array_low_limit[x]) && (analog_line_read_average <= button_array_high_limit[x])) {
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F(" analogbuttonpressed: returning: "));
debug_serial_port->print(x);
debug_serial_port->print(F(" analog_line_read_average: "));//sp5iou
debug_serial_port->println(analog_line_read_average);//sp5iou
#endif
return x;
}
}
}
#else //OPTION_REVERSE_BUTTON_ORDER
if (analogRead(analog_buttons_pin) <= button_array_high_limit[0]) {
for (byte x = 0;x < 19;x++){
analog_read_temp = analogRead(analog_buttons_pin);
if (analog_read_temp <= button_array_high_limit[0]){
analog_line_read_average = (analog_line_read_average + analog_read_temp) / 2;
}
}
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F(" analogbuttonpressed: analog_line_read_average: "));
debug_serial_port->println(analog_line_read_average);
#endif
for (int x = 0;x < analog_buttons_number_of_buttons;x++) {
if ((analog_line_read_average > button_array_low_limit[x]) && (analog_line_read_average <= button_array_high_limit[x])) {
#ifdef DEBUG_BUTTONS
//if (!debug_flag) {
debug_serial_port->print(F(" analogbuttonpressed: returning: "));
debug_serial_port->println(x);
// debug_flag = 1;
//}
#endif
return x;
}
}
}
#endif //OPTION_REVERSE_BUTTON_ORDER
#endif // OPTION_DFROBOT_LCD_COMMAND_BUTTONS
return 255;
}
#endif //FEATURE_COMMAND_BUTTONS
//------------------------------------------------------------------
#ifdef FEATURE_COMMAND_BUTTONS
byte analogbuttonread(byte button_number) {
// button numbers start with 0
int analog_line_read = analogRead(analog_buttons_pin);
#if defined(OPTION_DFROBOT_LCD_COMMAND_BUTTONS)
// based on code from: https://www.dfrobot.com/wiki/index.php/Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)#Pin_Allocation
if ((analog_line_read < dfrobot_btnRIGHT_analog) && (button_number == dfrobot_btnRIGHT)){
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\nanalogbuttonread: analog_line_read: "));
debug_serial_port->print(analog_line_read);
debug_serial_port->println(F(" dfrobot_btnRIGHT"));
#endif
return 1;
}
if ((analog_line_read < dfrobot_btnUP_analog) && (button_number == dfrobot_btnUP)){
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\nanalogbuttonread: analog_line_read: "));
debug_serial_port->print(analog_line_read);
debug_serial_port->println(F(" dfrobot_btnUP"));
#endif
return 1;
}
if ((analog_line_read < dfrobot_btnDOWN_analog) && (button_number == dfrobot_btnDOWN)){
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\nanalogbuttonread: analog_line_read: "));
debug_serial_port->print(analog_line_read);
debug_serial_port->println(F(" dfrobot_btnDOWN"));
#endif
if (button_array.Pressed(button_number)) {
return 1;
}
if ((analog_line_read < dfrobot_btnLEFT_analog) && (button_number == dfrobot_btnLEFT)){
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\nanalogbuttonread: analog_line_read: "));
debug_serial_port->print(analog_line_read);
debug_serial_port->println(F(" dfrobot_btnLEFT"));
#endif
return 1;
}
if ((analog_line_read < dfrobot_btnSELECT_analog) && (button_number == dfrobot_btnSELECT)){
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\nanalogbuttonread: analog_line_read: "));
debug_serial_port->print(analog_line_read);
debug_serial_port->println(F(" dfrobot_btnSELECT"));
#endif
return 1;
}
return 0;
#else // OPTION_DFROBOT_LCD_COMMAND_BUTTONS
#ifdef DEBUG_BUTTONS
static byte debug_flag = 0;
#endif
if (analog_line_read < 1000) {
if ((analog_line_read > button_array_low_limit[button_number]) && (analog_line_read < button_array_high_limit[button_number])) {
#ifdef DEBUG_BUTTONS
if (!debug_flag) {
debug_serial_port->print(F("\nanalogbuttonread: analog_line_read: "));
debug_serial_port->print(analog_line_read);
debug_serial_port->print(F(" button pressed: "));
debug_serial_port->println(button_number);
debug_flag = 1;
}
#endif
return 1;
}
}
#ifdef DEBUG_BUTTONS
debug_flag = 0;
#endif
return 0;
#endif //OPTION_DFROBOT_LCD_COMMAND_BUTTONS
}
#endif
@ -8394,69 +8150,72 @@ void check_command_buttons()
#endif
static long last_button_action = 0;
byte analogbuttontemp = analogbuttonpressed();
byte analogbuttontemp = button_array.Pressed();
long button_depress_time;
byte paddle_was_hit = 0;
//byte store_key_tx = key_tx; //Commented this out as not needed with new code (WD9DMP)
byte previous_sidetone_mode = 0;
if ((analogbuttontemp < analog_buttons_number_of_buttons) && ((millis() - last_button_action) > 200)) {
#ifdef FEATURE_MEMORIES
repeat_memory = 255;
#endif
button_depress_time = millis();
while ((analogbuttontemp == analogbuttonpressed()) && ((millis() - button_depress_time) < 1000)) {
if ((paddle_pin_read(paddle_left) == LOW) || (paddle_pin_read(paddle_right) == LOW)) {
button_depress_time = 1001; // if button 0 is held and a paddle gets hit, assume we have a hold and shortcut out
if (analogbuttontemp <0 ) {
// no button pressed.
return;
}
#ifdef FEATURE_MEMORIES
repeat_memory = 255;
#endif
button_depress_time = button_array.last_pressed_ms;
while (button_array.Held(analogbuttontemp, button_depress_time + 1000)) {
if ((paddle_pin_read(paddle_left) == LOW) || (paddle_pin_read(paddle_right) == LOW)) {
button_depress_time = 1001; // if button 0 is held and a paddle gets hit, assume we have a hold and shortcut out
}
}
if ((millis() - button_depress_time) < 500) {
if (analogbuttontemp == 0) {
command_mode_disable_tx = !key_tx; //Added to sync the Command Mode entry state to actual key_tx state in case changed by CLI or keyboard (WD9DMP)
key_tx = 0;
command_mode();
if (command_mode_disable_tx) {
//key_tx = !store_key_tx; //Inverting pre-command mode state seems to cause Command Mode sync issues (WD9DMP)
key_tx = 0; //Added this line to explicitly disable key_tx if command_mode_disable_tx is set after exiting Command Mode (WD9DMP)
} else {
key_tx = 1;
}
}
if ((millis() - button_depress_time) < 500) {
if (analogbuttontemp == 0) {
command_mode_disable_tx = !key_tx; //Added to sync the Command Mode entry state to actual key_tx state in case changed by CLI or keyboard (WD9DMP)
key_tx = 0;
command_mode();
if (command_mode_disable_tx) {
//key_tx = !store_key_tx; //Inverting pre-command mode state seems to cause Command Mode sync issues (WD9DMP)
key_tx = 0; //Added this line to explicitly disable key_tx if command_mode_disable_tx is set after exiting Command Mode (WD9DMP)
} else {
key_tx = 1;
}
}
#ifdef FEATURE_MEMORIES
if ((analogbuttontemp > 0) && (analogbuttontemp < (number_of_memories + 1)) && ((millis() - button_last_add_to_send_buffer_time) > 400)) {
#ifdef FEATURE_WINKEY_EMULATION
#ifndef OPTION_WINKEY_2_SUPPORT
#ifdef FEATURE_MEMORIES
if ((analogbuttontemp > 0) && (analogbuttontemp < (number_of_memories + 1)) && ((millis() - button_last_add_to_send_buffer_time) > 400)) {
#ifdef FEATURE_WINKEY_EMULATION
#ifndef OPTION_WINKEY_2_SUPPORT
add_to_send_buffer(SERIAL_SEND_BUFFER_MEMORY_NUMBER);
add_to_send_buffer(analogbuttontemp - 1);
#else //OPTION_WINKEY_2_SUPPORT
if ((winkey_host_open) && (wk2_mode == 2)) { // if winkey is open and in wk2 mode, tell it about the button press
byte winkey_byte_to_send = 0xc8;
switch(analogbuttontemp) {
case 1: winkey_byte_to_send = winkey_byte_to_send | 1; break;
case 2: winkey_byte_to_send = winkey_byte_to_send | 2; break;
case 3: winkey_byte_to_send = winkey_byte_to_send | 4; break;
case 4: winkey_byte_to_send = winkey_byte_to_send | 16; break;
}
winkey_port_write(winkey_byte_to_send,0);
winkey_port_write(0xc8,0); // tell it that the button is unpressed
} else { // otherwise, have the buttons act as normal
add_to_send_buffer(SERIAL_SEND_BUFFER_MEMORY_NUMBER);
add_to_send_buffer(analogbuttontemp - 1);
#else //OPTION_WINKEY_2_SUPPORT
if ((winkey_host_open) && (wk2_mode == 2)) { // if winkey is open and in wk2 mode, tell it about the button press
byte winkey_byte_to_send = 0xc8;
switch(analogbuttontemp) {
case 1: winkey_byte_to_send = winkey_byte_to_send | 1; break;
case 2: winkey_byte_to_send = winkey_byte_to_send | 2; break;
case 3: winkey_byte_to_send = winkey_byte_to_send | 4; break;
case 4: winkey_byte_to_send = winkey_byte_to_send | 16; break;
}
winkey_port_write(winkey_byte_to_send,0);
winkey_port_write(0xc8,0); // tell it that the button is unpressed
} else { // otherwise, have the buttons act as normal
add_to_send_buffer(SERIAL_SEND_BUFFER_MEMORY_NUMBER);
add_to_send_buffer(analogbuttontemp - 1);
}
#endif //OPTION_WINKEY_2_SUPPORT
#else //FEATURE_WINKEY_EMULATION
add_to_send_buffer(SERIAL_SEND_BUFFER_MEMORY_NUMBER);
add_to_send_buffer(analogbuttontemp - 1);
#endif //FEATURE_WINKEY_EMULATION
}
#endif //OPTION_WINKEY_2_SUPPORT
#else //FEATURE_WINKEY_EMULATION
add_to_send_buffer(SERIAL_SEND_BUFFER_MEMORY_NUMBER);
add_to_send_buffer(analogbuttontemp - 1);
#endif //FEATURE_WINKEY_EMULATION
button_last_add_to_send_buffer_time = millis();
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\ncheck_buttons: add_to_send_buffer: "));
debug_serial_port->println(analogbuttontemp - 1);
#endif //DEBUG_BUTTONS
}
#endif
} else {
button_last_add_to_send_buffer_time = millis();
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\ncheck_buttons: add_to_send_buffer: "));
debug_serial_port->println(analogbuttontemp - 1);
#endif //DEBUG_BUTTONS
}
#endif
} else {
// if ((millis() - button_depress_time) < 1000) {
// if ((analogbuttontemp > 0) && (analogbuttontemp < 7)) {
// key_tx = 0;
@ -8464,86 +8223,86 @@ void check_command_buttons()
// key_tx = 1;
// }
// } else { // we got a button hold
if (analogbuttontemp == 0) {
key_tx = 0;
// do stuff if this is a command button hold down
while (analogbuttonpressed() == 0) {
if (paddle_pin_read(paddle_left) == LOW) { // left paddle increase speed
speed_change(1);
previous_sidetone_mode = configuration.sidetone_mode;
configuration.sidetone_mode = SIDETONE_ON;
sending_mode = MANUAL_SENDING;
send_dit();
configuration.sidetone_mode = previous_sidetone_mode;
//speed_button_cmd_executed = 1;
dit_buffer = 0;
if (analogbuttontemp == 0) {
key_tx = 0;
// do stuff if this is a command button hold down
while (button_array.Held(analogbuttontemp)) {
if (paddle_pin_read(paddle_left) == LOW) { // left paddle increase speed
speed_change(1);
previous_sidetone_mode = configuration.sidetone_mode;
configuration.sidetone_mode = SIDETONE_ON;
sending_mode = MANUAL_SENDING;
send_dit();
configuration.sidetone_mode = previous_sidetone_mode;
//speed_button_cmd_executed = 1;
dit_buffer = 0;
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F("\ncheck_buttons: speed_change(1)"));
#endif //DEBUG_BUTTONS
#if defined(FEATURE_WINKEY_EMULATION) && defined(FEATURE_POTENTIOMETER)
if ((primary_serial_port_mode == SERIAL_WINKEY_EMULATION) && (winkey_host_open)) {
winkey_port_write(((configuration.wpm-pot_wpm_low_value)|128),0);
winkey_last_unbuffered_speed_wpm = configuration.wpm;
}
#endif
}
if (paddle_pin_read(paddle_right) == LOW) { // right paddle decreases speed
speed_change(-1);
previous_sidetone_mode = configuration.sidetone_mode;
configuration.sidetone_mode = SIDETONE_ON;
sending_mode = MANUAL_SENDING;
send_dah();
configuration.sidetone_mode = previous_sidetone_mode;
//speed_button_cmd_executed = 1;
dah_buffer = 0;
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F("\ncheck_buttons: speed_change(-1)"));
#endif //DEBUG_BUTTONS
#if defined(FEATURE_WINKEY_EMULATION) && defined(FEATURE_POTENTIOMETER)
if ((primary_serial_port_mode == SERIAL_WINKEY_EMULATION) && (winkey_host_open)) {
winkey_port_write(((configuration.wpm-pot_wpm_low_value)|128),0);
winkey_last_unbuffered_speed_wpm = configuration.wpm;
}
#endif
}
}
key_tx = 1;
} //(analogbuttontemp == 0)
if ((analogbuttontemp > 0) && (analogbuttontemp < analog_buttons_number_of_buttons)) {
while (button_array.Held(analogbuttontemp)) {
if (((paddle_pin_read(paddle_left) == LOW) || (paddle_pin_read(paddle_right) == LOW)) && (analogbuttontemp < (number_of_memories + 1))){
#ifdef FEATURE_MEMORIES
repeat_memory = analogbuttontemp - 1;
last_memory_repeat_time = 0;
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F("\ncheck_buttons: speed_change(1)"));
#endif //DEBUG_BUTTONS
#if defined(FEATURE_WINKEY_EMULATION) && defined(FEATURE_POTENTIOMETER)
if ((primary_serial_port_mode == SERIAL_WINKEY_EMULATION) && (winkey_host_open)) {
winkey_port_write(((configuration.wpm-pot_wpm_low_value)|128),0);
winkey_last_unbuffered_speed_wpm = configuration.wpm;
}
#endif
}
if (paddle_pin_read(paddle_right) == LOW) { // right paddle decreases speed
speed_change(-1);
previous_sidetone_mode = configuration.sidetone_mode;
configuration.sidetone_mode = SIDETONE_ON;
sending_mode = MANUAL_SENDING;
send_dah();
configuration.sidetone_mode = previous_sidetone_mode;
//speed_button_cmd_executed = 1;
dah_buffer = 0;
#ifdef DEBUG_BUTTONS
debug_serial_port->println(F("\ncheck_buttons: speed_change(-1)"));
#endif //DEBUG_BUTTONS
#if defined(FEATURE_WINKEY_EMULATION) && defined(FEATURE_POTENTIOMETER)
if ((primary_serial_port_mode == SERIAL_WINKEY_EMULATION) && (winkey_host_open)) {
winkey_port_write(((configuration.wpm-pot_wpm_low_value)|128),0);
winkey_last_unbuffered_speed_wpm = configuration.wpm;
}
#endif
}
}
key_tx = 1;
} //(analogbuttontemp == 0)
if ((analogbuttontemp > 0) && (analogbuttontemp < analog_buttons_number_of_buttons)) {
while (analogbuttonpressed() == analogbuttontemp) {
if (((paddle_pin_read(paddle_left) == LOW) || (paddle_pin_read(paddle_right) == LOW)) && (analogbuttontemp < (number_of_memories + 1))){
#ifdef FEATURE_MEMORIES
repeat_memory = analogbuttontemp - 1;
last_memory_repeat_time = 0;
#ifdef DEBUG_BUTTONS
debug_serial_port->print(F("\ncheck_buttons: repeat_memory:"));
debug_serial_port->println(repeat_memory);
#endif //DEBUG_BUTTONS
#endif
paddle_was_hit = 1;
}
}
if (!paddle_was_hit) { // if no paddle was hit, this was a button hold to change transmitters
key_tx = 0;
previous_sidetone_mode = configuration.sidetone_mode;
configuration.sidetone_mode = SIDETONE_ON;
switch_to_tx(analogbuttontemp);
key_tx = 1;
configuration.sidetone_mode = previous_sidetone_mode;
}
}
//} // button hold
}
last_button_action = millis();
#ifdef FEATURE_SLEEP
last_activity_time = millis();
#endif //FEATURE_SLEEP
debug_serial_port->print(F("\ncheck_buttons: repeat_memory:"));
debug_serial_port->println(repeat_memory);
#endif //DEBUG_BUTTONS
#endif
paddle_was_hit = 1;
}
}
if (!paddle_was_hit) { // if no paddle was hit, this was a button hold to change transmitters
key_tx = 0;
previous_sidetone_mode = configuration.sidetone_mode;
configuration.sidetone_mode = SIDETONE_ON;
switch_to_tx(analogbuttontemp);
key_tx = 1;
configuration.sidetone_mode = previous_sidetone_mode;
}
}
//} // button hold
}
last_button_action = millis();
#ifdef FEATURE_SLEEP
last_activity_time = millis();
#endif //FEATURE_SLEEP
}
#endif //FEATURE_COMMAND_BUTTONS

Wyświetl plik

@ -24,7 +24,7 @@
#define potentiometer_enable_pin 0 // if defined, the potentiometer will be enabled only when this pin is held low; set to 0 to ignore this pin
#ifdef FEATURE_COMMAND_BUTTONS
#define analog_buttons_pin A1
#define analog_buttons_pin A3
#define command_mode_active_led 0
#endif //FEATURE_COMMAND_BUTTONS

Wyświetl plik

@ -0,0 +1,138 @@
#include "arduino.h"
#include "buttonarray.h"
Button::InitLimits(uint8_t step){
/*
typical button values:
0: -56 - 46
1: 47 - 131
2: 132 - 203
3: 203 - 264
*/
int32_t button_value;
int32_t lower_button_value;
int32_t higher_button_value;
button_value = uint32_t(max_value * (float(step * r2_value)/float((step * r2_value) + r1_value)));
lower_button_value = uint32_t(max_value * (float((step-1) * r2_value)/float(((step-1) * r2_value) + r1_value)));
higher_button_value = uint32_t(max_value * (float((step+1) * r2_value)/float(((step+1) * r2_value) + r1_value)));
low_limit_= (button_value - ((button_value - lower_button_value)/2));
high_limit_= (button_value + ((higher_button_value - button_value)/2));
step_ = step;
}
Button::InitLimits(uint8_t step, int32_t low_limit, int32_t high_limit){
low_limit_ = low_limit;
high_limit_ = high_limit;
step_ = step;
}
bool Button::Pressed(int32_t analog_reading){
if ((analog_reading > low_limit_) && (analog_reading <= high_limit_)) {
return true;
}
return false;
}
int32_t Button::high_limit(){
return high_limit_;
}
int32_t Button::low_limit(){
return low_limit_;
}
// Add all buttons in incremental order
ButtonArray::AddAll(){
size_t index;
if (reversed_) {
index = nb_buttons_ - 1;
}
for(size_t i = 0; i < nb_buttons_; i++)
{
if (reversed_) {
Add(i, index);
index --;
} else {
Add(i, i);
}
}
}
// Adds a single button to the array
// Takes a step (rank in the resistor ladder), and the index in the button array.
ButtonArray::Add(uint8_t step, uint8_t index){
Button button;
button.InitLimits(step);
button_array_[index] = button;
high_limit_ = max(button.high_limit() , high_limit_);
}
ButtonArray::Add(uint8_t step, uint8_t index, int32_t low_limit, int32_t high_limit){
Button button;
button.InitLimits(step, low_limit, high_limit);
button_array_[index] = button;
high_limit_ = max(high_limit, high_limit_);
}
int32_t ButtonArray::high_limit(){
return high_limit_;
}
int8_t ButtonArray::ReadButtons(){
uint32_t analog_read_temp =0;
uint32_t analog_line_read_average=0;
for (byte x = 0; x < 19; x++){
analog_read_temp = analogRead(pin_);
if (analog_read_temp <= high_limit_){
analog_line_read_average = (analog_line_read_average + analog_read_temp) / 2;
}
}
for (size_t x = 0; x < nb_buttons_; x++) {
Button button = button_array_[x];
if (button.Pressed(analog_line_read_average)) {
last_pressed_ms = millis();
return x;
}
}
return -1;
}
// returns the index of the pressed button or -1 if none pressed
int8_t ButtonArray::Pressed() {
if ((analogRead(pin_) <= high_limit_) && ((millis() - last_pressed_ms) > DEBOUNCE_MS )){
return ReadButtons();
}
return -1;
}
// returns true if button at the provided index is pressed
bool ButtonArray::Pressed(uint8_t index) {
uint32_t analog_read_temp =0;
analog_read_temp = analogRead(pin_);
if ((analog_read_temp <= high_limit_) && ( index < nb_buttons_)) {
Button button = button_array_[index];
return button.Pressed(analog_read_temp);
}
return false;
}
// Return true as long as the indicated button is held and the deadline not reached.
bool ButtonArray::Held(uint8_t index, uint32_t deadline) {
if ((analogRead(pin_) <= high_limit_) &&
(millis() < deadline) &&
(ReadButtons() == index)) {
return true;
}
return false;
}
// Return true as long as the indicated button is held
bool ButtonArray::Held(uint8_t index) {
if ((analogRead(pin_) <= high_limit_) && (ReadButtons() == index)) {
return true;
}
return false;
}

Wyświetl plik

@ -0,0 +1,54 @@
#ifndef buttonarray_h
#define buttonarray_h
#include "Arduino.h"
#define MAX_BUTTONS 8
#define DEBOUNCE_MS 200
#if defined(ARDUINO_ARCH_ESP32)
#define max_value 4095
#else
#define max_value 1023
#endif
#define r1_value 10
#define r2_value 1
class Button {
private:
int32_t low_limit_;
int32_t high_limit_;
uint8_t step_;
public:
Button(){};
InitLimits(uint8_t step);
InitLimits(uint8_t step, int32_t low_limit, int32_t high_limit);
bool Pressed(int32_t analog_reading);
int32_t high_limit();
int32_t low_limit();
};
class ButtonArray {
private:
Button button_array_[MAX_BUTTONS];
uint8_t pin_;
uint8_t nb_buttons_;
int32_t high_limit_;
bool reversed_;
int8_t ReadButtons();
public:
uint32_t last_pressed_ms;
ButtonArray(uint8_t pin, uint8_t nb, bool reversed): pin_(pin), nb_buttons_(nb), reversed_(reversed){};
AddAll();
Add(uint8_t step, uint8_t index);
Add(uint8_t step, uint8_t index, int32_t low_limit, int32_t high_limit);
int32_t high_limit();
int8_t Pressed();
bool Pressed(uint8_t index);
bool Held(uint8_t index);
bool Held(uint8_t index, uint32_t deadline );
};
#endif

Wyświetl plik

@ -0,0 +1,116 @@
#include "arduino.h"
#include "buttonarray.h"
Button::InitLimits(uint8_t step){
int32_t button_value;
int32_t lower_button_value;
int32_t higher_button_value;
button_value = uint32_t(max_value * (float(step * r2_value)/float((step * r2_value) + r1_value)));
lower_button_value = uint32_t(max_value * (float((step-1) * r2_value)/float(((step-1) * r2_value) + r1_value)));
higher_button_value = uint32_t(max_value * (float((step+1) * r2_value)/float(((step+1) * r2_value) + r1_value)));
low_limit_= (button_value - ((button_value - lower_button_value)/2));
high_limit_= (button_value + ((higher_button_value - button_value)/2));
step_ = step;
}
bool Button::Pressed(int32_t analog_reading)
{
if ((analog_reading > low_limit_) && (analog_reading <= high_limit_)) {
return true;
}
return false;
}
int32_t Button::high_limit()
{
return high_limit_;
}
int32_t Button::low_limit()
{
return low_limit_;
}
// Add all buttons in incremental order
ButtonArray::AddAll()
{
for(size_t i = 0; i < nb_buttons_; i++)
{
ButtonArray::Add(i, i);
}
}
// Adds a single button to the array
// Takes a step (rank in the resistor ladder), and the index in the button array.
ButtonArray::Add(uint8_t step, uint8_t index){
Button button;
button.init_limits(step);
button_array_[index] = button;
if (button.high_limit() > high_limit_) {
high_limit_ = button.high_limit();
}
}
int32_t ButtonArray::high_limit(){
return high_limit_;
}
int8_t ButtonArray::ReadButtons(){
uint32_t analog_read_temp =0;
uint32_t analog_line_read_average=0;
for (byte x = 0; x < 19; x++){
analog_read_temp = analogRead(pin_);
if (analog_read_temp <= high_limit_){
analog_line_read_average = (analog_line_read_average + analog_read_temp) / 2;
}
}
for (size_t x = 0; x < nb_buttons_; x++) {
Button button = button_array_[x];
if (button.Pressed(analog_line_read_average)) {
last_pressed_ms = millis();
return x;
}
}
return -1;
}
// returns the index of the pressed button or -1 if none pressed
int8_t ButtonArray::Pressed()
{
if ((analogRead(pin_) <= high_limit_) && ((millis() - last_pressed_ms) > DEBOUNCE_MS )){
return ReadButtons();
}
return -1;
}
// returns true if button at the provided index is pressed
bool ButtonArray::Pressed(uint8_t index)
{
uint32_t analog_read_temp =0;
analog_read_temp = analogRead(pin_);
if (analog_read_temp <= high_limit_) && ( index < nb_buttons_)) {
Button button = button_array_[index];
return button.Pressed(analog_read_temp)
}
return false;
}
// Return true as long as the indicated button is held and the deadline not reached.
bool ButtonArray::Held(uint8_t index, uint32_t deadline)
{
if ((analogRead(pin_) <= high_limit_) &&
(millis() < deadline) &&
(ReadButtons() == index)) {
return true;
}
return false;
}
// Return true as long as the indicated button is held
bool ButtonArray::Held(uint8_t index)
{
if ((analogRead(pin_) <= high_limit_) && (ReadButtons() == index)) {
return true;
}
return false;
}

Wyświetl plik

@ -0,0 +1,50 @@
#ifndef buttonarray_h
#define buttonarray_h
#include "Arduino.h"
#define MAX_BUTTONS 8
#define DEBOUNCE_MS 200
#if defined(ARDUINO_ARCH_ESP32)
#define max_value 4095
#else
#define max_value 1023
#endif
#define r1_value 10
#define r2_value 1
class Button {
private:
int32_t low_limit_;
int32_t high_limit_;
uint8_t step_;
public:
Button(){};
InitLimits(uint8_t step);
bool Pressed(int32_t analog_reading);
int32_t high_limit();
int32_t low_limit();
};
class ButtonArray {
private:
Button button_array_[MAX_BUTTONS];
uint8_t pin_;
uint8_t nb_buttons_;
int32_t high_limit_;
int8_t ReadButtons();
public:
uint32_t last_pressed_ms;
ButtonArray(uint8_t pin, uint8_t nb): pin_(pin), nb_buttons_(nb){};
AddAll();
Add(uint8_t step, uint8_t index);
int32_t high_limit();
int8_t Pressed();
bool Pressed(uint8_t index);
bool Held(uint8_t index, uint32_t deadline );
};
#endif