Count the number of rising edges

Hi,

I want to count the number of rising edges on the A encoder signals coming out form the motor between two rising edges of the z encoder pulse. My code is as below,

int countA = 0;

void setup()
{
pinMode(2, INPUT); //z encoder
pinMode(3, INPUT); //A encoder

Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), doEncoder, RISING);
Serial.println("start");
}
void loop(){

}
void doEncoder()
{

for (digitalRead(2) == HIGH) {
if (digitalRead(3) == HIGH) {
countA = countA + 1;
}
}Serial.println(countA, DEC);

}

May i know what's wrong with the code as it won't stop counting the positive edge on encoder A. I only want it to count once when there is a rising edge of z encoder.

Thanks.

Do not output to Serial inside an interrupt handler. Serial IO requires use of interrupts, which are blocked while a handler is running.

The pattern to use is:

volatile boolean something_just_happened = false;
volatile int some_important_number;

void interruptHandler() {
  some_important_number ++;
  something_just_happened = true;
}

void loop() {
  // check the status of the interrupt stuff
  // the *only* thing that happens in this section of code is that we 
  // retreive the values that the interrupt handler updates
  // and reset them as needed

  noInterrupts();
  int important_number_copy;
  boolean something_just_happened_copy = something_just_happened;
  if(something_just_happened) {
    important_number_copy =   some_important_number;
    some_important_number = 0; // reset the count
    something_just_happened = false; // reset the flag
  }
  interrupts();

  // end of the nointerrupts block. Now we examine the data that we just retrieved
  // and potentially do something with it
  
  if(something_just_happened_copy) {
    Serial.print("There were ");
    Serial.print(important_number_copy);
    Serial.println(" ticks");
  }
}

May i know what's wrong with the code as it won't stop counting the positive edge on encoder A. I only want it to count once when there is a rising edge of z encoder.

Which pin is the z encoder connected to? Where are you detecting the RISING edge of that pin? The only thing I see you doing is determining if pin 3 IS high (not BECAME high).

It's pretty dumb to check that pin 2 is HIGH in the ISR. The ISR would not have been called unless pin 2 just went HIGH.

Serial.print() has no place in an interrupt handler.

htliew:
Hi,

I want to count the number of rising edges on the A encoder signals coming out form the motor between two rising edges of the z encoder pulse. My code is as below,

  for (digitalRead(2) == HIGH) {

if (digitalRead(3) == HIGH) {
      countA = countA + 1;
    }

What do you suppose that 'for' does? Perhaps you meant 'while' ?

htliew:
Hi,

I want to count the number of rising edges on the A encoder signals coming out form the motor between two rising edges of the z encoder pulse. My code is as below,

int countA = 0;

void setup()
{
pinMode(2, INPUT); //z encoder
pinMode(3, INPUT); //A encoder

Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), doEncoder, RISING);
Serial.println("start");
}
void loop(){

}
void doEncoder()
{

for (digitalRead(2) == HIGH) {
if (digitalRead(3) == HIGH) {
countA = countA + 1;
}
}Serial.println(countA, DEC);

}

May i know what's wrong with the code as it won't stop counting the positive edge on encoder A. I only want it to count once when there is a rising edge of z encoder.

Thanks.

Just curious - how does the above code compile? The complier should generate syntax error on incorrect "for(...)".

The code would be much simpler, less variables, if you gate in the ISR on z first then advance the "new rising edge " counter.

if(z)
new rising edge counter++

then in loop() compare new and old rising edge counter and if different do your processing.

But .. you will need a code to monitor the z "pulse" window , perhaps add an ISR for z also.

Time to draw a flow chart before coding.