Hello, i have the following library that I was using with Uno R3 and it was working perfect. Now I switch the boards and I am trying to adapt it to Nano 33 IoT but I have a compile error and it looks like an interrupt or macros problem.
#define ENC_RD PIND //encoder port read
#define A_PIN 2 // pdip 4, associated with INT0 vector; PD2
#define B_PIN 3 // pdip 5, associated with INT1 vector; PD3
#define rstbtn 4 // reset button
volatile long counter = 0;
const float R = 0.15;
float distance = 0;
void setup() {
Serial.begin(115200);
pinMode(A_PIN, INPUT_PULLUP);
pinMode(B_PIN, INPUT_PULLUP);
pinMode(rstbtn, INPUT_PULLUP);
attachInterrupt(0, evaluateRotary, CHANGE);
attachInterrupt(1, evaluateRotary, CHANGE);
}
void resetCounter() {
noInterrupts();
counter = 0;
interrupts();
}
void loop() {
static long lastCounter = 0;
distance = R * lastCounter;
// this use of 'counter' must be protected from interruption:
noInterrupts();
lastCounter = counter;
interrupts();
Serial.println();
Serial.print(distance);
if (digitalRead(rstbtn) == LOW) {
resetCounter();
}
}
void evaluateRotary() {
/* encoder routine. Expects encoder with four state changes between detents */
/* and both pins open on detent */
static uint8_t old_AB = 3; //lookup table index
static int8_t encval = 0; //encoder value
static const int8_t enc_states[] PROGMEM = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; //encoder lookup table
/**/
old_AB <<= 2; //remember previous state
old_AB |= ((ENC_RD >> 2) & 0x03);
encval += pgm_read_byte(&(enc_states[(old_AB & 0x0f)]));
if (encval > 3) { //four steps forward
counter++;
encval = 0;
} else if (encval < -3) { //four steps backwards
counter--;
encval = 0;
}
}
C:\Users\Bobby\Documents\Arduino\WORKING_ENCODER_CODE!!!\WORKING_ENCODER_CODE!!!.ino: In function 'void evaluateRotary()':
C:\Users\Bobby\Documents\Arduino\WORKING_ENCODER_CODE!!!\WORKING_ENCODER_CODE!!!.ino:1:16: error: 'PIND' was not declared in this scope
#define ENC_RD PIND //encoder port read
^
C:\Users\Bobby\Documents\Arduino\WORKING_ENCODER_CODE!!!\WORKING_ENCODER_CODE!!!.ino:51:15: note: in expansion of macro 'ENC_RD'
old_AB |= ((ENC_RD >> 2) & 0x03);
^~~~~~
C:\Users\Bobby\Documents\Arduino\WORKING_ENCODER_CODE!!!\WORKING_ENCODER_CODE!!!.ino:1:16: note: suggested alternative: 'SING'
#define ENC_RD PIND //encoder port read
^
C:\Users\Bobby\Documents\Arduino\WORKING_ENCODER_CODE!!!\WORKING_ENCODER_CODE!!!.ino:51:15: note: in expansion of macro 'ENC_RD'
old_AB |= ((ENC_RD >> 2) & 0x03);
^~~~~~
exit status 1
Compilation error: 'PIND' was not declared in this scope
PIND is a register that exists on the UNO or Nano etc. You don't have the same chip in your Nano 33 IoT and accessing GPIOs does not work in the same way.
I use this encoder library but never tried it on a Nano 33 IoT. (it works with the Teensy LC which uses also a Cortex M0 core as in Nano 33 IoT)
The change is only superficial, you still haven't changed the vital thing that is missing and that is the pind register does not exist in your processor.
See this link
you'll probably find that your encoder provides 4 ticks per click, it's just a matter of dividing the read() by 4 in that case (you can use >> 2 to do so)
The code now works, but it constantly adds the next value after I return it to 0....
if say i rotate it from 0 to 20 and back to 0 it shows 20. Then when I rotate it again from 0 to 10 it adds the last value to the previous and the final print in the serial monitor is 30 and so on, the number constantly grows.
I think I didn't explain myself. The reset button is working, when I press the button it zeroes the value and the encoder starts counting from zero again.
The problem is when the encoder is returned to its physical zero position the reading on the display doesn't go to zero but stays in the last encoder position.
and when the encoder is rotated again from its physical zero position the reading adds this new value to the previous. And even though the encoder is back in its physical position the value is even bigger cos it was a sum of all previous encoder movements.
Hopefully, that makes sense.
Done the pin swap on the board, still the same. All day today I am trying different libraries and all of them are working except that the value constantly grows .........just multiplies itself every time you rotate the encoder. It doesn't register the reverse direction only adds the forward direction. Very strange.
this is the bit of the code that does what I want but I can't get my head around how to do the internal pinD processes equivalent in this new processor.
void evaluateRotary() {
/* encoder routine. Expects encoder with four state changes between detents */
/* and both pins open on detent */
static uint8_t old_AB = 3; //lookup table index
static int8_t encval = 0; //encoder value
static const int8_t enc_states[] PROGMEM = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; //encoder lookup table
/**/
old_AB <<= 2; //remember previous state
old_AB |= ((ENC_RD >> 2) & 0x03);
encval += pgm_read_byte(&(enc_states[(old_AB & 0x0f)]));
if (encval > 3) { //four steps forward
counter++;
encval = 0;
} else if (encval < -3) { //four steps backwards
counter--;
encval = 0;
}
}