diff --git a/encoder.cpp b/encoder.cpp new file mode 100644 index 0000000..c5bc049 --- /dev/null +++ b/encoder.cpp @@ -0,0 +1,72 @@ +/* + * SmittyHalibut's encoder handling, using interrupts. Should be quicker, smoother handling. + */ +int8_t enc_count; +uint8_t prev_enc; + +uint8_t enc_state (void) { + return (digitalRead(ENC_A)?1:0 + digitalRead(ENC_B)?2:0); +} + +/* + * The Interrupt Service Routine for Pin Change Interrupts on A0-A5. + */ +ISR (PCINT1_vect) { + uint8_t cur_enc = enc_state(); + if (prev_enc == cur_enc) { + //Serial.println("unnecessary ISR"); + return; + } + //Serial.print(prev_enc); + //Serial.println(cur_enc); + + //these transitions point to the enccoder being rotated anti-clockwise + if ((prev_enc == 0 && cur_enc == 2) || + (prev_enc == 2 && cur_enc == 3) || + (prev_enc == 3 && cur_enc == 1) || + (prev_enc == 1 && cur_enc == 0)) + { + enc_count-=1; + } + //these transitions point to the enccoder being rotated clockwise + else if ((prev_enc == 0 && cur_enc == 1) || + (prev_enc == 1 && cur_enc == 3) || + (prev_enc == 3 && cur_enc == 2) || + (prev_enc == 2 && cur_enc == 0)) + { + enc_count+=1; + } + else { + // A change to two states, we can't tell whether it was forward or backward, so we skip it. + //Serial.println("skip"); + } + prev_enc = cur_enc; // Record state for next pulse interpretation +} + +/* + * Setup the encoder interrupts and global variables. + */ +void pci_setup(byte pin) { + *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin + PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt + PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group +} + +void enc_setup(void) +{ + enc_count = 0; + // This is already done in setup() ? + //pinMode(ENC_A, INPUT); + //pinMode(ENC_B, INPUT); + prev_enc = enc_state(); + + // Setup Pin Change Interrupts for the encoder inputs + pci_setup(ENC_A); + pci_setup(ENC_B); +} + +int enc_read(void) { + int8_t ret = enc_count; + enc_count = 0; + return int(ret); +} \ No newline at end of file diff --git a/encoder.h b/encoder.h new file mode 100644 index 0000000..5176684 --- /dev/null +++ b/encoder.h @@ -0,0 +1,4 @@ +#pragma once + +void enc_setup(void); +int enc_read(void); \ No newline at end of file diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index 624705f..6f11eb7 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -541,148 +541,6 @@ void updateDisplay() { displayVFO(globalSettings.activeVfo); } - -/** - * The A7 And A6 are purely analog lines on the Arduino Nano - * These need to be pulled up externally using two 10 K resistors - * - * There are excellent pages on the Internet about how these encoders work - * and how they should be used. We have elected to use the simplest way - * to use these encoders without the complexity of interrupts etc to - * keep it understandable. - * - * The enc_state returns a two-bit number such that each bit reflects the current - * value of each of the two phases of the encoder - * - * The enc_read returns the number of net pulses counted over 50 msecs. - * If the puluses are -ve, they were anti-clockwise, if they are +ve, the - * were in the clockwise directions. Higher the pulses, greater the speed - * at which the enccoder was spun - */ - -/* -int enc_prev_state = 3; - -byte enc_state (void) { - //Serial.print(digitalRead(ENC_A)); Serial.print(":");Serial.println(digitalRead(ENC_B)); - return (digitalRead(ENC_A) == 1 ? 1 : 0) + (digitalRead(ENC_B) == 1 ? 2: 0); -} - - -int enc_read(void) { - int result = 0; - byte newState; - int enc_speed = 0; - - long stop_by = millis() + 200; - - while (millis() < stop_by) { // check if the previous state was stable - newState = enc_state(); // Get current state - -// if (newState != enc_prev_state) -// active_delay(20); - - if (enc_state() != newState || newState == enc_prev_state) - continue; - //these transitions point to the encoder being rotated anti-clockwise - if ((enc_prev_state == 0 && newState == 2) || - (enc_prev_state == 2 && newState == 3) || - (enc_prev_state == 3 && newState == 1) || - (enc_prev_state == 1 && newState == 0)){ - result--; - } - //these transitions point o the enccoder being rotated clockwise - if ((enc_prev_state == 0 && newState == 1) || - (enc_prev_state == 1 && newState == 3) || - (enc_prev_state == 3 && newState == 2) || - (enc_prev_state == 2 && newState == 0)){ - result++; - } - enc_prev_state = newState; // Record state for next pulse interpretation - enc_speed++; - active_delay(1); - } - //if (result) - // Serial.println(result); - return(result); -} -*/ - -/* - * SmittyHalibut's encoder handling, using interrupts. Should be quicker, smoother handling. - */ -int8_t enc_count; -uint8_t prev_enc; - -uint8_t enc_state (void) { - return (digitalRead(ENC_A)?1:0 + digitalRead(ENC_B)?2:0); -} - -/* - * Setup the encoder interrupts and global variables. - */ -void pci_setup(byte pin) { - *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin - PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt - PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group -} - -void enc_setup(void) { - enc_count = 0; - // This is already done in setup() ? - //pinMode(ENC_A, INPUT); - //pinMode(ENC_B, INPUT); - prev_enc = enc_state(); - - // Setup Pin Change Interrupts for the encoder inputs - pci_setup(ENC_A); - pci_setup(ENC_B); -} - -/* - * The Interrupt Service Routine for Pin Change Interrupts on A0-A5. - */ -ISR (PCINT1_vect) { - uint8_t cur_enc = enc_state(); - if (prev_enc == cur_enc) { - //Serial.println("unnecessary ISR"); - return; - } - //Serial.print(prev_enc); - //Serial.println(cur_enc); - - //these transitions point to the enccoder being rotated anti-clockwise - if ((prev_enc == 0 && cur_enc == 2) || - (prev_enc == 2 && cur_enc == 3) || - (prev_enc == 3 && cur_enc == 1) || - (prev_enc == 1 && cur_enc == 0)) - { - enc_count-=1; - } - //these transitions point to the enccoder being rotated clockwise - else if ((prev_enc == 0 && cur_enc == 1) || - (prev_enc == 1 && cur_enc == 3) || - (prev_enc == 3 && cur_enc == 2) || - (prev_enc == 2 && cur_enc == 0)) - { - enc_count+=1; - } - else { - // A change to two states, we can't tell whether it was forward or backward, so we skip it. - //Serial.println("skip"); - } - prev_enc = cur_enc; // Record state for next pulse interpretation -} - -int enc_read(void) { - int8_t ret = enc_count; - enc_count = 0; - return int(ret); -} - - - - void ritToggle(struct Button *button){ if(!globalSettings.ritOn){ ritEnable(GetActiveVfoFreq());