diff --git a/firmware/Examples/Advanced/OpenLCD_Qwiic_RGB_Backlight/OpenLCD_Qwiic_RGB_Backlight.ino b/firmware/Examples/Advanced/OpenLCD_Qwiic_RGB_Backlight/OpenLCD_Qwiic_RGB_Backlight.ino new file mode 100644 index 0000000..1820d2c --- /dev/null +++ b/firmware/Examples/Advanced/OpenLCD_Qwiic_RGB_Backlight/OpenLCD_Qwiic_RGB_Backlight.ino @@ -0,0 +1,245 @@ +/* + * This sketch changes the backlight color and displays text using + * the OpenLCD functions. + * + *The circuit: + * Sparkfun RGB OpenLCD Serial display connected through + * a Sparkfun Qwiic adpater to an Ardruino with a + * Qwiic shield or a Sparkfun Blackboard with Qwiic built in. + * + * The Qwiic adapter should be attached to the display as follows: + * + * Display Qwiic Qwiic Cable Color + * GND GND Black + * RAW 3.3V Red + * SDA SDA Blue + * SCL SCL Yellow + * + * Note: If you connect directly to a 5V Arduino instead, you *MUST* use + * a level-shifter to convert the i2c voltage levels down to 3.3V for the display. + + OpenLCD is an LCD with Serial/I2C/SPI interfaces. + By: Nathan Seidle + SparkFun Electronics + Date: April 19th, 2015 + License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). + OpenLCD gives the user multiple interfaces (serial, I2C, and SPI) to control an LCD. SerLCD was the original + serial LCD from SparkFun that ran on the PIC 16F88 with only a serial interface and limited feature set. + This is an updated serial LCD. + + This example shows how to change brightness of the three backlight controls. + + Please Note: 0x72 is the 7-bit I2C address. If you are using a different language than Arduino you will probably + need to add the Read/Write bit to the end of the address. This means the default read address for the OpenLCD + is 0b.1110.0101 or 0xE5 and the write address is 0b.1110.0100 or 0xE4. + For more information see https://learn.sparkfun.com/tutorials/i2c + Note: This code expects the display to be listening at the default I2C address. If your display is not at 0x72, you can + do a hardware reset. Tie the RX pin to ground and power up OpenLCD. You should see the splash screen + then "System reset Power cycle me" and the backlight will begin to blink. Now power down OpenLCD and remove + the RX/GND jumper. OpenLCD is now reset. + + To get this code to work, attached an OpenLCD to an Arduino Uno using the following pins: + SCL (OpenLCD) to A5 (Arduino) + SDA to A4 + VIN to 5V + GND to GND + + The OpenLCD has 4.7k pull up resistors on SDA and SCL. If you have other devices on the + I2C bus then you may want to disable the pull up resistors by clearing the PU (pull up) jumper. + + OpenLCD will work at 400kHz Fast I2C. Use the .setClock() call shown below to set the data rate + faster if needed. + Command cheat sheet: + ASCII / DEC / HEX + '|' / 124 / 0x7C - Put into setting mode + Ctrl+c / 3 / 0x03 - Change width to 20 + Ctrl+d / 4 / 0x04 - Change width to 16 + Ctrl+e / 5 / 0x05 - Change lines to 4 + Ctrl+f / 6 / 0x06 - Change lines to 2 + Ctrl+g / 7 / 0x07 - Change lines to 1 + Ctrl+h / 8 / 0x08 - Software reset of the system + Ctrl+i / 9 / 0x09 - Enable/disable splash screen + Ctrl+j / 10 / 0x0A - Save currently displayed text as splash + Ctrl+k / 11 / 0x0B - Change baud to 2400bps + Ctrl+l / 12 / 0x0C - Change baud to 4800bps + Ctrl+m / 13 / 0x0D - Change baud to 9600bps + Ctrl+n / 14 / 0x0E - Change baud to 14400bps + Ctrl+o / 15 / 0x0F - Change baud to 19200bps + Ctrl+p / 16 / 0x10 - Change baud to 38400bps + Ctrl+q / 17 / 0x11 - Change baud to 57600bps + Ctrl+r / 18 / 0x12 - Change baud to 115200bps + Ctrl+s / 19 / 0x13 - Change baud to 230400bps + Ctrl+t / 20 / 0x14 - Change baud to 460800bps + Ctrl+u / 21 / 0x15 - Change baud to 921600bps + Ctrl+v / 22 / 0x16 - Change baud to 1000000bps + Ctrl+w / 23 / 0x17 - Change baud to 1200bps + Ctrl+x / 24 / 0x18 - Change the contrast. Follow Ctrl+x with number 0 to 255. 120 is default. + Ctrl+y / 25 / 0x19 - Change the TWI address. Follow Ctrl+x with number 0 to 255. 114 (0x72) is default. + Ctrl+z / 26 / 0x1A - Enable/disable ignore RX pin on startup (ignore emergency reset) + '-' / 45 / 0x2D - Clear display. Move cursor to home position. + / 128-157 / 0x80-0x9D - Set the primary backlight brightness. 128 = Off, 157 = 100%. + / 158-187 / 0x9E-0xBB - Set the green backlight brightness. 158 = Off, 187 = 100%. + / 188-217 / 0xBC-0xD9 - Set the blue backlight brightness. 188 = Off, 217 = 100%. +For example, to change the baud rate to 115200 send 124 followed by 18. + '+' / 43 / 0x2B - Set Backlight to RGB value, follow + by 3 numbers 0 to 255, for the r, g and b values to set. + For example, to change the backlight to yellow send + followe by 255, 255 and 0. + + +*/ + +#include + +#define DISPLAY_ADDRESS1 0x72 //This is the default address of the OpenLCD + +void setup() +{ + Wire.begin(); //Join the bus as master + + //By default .begin() will set I2C SCL to Standard Speed mode of 100kHz + Wire.setClock(400000); //Optional - set I2C SCL to High Speed Mode of 400kHz + + Serial.begin(9600); //Start serial communication at 9600 for debug statements + Serial.println("OpenLCD Example Code"); + + //Send the reset command to the display - this forces the cursor to return to the beginning of the display + Wire.beginTransmission(DISPLAY_ADDRESS1); + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.endTransmission(); + Wire.print("Testing Set RGB"); + delay(2000); +} + +void loop() +{ + //Turn off backlight (black) + Serial.println("Setting RGB backlight to black"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0x00); //Send the red value + Wire.write(0x00); //Send the green value + Wire.write(0x00); //Send the blue value + Wire.print("Black (Off)!"); + Wire.endTransmission(); //Stop I2C transmission + + delay(2000); + + + //Set red backlight + Serial.println("Setting RGB backlight to red"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0xFF); //Send the red value + Wire.write(0x00); //Send the green value + Wire.write(0x00); //Send the blue value + Wire.print("Red!"); + Wire.endTransmission(); //Stop I2C transmission + + delay(2000); + + //Set Orange backlight + Serial.println("Setting RGB backlight to orange"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0xFF); //Send the red value + Wire.write(0x8C); //Send the green value + Wire.write(0x00); //Send the blue value + Wire.print("Orange!"); + Wire.endTransmission(); //Stop I2C transmission + + delay(2000); + + //Set yellow backlight + Serial.println("Setting RGB backlight to yellow"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0xFF); //Send the red value + Wire.write(0xFF); //Send the green value + Wire.write(0x00); //Send the blue value + Wire.print("Yellow!"); + Wire.endTransmission(); //Stop I2C transmission + + delay(2000); + + //Set green backlight + Serial.println("Setting RGB backlight to green"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0x00); //Send the red value + Wire.write(0xFF); //Send the green value + Wire.write(0x00); //Send the blue value + Wire.print("Green!"); + Wire.endTransmission(); //Stop I2C transmission + delay(2000); + + //Set blue backlight + Serial.println("Setting RGB backlight to blue"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0x00); //Send the red value + Wire.write(0x00); //Send the green value + Wire.write(0xFF); //Send the blue value + Wire.print("Blue!"); + Wire.endTransmission(); //Stop I2C transmission + delay(2000); + + //Set violet backlight + Serial.println("Setting RGB backlight to violet"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0xA0); //Send the red value + Wire.write(0x20); //Send the green value + Wire.write(0xF0); //Send the blue value + Wire.print("Violet!"); + Wire.endTransmission(); //Stop I2C transmission + delay(2000); + + //Turn on all (white) + Serial.println("Setting RGB backlight to white"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0xFF); //Send the red value + Wire.write(0xFF); //Send the green value + Wire.write(0xFF); //Send the blue value + Wire.print("White!"); + Wire.endTransmission(); //Stop I2C transmission + delay(2000); + + //Set to Gray + Serial.println("Setting RGB backlight to gray"); + Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1 + Wire.write('|'); //Put LCD into setting mode + Wire.write('-'); //Send clear display command + Wire.write('|'); //Put LCD into setting mode + Wire.write('+'); //Send the Set RGB command + Wire.write(0x80); //Send the red value + Wire.write(0x80); //Send the green value + Wire.write(0x80); //Send the blue value + Wire.print("Gray!"); + Wire.endTransmission(); //Stop I2C transmission + delay(2000); +} diff --git a/firmware/OpenLCD/OpenLCD.ino b/firmware/OpenLCD/OpenLCD.ino index 5d657d0..514ed0a 100644 --- a/firmware/OpenLCD/OpenLCD.ino +++ b/firmware/OpenLCD/OpenLCD.ino @@ -71,11 +71,17 @@ byte customCharData[8]; //Records incoming custom character data byte customCharSpot = 0 ; //Keeps track of where we are in custCharData array byte customCharNumber = 0; //LCDs can store 8 custom chars, this keeps track +//New variables for Set RGB command +byte rgbData[3]; //Records incoming backlight rgb triplet +byte rgbSpot = 0 ; //Keeps track of where we are in rgbData array + bool modeCommand = false; //Used to indicate if a command byte has been received bool modeSetting = false; //Used to indicate if a setting byte has been received bool modeContrast = false; //First setting mode, then contrast change mode, then the value to change to bool modeTWI = false; //First setting mode, then TWI change mode, then the value to change to bool modeRecordCustomChar = false; //First setting mode, then custom char mode, then record 8 bytes +//New command mode for Set RGB +bool modeSetRGB = false; //First setting mode, then RGB mode, then get 3 bytes // Struct for circular data buffer // Data received over UART, SPI and I2C are all sent into a single buffer @@ -146,8 +152,8 @@ void updateDisplay() buffer.tail = (buffer.tail + 1) % BUFFER_SIZE; // and update the tail to the next oldest //If the last byte received wasn't special - if (modeCommand == false && modeSetting == false && modeContrast == false && modeTWI == false && modeRecordCustomChar == false) - { + if (modeCommand == false && modeSetting == false && modeContrast == false && modeTWI == false + && modeRecordCustomChar == false && modeSetRGB == false) { //Check to see if the incoming byte is special if (incoming == SPECIAL_SETTING) modeSetting = true; //SPECIAL_SETTING is 127 else if (incoming == SPECIAL_COMMAND) modeCommand = true; //SPECIAL_COMMAND is 254 @@ -275,6 +281,10 @@ void updateDisplay() currentFrame[characterCount++] = incoming; //Record this character to the display buffer if (characterCount == settingLCDwidth * settingLCDlines) characterCount = 0; //Wrap condition } + //Set Backlight RGB in one command to eliminate flicker + else if (incoming == 43) { + modeSetRGB = true; + } modeSetting = false; } else if (modeTWI == true) @@ -421,6 +431,20 @@ void updateDisplay() changeContrast(incoming); modeContrast = false; //Exit this mode } + else if (modeSetRGB == true) + { + //We get into this mode if the user has sent the + (43) command to set the backlight rgb values + rgbData[rgbSpot] = incoming; //Record this byte to the array + + rgbSpot++; + if (rgbSpot > 2) + { + //Once we have 3 bytes, stop listening and change the backlight color + rgbSpot = 0; + changeBacklightRGB(rgbData[0], rgbData[1], rgbData[2]); + modeSetRGB = false; //Exit this mode + } //if (rgbSpot > 2) + } // else if modeSetRGB } diff --git a/firmware/OpenLCD/Setting_Control.ino b/firmware/OpenLCD/Setting_Control.ino index 4bd3734..24c9f7c 100644 --- a/firmware/OpenLCD/Setting_Control.ino +++ b/firmware/OpenLCD/Setting_Control.ino @@ -143,6 +143,26 @@ void changeBLBrightness(byte color, byte brightness) displayFrameBuffer(); //Display what was there before } +//Changes the brightness of all three backlight pins and updates the EEPROM locations +//with their rgb values to eliminate flicker. Incoming brightness values should be 0 to 255 +void changeBacklightRGB(byte red, byte green, byte blue) { + //update red + EEPROM.write(LOCATION_RED_BRIGHTNESS, red); //Record new setting + analogWrite(BL_RW, 255 - red); //Controlled by PNP so reverse the brightness value + //update green + EEPROM.write(LOCATION_GREEN_BRIGHTNESS, green); //Record new setting + analogWrite(BL_G, 255 - green); //Controlled by PNP so reverse the brightness value + //update blue (SoftPWM) + EEPROM.write(LOCATION_BLUE_BRIGHTNESS, blue); //Record new setting + //analogWrite(BL_B, 255 - brightness); //Controlled by PNP so reverse the brightness value + SoftPWMSet(BL_B, 255 - blue); //Controlled by software PWM + + petSafeDelay(SYSTEM_MESSAGE_DELAY); + + displayFrameBuffer(); //Display what was there before +} + + //Changes the baud rate setting //Assumes caller is passing a number 0 to 12 void changeUARTSpeed(byte setting)