Go Down

Topic: Trouble sending IR command to rc curtains (Read 10622 times) previous topic - next topic

juntao65

I think I love you!!

I used AnalysisIR export to get the other remote functions to work as well. Like you said they only work with IRlib but not IRremote.

But...

Before changing my code to use the new library, I wanted to test all of the curtain's commands. OPEN and STOP work as expected, but CLOSE is giving me problems again. It just doesn't work. How is it possible that the same raw code that works fine on IRremote does not work with IRlib?

I tried changing the frequencies as well with no luck. Not sure what to do next.

juntao65

SOLVED!

And I'm even more confused...

I was able to get it to work because I remembered you mentioning that delayMicroseconds has a maximum allowable value of 16383. Well the close code I used had values far larger than this. So I made a sketch to figure out exactly what IRremote was doing when it called delayMicroseconds for values larger than 16383.

Code: [Select]

void loop() {
  if (Serial.read() != -1) {
    float start = micros();
   
    delayMicroseconds(95000);
   
    float ending = micros();
   
    float diff = ending - start;
   
    Serial.println(diff);
   
    delay(1000);
  }
}


So I took all of the values larger than 16383 from my original CLOSE array and replaced them with the numbers outputted through the above sketch.

Some example conversions:
95000 became 13160
33175 became 408
84350 became 2448

Original array:
Code: [Select]
PROGMEM unsigned int Signal_Close[] = {1175,400,1200,400,400,1200,1200,400,400,1200,400,1200,1200,400,400,1200,400,1200,400,1200,400,1200,400,33175,1200,400,1200,400,400,1200,1200,400,400,1200,400,1200,850,750,100,1575,400,1200,400,1200,400,1200,400,84350,1200,400,1200,400,400,1200,1200,400,400,1200,400,1200,925,675,100,1575,400,1200,400,1200,400,1200,400,33175,1200,400,1200,400,400,1200,1200,400,400,1200,400,1200,400,1200,400,1200,400,1200,400,1200,400,1200,400,95000};


New array:
Code: [Select]
PROGMEM unsigned int Signal_Close[] = {1175,400,1200,400,400,1200,1200,400,400,1200,400,1200,1200,400,400,1200,400,1200,400,1200,400,1200,400,408,1200,400,1200,400,400,1200,1200,400,400,1200,400,1200,850,750,100,1575,400,1200,400,1200,400,1200,400,2448,1200,400,1200,400,400,1200,1200,400,400,1200,400,1200,925,675,100,1575,400,1200,400,1200,400,1200,400,408,1200,400,1200,400,400,1200,1200,400,400,1200,400,1200,400,1200,400,1200,400,1200,400,1200,400,1200,400,13160};


So if IRremote didn't have that delaymicrosecond limit then I would have never got close to work.... wth right?

AnalysIR

I am not sure if you still have a problem? & if so what it is?

However, using floats for your calculations is likely to be inaccurate or incorrect.

If I remember correctly, delayMicroseconds takes an unsigned int (16 binary bits) as the delay value which has a max value of  65535 (256*256-1 = 65535)

It then multiplies it by 4 (reason below) which means anything more than 16383 overflows and which is why the max is 16383.

So when you have, say 84530, it is passed as a 16 bit unsigned int as (85530-65536) = 19994.

Then it is multiplied by 4 to get 79976, which also overflows to (79976-65536) 14440 .

So your actual delay ends up being 14440/4 = 3610 uSecs.


The reason for the x4 multiplication is that a very accurate 0.25 uSec delay is used within the function  (4 clock cycles of a 16MHz AVR 8 but MCU is exactly 0.25 uSecs).

For longer delays I often use, for example:
Code: [Select]
unsigned long uSecDelay = 84530;  //too long for delayMicroseconds!
unsigned long startTime = micros();
while ((micros()-startTime ) > uSecDelay);//wait here until uSec delay has elapsed

note the use of unsigned long vs unsigned int.


Conclusion: if you have signals with marks or spaces longer than 16383 uSecs....use the latest version of IRLib.

Go Up