Author Topic: Timer error I can´t find  (Read 1938 times)

0 Members and 1 Guest are viewing this topic.

Offline paul23Topic starter

  • Regular Contributor
  • *
  • Posts: 91
  • Country: es
Timer error I can´t find
« on: May 01, 2013, 05:57:39 pm »
I am working on a project that takes Ir remote codes from air con systems.  for those that don't know air con remotes send weird codes depending on the manufacturer, there isn't a standard as such.  Now, my code works, it receives the code, saves it (more on this is a minute), loads it back up and send it out again.  The sent code matches the received code perfectly (viewing on the scope). 

There is a problem though.  The first bit sent is always too long.  I don't know why.  As an example, a Samsung remote sends a pulse of 3.2mSec as the first pulse.  My code sends a 48mSec pulse as the first pulse, even though the saved value for the first pulse is 3,2mSec.  The problem carries over to other manufacturers remotes as well.  The first pulse is always wrong, except for one.  Daikin remotes send a 480uSec pulse and that works with my code, but it only works if I add the ledBlink(2); in to the sendCode() function.  I don´t know why this works and without it I get the same problem.  Everything after the first pulse is correct.

The way I am saving the code is to capture all the raw timing values from the remote first and save that in to the data[] array.  Then I find the common 0 (shorter pulses) and common 1´s(longer pulses) and save the timing values.  By looping through the code I can now change all the timing values to either a 1, 0 or other.  The others I just save their position in the code and raw timing value to separate array, there are normally 6 or 7 of these.  The rest of the code can broke up in to 8 bit blocks and I can save 8 values in to just 2 bytes in an array.  This bit works, but once I get the timing thing sorted, I will then copy the values to the EEPROM, which is why I need to make the values as small as possible.  Its not unlikely that a raw code could be up to 700bits long, which means I wouldn´t get many codes on an EEPROM if just saved them raw.

For now  I am using an ATMEGA328P at 8MhZ, but once this project is fully working that might (probably will) change to something smaller, if I can.

Here is the relevant code,  any more info needed, just ask.

Code: [Select]
ISR (TIMER1_COMPA_vect)
{
if(setMode)
{
OCR1A = data[bitnumber]; // Set CTC compare value to the next data bit length
  irLED_PORT ^= (1<<irLED);  //Toggle the ir led
  bitnumber++; //Go to the next bit
}
else
{
qtrSecTimer++;  //Add 1 to the quarter second timer.
}
}
void sendCode()  //TEMPORY FUNCTION FOR TESTING DATA
{

setMode = 0; //disable Set Mode

LEDblink(2);

bitnumber = 0;  //Start at the second bit, the first bit is sent manually, outside the ISR

TCCR1B = 0;
TIMSK1 = 0;

TCCR1B = (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK1 = (1 << OCIE1A); // Enable CTC interrupt

OCR1A   = data[0]; // Set CTC compare value to the first data bit length
TCCR1B |= (1 << CS11); // Start timer at F_cpu/8

sei(); //  Enable global interrupts

setMode = 1; //Enable Set Mode

while (bitnumber <= lengthOfData);  //Do nothing until all the data is sent

cli();

resetData();

statusLED_PORT |= 1<<statusLED; //Switch on the status LED
}
void LEDblink(uint8_t errorCode)
{
qtrSecTimer = 0;

TCCR1B |= (1 << WGM12); //Configure timer 1 for CTC mode
TIMSK1 |= (1 << OCIE1A); //Enable CTC interrupt
sei(); //Enable global interrupts
OCR1A   = 31249; //Set CTC compare value to 0.25 seconds
TCCR1B |= (1 << CS11) | (1 << CS10); //Start timer at F_cpu/64

for (uint8_t i=0; i<errorCode;i++)
{
statusLED_PORT ^= 1<<statusLED; //Toggle the Status LED
while(qtrSecTimer < LEDflashRate); //Wait until the timer matches
qtrSecTimer = 0; //Reset the Timer
}
}


Thanks
paul..
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Timer error I can´t find
« Reply #1 on: May 02, 2013, 01:30:21 am »
I'm pretty sure the problem has to do with the fact that you're not explicitly setting the counter's value for the first bit.  It happens to work when you call LedBlink() because the counter gets cleared as a side effect of running that function.

Add this line to the timer initialization code of sendCode() and you should be golden:

Code: [Select]
TCNT1 = 0;
 

Offline paul23Topic starter

  • Regular Contributor
  • *
  • Posts: 91
  • Country: es
Re: Timer error I can´t find
« Reply #2 on: May 02, 2013, 07:38:44 am »
You beauty, it seems to work a treat now.  I´ll try more later when I get home, but the few I have tried were perfect.  I knew it would be something simple.

Thanks a lot, much appreciated.
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Timer error I can´t find
« Reply #3 on: May 02, 2013, 08:16:42 am »
Right on!   :-+
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf