generate 38KHz carrier problem

I followed ladyada’s article, Sensor tutorials - IR remote receiver/decoder tutorial , to build an IR remote control with Arduino MEGA1280, the interval value between HIGH level and LOW level was changed to 6?s in accordance to MEGA1280. The codes worked properly when the carrier wave was below 1000 microseconds, but when I tried to generate about 9130?s carrier wave, the actual wave was about 816?s long, far below than the intervals (12?s/cycle * 352 cycles = 4224?s). :frowning:

=====
the debug info
carrier expected actual results
9130 352cycles and takes 816 ?s
850 33cycles and takes 856 ?s

560 22cycles and takes 572 ?s
7190 277cycles and takes 948 ?s
560 22cycles and takes 572 ?s

//code snippets

int IRledPin =  13;    // LED connected to digital pin 13
int _38HZ_Space=6;     //38KHz interval

long PowerOnArray[][2]=
{
  1,913,0,412,1,85,0,22,1,87,0,23,1,87,0,25,1,85,0,25,1,85,0,26,1,85,0,
  27,1,83,0,27,1,84,0,27,1,84,0,138,1,83,0,138,1,83,0,138,1,82,0,138,1,
  82,0,139,1,82,0,140,1,80,0,32,1,75,0,144,1,76,0,146,1,74,0,38,1,69,0,
  153,1,66,0,156,1,64,0,46,1,64,0,47,1,63,0,48,1,61,0,50,1,59,0,51,1,59,
  0,163,1,56,0,55,1,56,0,55,1,55,0,166,1,56,0,165,1,56,0,166,1,55,0,165,
  1,56,0,4021,1,719,0,209,1,56,0,0
};

void setup()   {               
  pinMode(IRledPin, OUTPUT);     

  Serial.begin(9600);
}

void loop()                     
{
  //Serial.println("Sending IR signal");

  char Recv;

  if (Serial.available()>0)
  {
    //Serial.println("Has incoming chars");
    Recv=Serial.read();
    Serial.println(Recv);

    switch (Recv)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      {
        Serial.println("Power On...");
        _38HZ_Space = Recv - 48;
        Serial.println(_38HZ_Space);
        PowerOn();
        break;
      };
    default:
      { 
      };
    }
  }

}

void PowerOn()
{
  long i,c;
  long cmd,value;
  c=sizeof(PowerOnArray)/sizeof(PowerOnArray[0][0]);
  for (i=0; i<=c; i++)
  {
    cmd=PowerOnArray[0];
    value=PowerOnArray[1];
    if (cmd==1)
      pulseIR(value*10,_38HZ_Space);
    else
      delayMicroseconds(value*10);
  }
}

void pulseIR(long microsecs, long Interval) {
  Serial.print(microsecs);

  long i;   
  i= micros();
  long c;   
  c=0;  

  cli(); 
  while (microsecs > 0) {
    digitalWrite(IRledPin, HIGH); 
    delayMicroseconds(Interval);     // hang out for 6 microseconds   
    digitalWrite(IRledPin, LOW);  
    delayMicroseconds(Interval);         
    microsecs -= 26;
    c++;
  }
  sei();  
  i = micros() -i;

  Serial.print("  "); 
  Serial.print(c ); 
  Serial.print("cycles and takes  ");
  Serial.print(i); 
  Serial.println(" us");
}

What happens if you comment out cli() and sei()?

Thanks, James, it works after commenting them out.

I don't understand why the original example turned off interrupts. However, I suspect that the code was always "working." micros() and millis() won't work correctly if interrupts are turned off. So it is likely your measurement was incorrect.

So, the result is buggy?

I am not sure the interrupts are turned on or not by default, since both cli() and sei() are commented out, so, are those interrupts in default state? I have no OScopes to measure the wave time, those values are traced by the following codes, and the values are for referrence only. :)

long i; i= micros(); long c; c=0;

//cli(); while (microsecs > 0) { digitalWrite(IRledPin, HIGH); delayMicroseconds(Interval); // hang out for 6 microseconds digitalWrite(IRledPin, LOW); delayMicroseconds(Interval); microsecs -= 26; c++; } //sei(); i = micros() -i;

ardypro: I am not sure the interrupts are turned on or not by default, since both cli() and sei() are commented out

Interrupts are on by default, it is how millis() and micros() work...

cli() turns off interrupts, sei() turns them back on.

millis() relies on timer0 overflow interrupt to count. So turning off the interrupts while you are trying to use millis() or micros() will give invalid results.

Which is why I say, I suspect your pulses were working correctly... your debug values were ... well... buggy. ;)