/* * UNO Monitor Receiver v.0.1.0 (4-bit LCD Version) * Kidacro * https://kidacro.archamedis.net/git/kidacro/Arduino/src/branch/main/uno-stats-monitor * * uno_reciever.ino - Arduino Receiver * * Waits for input over serial connection and displays on LCD & LED * Receives IR events and reports them over serial connection to a daemon * * Input Schema: * Start char is: '#' * End char is: '@' * 2nd char denotes which line number/mode to use * * Setting Schema: * LCDLength:LCDRows:LCDDelay:LEDBrightness:LEDDelay * 16:2:5:1:3 * * Example: * Line 1: #1Archamedis Status@ * Line 2: #299% free / etc.@ * LAVG -: #-24@ * LSET 0: #016:2:5:1:3@ * Output Schema: * Multimedia Controls use single characters to denote which button was pressed * P power * M mute * m mode * p pause/play * b back * f forward * e eq * - vol down * + vol up * r return * u usb scan * 0 number 0 * 1 number 1 * 2 number 2 * 3 number 3 * 4 number 4 * 5 number 5 * 6 number 6 * 7 number 7 * 8 number 8 * 9 number 9 * R repeat * Z other button pressed */ #include #include #include /* LCD Pinout: * LCD RS pin to digital pin 12 * LCD Enable pin to digital pin 11 * LCD D4 pin to digital pin 5 * LCD D5 pin to digital pin 4 * LCD D6 pin to digital pin 3 * LCD D7 pin to digital pin 2 * LCD R/W pin to ground * LCD VSS pin to ground * LCD VCC pin to 5V * 10K potentiometer: * ends to +5V and ground * wiper to LCD VO pin (pin 3) */ /* LED Pinout: * LED DataIn(DIN) to digital pin 10 * LED LOAD(CS) to digital pin 9 * LED CLK to digital pin 8 * LED VSS pin to 5V * LED GND to ground */ /* IR Pinout * IR Signal to digital pin 13 * IR VSS pin to 5V * IR GND to ground */ // LCD vars const int LCDRS = 12, LCDEN = 11, LCDD4 = 5, LCDD5 = 4, LCDD6 = 3, LCDD7 = 2; int LCDLength = 16; int LCDRows = 2; int LCDDelay = 10; LiquidCrystal LCD(LCDRS, LCDEN, LCDD4, LCDD5, LCDD6, LCDD7); // LED vars const int LEDIN = 10, LEDCS = 9, LEDCLK = 8; LedControl LEDlc=LedControl(LEDIN,LEDCLK,LEDCS,1); int LEDBrightness = 8; // default = 8 / max = 15 unsigned long LEDDelay=10; // IR vars const int IRSIG = 13; IRrecv Irrecv(IRSIG); decode_results IRresults; // Serial vars const byte SERnumChars = 32; char SERrecvChars[SERnumChars]; boolean SERnewData = false; // Debugging boolean DEBUG = false; void LEDSetup(void) { /* The MAX72XX is in power-saving mode on startup, we have to do a wakeup call */ LEDlc.shutdown(0,false); /* Set the brightness */ LEDlc.setIntensity(0,LEDBrightness); /* and clear the display */ LEDlc.clearDisplay(0); } void LcdSetup(void) { // set up the LCD's number of columns and rows: LCD.begin(LCDLength, LCDRows); // clear LCD.clear(); } void IRSetup(void) { // start the receiver Irrecv.enableIRIn(); } // dynamic lines & character wiping (LCDLength) void LcdLd(int line = 1, boolean wipe = false) { char myline[LCDLength]; int x = 0; // physical line #'s to logical if(line > 0) { line--; } // don't go past last row if(line > LCDRows) { line = LCDRows; } delay(LCDDelay); LCD.setCursor(0, line); // Define the cursor position as the 1st position of the specified line if(wipe) { for(x=0;x LCDLength) { mylen = LCDLength; } // Debug input and length if(DEBUG) { Serial.println("\n\nString: "); Serial.println(mymessage); Serial.println(mymessage.length()); } // Output string //LCD.print(mymessage); // Output character by character for(i=0; i < mylen; i++) { char c = mymessage[i]; delay(LCDDelay); LCD.print(c); delay(LCDDelay); } } // TODO: make segment_row & segment_col dynamic and configurable void LedIntro() { for(int row=0;row<8;row++) { for(int col=0;col<8;col++) { delay(LEDDelay); LEDlc.setLed(0,row,col,true); delay(LEDDelay); for(int i=0;i= 12) segments = 1; if(myload >= 25) segments = 2; if(myload >= 37) segments = 3; if(myload >= 50) segments = 4; if(myload >= 62) segments = 5; if(myload >= 75) segments = 6; if(myload >= 87) segments = 7; if(myload >= 95) segments = 8; // segments as rows for(int row=0;row<8;row++) { for(int col=0;col 0 && SERnewData == false) { // process serial signal rc = Serial.read(); if(recvInProgress == true) { if(rc != endMarker) { SERrecvChars[ndx] = rc; ndx++; if (ndx >= SERnumChars) { ndx = SERnumChars - 1; } } else { SERrecvChars[ndx] = '\0'; // terminate the string recvInProgress = false; ndx = 0; SERnewData = true; } } else if(rc == startMarker) { recvInProgress = true; } } } // process new data // data schema: // 1st character denotes function: // 1 - print on 1st line as is // 2 - print on 2nd line as is // - - display load on LCD matrix // 0 - set a setting void procNewData() { int line = 0; if(SERnewData == true) { if(DEBUG) { Serial.print("Receiver says: "); Serial.println(SERrecvChars); } // print to given line on LCD if(SERrecvChars[0] != '-' && SERrecvChars[0] != '0') { line = SERrecvChars[0] - '0'; LcdLd(line,true); memmove(SERrecvChars, SERrecvChars+1, strlen(SERrecvChars)); LcdWrite(SERrecvChars); } // show load on LED matrix if(SERrecvChars[0] == '-') { memmove(SERrecvChars, SERrecvChars+1, strlen(SERrecvChars)); LedShowLoad(SERrecvChars); } // load new settings if(SERrecvChars[0] == '0') { memmove(SERrecvChars, SERrecvChars+1, strlen(SERrecvChars)); LoadSettings(SERrecvChars); } SERnewData = false; } } // settings schema: // LCDLength:LCDRows:LCDDelay:LEDBrightness:LEDDelay // 16:2:5:1:3 void LoadSettings(char* mysettings) { LCDLength = atoi(strtok(mysettings, ":")); LCDRows = atoi(strtok(NULL, ":")); LCDDelay = atoi(strtok(NULL, ":")); LEDBrightness = atoi(strtok(NULL, ":")); LEDDelay = atoi(strtok(NULL, ":")); LEDlc.setIntensity(0,LEDBrightness); } void setup (void) { // init HW LcdSetup(); LEDSetup(); IRSetup(); // open serial port Serial.begin(9600); // display intros LcdIntro(); LedIntro(); } // main() void loop (void) { // process IR signal if(Irrecv.decode(&IRresults)) { IRtranslate(); // process result Irrecv.resume(); // receive the next command } // process serial input SERrecv(); // process new data procNewData(); }