I am new to arduino and electronics in general and back to some coding after a hiatus of 20 years
Reading a pin with digitalRead() in a tight loop, is it correct to assume that each call to digitalRead() for a specific pin takes the same time?
Doing some empirical testing on an UNO R3 I am getting constant values reading from the same pin even across power cycles although slightly different per pin.
I am just 'toying about' without a specific task at hand but the idea is to keep a rough track of the wall clock while polling for a pin state change without introducing added latency of time functions.
I wouldn't want to assume that the elapsed time was consistent per pin or between pins, even if your empirical testing suggests it is. Is there some hard real time requirement which precludes the use of micros() or millis() to control time-based activities?
The timing does seem to be constant per pin but varies slightly across pins.
Nick - I tried to look up information about the timer interrupt but failed to land on anything that seems relevant. Is there a timer interrupt that fires to keep a clock updated and possibly other tasks?
Peter - On my uno r3 a digitalRead() takes > 4us. A micros() takes > 3us. So having both calls in a tight loop introduces about 8us per iteration.
The emphasis so far has been on 'toying about' as I ease myself back into some coding and acquaint myself to this joyous world of arduino + hobbyist electronics. In this specific case I was listening in to a device, a dht11 on pin 2, and wanted to visualise the change in signal which i did by storing in memory and then exporting and graphing.
synerr:
Nick - I tried to look up information about the timer interrupt but failed to land on anything that seems relevant. Is there a timer interrupt that fires to keep a clock updated and possibly other tasks?
Every 1024 ยตS an interrupt fires controlled by Timer 0, this is used to update the counter used by millis() and micros() function calls. It would take a few clock cycles to do this, hence this would introduce jitter into any tight loops.
int digitalRead(uint8_t pin)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return LOW;
// If the pin that support PWM output, we need to turn it off
// before getting a digital reading.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
if (*portInputRegister(port) & bit) return HIGH;
return LOW;
}
one can see that there are different code paths
the first return LOW is way faster than the second one
If turnOffPWM needs to be called makes a diff in timing.!!!
the last 2 paths I think are equal in time (compiler can optimize this I expect)
Thanks all for kind help. Mission now accomplished.
PeterH - As a learning exercise I wanted to write an interface to a DTH11 from which the arduino receives a digital transmission with pulses in the order of microseconds without looking at any reference implementation. To see what I was doing my first self imposed task was to visualise the incoming signal at the highest resolution possible. I achieved that by iterating tightly over a digitalRead() saving the state change and iteration number to an array, exporting the results, and graphing them
NickG - Thanks. From that code it does seem that at least for a pin not on a timer the read time should be the same while accounting for interrupt jitter. Found some reading points on interrupts. Now I know what I'm going to be doing next weekend.
Next time I'd recommend using interrupts to capture the edges, or (or you have some specific reason to poll them) use the fast digital pin library - a performance-optimised I/O library with a similar API to the standard Arduino digitalRead()/digitalWrite() functions. Using interrupts would be a better way to capture a high speed digital signal though, IMO.