NEC decoder with interrupts

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I have found many codes online which can deal with NEC protocol. However, all I have seen is the program waits while(IR_HIGH); and when it goes low, it executes the code. I even tried one and it seems to be working fine. However, the issue is I need an interrupt based solution. This makes it easy for me to do other programming while any interrupt will store button "code" into the memory and I can take actions based on the code.

 

Here is one such program which is a modified version of code I found. It is working ok till I print the code into LCD. But I need a solution which can throw the code into memory and just stay there until called in the main program. Any help please?

 

#include <avr/io.h>
#include "irdecoder.h"
#include <avr/interrupt.h>
#include "lib/lcd.h"

unsigned int time;
unsigned int code=0;
unsigned char repeatCount = 0;
unsigned char bitVal;
unsigned char i;
static unsigned int lastCode = 0;

void init_ir(){
	TCCR1B = TIMER1_PRESCALER;	// Initialize timer's prescaler
    DDRD &= ~(1 << DDD2);     // Clear the PD2 pin
    // PD2 (PCINT0 pin) is now an input
    PORTD |= (1 << PORTD2);    // turn On the Pull-up
    // PD2 is now an input with pull-up enabled
    EICRA |= (1 << ISC01);    // set INT0 to trigger on ANY logic change
    EIMSK |= (1 << INT0);     // Turns on INT0
	sei();
}

unsigned int protocolNEC(unsigned int code)
{
		//TCNT1 = 0;
		while(IR_HIGH);
		time = TCNT1;
		TCNT1 = 0;

		if(time > CONV(4200))	// if this is a regular button press
		{
			repeatCount = 0;
		} else {				// if this is hold button press
								// send last keycode
			if(++repeatCount == NEC_REPEAT_RATE)
			{
				repeatCount = 0;
				return lastCode;
			}
			return 0;
		}
		code = 0;

		// Read 32 data bits
		for(i = 0; i < 32; i++)
		{

			while(IR_LOW);
			while(IR_HIGH);

			time = TCNT1;
			TCNT1 = 0;

			// 1650 us
			if(time > CONV(1650))
			{
				bitVal = 1;
			} else {
				bitVal = 0;
			}

			if((i < 8) || (i >= 16 && i < 24))
			{
				code = code << 1;
				code |= bitVal;
			}
		}
		lastCode = code;
		return code;
}

ISR (INT0_vect)
{
	TCNT1 = 0;
	while(IR_LOW);
	cli();
		time = TCNT1;
		TCNT1 = 0;
		code = protocolNEC(code);
		lcd_put_int(code);
	sei();
}

 

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bump!

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

Last Edited: Sun. Jun 21, 2015 - 08:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't ever use sei() inside an ISR. While it's OK to use cli() it's pointless.

 

Also do not call functions from an ISR() and especially don't ever call LONG functions like LCD output. restructure your code so that stuff is in the main() loop.

 

As to the code - how could anyone help? It uses defined macros like IR_LOW that are not shown. You haven't even shown main().

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Orininal post:  Sun. Jun 21, 2015 - 04:30 PM

At 05:54 PM, praveen_khm wrote:
Bump!

A little patience might be in order!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bump!