/*--------------------------------------------------------------*/ /* Projet: OFFOK */ /* File : offok.ino */ /* Author: JeARZ 02/14/21 */ /*--------------------------------------------------------------*/ /* This gets IR codes send by a TvBeGone & displays results on OLED 02/14/21: First proof of IR sensor & Oled on UNO 02/17/21: Updated to new lib U8g2lib, works OK on UNO 04/05/21: works OK on NANO 04/22/21: new logo, display hex code, test piezo OK 05/19/21: added offok_tunes.h for rtttl libraries & ringtones logo.h renamed to offok_logo.h 10/08/21: enun t_tune for calls of play_r3tl for when SOUND is OFF TODO: adjust parameters, use protothreads ? */ #include /* Graphics settings */ #include #ifdef U8X8_HAVE_HW_SPI #include #endif #ifdef U8X8_HAVE_HW_I2C #include #endif U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2\ (U8G2_R0, /* RST=*/ U8X8_PIN_NONE); #include "offok_logo.h" // Home logo :-) /* IR settings */ #include /* the function tone() uses timer2 by default, so does IRremote lib. * File IRremoteBoardDefs.h, in lib IRremote define wich timer to use */ // #define IR_USE_TIMER1 // use Timer 1 instead of Timer 2 #define NBCODES 120 // min number of codes to qualify a kit #define ACQUINONE 3000 // no IR signal timeout in millisecond const int RECV_PIN = 2; // IR receiver signal pin IRrecv irrecv(RECV_PIN); decode_results results; /* * Sound settings */ #define SOUND_ON // comment if you can't stand the noise ! enum t_tune {NoTone, Intro, CountOK, CountKO, GetIR }; #ifdef SOUND_ON #define PIEZO 7 // Loudspeaker pin #include "offok_tunes.h" // predefined ringtones juke-box :-) #endif //#define DEBUG // ==================== Functions ==================== void showTrace(); // defined after main ifdef DEBUG void showCount(int val) ; // defined after main not used anymore // play a rtttl ringtone defined in offok_tunes.h void play_r3tl (t_tune itune){ char * rtune; #ifdef SOUND_ON switch (itune) { // ugly code to manage SOUND off case NoTone : noTone(PIEZO); return; case Intro : rtune = _rIntro_ ; break; case CountOK : rtune = _rCountOK_ ; break; case CountKO : rtune = _rCountKO_ ; break; case GetIR : rtune = _rGetIR_ ; break; default : rtune = _rCountOK2_; } anyrtttl::blocking::play(PIEZO, rtune); #endif // else: do nothing when ! SOUND_OFF } void drawLogo(void) { // draw the logo screen u8g2.firstPage(); do { u8g2.drawXBMP( 0, 0, logo_width, logo_height, logo_bits); } while ( u8g2.nextPage() ); } // Oled brightness dimmer, slope up or down void contrastSlope(int depart, int aim, int inc, int lag) { int i=depart; // at first, if increasing then if (inc > 0) u8g2.setPowerSave(0); // disable oled do { i=constrain(i,0,255); u8g2.setContrast(i); // 0 (no contrast) to 255 delay (lag); i=i+inc; } while (i != aim); // at end, if decreasing then if (inc < 0) u8g2.clear(); // clear oled } // & at the end ... the winner is void showResult(int val){ char l1[8]; sprintf(l1, "%4d",val); u8g2.firstPage(); do { u8g2.setFont(u8g2_font_profont17_tr); u8g2.drawStr(10,24, "Total recus :"); u8g2.setFont(u8g2_font_profont22_tr); u8g2.drawStr(35,55, l1); } while ( u8g2.nextPage() ); if (val > NBCODES) play_r3tl(CountOK); else play_r3tl(CountKO); play_r3tl(NoTone); } // display incoming IR frame code void showCode(unsigned long val) { char buf[16]; play_r3tl(GetIR); u8g2.firstPage(); do { u8g2.setFont(u8g2_font_profont17_tr); u8g2.drawStr(16,24, "Code recu :"); sprintf(buf, "%08X", val ) ; u8g2.setFont(u8g2_font_profont22_tr); u8g2.drawStr(16,54,buf); } while ( u8g2.nextPage() ); } void setup(void) { play_r3tl(NoTone); u8g2.begin(); u8g2.clear(); #ifdef DEBUG Serial.begin(9600); #endif play_r3tl(Intro); drawLogo(); contrastSlope(0, 255, 1, 15); irrecv.enableIRIn(); // Start the receiver delay(1000); } // ==================== Main ==================== // Global parameters int cl=0; unsigned long lastReading=0, currentt=0; void loop(void) { play_r3tl(NoTone); if (irrecv.decode(&results)) { // if we keep getting signals, it is running lastReading=millis(); cl += 1; showCode(results.value); //showCount(cl); irrecv.resume(); } else // got no more reading { // if we keep getting nothing, then it is over currentt = millis(); if ((lastReading + ACQUINONE < currentt) && ( cl > 0)) { // lastReading too old showTrace(); showResult(cl); cl = 0; contrastSlope(255, 0, -1, 35); // fades results in ~ 9 sec delay(1000); drawLogo(); contrastSlope(0, 255, 1, 15); // takes ~ 4 sec for logo to be full bright } } } // loop // debugging void showTrace() { #ifdef DEBUG Serial.print("OK cl : "); Serial.print(cl); Serial.print(" currentt : "); Serial.print(currentt); Serial.print(" lastReading : "); Serial.println(lastReading); #endif } // show IR frames count, replaced by showResult void showCount(int val) { char buf[16]; u8g2.firstPage(); do { u8g2.setFont(u8g2_font_fub14_tr); u8g2.drawStr(12,28,"Codes lus :"); sprintf(buf, "%3d", val ) ; u8g2.setFont(u8g2_font_fub20_tr); u8g2.drawStr(40,60,buf); } while ( u8g2.nextPage() ); }