Move encoder functions to their own file

This commit is contained in:
Reed Nightingale 2020-01-19 22:49:59 -08:00
parent 59347af9ed
commit 9fb4efc5ac
3 changed files with 76 additions and 142 deletions

72
encoder.cpp Normal file
View File

@ -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);
}

4
encoder.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
void enc_setup(void);
int enc_read(void);

View File

@ -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());