Getting the value of a digital pin at high speed

I have a code to read pulses of a control for the air conditioner, the code is based on pin manipulation to quickly read the pin value, but the code is only compatible with avr-based Arduinos
I use an arduino nano rp2040 connect in which moniflation on pins does not work I saw posts that talk about it but only on the subject of turning on the number of pins but I did not find anyone who talks about the subject of speed
//I'm new to Arduino, I used a translation hope I'm understood

code:

#define IRpin_PIN PIND
#define IRpin 2
 
 
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
 
 
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20
 
 
// we will store up to 300 pulse pairs (this is -a lot-)
uint16_t pulses[300][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
 
 
void setup(void) {
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}
 
 
void loop(void) {
  uint16_t highpulse, lowpulse; // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length
 
 
// while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & (1 << IRpin)) {
     // pin is still HIGH
 
 
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);
 
 
     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
 
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;
 
 
  // we read one high-low pulse successfully, continue!
  currentpulse++;
}
 
 
void printpulses(void) {
 
 
  for (uint8_t i = 0; i < currentpulse; i++) {
    if(i!=0){
 
//################### First Array Code Pulse Division ########################
   
if((int)(pulses[i][0] * RESOLUTION)>7000.0){
      Serial.print("3");
}
if((pulses[i][0] * RESOLUTION>4000)&&(pulses[i][0] * RESOLUTION<5000)){
      Serial.print("2");
}
if((pulses[i][0] * RESOLUTION>1000)&&(pulses[i][0] * RESOLUTION<2000)){
      Serial.print("1");
}
if((pulses[i][0] * RESOLUTION>0)&&(pulses[i][0] * RESOLUTION<1000)){
      Serial.print("0");
}
//########################### End of First Array ##############################
    Serial.print(", ");
}
 
//################### Second Array Code Pulse Division ########################
 
if((int)(pulses[i][1] * RESOLUTION)>7000.0){
      Serial.print("3");
}
if((pulses[i][1] * RESOLUTION>4000)&&(pulses[i][1] * RESOLUTION<5000)){
      Serial.print("2");
}
if((pulses[i][1] * RESOLUTION>1000)&&(pulses[i][1] * RESOLUTION<2000)){
      Serial.print("1");
}
if((pulses[i][1] * RESOLUTION>0)&&(pulses[i][1] * RESOLUTION<1000)){
      Serial.print("0");
}  
//########################### End of Second Array ##############################
 
    Serial.print(", ");
  }
Serial.println("");
}

this is what makes it fast on your AVR

PIND is the register that lets you know the state of the pin and when you mask it in the while, it gives you the state of the IRpin

your arduino nano rp2040 connect does not use the same type of 8 bit register and is run from GitHub - arduino/ArduinoCore-mbed

you can have a look at how they implement digitalRead

here is the DigitalIn.h read()

1 Like

Is there a way to check if the pin reading speed is sufficient to read the ir pulses?

just try :wink:

I can't, because in any case it keeps data and the question is whether the data is standard

I did not get what you are saying… sorry

It's hard for me to explain (because of the translation)
Is it possible to check the reading speed from the pin and compare it with the speed of the pulses (38Hz)?

38Hz is pretty slow for any MCU... it would be no problem if that was that slow

usual IR signals run at 38KHz

on a slow arduino like the UNO, a digitalRead takes less than 5µs so theoretically you could read at 200KHz

What matters is what the rest of the loop does and to ensure that you don't miss a beat. that's why IR libraries usually rely on timers and interrupts and fast GPIO access.


you can write a simple code where you record the value of micros() before calling digitalRead() and the value of micros() after and look at the time différence. it won't be super precise as of course the function call takes time too, but will give you a clue for your target architecture.

1 Like

Assuming that it is a 38 KHz, i would say that pin reading speed of RP2040 mcu is definitely not a problem in your case.
The typical pin access speed in modern microcontrollers is 10-50 MHz, that is, about 1000 times faster than your RF signal. And in RP2040 there are such features as PIO machines that work even faster.

1 Like

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