//for LCD
#define RS 12
#define EN 11
#define D4 10
#define D5 9
#define D6 8
#define D7 7
//for NEC decoding
volatile char text[5];
volatile boolean nec_ok = 0;
volatile byte i, nec_state = 0, command, inv_command , address ;
volatile unsigned long nec_code; //32bit
// ============= External interrupt ===========
void detectInterrupt(int mode) {
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
EIMSK |= (1 << INT0);
}
void endInterrupt() {
EIMSK &= ~(1 << INT0);
}
// ==============================================
// ============== LCD function ==============
void pulseEnable() {
digitalWrite(EN, HIGH);
delayMicroseconds(1);
digitalWrite(EN, LOW);
delayMicroseconds(50);
}
void sendCommand(byte cmd) {
digitalWrite(RS, LOW);
digitalWrite(D4, (cmd >> 4) & 1);
digitalWrite(D5, (cmd >> 5) & 1);
digitalWrite(D6, (cmd >> 6) & 1);
digitalWrite(D7, (cmd >> 7) & 1);
pulseEnable();
digitalWrite(D4, cmd & 1);
digitalWrite(D5, (cmd >> 1) & 1);
digitalWrite(D6, (cmd >> 2) & 1);
digitalWrite(D7, (cmd >> 3) & 1);
pulseEnable();
}
void sendData(byte data) {
digitalWrite(RS, HIGH);
digitalWrite(D4, (data >> 4) & 1);
digitalWrite(D5, (data >> 5) & 1);
digitalWrite(D6, (data >> 6) & 1);
digitalWrite(D7, (data >> 7) & 1);
pulseEnable();
digitalWrite(D4, data & 1);
digitalWrite(D5, (data >> 1) & 1);
digitalWrite(D6, (data >> 2) & 1);
digitalWrite(D7, (data >> 3) & 1);
pulseEnable();
}
void printText(const char* text, int row, int col) {
int position = col + (row == 1 ? 0x40 : 0x00);
sendCommand(0x80 | position); // Set DDRAM address
for (int i = 0; text[i] != '\0'; ++i) {
sendData(text[i]);
}
}
void commandConvert(int command){
switch(command){
case 80:
Serial.println(command);
printText("Input",1, 9);
return;
case 208:
Serial.println(command);
printText("Power ",1, 9);
return;
case 48:
Serial.println(command);
printText("Menu ",1, 9);
return;
case 112:
Serial.println(command);
printText("ESC ",1, 9);
return;
case 180:
Serial.println(command);
printText("KST- ",1, 9);
return;
case 84:
Serial.println(command);
printText("KST+ ",1, 9);
return;
case 52:
Serial.println(command);
printText("VOL+ ",1, 9);
return;
case 244:
Serial.println(command);
printText("VOL- ",1, 9);
return;
case 212:
Serial.println(command);
printText("ZOOM+",1, 9);
return;
case 116:
Serial.println(command);
printText("ZOOM-",1, 9);
return;
}
return;
}
// ===============================================
void setup() {
Serial.begin(9600);
pinMode(RS, OUTPUT);
pinMode(EN, OUTPUT);
pinMode(D4, OUTPUT);
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
sendCommand(0x33);
sendCommand(0x32);
sendCommand(0x28);
sendCommand(0x0C);
sendCommand(0x06);
sendCommand(0x01);
delay(500);
printText("Group 2 ",0, 0);
printText("Hello Mr Hung",1,0);
// Timer1 config
TCCR1A = 0;
TCCR1B = 0; // Disable Timer1 module
TCNT1 = 0; // Set Timer1 preload value to 0
TIMSK1 = 1; // Enable Timer1 overflow interrupt
detectInterrupt(CHANGE);
}
void remote_read() {
unsigned int timer_value;
if(nec_state != 0){
timer_value = TCNT1; // Store Timer1 value
TCNT1 = 0; // Reset Timer1
}
switch(nec_state){
case 0 : // Start receiving IR (9ms pulse)
TCNT1 = 0; // Reset Timer1
TCCR1B = 2; // set prescaler, start measure time
nec_state = 1; // end of 9ms pulse (start 4.5ms space)
i = 0;
return;
case 1 : // End of 9ms pulse
if((timer_value > 19000) || (timer_value < 17000)){ // Invalid interval
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else
nec_state = 2; // end of 4.5ms space (start of 562µs pulse)
return;
case 2 : // End of 4.5ms space
if((timer_value > 10000) || (timer_value < 8000)){
nec_state = 0;
TCCR1B = 0;
}
else
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
return;
case 3 : // End of 562µs pulse
if((timer_value > 1400) || (timer_value < 800)){
TCCR1B = 0;
nec_state = 0;
}
else
nec_state = 4; // Next state: end of 562µs or 1687µs space
return;
case 4 : // End of 562µs or 1687µs space
if((timer_value > 3600) || (timer_value < 800)){
TCCR1B = 0;
nec_state = 0;
return;
}
// if received a bit successfully
if( timer_value > 2000) // long space
nec_code |= (1UL << (31 - i));
else // short space
nec_code &= ~(1UL << (31 - i));
i++;
if(i > 31){ // If all bits are received
nec_ok = 1;
endInterrupt(); // Disable external interrupt (INT0)
return;
}
nec_state = 3; // Next state -> start of 562µs or 1687µs space
}
}
ISR(TIMER1_OVF_vect) {
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
ISR(INT0_vect) {
remote_read();
}
void loop() {
if(nec_ok){ // mcu receives NEC message successfully
nec_ok = 0; // Reset decoding process
nec_state = 0;
TCCR1B = 0; // Disable Timer1
address = nec_code >> 24;
command = nec_code >> 8;
inv_command = nec_code;
printText("Address:",0,0);
printText("Command:",1,0);
sprintf(text, "%02X", address);
printText("0x",0,9);
printText(text,0,11);
sprintf(text, "%02X", command);
Serial.println(command);
commandConvert(command);
detectInterrupt(CHANGE);
}
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
lcd:VSS
lcd:VDD
lcd:V0
lcd:RS
lcd:RW
lcd:E
lcd:D0
lcd:D1
lcd:D2
lcd:D3
lcd:D4
lcd:D5
lcd:D6
lcd:D7
lcd:A
lcd:K
r1:1
r1:2
ir1:GND
ir1:VCC
ir1:DAT