/* ************************************************************** * RGB_I2C_MessageBoard * Created by CH, Chen(Taiwan) * 2012.7.21 * ************************************************************** */ #include #include #define THIS_DEVICE 0x31 #define DEVICE_VERSION 0x00 #define VENDOR_ID 0x08 #define DEVICE_ID 0x10 #define IS_NEXT_DISPLAY 0x40 #define SET_STR_BACK_COLOR 0x41 #define DISPLAY_BLACK_FONT 0x42 #define DISPLAY_RED_FONT 0x43 #define DISPLAY_GREEN_FONT 0x44 #define DISPLAY_BLUE_FONT 0x45 #define DISPLAY_BROWN_FONT 0x46 #define DISPLAY_PURPLE_FONT 0x47 #define DISPLAY_TEAL_FONT 0x48 #define DISPLAY_WHITE_FONT 0x49 #define DISPLAY_CODE 0x50 #define SET_CODE_FONT_COLOR 0x51 #define SET_CODE_BACK_COLOR 0x52 #define DISPLAY_CODE_1 '1' #define DISPLAY_CODE_9 '9' #define RGB_COLOR_BLACK 'b' #define RGB_COLOR_RED 'R' #define RGB_COLOR_GREEN 'G' #define RGB_COLOR_BLUE 'B' #define RGB_COLOR_BROWN 'r' #define RGB_COLOR_PURPLE 'P' #define RGB_COLOR_TEAL 'T' #define RGB_COLOR_WHITE 'W' uint8_t softwareVersion[9] = "V1.00 "; uint8_t vendorID[9] = "CH_Lego "; uint8_t deviceID[9] = "MsgBoard"; #define BLACK 0 #define RED 0xE0 #define GREEN 0x1C #define BLUE 0x03 #define BROWN (RED|GREEN) #define PURPLE (RED|BLUE) #define TEAL (GREEN|BLUE) #define WHITE (RED|GREEN|BLUE) const int CS_pin = 10; const int MOSI_pin = 11; const int SCLK_pin = 13; const int MISO_pin = 12; // Captial character font (A - Z) const byte captialFont[] = {0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0, 0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00, 0xE0, 0X90, 0x88, 0x88, 0x88, 0x90, 0xE0, 0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8, 0x00, 0x78, 0x88, 0x88, 0x98, 0x80, 0x88, 0x70, 0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x60, 0x90, 0x90, 0x10, 0x10, 0x10, 0x38, 0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88, 0x00, 0xF8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xD8, 0x88, 0x00, 0x88, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x88, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x88, 0x88, 0xF0, 0x00, 0x08, 0x70, 0xA8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x88, 0x90, 0xA0, 0xF0, 0x88, 0x88, 0xF0, 0x00, 0x70, 0x88, 0x08, 0x70, 0x80, 0x88, 0x70, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x20, 0x50, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x50, 0xA8, 0xA8, 0xA8, 0x88, 0x88, 0x88, 0x00, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00, 0x20, 0x20, 0x20, 0x50, 0x88, 0x88, 0x88, 0x00, 0xF8, 0x80, 0x40, 0x20, 0x10, 0x08, 0xF8, 0x00 }; // Lower case character font(a - z) const byte lowerFont[] = {0x78, 0x88, 0x78, 0x08, 0x70, 0x00, 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x00, 0x78, 0x80, 0x80, 0x88, 0x70, 0x00, 0x00, 0x00, 0x78, 0x88, 0x88, 0x88, 0x78, 0x08, 0x08, 0x00, 0x78, 0x80, 0xF8, 0x88, 0x70, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x40, 0x30, 0x00, 0xF0, 0x08, 0x78, 0x88, 0x88, 0x70, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x00, 0x70, 0x20, 0x20, 0x20, 0x60, 0x00, 0x20, 0x00, 0x60, 0x90, 0x10, 0x10, 0x30, 0x00, 0x10, 0x00, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x80, 0x80, 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xF0, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0xF0, 0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0xF0, 0x00, 0x00, 0x08, 0x08, 0x78, 0x88, 0x88, 0x78, 0x00, 0x00, 0x40, 0x40, 0x40, 0x48, 0xB0, 0x00, 0x00, 0x00, 0xF0, 0x08, 0x70, 0x80, 0x78, 0x00, 0x00, 0x00, 0x30, 0x40, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x00, 0x78, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x20, 0x50, 0x50, 0x88, 0x88, 0x00, 0x00, 0x00, 0x50, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x88, 0x88, 0x00, 0x00, 0xF8, 0x40, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00 }; // Number character font(0 - 9) const byte numberFont[] = {0x70, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x70, 0x00, 0xF8, 0x20, 0x20, 0x20, 0xA0, 0x60, 0x20, 0x00, 0xF8, 0x80, 0x40, 0x30, 0x08, 0x88, 0x70, 0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x88, 0x70, 0x00, 0x10, 0x10, 0xF8, 0x90, 0x50, 0x30, 0x10, 0x00, 0x70, 0x88, 0x08, 0x08, 0xF0, 0x80, 0xF8, 0x00, 0x70, 0x88, 0x88, 0xF0, 0x80, 0x40, 0x30, 0x00, 0x40, 0x40, 0x40, 0x20, 0x10, 0x08, 0xF8, 0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70, 0x00, 0x60, 0x10, 0x08, 0x78, 0x88, 0x88, 0x70, 0x00 }; const byte dotFont[] = {0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}; // . const byte dashFont[] = {0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00}; // - const byte commaFont[] = {0x60, 0x10, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00}; // , const byte slashFont[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00}; // / const byte exclamFont[] = {0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}; // ! const byte questionFont[]= {0x20, 0x00, 0x20, 0x10, 0x08, 0x88, 0x70, 0x00}; // ? const byte colonFont[] = {0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x00}; // : const byte semicolonFont[]={0x60, 0x10, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00}; // ; // Chinese font - GoGO + Heart logo int C1_strLen = 4; const byte C1_gogoFont[] ={0xA0, 0x57, 0x55, 0x55, 0x55, 0x55, 0xF7, 0x40, 0x27, 0x15, 0x05, 0x37, 0x05, 0x05, 0x17, 0x21, 0xC1, 0x43, 0x45, 0xCB, 0x4B, 0x4B, 0xC6, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xC0, 0x00}; // Chinese font - TouchClass + NXT Logo int C9_strLen = 4; const byte C9_TouchFont[] ={0x55, 0x4E, 0xC4, 0x7F, 0x44, 0x4A, 0xF1, 0x5F, 0x0C, 0x0C, 0x00, 0x2F, 0x18, 0x05, 0x1F, 0x02, 0x87, 0x87, 0x87, 0xC5, 0xC7, 0x04, 0xC4, 0x07, 0xF0, 0x70, 0xF0, 0x50, 0xF0, 0x10, 0x10, 0xF0}; #define FONT_WIDTH 8 #define FONT_HEIGHT 8 #define MAX_STR_LENGTH 16 #define DISPLAY_SPEED 100 char receiveBuffer[MAX_STR_LENGTH]; char g_displayCode, g_CodefontColor=RED, g_CodebackColor=BLACK, g_StrfontColor=RED, g_StrbackColor=BLACK; int g_strLen=0; byte requestRegister, requestCommand; boolean isDisplayString, isDisplayCode; void setup() { Serial.begin(9600); Wire.begin(THIS_DEVICE); Wire.onReceive(receiveEvent); Wire.onRequest(requestEvent); pinMode (CS_pin, OUTPUT); pinMode (MOSI_pin, OUTPUT); pinMode (SCLK_pin, OUTPUT); SPI.setClockDivider(SPI_CLOCK_DIV64); SPI.begin(); } void loop() { if(isDisplayString) { displayStringMarqueeEX(receiveBuffer, g_strLen, g_StrfontColor, g_StrbackColor); } else if(isDisplayCode) { displayCodeMarqueeEX(g_displayCode, g_strLen, g_CodefontColor, g_CodebackColor); } delay(100); } /* ************************************************************ * I2C write handler * ************************************************************ */ void receiveEvent(int howMany) { requestRegister = Wire.read(); if(requestRegister == SET_STR_BACK_COLOR) { char r_StrbackColor = Wire.read(); switch(r_StrbackColor) { case RGB_COLOR_BLACK: g_StrbackColor = BLACK; break; case RGB_COLOR_RED: g_StrbackColor = RED; break; case RGB_COLOR_GREEN: g_StrbackColor = GREEN; break; case RGB_COLOR_BLUE: g_StrbackColor = BLUE; break; case RGB_COLOR_BROWN: g_StrbackColor = BROWN; break; case RGB_COLOR_PURPLE: g_StrbackColor = PURPLE; break; case RGB_COLOR_TEAL: g_StrbackColor = TEAL; break; case RGB_COLOR_WHITE: g_StrbackColor = WHITE; break; default: g_StrbackColor = BLACK; break; } } else if(requestRegister == DISPLAY_CODE) { char r_displayCode = Wire.read(); char r_CodefontColor = Wire.read(); char r_CodebackColor = Wire.read(); switch(r_displayCode) { case DISPLAY_CODE_1: isDisplayString = false; isDisplayCode = true; g_displayCode = DISPLAY_CODE_1; g_strLen = C1_strLen; break; case DISPLAY_CODE_9: isDisplayString = false; isDisplayCode = true; g_displayCode = DISPLAY_CODE_9; g_strLen = C9_strLen; break; default: isDisplayCode = false; break; } switch(r_CodefontColor) { case RGB_COLOR_BLACK: g_CodefontColor = BLACK; break; case RGB_COLOR_RED: g_CodefontColor = RED; break; case RGB_COLOR_GREEN: g_CodefontColor = GREEN; break; case RGB_COLOR_BLUE: g_CodefontColor = BLUE; break; case RGB_COLOR_BROWN: g_CodefontColor = BROWN; break; case RGB_COLOR_PURPLE: g_CodefontColor = PURPLE; break; case RGB_COLOR_TEAL: g_CodefontColor = TEAL; break; case RGB_COLOR_WHITE: g_CodefontColor = WHITE; break; default: g_CodefontColor = RED; break; } switch(r_CodebackColor) { case RGB_COLOR_BLACK: g_CodebackColor = BLACK; break; case RGB_COLOR_RED: g_CodebackColor = RED; break; case RGB_COLOR_GREEN: g_CodebackColor = GREEN; break; case RGB_COLOR_BLUE: g_CodebackColor = BLUE; break; case RGB_COLOR_BROWN: g_CodebackColor = BROWN; break; case RGB_COLOR_PURPLE: g_CodebackColor = PURPLE; break; case RGB_COLOR_TEAL: g_CodebackColor = TEAL; break; case RGB_COLOR_WHITE: g_CodebackColor = WHITE; break; default: g_CodebackColor = BLACK; break; } } else { g_strLen = 0; while(Wire.available()) { receiveBuffer[g_strLen] = (char)Wire.read(); g_strLen++; if(g_strLen>=MAX_STR_LENGTH) break; } if(g_strLen>0) { isDisplayString = true; isDisplayCode = false; switch((char)requestRegister) { case DISPLAY_BLACK_FONT: g_StrfontColor = BLACK; break; case DISPLAY_RED_FONT: g_StrfontColor = RED; break; case DISPLAY_GREEN_FONT: g_StrfontColor = GREEN; break; case DISPLAY_BLUE_FONT: g_StrfontColor = BLUE; break; case DISPLAY_BROWN_FONT: g_StrfontColor = BROWN; break; case DISPLAY_PURPLE_FONT: g_StrfontColor = PURPLE; break; case DISPLAY_TEAL_FONT: g_StrfontColor = TEAL; break; case DISPLAY_WHITE_FONT: g_StrfontColor = WHITE; break; default: g_StrfontColor = RED; break; } } } } /* ************************************************************ * I2C Read handler * ************************************************************ */ void requestEvent() { if(requestRegister == DEVICE_VERSION) { Wire.write(softwareVersion, 8); } else if(requestRegister == VENDOR_ID) { Wire.write(vendorID, 8); } else if(requestRegister == DEVICE_ID) { Wire.write(deviceID, 8); } else if(requestRegister == IS_NEXT_DISPLAY) { Wire.write('Y'); isDisplayCode = false; isDisplayString = false; } } /* ************************************************************ * display string with marquee effect extended function * ************************************************************ */ void displayStringMarqueeEX(char* displayStr, int strLen, char fontColor, char backColor) { char fontBuffer[FONT_HEIGHT*MAX_STR_LENGTH]; if(strLen > MAX_STR_LENGTH) strLen = MAX_STR_LENGTH; for(int idx=0; idx MAX_STR_LENGTH) strLen = MAX_STR_LENGTH; for(int idx=0; idx= 'A') && (displayChar <= 'Z')) for(int idx=0; idx= 'a') && (displayChar <= 'z')) for(int idx=0; idx= '0') && (displayChar <= '9')) for(int idx=0; idx=0; fidx--) { // From MSB to LSB for(int xrow=0; xrow<8; xrow++) { // Each row for(int xcol=7, fcnt=fidx; xcol>=0; xcol--, fcnt++) { // Each column dotMatrixBuffer[xrow*8+xcol] = backColor; if((fcnt<=FONT_WIDTH-1)) { if(bitRead(fontBuffer[cidx*FONT_HEIGHT+xrow], fcnt)) dotMatrixBuffer[xrow*8+xcol] = fontColor; } else if(cidx>0) { if(bitRead(fontBuffer[(cidx-1)*FONT_HEIGHT+xrow], fcnt-FONT_WIDTH)) dotMatrixBuffer[xrow*8+xcol] = fontColor; } } } transferRGBMatrix(dotMatrixBuffer, DISPLAY_SPEED); } } } /* ************************************************************ * SPI write to RGB Matrix * ************************************************************ */ void transferRGBMatrix(char* dotMatrixBuffer, int delayMillis) { digitalWrite(CS_pin, LOW); delay(1); for(int xi=0; xi<64; xi++) SPI.transfer(dotMatrixBuffer[xi]); digitalWrite(CS_pin, HIGH); delay (delayMillis); }