I am moving from the standard Nano to a Nano every. Same code, same PCB etc. Everything compiles and downloads well, and everything else works (Interrupts, rotary encodes, keyboard, inputs and outputs etc) except the I2C on pins A5 & A5.
I am just unplugging a standard Nano and plugging in an EVERY with identical code.
There is no activity there on an oscilloscope and the lines stay at a level '1'.
Any ideas? Is this a library issue with wire.h? I think I am using a current version.
OK, It's fixed. Not sure which, but it was one of:
a) Updated to Arduino 1.8.13 IDE for Win 10
b) Changed Wire.begin(1); to Wire.begin(); (Shouldn't be it)
All good now... M
What code did you use for the rotary encoder? I had some trouble getting the Every to work with mine that was working perfectly with the original Nano. I think I have it sorted now but it took some work!
Hi. I use two rotary encoders. I had no issues with this going to the EVEARZY... 1 is a 400ppr and the other about 20ppr (See www.hampiradio.com for pictures. For the first I made an interrupt routine and the second is just polled every time around the loop. I'll try yo copy a bit of code here for you: (Let me know if this helps, will be interesting to see if it works for you. Cheers Michael, in New Zealand)
// ------------------------------------------------------------------------------------------
// Interrupt Service Routines
// ------------------------------------------------------------------------------------------
void ISR2() {
if ( locked ) return;
detachInterrupt(digitalPinToInterrupt(2));
// detachInterrupt(digitalPinToInterrupt(3));
c = digitalRead(encoderPinA); // read pin a
c = c * 2 + digitalRead(encoderPinB); // shift bit 0 left one and fetch bit 0 from pin b
if (c == 0 || c == 3 ) { // 0 or 3 = anti-clockwise
tune_cnt -= 1;
} else { // else must be 1 or 2 clockwise
tune_cnt += 1;
}
attachInterrupt(digitalPinToInterrupt(2), ISR2, CHANGE);
// attachInterrupt(digitalPinToInterrupt(3), ISR2, CHANGE);
}
void setup() {
// just the relevant code...
attachInterrupt(digitalPinToInterrupt(2), ISR2, CHANGE);
}
Just read tune_count in a main loop function, and clear it when processed...
For the 20ppr rotaty encoder:
void aux_encoder() {
aux_encoderB = digitalRead(aux_encoderPinB); // Read the encoder pinB
if (aux_encoderB != aux_encoderB_temp) {
aux_encoderA = digitalRead(aux_encoderPinA); // Read the encoder pin A
aux_encoderB = digitalRead(aux_encoderPinB);
d = aux_encoderA * 2 + aux_encoderB; // c = 1 2 3 or 4
if (d == 1 || d == 2) { // 1 2 if RIT & clockwise
aux_cnt++;
}
else { // counter-clockwise
aux_cnt--;
}
aux_encoderB_temp = aux_encoderB; // save the last position
}
if ( !aux_cnt ) return;
Then use / clear aux_cnt elsewhere.
Thanks Michael I will give this a try later.
My encoder is just a simple 24PPR Bourns encoder. I only need to know if it was turned, and if the direction was CW or CCW.
My original code for the standard Nano used a couple of lines of Assembler to set up the interrupts rather than the attachInterrupt() function. Because the ATmega4809 on the Nano Every has totally different interrupt registers and vectors it obviously wouldn't work with the ATmega328 assembler code I had used but I managed to re-write that.
I had tried attachInterrupt() but couldn't get it to work. My ISR has a parameter for the interrupt vector - that's probably why it didn't work with the Every as that has different vectors.
This was the code for the standard Nano:
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result) {
rotary_iresult = result;
}
}
I am using interrupts on both the encoder pins. On the Nano they are D2 and D3 and both are on the same port (PORTA) but on the Every they are on PORTA and PORTF so I needed two ISRs:
#define PA0_INTERRUPT PORTA.INTFLAGS & PIN0_bm
#define PA0_CLEAR_INTERRUPT_FLAG PORTA.INTFLAGS &= PIN0_bm
#define PF5_INTERRUPT PORTF.INTFLAGS & PIN5_bm
#define PF5_CLEAR_INTERRUPT_FLAG PORTF.INTFLAGS &= PIN5_bm
ISR(PORTA_PORT_vect) {
unsigned char result = r.process();
if (PA0_INTERRUPT)
PA0_CLEAR_INTERRUPT_FLAG;
if (result) {
// Serial.println(result == DIR_CW ? "Right" : "Left");
rotary_iresult = result;
}
}
ISR(PORTF_PORT_vect) {
unsigned char result = r.process();
if (PF5_INTERRUPT)
PF5_CLEAR_INTERRUPT_FLAG;
if (result) {
// Serial.println(result == DIR_CW ? "Right" : "Left");
rotary_iresult = result;
}
}
I didn't even know there was a detachInterrupt() function! Why is it needed?
Regards, Phil.
PS You should put your code in between the CODE tags (see </> icon on the toolbar so it formats better and can be copied easily.
hampiradio:
OK, It's fixed. Not sure which, but it was one of:
a) Updated to Arduino 1.8.13 IDE for Win 10
b) Changed Wire.begin(1); to Wire.begin(); (Shouldn't be it)All good now... M
For the record, Wire.begin(1) would configure the TWI as a slave at address 1, while Wire.begin() configures it as a master. So that was certainly a factor! FYI while the TWI interface in the ATmega4809 is capable of running as both a master and slave at the same time, the Arduino library explicitly prevents that from happening. For this reason if you use Wire.begin(1) you cannot proceed with master read/write commands.