Notifications
Clear all

Mystery: Arduino pulse count interrupts with FALLING and RISING edge  

  RSS

mbogelund
(@mbogelund)
Active Member
Joined: 1 year ago
Posts: 19
2020-04-10 7:15 am  

My fellow Dronebotters 🙂

I'm building a robot that has an Arduino Nano controlling 2 motors with rotary encoders. The Nano also reads sensor input from LDR's, and communicates with a Raspberry Pi over I2C (Nano as slave).

I have encountered something that is a mystery to me, and I hope that one of you can help me understand what is going on.

I'm having an issue with counting pulses from the 2 motors' rotary encoders, and I have the following working test code:

const byte interruptPin1 = 2;
const byte interruptPin2 = 3;
volatile int pulseCountLeft = 0;
volatile int pulseCountRight = 0;

void setup() {
Serial.begin(9600);
pinMode(interruptPin1, INPUT_PULLUP);
pinMode(interruptPin2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin1), LeftCount, RISING);
attachInterrupt(digitalPinToInterrupt(interruptPin2), RightCount, RISING);
}

void loop() {
if(pulseCountLeft > 100) {
Serial.println((String)"Left pulses: " + pulseCountLeft);
pulseCountLeft = 0;
}
if(pulseCountRight > 100) {
Serial.println((String)"Right pulses: " + pulseCountRight);
pulseCountRight = 0;
}
}

void LeftCount() {
pulseCountLeft++;
}

void RightCount() {
pulseCountRight++;
}


This works exactly as expected; I turn the wheels on my robot manually, and for every 100 pulses I get a message in the serial monitor for the left or right motor, respectively:

Right pulses: 101
Left pulses: 101
Left pulses: 101
Left pulses: 101
...

In my actual controller program, I have to do the following to make pulse counting work:

  // Attach interrupts to motor pulse pins
attachInterrupt(digitalPinToInterrupt(motor_pulseA_pins[0]), RisingMot1A, RISING);
attachInterrupt(digitalPinToInterrupt(motor_pulseA_pins[1]), RisingMot2A, FALLING);

Ie. the difference here is that I have to attach one interrupt as RISING and the other as FALLING; if both are RISING or both are FALLING, the first ISR (RisingMot1A which is on digital pin 2) isn't called, only the other one works (RisingMot2A on pin 3).

My question is: What is causing this? What could be causing this? I've concluded that my hardware setup works, since everything works fine in my test sketch and when I use one FALLING and one RISING ISR, so I guess it's something about my I2C communication or analog reading of LDR's that is messing with my pulse counting.

Any hints about what to look for in my code is appreciated - thank you 🙂

vkr Martin

 

This topic was modified 7 months ago 3 times by mbogelund

Quote
mbogelund
(@mbogelund)
Active Member
Joined: 1 year ago
Posts: 19
2020-04-10 8:25 am  

Good news, everyone!

I figured it out myself 🙂

In my motor controller code I have a section in setup() where I set up my motor pins. It looked like this:

  // Initialize the motor pins and speed:
for(uint8_t idx = 0; idx < MOTORS; idx++) {
// Pulse reading pins
pinMode(motor_pulseA_pins[idx], INPUT_PULLUP);
pinMode(motor_pulseB_pins[idx], INPUT_PULLUP);
pinMode(motor_ENA_pins[idx], OUTPUT);
pinMode(motor_IN1_pins[idx], OUTPUT);
pinMode(motor_IN2_pins[idx], OUTPUT);
analogWrite(motor_ENA_pins, motor_PWM[idx]);
digitalWrite(motor_IN1_pins[idx], LOW);
digitalWrite(motor_IN2_pins[idx], LOW);
}

MOTORS holds the number of motors on my robot, currently set to 2, so in the above I loop over arrays of setup parameters, and set up my motor pins.

Notice the line

analogWrite(motor_ENA_pins, motor_PWM[idx]);

It has no index on the motor_ENA_pins array. Adding the index fixed it:

analogWrite(motor_ENA_pins[idx], motor_PWM[idx]);

So all in all, analogWrite to an array can ruin your pulse counting... At least I learned something today 🙂


ReplyQuote