PWMmeasurement with interrupt: need volatile type or not?

Hello,

I am busy writing code for a project that uses one channel of remote control pwm signal as an input signal. I know there is a good library for this, but still I like to write my own ISR routine for this since I only use one channel it will save me on overhead.
What I wonder is: given the code below, should I define the variable pwmInValue as volatile or not?

unsigned long TsA, TsB;
unsigned int pwmInValue, pwmMeasuredValue; 
byte pwmInPin = 2;


void setup() {
  pinMode(pwmInPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(pwmInPin), PWMTStamps, CHANGE);
}


void loop(){

  pwmMeasuredValue = pwmInValue;
  /*
  *
  * do stuff with pwmMeasuredValue
  */

}

void PWMTStamps() {
  if (digitalRead(pwmInPin)) {
    TsA = micros();
    }
  else {
    TsB = micros();
    pwmInValue = TsB - TsA;
    }
}

Regards,
Peet

From the reference for the volatile keyword:

A variable should be declared volatile whenever its value can be changed by something beyond the control of the code section in which it appears, such as a concurrently executing thread. In the Arduino, the only place that this is likely to occur is in sections of code associated with interrupts, called an interrupt service routine.

You will need to disable interrupts for that assignment,
it is a two byte variable.

Yes, you should make it volatile. Also TsA and TsB you can declare static within ISR itself

Protect the above critical section as follows so that the chance for the variable pwmInValue to undergo change by the PWMTStamos() ISR is nil while being accessed in the loop() function.

noInterrupts();
pwmMeasuredValue = pwmInValue;
interrupts();

OK, everybody sofar: thank you for your replies.

A few thoughts:
@GolamMostafa: considering pwmInValue is a 16 bit variable, shouldn't it then be

ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  pwmMeasuredValue = pwmInValue;
}

rather then just disabling and restarting interrupts?

The thing behind my initial question: I studied Arduino-PWM-Reader-master library and noticed that nowhere in that library interrupts are disabled or enabled nor is the atomic_block macro used (or advised to use in the main loop). Yet this library seem to work quite good I am puzzeled why... I must be overlooking something, but I don't see it. Hopefully someone can enlighten me.

Regards,
Peet

Thank you for this reference, good stuff!

However... if I look at the example given on that webpage called "Example code of a pump timer" I noticed that the variable

volatile boolean buttonPressed; 

Yet, nowhere in the main loop of that piece of code I see interrupts being disabled and re-enabled when the variable buttonPressed is read or changed. These are exactly the kind of examples that confuse me...

Regards,
Peet

A bool variable is likely a single byte so access will be atomic even on an 8-bit AVR.

There is no difference between the two when used in non-ISR code running on a single-core processor.

1 Like

True it is 8 bits, thank you for clarification.

You are right, I read the arduino reference on this once more and it is clear now. Thank you.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.