#include #include #include #include #include "printf.h" #include "string.h" // RF24 by TMRh20 library char radiosend [20]; // RC5 Protocol decoder Arduino code // Define number of Timer1 ticks (with a prescaler of 1/8) #define short_time 1400 // minimum time for short pulse or short space ( ==> 700 us) #define med_time 2400 // maximum time for short pulse or short space ( ==> 1200 us) #define long_time 4000 // maximum time for long pulse or long space ( ==> 2000 us) #define ir_pin 2 // TSOP1738 out pin struct RF_Data //this must match dataToSend in the TX { int cmd; int data; }; unsigned long key_value = 0; // variable to store the pressed key value boolean success = 0, toggle_bit; boolean toggle_bit_old=0; byte state = 0, j, address, command; unsigned int rc5_code; // RF init RF24 radio(9, 10); // CE, CSN int RX_cmd_data =0; boolean button_stateA = 0; boolean button_stateB = 0; #define TIMER_FREQ_HZ 1000 #define true 1 #define false 0 #define MAX_GRAPHICS 40 // RF or RS232 COMMANDS DEFINES #define SET_CHAR_0 0x01 #define SET_CHAR_1 0x02 #define SET_CHAR_2 0x03 #define SET_CHAR_3 0x04 #define SET_CHAR_4 0x05 #define SET_CHAR_5 0x06 #define SET_CHAR_6 0x07 #define SET_CHAR_7 0x08 #define SET_HEURE_DIZAINE 0x09 #define SET_HEURE_UNIT 0x0A #define SET_MINUTE_DIZAINE 0x0B #define SET_MINUTE_UNIT 0x0C #define SET_SECONDE_DIZAINE 0x0D #define SET_SECONDE_UNIT 0x0E #define START_STOP_TIME_COMPUTE 0x0F #define START_STOP_GRAPHICS 0x10 #define START_WRITE_GRAPHICS 0x11 #define DATA_WRITE_GRAPHICS 0x12 #define DISPLAY_ON_OFF 0x13 #define CHECK_SYNC 0x14 #define RESET 0x15 #define GET_VERSION 0x16 // DISPLAY GRAPHICS Defines #define GRAPHICS_MODE 2 #define TEXT_MODE 0 char Version [] = "FCALLBOX3 DISPLAY 5x7 V4.00\n\r"; char text[30]; /************************************** ; matrix 5x7 table ; organisation char = 5 bytes (segment) ; to get a char segment , do a call MatrixTable with W = char-32 ; char code need to be -32 because of table does not show char bellow 32 ; ************************************* */ char MatrixTableSeg0 [] = {0x00, 0x00, 0x00, 0x28, 0x24, 0xC4, 0x6C, 0x00, 0x00, 0x00, 0x28, 0x10, 0x00, 0x10, 0x00, 0x04, 0x7C, 0x00, 0x42, 0x84, 0x18, 0xE4, 0x3C, 0x80, 0x6C, 0x60, 0x00, 0x00, 0x10, 0x28, 0x00, 0x40, 0x4C, 0x7E, 0xFE, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0xFE, 0x00, 0x04, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0xFE, 0x7C, 0xFE, 0x62, 0x80, 0xFC, 0xF8, 0xFC, 0xC6, 0xE0, 0x86, 0x00, 0x40, 0x00, 0x20, 0x02, 0x00, 0x04, 0xFE, 0x1C, 0x0C, 0x1C, 0x00, 0x12, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x3E, 0x3E, 0x1C, 0x3E, 0x10, 0x3E, 0x12, 0x20, 0x3C, 0x38, 0x3C, 0x22, 0x20, 0x22, 0x00, 0x00, 0x82, 0x20, 0xA8}; char MatrixTableSeg1 [] = {0x00, 0x00, 0xE0, 0xFE, 0x54, 0xC8, 0x92, 0xA0, 0x38, 0x82, 0x10, 0x10, 0x0A, 0x10, 0x06, 0x08, 0x8A, 0x42, 0x86, 0x82, 0x28, 0xA2, 0x52, 0x8E, 0x92, 0x92, 0x6C, 0x6A, 0x28, 0x28, 0x82, 0x80, 0x92, 0x88, 0x92, 0x82, 0x82, 0x92, 0x90, 0x82, 0x10, 0x82, 0x02, 0x10, 0x02, 0x40, 0x20, 0x82, 0x90, 0x82, 0x90, 0x92, 0x80, 0x02, 0x04, 0x02, 0x28, 0x10, 0x8A, 0xFE, 0x20, 0x82, 0x40, 0x02, 0x80, 0x2A, 0x12, 0x22, 0x12, 0x2A, 0x10, 0x2A, 0x10, 0x00, 0x02, 0xFE, 0x82, 0x20, 0x10, 0x22, 0x28, 0x28, 0x10, 0x2A, 0x20, 0x02, 0x04, 0x02, 0x14, 0x12, 0x26, 0x10, 0x00, 0x82, 0x40, 0x68}; char MatrixTableSeg2 [] = {0x00, 0xF2, 0x00, 0x28, 0xFE, 0x10, 0xAA, 0xC0, 0x44, 0x44, 0x7C, 0x7C, 0x0C, 0x10, 0x06, 0x10, 0x92, 0xFE, 0x8A, 0xA2, 0x48, 0xA2, 0x92, 0x90, 0x92, 0x92, 0x6C, 0x6C, 0x44, 0x28, 0x44, 0x8A, 0x9E, 0x88, 0x92, 0x82, 0x82, 0x92, 0x90, 0x92, 0x10, 0xFE, 0x82, 0x28, 0x02, 0x30, 0x10, 0x82, 0x90, 0x8A, 0x98, 0x92, 0xFE, 0x02, 0x02, 0x0C, 0x10, 0x0E, 0x92, 0x82, 0x10, 0x82, 0x80, 0x02, 0x40, 0x2A, 0x12, 0x22, 0x12, 0x2A, 0x7E, 0x2A, 0x10, 0x5E, 0x02, 0x08, 0xFE, 0x1C, 0x20, 0x22, 0x28, 0x28, 0x20, 0x2A, 0xFC, 0x02, 0x02, 0x0C, 0x08, 0x0C, 0x2A, 0x6C, 0xEE, 0x6C, 0x40, 0x3E}; char MatrixTableSeg3 [] ={0x00, 0x00, 0xE0, 0xFE, 0x54, 0x26, 0x44, 0x00, 0x82, 0x38, 0x10, 0x10, 0x00, 0x10, 0x00, 0x20, 0xA2, 0x02, 0x92, 0xD2, 0xFE, 0xA2, 0x92, 0xA0, 0x92, 0x94, 0x00, 0x00, 0x82, 0x28, 0x28, 0x90, 0x82, 0x88, 0x92, 0x82, 0x44, 0x92, 0x90, 0x92, 0x10, 0x82, 0xFC, 0x44, 0x02, 0x40, 0x08, 0x82, 0x90, 0x84, 0x94, 0x92, 0x80, 0x02, 0x04, 0x02, 0x28, 0x10, 0xA2, 0x82, 0x08, 0xFE, 0x40, 0x02, 0x20, 0x2A, 0x12, 0x22, 0x12, 0x2A, 0x90, 0x2A, 0x10, 0x00, 0xBC, 0x14, 0x02, 0x20, 0x20, 0x22, 0x28, 0x28, 0x20, 0x2A, 0x22, 0x02, 0x04, 0x02, 0x14, 0x10, 0x32, 0x82, 0x00, 0x10, 0x40, 0x68}; char MatrixTableSeg4 [] ={0x00, 0x00, 0x00, 0x28, 0x48, 0x46, 0x0A, 0x00, 0x00, 0x00, 0x28, 0x10, 0x00, 0x10, 0x00, 0x40, 0x7C, 0x00, 0x62, 0x8C, 0x08, 0x9C, 0x0C, 0xC0, 0x6C, 0x78, 0x00, 0x00, 0x00, 0x28, 0x10, 0x60, 0x7C, 0x7E, 0x6C, 0x44, 0x38, 0x82, 0x80, 0x5E, 0xFE, 0x00, 0x80, 0x82, 0x02, 0xFE, 0xFE, 0x7C, 0x60, 0x7A, 0x62, 0x8C, 0x80, 0xFC, 0xF8, 0xFC, 0xC6, 0xE0, 0xC2, 0x00, 0x04, 0x00, 0x20, 0x02, 0x00, 0x1E, 0x0C, 0x22, 0xFE, 0x1A, 0x40, 0x3C, 0x0E, 0x00, 0x00, 0x22, 0x00, 0x3E, 0x1E, 0x1C, 0x10, 0x3E, 0x10, 0x24, 0x24, 0x3C, 0x38, 0x3C, 0x22, 0x20, 0x22, 0x82, 0x00, 0x00, 0x80, 0xA8}; // # 0 # 1 #2 #3 #4 #5 #6 #7 #8 #9 char Digit_graphic [] = { 0x7C,0x44,0x7C, 0x00,0x00,0x7C, 0x5C,0x54,0x74, 0x44,0x54,0x7C, 0x70,0x10,0x7C, 0x74,0x54,0x5C, 0x7C,0x54,0x5C, 0x60,0x40,0x7C, 0x7C,0x54,0x7C, 0x74,0x54,0x7C}; // # A #B #C #D #E #F // #M #N #O #P #Q #R #S #T #U #V #W #X #Y #Z char Letter_graphic [] = { 0x7C,0x50,0x7C, 0x7C,0x54,0x28, 0x7C,0x44,0x44, 0x7C,0x44,0x38, 0x7C,0x54,0x54, // #G #H #I #J #K #L 0x7C,0x50,0x50, 0x7C,0x44,0x5C, 0x7C,0x10,0x7C, 0x44,0x7C,0x44, 0x04,0x04,0x7C, 0x7C,0x10,0x6C, 0x7C,0x04,0x04, 0x7C,0x20,0x7C, 0x7C,0x18,0x7C, 0x7C,0x44,0x7C, 0x7C,0x50,0x70, 0x78,0x48,0x74, 0x7C,0x58,0x74, 0x74,0x54,0x5C, 0x40,0x7C,0x40, 0x7C,0x04,0x7C, 0x78,0x04,0x78, 0x7C,0x08,0x7C, 0x6C,0x10,0x6C, 0x60,0x1C,0x60, 0x4C,0x54,0x64 }; unsigned char CHAR_SERIAL ; unsigned char CHAR_x [8]; int Timer_interrupt_count=0; int Display_counter=0; unsigned char digit,row; int RX_cmd,RX_data=0; unsigned char HeureDizaine = '1'; unsigned char HeureUnit ='1'; unsigned char MinuteDizaine ='4'; unsigned char MinuteUnit ='0'; unsigned char SecondeDizaine ='0'; unsigned char SecondeUnit ='0'; unsigned char bComputeTime = true; unsigned char bGraphics = false; unsigned char index=0; unsigned char Graphics_data_index=0; unsigned char Graphics [MAX_GRAPHICS]; unsigned char Graphics_tmp [MAX_GRAPHICS]; unsigned char cmd_order = 0; unsigned char RF_char =0; unsigned char CRC =0; char tmp [20]; #define tunnel1 "1FCA18" // TX MAIN SERVER (-> DIPLA§Y GRAPHIC) #define tunnel2 "2FCALL" // DISPLAY IR #define tunnel3 "3FCALL" // TEMPERATURE SENSOR #define tunnel4 "4FCALL" // DOMOTIC / ALARM #define tunnel5 "5FCALL" // FREE #define tunnel6 "6FCALL" // FREE const byte addresses[][6] = {tunnel1, tunnel2, tunnel3, tunnel4, tunnel5, tunnel6}; volatile int data; // timeout 30mn #define TIMEOUT 1800 int check_RX_from_main = TIMEOUT; // counter to check if main has sent cmd (theorycally less than 10mn) int i,k,x,l; // the setup function runs once when you press reset or power the board void setup() { Serial.begin(115200); // Timer1 module configuration TCCR1A = 0; TCCR1B = 0; // Disable Timer1 module TCNT1 = 0; // Set Timer1 preload value to 0 (reset) TIMSK1 = 1; // enable Timer1 overflow interrupt // attachInterrupt(digitalPinToInterrupt(ir_pin), RC5_read, CHANGE); // Enable external interrupt // start RF start_RF(); // set display matrix as output //pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(A3, OUTPUT); pinMode(9, OUTPUT); pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); // text to display at startup CHAR_x[0]=' '; CHAR_x[1]=' '; CHAR_x[2]='W'; CHAR_x[3]='A'; CHAR_x[4]='I'; CHAR_x[5]='T'; CHAR_x[6]='2'; CHAR_x[7]=' '; // init GPIO ReSetC5(); ReSetC4(); ReSetC3(); ReSetC2(); ReSetC1(); ReSetCLR (); SetC1(); SetC2(); SetC3(); SetC4(); SetC5(); SetCLR(); cli(); //stop interrupts for till we make the settings //1. First we reset the control register to amke sure we start with everything disabled. TCCR2A = B00000010; // Reset entire TCCR1A to 0 //TCCR2B = B000000; // Reset entire TCCR1B to 0 //2. We set the prescalar to the desired value by changing the CS10 CS12 and CS12 bits. TCCR2B = B00000110; //Set CS12 to 1 so we get prescalar 256 //3. We enable compare match mode on register A TIMSK2 = B00000010; //Set OCIE1A to 1 so we enable compare match A //4. Set the value of register A to 31250 OCR2A = 62; //Finally we set compare register A to this value sei(); //Enable back the interrupts Serial.println("boot"); } // the loop function runs over and over again forever void loop() { uint8_t pipe=0; if(success) { // If the mcu receives RC5 message with successful success = 0; // Reset decoding process state = 0; TCCR1B = 0; // Disable Timer1 module toggle_bit = bitRead(rc5_code, 11); // Toggle bit is bit number 11 address = (rc5_code >> 6) & 0x1F; // Next 5 bits are for address command = rc5_code & 0x3F; // The 6 LSBits are command bits if (toggle_bit_old != toggle_bit) { //sprintf(text, "%02X", toggle_bit); //Serial.println(text); //sprintf(text, "%02X", command); //Serial.println(command); sprintf (text,"IR;%d;%d\n",address,command); radio.stopListening(); radio.write(&text, sizeof(text)); //Sending the data , return the version for the moment toggle_bit_old = toggle_bit; } // attachInterrupt(digitalPinToInterrupt(ir_pin), RC5_read, CHANGE); // Enable external interrupt } radio.startListening(); if (radio.available()) //Looking for incoming data { check_RX_from_main = TIMEOUT; // RF cmd received, reload timeout radio.read(&tmp, sizeof(tmp)); // Serial.println(tmp); /* radio.read(&RF_char, sizeof(RF_char)); Serial.print("RX "); // echo Serial.print(cmd_order); // echo Serial.print("\t"); // echo Serial.print(RF_char); Serial.print("\t"); // echo Serial.println(RF_char,HEX); */ // NEW PROTOCOL 2025 // // <55> // 7 bits // 4 bits // 4 bits // sum of AA 55 CMD DATA_HIGH DATA_LOW // if CRC is OK return <"O"> else <"B"> /* 12h40 12h56 md 15 data 1 CRC received 15 CRC computed 15 OK cmd 15 data 1 CRC received 15 CRC computed 15 OK cmd 9 data 49 CRC received 12 CRC computed 12 OK cmd 10 data 50 CRC received 14 CRC computed 14 OK cmd 3 data 58 CRC received 15 CRC computed 15 OK cmd 4 data 53 CRC received 11 CRC computed 11 OK cmd 5 data 52 CRC received 11 CRC computed 11 OK cmd 13 data 53 CRC received 20 CRC computed 20 OK cmd 14 data 57 CRC received 25 CRC computed 25 OK cmd 15 data 0 CRC received 14 CRC computed 14 OK cmd 15 data 0 CRC received 14 CRC computed 14 OK cmd 15 data 0 CRC received 14 CRC computed 14 OK cmd 16 data 0 CRC received 15 CRC computed 15 OK cmd 16 data 0 CRC received 15 CRC computed 15 OK cmd 16 data 0 CRC received 15 CRC computed 15 OK Serial.println("decoding"); Serial.println((int)tmp[0],HEX); Serial.println((int)tmp[1],HEX); Serial.println((int)tmp[2],HEX); Serial.println((int)tmp[3],HEX); Serial.println((int)tmp[4],HEX); Serial.println((int)tmp[5],HEX); */ if ((unsigned char)tmp[0]==0xAA && (unsigned char)tmp[1]==0x55) { //Serial.println("got header"); RX_cmd=(unsigned char)tmp[2]; RX_data = (unsigned char)tmp[3] <<4; RX_data += (unsigned char)tmp[4] & 0x0f; CRC = 0xAA; CRC +=0x55; CRC +=RX_cmd; CRC +=RX_data; /* Serial.println(RX_cmd,HEX); Serial.println(RX_data,HEX); Serial.println(CRC); */ if (CRC==(unsigned char)tmp[5]) { /* Serial.println("display CRC OK"); sprintf (text,"DISPOK\n"); radio.stopListening(); radio.write(&text, sizeof(text)); // ACK OK radio.startListening(); */ compute_cmd(); } else { /* Serial.println("display CRC ERROR"); sprintf (text,"DISPERR\n"); radio.stopListening(); radio.write(&text, sizeof(text)); // ACK BAD CRC */ radio.startListening(); } } } // check serial COM for debug if (Serial.available()>0) { CHAR_SERIAL = Serial.read(); if (CHAR_SERIAL== 'T') // display timeout state on radio.available { sprintf(text, "ERR %d", check_RX_from_main); Serial.println(text); } if (CHAR_SERIAL== 'F') // check radio failure { if (radio.failureDetected) { sprintf(text, "failure"); radio.failureDetected = 0; } else sprintf(text, "OK"); Serial.println(text); } if (CHAR_SERIAL== 'R') // restart radio { sprintf(text, "RESTART"); // restart Radio Serial.println(text); start_RF(); } if (CHAR_SERIAL== 'P') // restart radio { sprintf(text, "DETAILS"); // restart Radio Serial.println(text); printf_begin(); radio.printPrettyDetails(); radio.printDetails(); } } /* if (cmd_order==0) { RX_cmd = (int) Serial.read(); // CHAR_x[0]=RX_cmd; // Serial.print("RX_cmd"); // echo if (RX_cmd <= GET_VERSION) // allow to synchronize cmd_order=1; } else { RX_data = (int)Serial.read(); // Serial.print("RX_data "); // echo //CHAR_x[1]=RX_data; cmd_order=0; compute_cmd(); } */ } void display_err (void) { // RF command not received during TIMEOUT (30mn) // diplay RX ERR and time from last cmd for (x=0;x < (MAX_GRAPHICS-1);x++) Graphics_tmp[x]= 0; x=0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+0]; // R Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+2]; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('X'-'A')*3+0]; // X Graphics_tmp[x++] = Letter_graphic [('X'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('X'-'A')*3+2]; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('E'-'A')*3+0]; // E Graphics_tmp[x++] = Letter_graphic [('E'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('E'-'A')*3+2]; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+0]; // R Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+2]; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+0]; // R Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+2]; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('O'-'A')*3+0]; // O Graphics_tmp[x++] = Letter_graphic [('O'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('O'-'A')*3+2]; Graphics_tmp[x++] = 0; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+0]; // R Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+1]; Graphics_tmp[x++] = Letter_graphic [('R'-'A')*3+2]; Graphics_tmp[x++] = 0; x=0; for (l=0;l<6;l++) { for (k=7;k>=0;k--) Graphics [x++]=Graphics_tmp[k*5+l]; // colonn 5*0+1 } index=0; row=0; bGraphics=1; // graphics mode } // Display Matrix GPIO functions void SetCLK (void) { digitalWriteFast(A0, HIGH);} void ReSetCLK (void) { digitalWriteFast(A0, LOW);} void SetDATA (void) { digitalWriteFast(A3, HIGH);} void ReSetDATA (void) { digitalWriteFast(A3, LOW);} void SetCLR (void) { digitalWriteFast(8, HIGH);} void ReSetCLR (void) { digitalWriteFast(8, LOW);} void SetC1 (void) { digitalWriteFast(7, HIGH);} void ReSetC1 (void) { digitalWriteFast(7, LOW);} void SetC2 (void) { digitalWriteFast(6, HIGH);} void ReSetC2 (void) { digitalWriteFast(6, LOW);} void SetC3 (void) { digitalWriteFast(5, HIGH);} void ReSetC3 (void) { digitalWriteFast(5, LOW);} void SetC4 (void) { digitalWriteFast(4, HIGH);} void ReSetC4 (void) { digitalWriteFast(4, LOW);} void SetC5 (void) { digitalWriteFast(3, HIGH);} void ReSetC5 (void) { digitalWriteFast(3, LOW);} // write a Row void writeRow (unsigned char row_selected,unsigned char CHAR) { // clear all rows SetC1(); SetC2(); SetC3(); SetC4(); SetC5(); if (bGraphics) // graphics mode { data =CHAR; //Serial.print(data); } else { switch (row_selected) { case 0: data = MatrixTableSeg0 [CHAR-32]; break; case 1: data = MatrixTableSeg1 [CHAR-32]; break; case 2: data = MatrixTableSeg2 [CHAR-32]; break; case 3: data = MatrixTableSeg3 [CHAR-32]; break; case 4: data = MatrixTableSeg4 [CHAR-32]; break; } } if ((data & 0x02) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 if ((data & 0x04) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 if ((data & 0x08) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 if ((data & 0x10) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 if ((data & 0x20) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 if ((data & 0x40) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 if ((data & 0x80) >= 1) ReSetDATA(); else SetDATA(); ReSetCLK(); SetCLK(); // push the bit into the 74H164 switch (row_selected) { case 0: ReSetC1(); SetC2(); SetC3(); SetC4(); SetC5(); break; case 1: ReSetC2(); SetC1(); SetC3(); SetC4(); SetC5(); break; case 2: ReSetC3(); SetC1(); SetC2(); SetC4(); SetC5(); break; case 3: ReSetC4(); SetC1(); SetC2(); SetC3(); SetC5(); break; case 4: ReSetC5(); SetC1(); SetC2(); SetC3(); SetC4(); break; } } // pass here around 1ms ISR(TIMER2_COMPA_vect) { // Timer1 interrupt service routine (ISR) digitalWrite(A1, HIGH); Timer_interrupt_count++; Display_counter++; if (state!=0) { // clear all rows SetC1(); SetC2(); SetC3(); SetC4(); SetC5(); return; } ///////////////////// // compute Display // ///////////////////// // if (Display_counter ==4) { Display_counter=0; if (bGraphics) // graphics mode { for (digit=0;digit<8;digit++) { writeRow (row,Graphics [index++]); } row++; if (row==6) row=0; if (index> (MAX_GRAPHICS)) index=0; } else // text mode { for (digit=0;digit<8;digit++) { writeRow (row,CHAR_x[7-digit]); } row++; if (row==5) row=0; } } /////////////////////////////////////// // compute and update display buffer // /////////////////////////////////////// if (bComputeTime) Timer_interrupt_count=0; if (Timer_interrupt_count>=992 && !bComputeTime) { Timer_interrupt_count=0; check_RX_from_main--; // decrease RF timeout if (check_RX_from_main<0) check_RX_from_main=0; // Serial.print(check_RX_from_main); if (check_RX_from_main==1) display_err (); ////////////////// // compute time // ////////////////// SecondeUnit++; // increment second if (SecondeUnit>'9') // increment dizaine of second { SecondeUnit = '0'; SecondeDizaine++; if (SecondeDizaine>'5') // incremente minute { SecondeDizaine='0'; MinuteUnit++; if (MinuteUnit>'9') // incremente dizaine of minute { MinuteUnit='0'; MinuteDizaine++; if (MinuteDizaine>'5') // incremente minute { MinuteDizaine='0'; HeureUnit++; if (HeureDizaine=='0' && HeureUnit>'9') // incremente heure 0h to 10h { HeureDizaine='1'; HeureUnit='0'; } else { if (HeureDizaine=='1' && HeureUnit>'9') // incremente heure 10h to 19h { HeureDizaine='2'; HeureUnit ='0'; } else if (HeureDizaine=='2' && HeureUnit>'3') // incremente heure 20h to 24h { HeureDizaine ='0'; HeureUnit='0'; } } } } } } //////////////////// // update display // //////////////////// CHAR_x [7] = SecondeUnit; CHAR_x [6] = SecondeDizaine; CHAR_x [5] = ':'; CHAR_x [4] = MinuteUnit; CHAR_x [3] = MinuteDizaine; CHAR_x [2] = ':'; CHAR_x [1] = HeureUnit; CHAR_x [0] = HeureDizaine; } digitalWrite(A1, LOW); } void compute_cmd(void) { // Serial.write(RX_cmd); // echo // Serial.write(RX_data); // echo //Serial.println("compute"); switch (RX_cmd) { case SET_CHAR_0: CHAR_x[0]=RX_data; break; case SET_CHAR_1: CHAR_x[1]=RX_data; break; case SET_CHAR_2: CHAR_x[2]=RX_data; break; case SET_CHAR_3: CHAR_x[3]=RX_data; break; case SET_CHAR_4: CHAR_x[4]=RX_data; break; case SET_CHAR_5: CHAR_x[5]=RX_data; break; case SET_CHAR_6: CHAR_x[6]=RX_data; break; case SET_CHAR_7: CHAR_x[7]=RX_data; break; case SET_HEURE_DIZAINE : HeureDizaine=RX_data; break; case SET_HEURE_UNIT : HeureUnit=RX_data; break; case SET_MINUTE_DIZAINE : MinuteDizaine=RX_data; break; case SET_MINUTE_UNIT : MinuteUnit=RX_data; break; case SET_SECONDE_DIZAINE : SecondeDizaine=RX_data; break; case SET_SECONDE_UNIT : SecondeUnit=RX_data; break; case START_STOP_TIME_COMPUTE : bComputeTime = RX_data; break; case START_STOP_GRAPHICS : bGraphics = RX_data; index=0; row=0; break; case START_WRITE_GRAPHICS : Graphics_data_index=0; index=0;row=0; break; case DATA_WRITE_GRAPHICS : Graphics[Graphics_data_index++]= RX_data; if (Graphics_data_index > (MAX_GRAPHICS-1)) // avoid overflow due to host Graphics_data_index = MAX_GRAPHICS-1; break; case DISPLAY_ON_OFF : for (Graphics_data_index=0;Graphics_data_index < (MAX_GRAPHICS-1);Graphics_data_index++) Graphics[Graphics_data_index]= 0; Graphics_data_index=0; break; case CHECK_SYNC : if (RX_data==~CHECK_SYNC) Serial.print("1"); break; case RESET : // soft reset // _asm // reset // _endasm break; case GET_VERSION : put_string (Version); break; } } void put_string (char *str) { //int i=0; // for ( i=0; i < strlen(str);i++) { // Serial.print(str); } } ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR) state = 0; // Reset decoding process TCCR1B = 0; // Disable Timer1 module } void RC5_read() { unsigned int timer_value; if(state != 0) { timer_value = TCNT1; // Store Timer1 value TCNT1 = 0; // Reset Timer1 } switch(state) { case 0 : // Start receiving IR data (initially we're at the beginning of mid1) TCNT1 = 0; // Reset Timer1 TCCR1B = 2; // Enable Timer1 module with 1/8 prescaler ( 2 ticks every 1 us) state = 1; // Next state: end of mid1 j = 0; return; case 1 : // End of mid1 ==> check if we're at the beginning of start1 or mid0 if((timer_value > long_time) || (timer_value < short_time)){ // Invalid interval ==> stop decoding and reset state = 0; // Reset decoding process TCCR1B = 0; // Disable Timer1 module return; } bitSet(rc5_code, 13 - j); j++; if(j > 13) { // If all bits are received success = 1; // Decoding process is OK detachInterrupt(2); // Disable external interrupt return; } if(timer_value > med_time) { // We're at the beginning of mid0 state = 2; // Next state: end of mid0 if(j == 13){ // If we're at the LSB bit success = 1; // Decoding process is OK bitClear(rc5_code, 0); // Clear the LSB bit detachInterrupt(2); // Disable external interrupt return; } } else // We're at the beginning of start1 state = 3; // Next state: end of start1 return; case 2 : // End of mid0 ==> check if we're at the beginning of start0 or mid1 if((timer_value > long_time) || (timer_value < short_time)) { state = 0; // Reset decoding process TCCR1B = 0; // Disable Timer1 module return; } bitClear(rc5_code, 13 - j); j++; if(timer_value > med_time) // We're at the beginning of mid1 state = 1; // Next state: end of mid1 else // We're at the beginning of start0 state = 4; // Next state: end of start0 return; case 3 : // End of start1 ==> check if we're at the beginning of mid1 if((timer_value > med_time) || (timer_value < short_time)) { // Time interval invalid ==> stop decoding TCCR1B = 0; // Disable Timer1 module state = 0; // Reset decoding process return; } else // We're at the beginning of mid1 state = 1; // Next state: end of mid1 return; case 4 : // End of start0 ==> check if we're at the beginning of mid0 if((timer_value > med_time) || (timer_value < short_time)) { // Time interval invalid ==> stop decoding TCCR1B = 0; // Disable Timer1 module state = 0; // Reset decoding process return; } else // We're at the beginning of mid0 state = 2; // Next state: end of mid0 if(j == 13){ // If we're at the LSB bit success = 1; // Decoding process is OK bitClear(rc5_code, 0); // Clear the LSB bit detachInterrupt(2); // Disable external interrupt } } } void start_RF(void) { radio.begin(); //Starting the radio communication radio.openWritingPipe(addresses[0]); //Setting the address at which we will send the data radio.openReadingPipe(0, addresses[0]); // Ouverture du "tunnel2" en LECTURE (réception radio) radio.setPALevel(RF24_PA_MIN); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver. radio.setDataRate(RF24_250KBPS ); radio.setChannel(127); radio.startListening(); //This sets the module as receiver }