From 060386e0eb2ff6733f669c688a6098ec2656e802 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Thu, 30 Apr 2020 08:32:56 -0400 Subject: [PATCH 01/12] Added defineChar function and updated examples --- .../Example10_DefineChar.ino | 64 ++++ .../Example7_unkownChar.ino | 7 +- src/SparkFun_Alphanumeric_Display.cpp | 359 ++++++++---------- src/SparkFun_Alphanumeric_Display.h | 13 +- 4 files changed, 226 insertions(+), 217 deletions(-) create mode 100644 examples/Example10_DefineChar/Example10_DefineChar.ino diff --git a/examples/Example10_DefineChar/Example10_DefineChar.ino b/examples/Example10_DefineChar/Example10_DefineChar.ino new file mode 100644 index 0000000..c601dfa --- /dev/null +++ b/examples/Example10_DefineChar/Example10_DefineChar.ino @@ -0,0 +1,64 @@ +/************************************************************************************** + * This example redefines some characters of an alphanumeric display. + * + * Written by Gaston Williams + * April 30, 2020 + * + * Based on code written by + * Priyanka Makin @ SparkFun Electronics + * Original Creation Date: February 26, 2020 + * + * SparkFun labored with love to create this code. Feel like supporting open source hardware? + * Buy a board from SparkFun! https://www.sparkfun.com/products/16426 + * + * This code is beerware; if you see me (or any other SparkFun employee) at the + * local, and you've found our code helpful, please buy us a round! + * + * Hardware Connections: + * Attach Red Board to computer using micro-B USB cable. + * Attach Qwiic Alphanumeric board to Red Board using Qwiic cable. + * Don't close any of the address jumpers so that it defaults to address 0x70. + * + * Distributed as-is; no warranty is given. + *****************************************************************************************/ +#include +HT16K33 display; + +void setup() { + Serial.begin(115200); + Serial.println("Qwiic Alphanumeric examples"); + Wire.begin(); //Join I2C bus + + //check if displays will acknowledge + if (display.begin() == false) + { + Serial.println("Device did not acknowledge! Freezing."); + while(1); + } + Serial.println("Displays acknowledged."); + + //Just for demo purposes, show original characters before change + display.print("cafe"); + delay(500); + display.print("size"); + + + //Update a, e, f, s and z to new characters + //This change is not permanent, and lasts only for this program. + + //define 14 segment bits: nmlkjihgfedcba + display.defineChar('a', 0b01000001011000); + display.defineChar('e', 0b10000001011000); + display.defineChar('f', 0b01010101000000); + display.defineChar('s', 0b00100100001000); + display.defineChar('z', 0b10000001001000); +} + +void loop() +{ + //Show the new characters + delay(500); + display.print("cafe"); + delay(500); + display.print("size"); +} diff --git a/examples/Example7_unkownChar/Example7_unkownChar.ino b/examples/Example7_unkownChar/Example7_unkownChar.ino index 77918ed..50af555 100644 --- a/examples/Example7_unkownChar/Example7_unkownChar.ino +++ b/examples/Example7_unkownChar/Example7_unkownChar.ino @@ -3,9 +3,10 @@ * * Priyanka Makin @ SparkFun Electronics * Original Creation Date: March 13, 2020 + * Updated April 30, 2020 by Gaston Williams - changed exclamation to tab character * * SparkFun labored with love to create this code. Feel like supporting open source hardware? - * Buy a board from SparkFun! https://www.sparkfun.com/products/16391 + * Buy a board from SparkFun! LINK GOES HERE * * This code is Lemonadeware; if you see me (or any other SparkFun employee) at the * local, and you've found our code helpful, please buy us a round! @@ -18,7 +19,7 @@ ****************************************************************************************/ #include -#include //Click here to get the library: http://librarymanager/All#Alphanumeric_Display by SparkFun +#include //Click here to get the library: HT16K33 display; void setup() { @@ -34,7 +35,7 @@ void setup() { } Serial.println("Display acknowledged."); - display.print("!!!!"); + display.print("\t\t\t\t"); //tabs are not printable characters } void loop() diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index ea319a4..3013001 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -5,6 +5,8 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: February 25, 2020 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library +Updated April 30, 2020 by Gaston Williams to add defineChar function + Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 This file implements all functions of the HT16K33 class. Functions here range @@ -12,8 +14,8 @@ from printing to one or more Alphanumeric Displays, changing the display setting reading the RAM of the HT16K33. The Holtek HT16K33 seems to be susceptible to address changes intra-sketch. The ADR pins -are muxed with the ROW and COM drivers so as semgents are turned on/off that affect -the ADR1/ADR0 pins the address has been seen to change. The best way around this is +are muxed with the ROW and COM drivers so as semgents are turned on/off that affect +the ADR1/ADR0 pins the address has been seen to change. The best way around this is to do a isConnected check before updateRAM() is sent to the driver IC. Development environment specifics: @@ -318,37 +320,6 @@ bool HT16K33::setDisplayOnOff(uint8_t displayNumber, bool turnOnDisplay) return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } -//Turn on/off the entire display -bool HT16K33::displayOn() -{ - bool status = true; - - displayOnOff = ALPHA_DISPLAY_ON; - - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (displayOnSingle(i) == false) - status = false; - } - - return status; -} - -bool HT16K33::displayOff() -{ - bool status = true; - - displayOnOff = ALPHA_DISPLAY_OFF; - - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (displayOffSingle(i) == false) - status = false; - } - - return status; -} - bool HT16K33::decimalOnSingle(uint8_t displayNumber) { return setDecimalOnOff(displayNumber, true); @@ -362,52 +333,14 @@ bool HT16K33::decimalOffSingle(uint8_t displayNumber) bool HT16K33::setDecimalOnOff(uint8_t displayNumber, bool turnOnDecimal) { uint8_t adr = 0x03; - uint8_t dat; + uint8_t dat = 0x01; if (turnOnDecimal == true) - { decimalOnOff = ALPHA_DECIMAL_ON; - dat = 0x01; - } else - { decimalOnOff = ALPHA_DECIMAL_OFF; - dat = 0x00; - } - - displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; - updateDisplay(); -} - -//Turn on/off the entire display -bool HT16K33::decimalOn() -{ - bool status = true; - - decimalOnOff = ALPHA_DECIMAL_ON; - - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (decimalOnSingle(i) == false) - status = false; - } - - Serial.println(status); - return status; -} - -bool HT16K33::decimalOff() -{ - bool status = true; - - decimalOnOff = ALPHA_DECIMAL_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (decimalOffSingle(i) == false) - status = false; - } - return status; + displayRAM[adr] = displayRAM[adr] | dat; } bool HT16K33::colonOnSingle(uint8_t displayNumber) @@ -423,48 +356,44 @@ bool HT16K33::colonOffSingle(uint8_t displayNumber) bool HT16K33::setColonOnOff(uint8_t displayNumber, bool turnOnColon) { uint8_t adr = 0x01; - uint8_t dat; + uint8_t dat = 0x01; - if (turnOnColon == true) - { + if (turnOnColon = true) colonOnOff = ALPHA_COLON_ON; - dat = 0x01; - } else - { colonOnOff = ALPHA_COLON_OFF; - dat = 0x00; - } - displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; - updateDisplay(); + displayRAM[adr] = displayRAM[adr] | dat; } -bool HT16K33::colonOn() +//Turn on/off the entire display +bool HT16K33::displayOn() { bool status = true; - colonOnOff = ALPHA_COLON_ON; + displayOnOff = ALPHA_DISPLAY_ON; for (uint8_t i = 0; i < numberOfDisplays; i++) { - if (colonOnSingle(i) == false) + if (displayOnSingle(i) == false) status = false; } + return status; } -bool HT16K33::colonOff() +bool HT16K33::displayOff() { bool status = true; - - colonOnOff = ALPHA_COLON_OFF; + + displayOnOff = ALPHA_DISPLAY_OFF; for (uint8_t i = 0; i < numberOfDisplays; i++) { - if (colonOffSingle(i) == false) + if (displayOffSingle(i) == false) status = false; } + return status; } @@ -527,136 +456,131 @@ void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) } } -#define SFE_ALPHANUM_UNKNOWN_CHAR 89 +#define SFE_ALPHANUM_UNKNOWN_CHAR 95 //This is the lookup table of segments for various characters +static uint16_t alphanumeric_segs[96]{ + //nmlkjihgfedcba + 0b00000000000000, //' ' (space) + 0b00001000001000, //'!' - added to map + 0b00001000000010, //'"' - added to map + 0b1001101001110, //'#' + 0b1001101101101, //'$' + 0b10010000100100, //'%' + 0b110011011001, //'&' + 0b1000000000, //''' + 0b111001, //'(' + 0b1111, //')' + 0b11111010000000, //'*' + 0b1001101000000, //'+' + 0b10000000000000, //',' + 0b101000000, //'-' + 0b10, //'.' - DEBUG: need to test + 0b10010000000000, //'/' + 0b111111, //'0' + 0b10000000110, //'1' + 0b101011011, //'2' + 0b101001111, //'3' + 0b101100110, //'4' + 0b101101101, //'5' + 0b101111101, //'6' + 0b1010000000001, //'7' + 0b101111111, //'8' + 0b101100111, //'9' + 0b1, //':' - DEBUG: need to test + 0b10001000000000, //';' + 0b110000000000, //'<' + 0b101001000, //'=' + 0b10000010000000, //'>' + 0b01001000000000, //':' - Added to map + 0b10001000000000, //';' - Added to map + 0b101110111, //'A' + 0b1001100001111, //'B' + 0b111001, //'C' + 0b1001000001111, //'D' + 0b101111001, //'E' + 0b101110001, //'F' + 0b100111101, //'G' + 0b101110110, //'H' + 0b1001000001001, //'I' + 0b11110, //'J' + 0b110001110000, //'K' + 0b111000, //'L' + 0b10010110110, //'M' + 0b100010110110, //'N' + 0b111111, //'O' + 0b101110011, //'P' + 0b100000111111, //'Q' + 0b100101110011, //'R' + 0b110001101, //'S' + 0b1001000000001, //'T' + 0b111110, //'U' + 0b10010000110000, //'V' + 0b10100000110110, //'W' + 0b10110010000000, //'X' + 0b1010010000000, //'Y' + 0b10010000001001, //'Z' + 0b111001, //'[' + 0b100010000000, //'\' + 0b1111, //']' + 0b10100000000000, //'^' - Added to map + 0b1000, //'_' + 0b10000000, //'`' + 0b101011111, //'a' + 0b100001111000, //'b' + 0b101011000, //'c' + 0b10000100001110, //'d' + 0b1111001, //'e' + 0b1110001, //'f' + 0b110001111, //'g' + 0b101110100, //'h' + 0b1000000000000, //'i' + 0b1110, //'j' + 0b1111000000000, //'k' + 0b1001000000000, //'l' + 0b1000101010100, //'m' + 0b100001010000, //'n' + 0b101011100, //'o' + 0b10001110001, //'p' + 0b100101100011, //'q' + 0b1010000, //'r' + 0b110001101, //'s' + 0b1111000, //'t' + 0b11100, //'u' + 0b10000000010000, //'v' + 0b10100000010100, //'w' + 0b10110010000000, //'x' + 0b1100001110, //'y' + 0b10010000001001, //'z' + 0b10000011001001, //'{' + 0b1001000000000, //'|' + 0b110100001001, //'}' + 0b00000101010010, //'~' - Added to map + 0b11111111111111, //Unknown character (DEL or RUBOUT) +}; + +//Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { - - static uint16_t alphanumeric_segs[90]{ - 0b00000000000000, //' ' (space) - - 0b1001101001110, //'#' - 0b1001101101101, //'$' - 0b10010000100100, //'%' - 0b110011011001, //'&' - 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' - 0b11111010000000, //'*' - 0b1001101000000, //'+' - 0b10000000000000, //',' - 0b101000000, //'-' - 0b10, //'.' - DEBUG: need to test - 0b10010000000000, //'/' - 0b111111, //'0' - 0b10000000110, //'1' - 0b101011011, //'2' - 0b101001111, //'3' - 0b101100110, //'4' - 0b101101101, //'5' - 0b101111101, //'6' - 0b1010000000001, //'7' - 0b101111111, //'8' - 0b101100111, //'9' - 0b1, //':' - DEBUG: need to test - 0b10001000000000, //';' - 0b110000000000, //'<' - 0b101001000, //'=' - 0b10000010000000, //'>' - - 0b101110111, //'A' - 0b1001100001111, //'B' - 0b111001, //'C' - 0b1001000001111, //'D' - 0b101111001, //'E' - 0b101110001, //'F' - 0b100111101, //'G' - 0b101110110, //'H' - 0b1001000001001, //'I' - 0b11110, //'J' - 0b110001110000, //'K' - 0b111000, //'L' - 0b10010110110, //'M' - 0b100010110110, //'N' - 0b111111, //'O' - 0b101110011, //'P' - 0b100000111111, //'Q' - 0b100101110011, //'R' - 0b110001101, //'S' - 0b1001000000001, //'T' - 0b111110, //'U' - 0b10010000110000, //'V' - 0b10100000110110, //'W' - 0b10110010000000, //'X' - 0b1010010000000, //'Y' - 0b10010000001001, //'Z' - 0b111001, //'[' - 0b100010000000, //'\' - 0b1111, //']' - - 0b1000, //'_' - 0b10000000, //'`' - 0b101011111, //'a' - 0b100001111000, //'b' - 0b101011000, //'c' - 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' - 0b110001111, //'g' - 0b101110100, //'h' - 0b1000000000000, //'i' - 0b1110, //'j' - 0b1111000000000, //'k' - 0b1001000000000, //'l' - 0b1000101010100, //'m' - 0b100001010000, //'n' - 0b101011100, //'o' - 0b10001110001, //'p' - 0b100101100011, //'q' - 0b1010000, //'r' - 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' - 0b10000000010000, //'v' - 0b10100000010100, //'w' - 0b10110010000000, //'x' - 0b1100001110, //'y' - 0b10010000001001, //'z' - 0b10000011001001, //'{' - 0b1001000000000, //'|' - 0b110100001001, //'}' - - 0b11111111111111, //Unknown character - }; + //moved alphanumeric_segs array outside of function uint16_t characterPosition = 65532; //space if (displayChar == ' ') characterPosition = 0; - //Symbols - else if (displayChar >= '#' && displayChar <= '>') - { - characterPosition = displayChar - '#' + 1; - } - //Upper case letters + symbols - else if (displayChar >= 'A' && displayChar <= ']') + //Printable Symbols + else if (displayChar >= '!' && displayChar <= '~') { - characterPosition = displayChar - 'A' + 1 + 28; - } - //Symbols + lower case letters - else - { - characterPosition = displayChar - '_' + 1 + 28 + 29; + characterPosition = displayChar - '!' + 1; } - uint8_t dispNum = digitPosition / 4; + //Take care of special characters - if (characterPosition == 12) //'.' - decimalOnSingle(dispNum); - if (characterPosition == 24) //':' - colonOnSingle(dispNum); + if (characterPosition == 14) //'.' + decimalOnSingle(0); + if (characterPosition == 26) //':' + colonOnSingle(0); if (characterPosition == 65532) //unknown character characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; @@ -667,8 +591,29 @@ void HT16K33::printChar(uint8_t displayChar, uint8_t digit) illuminateChar(alphanumeric_segs[characterPosition], digit); } + +//Update the lookup table of segments for a particular character +bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) +{ + bool result = false; + + //Check to see if character is within range of displayable ASCII characters + if (displayChar >= '!' && displayChar <= '~') + { + //Get the index of character in map and update its 14-bit segment value + uint16_t characterPosition = displayChar - '!' + 1; + + //Mask the input segment value to 14 bits only + alphanumeric_segs[characterPosition] = (segmentsToTurnOn & 0x3FFF); + + //We're all good + result = true; + } + return result; +} + /* - * Write a byte to the display. + * Write a byte to the display.1 * Required for Print. */ size_t HT16K33::write(uint8_t b) diff --git a/src/SparkFun_Alphanumeric_Display.h b/src/SparkFun_Alphanumeric_Display.h index 117f6c6..044446d 100644 --- a/src/SparkFun_Alphanumeric_Display.h +++ b/src/SparkFun_Alphanumeric_Display.h @@ -5,6 +5,8 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: July 25, 2019 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library +Updated April 30, 2020 by Gaston Williams to add defineChar function + Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 This file prototypes the HT16K33 class, implemented in SparkFun_Alphanumeric_Display.cpp. @@ -26,7 +28,7 @@ Distributed as-is; no warranty is given. #include #define DEFAULT_ADDRESS 0x70 //Default I2C address when A0, A1 are floating -// #define DEV_ID 0x12 //Device ID that I just made up +#define DEV_ID 0x12 //Device ID that I just made up #define DEFAULT_NOTHING_ATTACHED 0xFF typedef enum @@ -91,7 +93,7 @@ class HT16K33 : public Print TwoWire &wirePort = Wire); // Sets the address of the device and opens the Wire port for communication bool isConnected(uint8_t displayNumber); bool initialize(); - // bool checkDeviceID(uint8_t displayNumber); + bool checkDeviceID(uint8_t displayNumber); uint8_t lookUpDisplayAddress(uint8_t displayNumber); //Display configuration functions @@ -118,16 +120,13 @@ class HT16K33 : public Print void illuminateChar(uint16_t disp, uint8_t digit); void printChar(uint8_t displayChar, uint8_t digit); bool updateDisplay(); + //Define Character Segment Map + bool defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn); //Colon and decimal - bool decimalOn(); - bool decimalOff(); bool decimalOnSingle(uint8_t displayNumber); bool decimalOffSingle(uint8_t displayNumber); bool setDecimalOnOff(uint8_t displayNumber, bool turnOnDecimal); - - bool colonOn(); - bool colonOff(); bool colonOnSingle(uint8_t displayNumber); bool colonOffSingle(uint8_t displayNumber); bool setColonOnOff(uint8_t displayNumber, bool turnOnColon); From fc53fd423843b3368d27d453663640f640bf0b7c Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 1 May 2020 13:40:21 -0400 Subject: [PATCH 02/12] Revert changes back to original code and redo updates --- .../Example10_DefineChar.ino | 64 ---- .../Example7_unkownChar.ino | 7 +- src/SparkFun_Alphanumeric_Display.cpp | 359 ++++++++++-------- src/SparkFun_Alphanumeric_Display.h | 13 +- 4 files changed, 217 insertions(+), 226 deletions(-) delete mode 100644 examples/Example10_DefineChar/Example10_DefineChar.ino diff --git a/examples/Example10_DefineChar/Example10_DefineChar.ino b/examples/Example10_DefineChar/Example10_DefineChar.ino deleted file mode 100644 index c601dfa..0000000 --- a/examples/Example10_DefineChar/Example10_DefineChar.ino +++ /dev/null @@ -1,64 +0,0 @@ -/************************************************************************************** - * This example redefines some characters of an alphanumeric display. - * - * Written by Gaston Williams - * April 30, 2020 - * - * Based on code written by - * Priyanka Makin @ SparkFun Electronics - * Original Creation Date: February 26, 2020 - * - * SparkFun labored with love to create this code. Feel like supporting open source hardware? - * Buy a board from SparkFun! https://www.sparkfun.com/products/16426 - * - * This code is beerware; if you see me (or any other SparkFun employee) at the - * local, and you've found our code helpful, please buy us a round! - * - * Hardware Connections: - * Attach Red Board to computer using micro-B USB cable. - * Attach Qwiic Alphanumeric board to Red Board using Qwiic cable. - * Don't close any of the address jumpers so that it defaults to address 0x70. - * - * Distributed as-is; no warranty is given. - *****************************************************************************************/ -#include -HT16K33 display; - -void setup() { - Serial.begin(115200); - Serial.println("Qwiic Alphanumeric examples"); - Wire.begin(); //Join I2C bus - - //check if displays will acknowledge - if (display.begin() == false) - { - Serial.println("Device did not acknowledge! Freezing."); - while(1); - } - Serial.println("Displays acknowledged."); - - //Just for demo purposes, show original characters before change - display.print("cafe"); - delay(500); - display.print("size"); - - - //Update a, e, f, s and z to new characters - //This change is not permanent, and lasts only for this program. - - //define 14 segment bits: nmlkjihgfedcba - display.defineChar('a', 0b01000001011000); - display.defineChar('e', 0b10000001011000); - display.defineChar('f', 0b01010101000000); - display.defineChar('s', 0b00100100001000); - display.defineChar('z', 0b10000001001000); -} - -void loop() -{ - //Show the new characters - delay(500); - display.print("cafe"); - delay(500); - display.print("size"); -} diff --git a/examples/Example7_unkownChar/Example7_unkownChar.ino b/examples/Example7_unkownChar/Example7_unkownChar.ino index 50af555..77918ed 100644 --- a/examples/Example7_unkownChar/Example7_unkownChar.ino +++ b/examples/Example7_unkownChar/Example7_unkownChar.ino @@ -3,10 +3,9 @@ * * Priyanka Makin @ SparkFun Electronics * Original Creation Date: March 13, 2020 - * Updated April 30, 2020 by Gaston Williams - changed exclamation to tab character * * SparkFun labored with love to create this code. Feel like supporting open source hardware? - * Buy a board from SparkFun! LINK GOES HERE + * Buy a board from SparkFun! https://www.sparkfun.com/products/16391 * * This code is Lemonadeware; if you see me (or any other SparkFun employee) at the * local, and you've found our code helpful, please buy us a round! @@ -19,7 +18,7 @@ ****************************************************************************************/ #include -#include //Click here to get the library: +#include //Click here to get the library: http://librarymanager/All#Alphanumeric_Display by SparkFun HT16K33 display; void setup() { @@ -35,7 +34,7 @@ void setup() { } Serial.println("Display acknowledged."); - display.print("\t\t\t\t"); //tabs are not printable characters + display.print("!!!!"); } void loop() diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index 3013001..ea319a4 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -5,8 +5,6 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: February 25, 2020 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library -Updated April 30, 2020 by Gaston Williams to add defineChar function - Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 This file implements all functions of the HT16K33 class. Functions here range @@ -14,8 +12,8 @@ from printing to one or more Alphanumeric Displays, changing the display setting reading the RAM of the HT16K33. The Holtek HT16K33 seems to be susceptible to address changes intra-sketch. The ADR pins -are muxed with the ROW and COM drivers so as semgents are turned on/off that affect -the ADR1/ADR0 pins the address has been seen to change. The best way around this is +are muxed with the ROW and COM drivers so as semgents are turned on/off that affect +the ADR1/ADR0 pins the address has been seen to change. The best way around this is to do a isConnected check before updateRAM() is sent to the driver IC. Development environment specifics: @@ -320,6 +318,37 @@ bool HT16K33::setDisplayOnOff(uint8_t displayNumber, bool turnOnDisplay) return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } +//Turn on/off the entire display +bool HT16K33::displayOn() +{ + bool status = true; + + displayOnOff = ALPHA_DISPLAY_ON; + + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (displayOnSingle(i) == false) + status = false; + } + + return status; +} + +bool HT16K33::displayOff() +{ + bool status = true; + + displayOnOff = ALPHA_DISPLAY_OFF; + + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (displayOffSingle(i) == false) + status = false; + } + + return status; +} + bool HT16K33::decimalOnSingle(uint8_t displayNumber) { return setDecimalOnOff(displayNumber, true); @@ -333,14 +362,52 @@ bool HT16K33::decimalOffSingle(uint8_t displayNumber) bool HT16K33::setDecimalOnOff(uint8_t displayNumber, bool turnOnDecimal) { uint8_t adr = 0x03; - uint8_t dat = 0x01; + uint8_t dat; if (turnOnDecimal == true) + { decimalOnOff = ALPHA_DECIMAL_ON; + dat = 0x01; + } else + { decimalOnOff = ALPHA_DECIMAL_OFF; + dat = 0x00; + } - displayRAM[adr] = displayRAM[adr] | dat; + displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; + updateDisplay(); +} + +//Turn on/off the entire display +bool HT16K33::decimalOn() +{ + bool status = true; + + decimalOnOff = ALPHA_DECIMAL_ON; + + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (decimalOnSingle(i) == false) + status = false; + } + + Serial.println(status); + return status; +} + +bool HT16K33::decimalOff() +{ + bool status = true; + + decimalOnOff = ALPHA_DECIMAL_OFF; + + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (decimalOffSingle(i) == false) + status = false; + } + return status; } bool HT16K33::colonOnSingle(uint8_t displayNumber) @@ -356,44 +423,48 @@ bool HT16K33::colonOffSingle(uint8_t displayNumber) bool HT16K33::setColonOnOff(uint8_t displayNumber, bool turnOnColon) { uint8_t adr = 0x01; - uint8_t dat = 0x01; + uint8_t dat; - if (turnOnColon = true) + if (turnOnColon == true) + { colonOnOff = ALPHA_COLON_ON; + dat = 0x01; + } else + { colonOnOff = ALPHA_COLON_OFF; + dat = 0x00; + } - displayRAM[adr] = displayRAM[adr] | dat; + displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; + updateDisplay(); } -//Turn on/off the entire display -bool HT16K33::displayOn() +bool HT16K33::colonOn() { bool status = true; - displayOnOff = ALPHA_DISPLAY_ON; + colonOnOff = ALPHA_COLON_ON; for (uint8_t i = 0; i < numberOfDisplays; i++) { - if (displayOnSingle(i) == false) + if (colonOnSingle(i) == false) status = false; } - return status; } -bool HT16K33::displayOff() +bool HT16K33::colonOff() { bool status = true; - - displayOnOff = ALPHA_DISPLAY_OFF; + + colonOnOff = ALPHA_COLON_OFF; for (uint8_t i = 0; i < numberOfDisplays; i++) { - if (displayOffSingle(i) == false) + if (colonOffSingle(i) == false) status = false; } - return status; } @@ -456,131 +527,136 @@ void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) } } -#define SFE_ALPHANUM_UNKNOWN_CHAR 95 +#define SFE_ALPHANUM_UNKNOWN_CHAR 89 //This is the lookup table of segments for various characters -static uint16_t alphanumeric_segs[96]{ - //nmlkjihgfedcba - 0b00000000000000, //' ' (space) - 0b00001000001000, //'!' - added to map - 0b00001000000010, //'"' - added to map - 0b1001101001110, //'#' - 0b1001101101101, //'$' - 0b10010000100100, //'%' - 0b110011011001, //'&' - 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' - 0b11111010000000, //'*' - 0b1001101000000, //'+' - 0b10000000000000, //',' - 0b101000000, //'-' - 0b10, //'.' - DEBUG: need to test - 0b10010000000000, //'/' - 0b111111, //'0' - 0b10000000110, //'1' - 0b101011011, //'2' - 0b101001111, //'3' - 0b101100110, //'4' - 0b101101101, //'5' - 0b101111101, //'6' - 0b1010000000001, //'7' - 0b101111111, //'8' - 0b101100111, //'9' - 0b1, //':' - DEBUG: need to test - 0b10001000000000, //';' - 0b110000000000, //'<' - 0b101001000, //'=' - 0b10000010000000, //'>' - 0b01001000000000, //':' - Added to map - 0b10001000000000, //';' - Added to map - 0b101110111, //'A' - 0b1001100001111, //'B' - 0b111001, //'C' - 0b1001000001111, //'D' - 0b101111001, //'E' - 0b101110001, //'F' - 0b100111101, //'G' - 0b101110110, //'H' - 0b1001000001001, //'I' - 0b11110, //'J' - 0b110001110000, //'K' - 0b111000, //'L' - 0b10010110110, //'M' - 0b100010110110, //'N' - 0b111111, //'O' - 0b101110011, //'P' - 0b100000111111, //'Q' - 0b100101110011, //'R' - 0b110001101, //'S' - 0b1001000000001, //'T' - 0b111110, //'U' - 0b10010000110000, //'V' - 0b10100000110110, //'W' - 0b10110010000000, //'X' - 0b1010010000000, //'Y' - 0b10010000001001, //'Z' - 0b111001, //'[' - 0b100010000000, //'\' - 0b1111, //']' - 0b10100000000000, //'^' - Added to map - 0b1000, //'_' - 0b10000000, //'`' - 0b101011111, //'a' - 0b100001111000, //'b' - 0b101011000, //'c' - 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' - 0b110001111, //'g' - 0b101110100, //'h' - 0b1000000000000, //'i' - 0b1110, //'j' - 0b1111000000000, //'k' - 0b1001000000000, //'l' - 0b1000101010100, //'m' - 0b100001010000, //'n' - 0b101011100, //'o' - 0b10001110001, //'p' - 0b100101100011, //'q' - 0b1010000, //'r' - 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' - 0b10000000010000, //'v' - 0b10100000010100, //'w' - 0b10110010000000, //'x' - 0b1100001110, //'y' - 0b10010000001001, //'z' - 0b10000011001001, //'{' - 0b1001000000000, //'|' - 0b110100001001, //'}' - 0b00000101010010, //'~' - Added to map - 0b11111111111111, //Unknown character (DEL or RUBOUT) -}; - -//Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { - //moved alphanumeric_segs array outside of function + + static uint16_t alphanumeric_segs[90]{ + 0b00000000000000, //' ' (space) + + 0b1001101001110, //'#' + 0b1001101101101, //'$' + 0b10010000100100, //'%' + 0b110011011001, //'&' + 0b1000000000, //''' + 0b111001, //'(' + 0b1111, //')' + 0b11111010000000, //'*' + 0b1001101000000, //'+' + 0b10000000000000, //',' + 0b101000000, //'-' + 0b10, //'.' - DEBUG: need to test + 0b10010000000000, //'/' + 0b111111, //'0' + 0b10000000110, //'1' + 0b101011011, //'2' + 0b101001111, //'3' + 0b101100110, //'4' + 0b101101101, //'5' + 0b101111101, //'6' + 0b1010000000001, //'7' + 0b101111111, //'8' + 0b101100111, //'9' + 0b1, //':' - DEBUG: need to test + 0b10001000000000, //';' + 0b110000000000, //'<' + 0b101001000, //'=' + 0b10000010000000, //'>' + + 0b101110111, //'A' + 0b1001100001111, //'B' + 0b111001, //'C' + 0b1001000001111, //'D' + 0b101111001, //'E' + 0b101110001, //'F' + 0b100111101, //'G' + 0b101110110, //'H' + 0b1001000001001, //'I' + 0b11110, //'J' + 0b110001110000, //'K' + 0b111000, //'L' + 0b10010110110, //'M' + 0b100010110110, //'N' + 0b111111, //'O' + 0b101110011, //'P' + 0b100000111111, //'Q' + 0b100101110011, //'R' + 0b110001101, //'S' + 0b1001000000001, //'T' + 0b111110, //'U' + 0b10010000110000, //'V' + 0b10100000110110, //'W' + 0b10110010000000, //'X' + 0b1010010000000, //'Y' + 0b10010000001001, //'Z' + 0b111001, //'[' + 0b100010000000, //'\' + 0b1111, //']' + + 0b1000, //'_' + 0b10000000, //'`' + 0b101011111, //'a' + 0b100001111000, //'b' + 0b101011000, //'c' + 0b10000100001110, //'d' + 0b1111001, //'e' + 0b1110001, //'f' + 0b110001111, //'g' + 0b101110100, //'h' + 0b1000000000000, //'i' + 0b1110, //'j' + 0b1111000000000, //'k' + 0b1001000000000, //'l' + 0b1000101010100, //'m' + 0b100001010000, //'n' + 0b101011100, //'o' + 0b10001110001, //'p' + 0b100101100011, //'q' + 0b1010000, //'r' + 0b110001101, //'s' + 0b1111000, //'t' + 0b11100, //'u' + 0b10000000010000, //'v' + 0b10100000010100, //'w' + 0b10110010000000, //'x' + 0b1100001110, //'y' + 0b10010000001001, //'z' + 0b10000011001001, //'{' + 0b1001000000000, //'|' + 0b110100001001, //'}' + + 0b11111111111111, //Unknown character + }; uint16_t characterPosition = 65532; //space if (displayChar == ' ') characterPosition = 0; - //Printable Symbols - else if (displayChar >= '!' && displayChar <= '~') + //Symbols + else if (displayChar >= '#' && displayChar <= '>') { - characterPosition = displayChar - '!' + 1; + characterPosition = displayChar - '#' + 1; + } + //Upper case letters + symbols + else if (displayChar >= 'A' && displayChar <= ']') + { + characterPosition = displayChar - 'A' + 1 + 28; + } + //Symbols + lower case letters + else + { + characterPosition = displayChar - '_' + 1 + 28 + 29; } - + uint8_t dispNum = digitPosition / 4; //Take care of special characters - if (characterPosition == 14) //'.' - decimalOnSingle(0); - if (characterPosition == 26) //':' - colonOnSingle(0); + if (characterPosition == 12) //'.' + decimalOnSingle(dispNum); + if (characterPosition == 24) //':' + colonOnSingle(dispNum); if (characterPosition == 65532) //unknown character characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; @@ -591,29 +667,8 @@ void HT16K33::printChar(uint8_t displayChar, uint8_t digit) illuminateChar(alphanumeric_segs[characterPosition], digit); } - -//Update the lookup table of segments for a particular character -bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) -{ - bool result = false; - - //Check to see if character is within range of displayable ASCII characters - if (displayChar >= '!' && displayChar <= '~') - { - //Get the index of character in map and update its 14-bit segment value - uint16_t characterPosition = displayChar - '!' + 1; - - //Mask the input segment value to 14 bits only - alphanumeric_segs[characterPosition] = (segmentsToTurnOn & 0x3FFF); - - //We're all good - result = true; - } - return result; -} - /* - * Write a byte to the display.1 + * Write a byte to the display. * Required for Print. */ size_t HT16K33::write(uint8_t b) diff --git a/src/SparkFun_Alphanumeric_Display.h b/src/SparkFun_Alphanumeric_Display.h index 044446d..117f6c6 100644 --- a/src/SparkFun_Alphanumeric_Display.h +++ b/src/SparkFun_Alphanumeric_Display.h @@ -5,8 +5,6 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: July 25, 2019 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library -Updated April 30, 2020 by Gaston Williams to add defineChar function - Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 This file prototypes the HT16K33 class, implemented in SparkFun_Alphanumeric_Display.cpp. @@ -28,7 +26,7 @@ Distributed as-is; no warranty is given. #include #define DEFAULT_ADDRESS 0x70 //Default I2C address when A0, A1 are floating -#define DEV_ID 0x12 //Device ID that I just made up +// #define DEV_ID 0x12 //Device ID that I just made up #define DEFAULT_NOTHING_ATTACHED 0xFF typedef enum @@ -93,7 +91,7 @@ class HT16K33 : public Print TwoWire &wirePort = Wire); // Sets the address of the device and opens the Wire port for communication bool isConnected(uint8_t displayNumber); bool initialize(); - bool checkDeviceID(uint8_t displayNumber); + // bool checkDeviceID(uint8_t displayNumber); uint8_t lookUpDisplayAddress(uint8_t displayNumber); //Display configuration functions @@ -120,13 +118,16 @@ class HT16K33 : public Print void illuminateChar(uint16_t disp, uint8_t digit); void printChar(uint8_t displayChar, uint8_t digit); bool updateDisplay(); - //Define Character Segment Map - bool defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn); //Colon and decimal + bool decimalOn(); + bool decimalOff(); bool decimalOnSingle(uint8_t displayNumber); bool decimalOffSingle(uint8_t displayNumber); bool setDecimalOnOff(uint8_t displayNumber, bool turnOnDecimal); + + bool colonOn(); + bool colonOff(); bool colonOnSingle(uint8_t displayNumber); bool colonOffSingle(uint8_t displayNumber); bool setColonOnOff(uint8_t displayNumber, bool turnOnColon); From 144872bcf8bf359afff60aef775287c30b5e7cc8 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 1 May 2020 14:13:49 -0400 Subject: [PATCH 03/12] Updated files with change, using a branch --- .../Example10_DefineChar.ino | 64 +++++++++++++++++++ .../Example7_unkownChar.ino | 3 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 examples/Example10_DefineChar/Example10_DefineChar.ino diff --git a/examples/Example10_DefineChar/Example10_DefineChar.ino b/examples/Example10_DefineChar/Example10_DefineChar.ino new file mode 100644 index 0000000..c601dfa --- /dev/null +++ b/examples/Example10_DefineChar/Example10_DefineChar.ino @@ -0,0 +1,64 @@ +/************************************************************************************** + * This example redefines some characters of an alphanumeric display. + * + * Written by Gaston Williams + * April 30, 2020 + * + * Based on code written by + * Priyanka Makin @ SparkFun Electronics + * Original Creation Date: February 26, 2020 + * + * SparkFun labored with love to create this code. Feel like supporting open source hardware? + * Buy a board from SparkFun! https://www.sparkfun.com/products/16426 + * + * This code is beerware; if you see me (or any other SparkFun employee) at the + * local, and you've found our code helpful, please buy us a round! + * + * Hardware Connections: + * Attach Red Board to computer using micro-B USB cable. + * Attach Qwiic Alphanumeric board to Red Board using Qwiic cable. + * Don't close any of the address jumpers so that it defaults to address 0x70. + * + * Distributed as-is; no warranty is given. + *****************************************************************************************/ +#include +HT16K33 display; + +void setup() { + Serial.begin(115200); + Serial.println("Qwiic Alphanumeric examples"); + Wire.begin(); //Join I2C bus + + //check if displays will acknowledge + if (display.begin() == false) + { + Serial.println("Device did not acknowledge! Freezing."); + while(1); + } + Serial.println("Displays acknowledged."); + + //Just for demo purposes, show original characters before change + display.print("cafe"); + delay(500); + display.print("size"); + + + //Update a, e, f, s and z to new characters + //This change is not permanent, and lasts only for this program. + + //define 14 segment bits: nmlkjihgfedcba + display.defineChar('a', 0b01000001011000); + display.defineChar('e', 0b10000001011000); + display.defineChar('f', 0b01010101000000); + display.defineChar('s', 0b00100100001000); + display.defineChar('z', 0b10000001001000); +} + +void loop() +{ + //Show the new characters + delay(500); + display.print("cafe"); + delay(500); + display.print("size"); +} diff --git a/examples/Example7_unkownChar/Example7_unkownChar.ino b/examples/Example7_unkownChar/Example7_unkownChar.ino index 77918ed..0d74022 100644 --- a/examples/Example7_unkownChar/Example7_unkownChar.ino +++ b/examples/Example7_unkownChar/Example7_unkownChar.ino @@ -3,6 +3,7 @@ * * Priyanka Makin @ SparkFun Electronics * Original Creation Date: March 13, 2020 + * Updated April 30, 2020 by Gaston Williams - changed exclamation to tab character * * SparkFun labored with love to create this code. Feel like supporting open source hardware? * Buy a board from SparkFun! https://www.sparkfun.com/products/16391 @@ -34,7 +35,7 @@ void setup() { } Serial.println("Display acknowledged."); - display.print("!!!!"); + display.print("\t\t\t\t"); //tabs are not printable characters } void loop() From 6c93df57be440eb683f90efd8bcd14d861b99782 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 1 May 2020 14:16:10 -0400 Subject: [PATCH 04/12] Updated src files with change, using a branch --- src/SparkFun_Alphanumeric_Display.cpp | 246 ++++++++++++++------------ src/SparkFun_Alphanumeric_Display.h | 5 + 2 files changed, 136 insertions(+), 115 deletions(-) diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index ea319a4..2623e42 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -5,6 +5,8 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: February 25, 2020 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library +Updated April 30, 2020 by Gaston Williams to add defineChar function + Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 This file implements all functions of the HT16K33 class. Functions here range @@ -12,8 +14,8 @@ from printing to one or more Alphanumeric Displays, changing the display setting reading the RAM of the HT16K33. The Holtek HT16K33 seems to be susceptible to address changes intra-sketch. The ADR pins -are muxed with the ROW and COM drivers so as semgents are turned on/off that affect -the ADR1/ADR0 pins the address has been seen to change. The best way around this is +are muxed with the ROW and COM drivers so as semgents are turned on/off that affect +the ADR1/ADR0 pins the address has been seen to change. The best way around this is to do a isConnected check before updateRAM() is sent to the driver IC. Development environment specifics: @@ -457,7 +459,7 @@ bool HT16K33::colonOn() bool HT16K33::colonOff() { bool status = true; - + colonOnOff = ALPHA_COLON_OFF; for (uint8_t i = 0; i < numberOfDisplays; i++) @@ -527,128 +529,122 @@ void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) } } -#define SFE_ALPHANUM_UNKNOWN_CHAR 89 +#define SFE_ALPHANUM_UNKNOWN_CHAR 95 //This is the lookup table of segments for various characters +static uint16_t alphanumeric_segs[96]{ + //nmlkjihgfedcba + 0b00000000000000, //' ' (space) + 0b00001000001000, //'!' - added to map + 0b00001000000010, //'"' - added to map + 0b1001101001110, //'#' + 0b1001101101101, //'$' + 0b10010000100100, //'%' + 0b110011011001, //'&' + 0b1000000000, //''' + 0b111001, //'(' + 0b1111, //')' + 0b11111010000000, //'*' + 0b1001101000000, //'+' + 0b10000000000000, //',' + 0b101000000, //'-' + 0b10, //'.' - DEBUG: need to test + 0b10010000000000, //'/' + 0b111111, //'0' + 0b10000000110, //'1' + 0b101011011, //'2' + 0b101001111, //'3' + 0b101100110, //'4' + 0b101101101, //'5' + 0b101111101, //'6' + 0b1010000000001, //'7' + 0b101111111, //'8' + 0b101100111, //'9' + 0b1, //':' - DEBUG: need to test + 0b10001000000000, //';' + 0b110000000000, //'<' + 0b101001000, //'=' + 0b10000010000000, //'>' + 0b01001000000000, //':' - Added to map + 0b10001000000000, //';' - Added to map + 0b101110111, //'A' + 0b1001100001111, //'B' + 0b111001, //'C' + 0b1001000001111, //'D' + 0b101111001, //'E' + 0b101110001, //'F' + 0b100111101, //'G' + 0b101110110, //'H' + 0b1001000001001, //'I' + 0b11110, //'J' + 0b110001110000, //'K' + 0b111000, //'L' + 0b10010110110, //'M' + 0b100010110110, //'N' + 0b111111, //'O' + 0b101110011, //'P' + 0b100000111111, //'Q' + 0b100101110011, //'R' + 0b110001101, //'S' + 0b1001000000001, //'T' + 0b111110, //'U' + 0b10010000110000, //'V' + 0b10100000110110, //'W' + 0b10110010000000, //'X' + 0b1010010000000, //'Y' + 0b10010000001001, //'Z' + 0b111001, //'[' + 0b100010000000, //'\' + 0b1111, //']' + 0b10100000000000, //'^' - Added to map + 0b1000, //'_' + 0b10000000, //'`' + 0b101011111, //'a' + 0b100001111000, //'b' + 0b101011000, //'c' + 0b10000100001110, //'d' + 0b1111001, //'e' + 0b1110001, //'f' + 0b110001111, //'g' + 0b101110100, //'h' + 0b1000000000000, //'i' + 0b1110, //'j' + 0b1111000000000, //'k' + 0b1001000000000, //'l' + 0b1000101010100, //'m' + 0b100001010000, //'n' + 0b101011100, //'o' + 0b10001110001, //'p' + 0b100101100011, //'q' + 0b1010000, //'r' + 0b110001101, //'s' + 0b1111000, //'t' + 0b11100, //'u' + 0b10000000010000, //'v' + 0b10100000010100, //'w' + 0b10110010000000, //'x' + 0b1100001110, //'y' + 0b10010000001001, //'z' + 0b10000011001001, //'{' + 0b1001000000000, //'|' + 0b110100001001, //'}' + 0b00000101010010, //'~' - Added to map + 0b11111111111111, //Unknown character (DEL or RUBOUT) +}; + +//Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { - - static uint16_t alphanumeric_segs[90]{ - 0b00000000000000, //' ' (space) - - 0b1001101001110, //'#' - 0b1001101101101, //'$' - 0b10010000100100, //'%' - 0b110011011001, //'&' - 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' - 0b11111010000000, //'*' - 0b1001101000000, //'+' - 0b10000000000000, //',' - 0b101000000, //'-' - 0b10, //'.' - DEBUG: need to test - 0b10010000000000, //'/' - 0b111111, //'0' - 0b10000000110, //'1' - 0b101011011, //'2' - 0b101001111, //'3' - 0b101100110, //'4' - 0b101101101, //'5' - 0b101111101, //'6' - 0b1010000000001, //'7' - 0b101111111, //'8' - 0b101100111, //'9' - 0b1, //':' - DEBUG: need to test - 0b10001000000000, //';' - 0b110000000000, //'<' - 0b101001000, //'=' - 0b10000010000000, //'>' - - 0b101110111, //'A' - 0b1001100001111, //'B' - 0b111001, //'C' - 0b1001000001111, //'D' - 0b101111001, //'E' - 0b101110001, //'F' - 0b100111101, //'G' - 0b101110110, //'H' - 0b1001000001001, //'I' - 0b11110, //'J' - 0b110001110000, //'K' - 0b111000, //'L' - 0b10010110110, //'M' - 0b100010110110, //'N' - 0b111111, //'O' - 0b101110011, //'P' - 0b100000111111, //'Q' - 0b100101110011, //'R' - 0b110001101, //'S' - 0b1001000000001, //'T' - 0b111110, //'U' - 0b10010000110000, //'V' - 0b10100000110110, //'W' - 0b10110010000000, //'X' - 0b1010010000000, //'Y' - 0b10010000001001, //'Z' - 0b111001, //'[' - 0b100010000000, //'\' - 0b1111, //']' - - 0b1000, //'_' - 0b10000000, //'`' - 0b101011111, //'a' - 0b100001111000, //'b' - 0b101011000, //'c' - 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' - 0b110001111, //'g' - 0b101110100, //'h' - 0b1000000000000, //'i' - 0b1110, //'j' - 0b1111000000000, //'k' - 0b1001000000000, //'l' - 0b1000101010100, //'m' - 0b100001010000, //'n' - 0b101011100, //'o' - 0b10001110001, //'p' - 0b100101100011, //'q' - 0b1010000, //'r' - 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' - 0b10000000010000, //'v' - 0b10100000010100, //'w' - 0b10110010000000, //'x' - 0b1100001110, //'y' - 0b10010000001001, //'z' - 0b10000011001001, //'{' - 0b1001000000000, //'|' - 0b110100001001, //'}' - - 0b11111111111111, //Unknown character - }; - + //moved alphanumeric_segs array outside of function uint16_t characterPosition = 65532; //space if (displayChar == ' ') characterPosition = 0; - //Symbols - else if (displayChar >= '#' && displayChar <= '>') - { - characterPosition = displayChar - '#' + 1; - } - //Upper case letters + symbols - else if (displayChar >= 'A' && displayChar <= ']') - { - characterPosition = displayChar - 'A' + 1 + 28; - } - //Symbols + lower case letters - else + //Printable Symbols + else if (displayChar >= '!' && displayChar <= '~') { - characterPosition = displayChar - '_' + 1 + 28 + 29; + characterPosition = displayChar - '!' + 1; } uint8_t dispNum = digitPosition / 4; @@ -667,6 +663,26 @@ void HT16K33::printChar(uint8_t displayChar, uint8_t digit) illuminateChar(alphanumeric_segs[characterPosition], digit); } +//Update the lookup table of segments for a particular character +bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) +{ + bool result = false; + + //Check to see if character is within range of displayable ASCII characters + if (displayChar >= '!' && displayChar <= '~') + { + //Get the index of character in map and update its 14-bit segment value + uint16_t characterPosition = displayChar - '!' + 1; + + //Mask the input segment value to 14 bits only + alphanumeric_segs[characterPosition] = (segmentsToTurnOn & 0x3FFF); + + //We're all good + result = true; + } + return result; +} + /* * Write a byte to the display. * Required for Print. diff --git a/src/SparkFun_Alphanumeric_Display.h b/src/SparkFun_Alphanumeric_Display.h index 117f6c6..58cd5ac 100644 --- a/src/SparkFun_Alphanumeric_Display.h +++ b/src/SparkFun_Alphanumeric_Display.h @@ -5,6 +5,8 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: July 25, 2019 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library +Updated April 30, 2020 by Gaston Williams to add defineChar function + Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 This file prototypes the HT16K33 class, implemented in SparkFun_Alphanumeric_Display.cpp. @@ -119,6 +121,9 @@ class HT16K33 : public Print void printChar(uint8_t displayChar, uint8_t digit); bool updateDisplay(); + //Define Character Segment Map + bool defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn); + //Colon and decimal bool decimalOn(); bool decimalOff(); From f370824d5b5518fbc74d65f3a09f0e00ef2c2372 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 1 May 2020 14:40:15 -0400 Subject: [PATCH 05/12] Fixed colon and decimal positions in code --- src/SparkFun_Alphanumeric_Display.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index 2623e42..3993936 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -649,9 +649,9 @@ void HT16K33::printChar(uint8_t displayChar, uint8_t digit) uint8_t dispNum = digitPosition / 4; //Take care of special characters - if (characterPosition == 12) //'.' + if (characterPosition == 14) //'.' decimalOnSingle(dispNum); - if (characterPosition == 24) //':' + if (characterPosition == 26) //':' colonOnSingle(dispNum); if (characterPosition == 65532) //unknown character characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; From cb088ce0b69ec515cf1312c413e02410425ab761 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 1 May 2020 17:57:34 -0400 Subject: [PATCH 06/12] Added constants for Segment binary values, updated example 10 --- .../Example10_DefineChar.ino | 7 ++++--- src/SparkFun_Alphanumeric_Display.h | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/examples/Example10_DefineChar/Example10_DefineChar.ino b/examples/Example10_DefineChar/Example10_DefineChar.ino index c601dfa..692d36f 100644 --- a/examples/Example10_DefineChar/Example10_DefineChar.ino +++ b/examples/Example10_DefineChar/Example10_DefineChar.ino @@ -46,12 +46,13 @@ void setup() { //Update a, e, f, s and z to new characters //This change is not permanent, and lasts only for this program. - //define 14 segment bits: nmlkjihgfedcba + //Define 14 segment bits: nmlkjihgfedcba display.defineChar('a', 0b01000001011000); display.defineChar('e', 0b10000001011000); display.defineChar('f', 0b01010101000000); - display.defineChar('s', 0b00100100001000); - display.defineChar('z', 0b10000001001000); + //Also use constants SEG_A - SEG_N to define characters + display.defineChar('s', SEG_L | SEG_I | SEG_D); // 0b00100100001000 + display.defineChar('z', SEG_N | SEG_G | SEG_D); // 0b10000001001000 } void loop() diff --git a/src/SparkFun_Alphanumeric_Display.h b/src/SparkFun_Alphanumeric_Display.h index 58cd5ac..7986182 100644 --- a/src/SparkFun_Alphanumeric_Display.h +++ b/src/SparkFun_Alphanumeric_Display.h @@ -31,6 +31,23 @@ Distributed as-is; no warranty is given. // #define DEV_ID 0x12 //Device ID that I just made up #define DEFAULT_NOTHING_ATTACHED 0xFF +//Define constants for segment bits +#define SEG_A 0x0001 +#define SEG_B 0x0002 +#define SEG_C 0x0004 +#define SEG_D 0x0008 +#define SEG_E 0x0010 +#define SEG_F 0x0020 +#define SEG_G 0x0040 +#define SEG_H 0x0080 +#define SEG_I 0x0100 +#define SEG_J 0x0200 +#define SEG_K 0x0400 +#define SEG_L 0x0800 +#define SEG_M 0x1000 +#define SEG_N 0x2000 + + typedef enum { ALPHA_BLINK_RATE_NOBLINK = 0b00, From 4dae1d0d8683192d49ae5461ba9a8f53ae9275b8 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 1 May 2020 18:01:31 -0400 Subject: [PATCH 07/12] Pretty print to fix whitespace expansion --- src/SparkFun_Alphanumeric_Display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SparkFun_Alphanumeric_Display.h b/src/SparkFun_Alphanumeric_Display.h index 7986182..201df5b 100644 --- a/src/SparkFun_Alphanumeric_Display.h +++ b/src/SparkFun_Alphanumeric_Display.h @@ -36,7 +36,7 @@ Distributed as-is; no warranty is given. #define SEG_B 0x0002 #define SEG_C 0x0004 #define SEG_D 0x0008 -#define SEG_E 0x0010 +#define SEG_E 0x0010 #define SEG_F 0x0020 #define SEG_G 0x0040 #define SEG_H 0x0080 From 12916e629bed7bf4cc41572c3ec1b528d538b63d Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Sun, 3 May 2020 14:57:27 -0400 Subject: [PATCH 08/12] Moved table to PROGMEM and updated code --- .../Example10_DefineChar.ino | 6 +- src/SparkFun_Alphanumeric_Display.cpp | 288 +++++++++++------- src/SparkFun_Alphanumeric_Display.h | 11 + 3 files changed, 185 insertions(+), 120 deletions(-) diff --git a/examples/Example10_DefineChar/Example10_DefineChar.ino b/examples/Example10_DefineChar/Example10_DefineChar.ino index 692d36f..6c34c5a 100644 --- a/examples/Example10_DefineChar/Example10_DefineChar.ino +++ b/examples/Example10_DefineChar/Example10_DefineChar.ino @@ -29,13 +29,13 @@ void setup() { Serial.println("Qwiic Alphanumeric examples"); Wire.begin(); //Join I2C bus - //check if displays will acknowledge + //check if display will acknowledge if (display.begin() == false) { Serial.println("Device did not acknowledge! Freezing."); while(1); } - Serial.println("Displays acknowledged."); + Serial.println("Display acknowledged."); //Just for demo purposes, show original characters before change display.print("cafe"); @@ -50,7 +50,7 @@ void setup() { display.defineChar('a', 0b01000001011000); display.defineChar('e', 0b10000001011000); display.defineChar('f', 0b01010101000000); - //Also use constants SEG_A - SEG_N to define characters + //Also can use constants SEG_A - SEG_N to define characters display.defineChar('s', SEG_L | SEG_I | SEG_D); // 0b00100100001000 display.defineChar('z', SEG_N | SEG_G | SEG_D); // 0b10000001001000 } diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index 3993936..4878a08 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -5,7 +5,7 @@ Priyanka Makin @ SparkFun Electronics Original Creation Date: February 25, 2020 https://github.com/sparkfun/SparkFun_Alphanumeric_Display_Arduino_Library -Updated April 30, 2020 by Gaston Williams to add defineChar function +Updated May 2, 2020 by Gaston Williams to add defineChar function Pickup a board here: https://sparkle.sparkfun.com/sparkle/storefront_products/16391 @@ -29,8 +29,113 @@ local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. ******************************************************************************/ +#include #include +/*--------------------------- Character Map ----------------------------------*/ +#define SFE_ALPHANUM_UNKNOWN_CHAR 95 + +//This is the lookup table of segments for various characters +static const uint16_t PROGMEM alphanumeric_segs[96]{ + //nmlkjihgfedcba + 0b00000000000000, //' ' (space) + 0b00001000001000, //'!' - added to map + 0b00001000000010, //'"' - added to map + 0b1001101001110, //'#' + 0b1001101101101, //'$' + 0b10010000100100, //'%' + 0b110011011001, //'&' + 0b1000000000, //''' + 0b111001, //'(' + 0b1111, //')' + 0b11111010000000, //'*' + 0b1001101000000, //'+' + 0b10000000000000, //',' + 0b101000000, //'-' + 0b00000000000000, //'.' - changed to blank + 0b10010000000000, //'/' + 0b111111, //'0' + 0b10000000110, //'1' + 0b101011011, //'2' + 0b101001111, //'3' + 0b101100110, //'4' + 0b101101101, //'5' + 0b101111101, //'6' + 0b1010000000001, //'7' + 0b101111111, //'8' + 0b101100111, //'9' + 0b00000000000000, //':' - changed to blank + 0b10001000000000, //';' + 0b110000000000, //'<' + 0b101001000, //'=' + 0b01000010000000, //'>' + 0b01000100000011, //'?' - Added to map + 0b00001100111011, //'@' - Added to map + 0b101110111, //'A' + 0b1001100001111, //'B' + 0b111001, //'C' + 0b1001000001111, //'D' + 0b101111001, //'E' + 0b101110001, //'F' + 0b100111101, //'G' + 0b101110110, //'H' + 0b1001000001001, //'I' + 0b11110, //'J' + 0b110001110000, //'K' + 0b111000, //'L' + 0b10010110110, //'M' + 0b100010110110, //'N' + 0b111111, //'O' + 0b101110011, //'P' + 0b100000111111, //'Q' + 0b100101110011, //'R' + 0b110001101, //'S' + 0b1001000000001, //'T' + 0b111110, //'U' + 0b10010000110000, //'V' + 0b10100000110110, //'W' + 0b10110010000000, //'X' + 0b1010010000000, //'Y' + 0b10010000001001, //'Z' + 0b111001, //'[' + 0b100010000000, //'\' + 0b1111, //']' + 0b10100000000000, //'^' - Added to map + 0b1000, //'_' + 0b10000000, //'`' + 0b101011111, //'a' + 0b100001111000, //'b' + 0b101011000, //'c' + 0b10000100001110, //'d' + 0b1111001, //'e' + 0b1110001, //'f' + 0b110001111, //'g' + 0b101110100, //'h' + 0b1000000000000, //'i' + 0b1110, //'j' + 0b1111000000000, //'k' + 0b1001000000000, //'l' + 0b1000101010100, //'m' + 0b100001010000, //'n' + 0b101011100, //'o' + 0b10001110001, //'p' + 0b100101100011, //'q' + 0b1010000, //'r' + 0b110001101, //'s' + 0b1111000, //'t' + 0b11100, //'u' + 0b10000000010000, //'v' + 0b10100000010100, //'w' + 0b10110010000000, //'x' + 0b1100001110, //'y' + 0b10010000001001, //'z' + 0b10000011001001, //'{' + 0b1001000000000, //'|' + 0b110100001001, //'}' + 0b00000101010010, //'~' - Added to map + 0b11111111111111, //Unknown character (DEL or RUBOUT) +}; + /*--------------------------- Device Status----------------------------------*/ bool HT16K33::begin(uint8_t addressLeft, uint8_t addressLeftCenter, uint8_t addressRightCenter, uint8_t addressRight, TwoWire &wirePort) @@ -394,7 +499,7 @@ bool HT16K33::decimalOn() status = false; } - Serial.println(status); + //Serial.println(status); return status; } @@ -529,109 +634,6 @@ void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) } } -#define SFE_ALPHANUM_UNKNOWN_CHAR 95 - -//This is the lookup table of segments for various characters -static uint16_t alphanumeric_segs[96]{ - //nmlkjihgfedcba - 0b00000000000000, //' ' (space) - 0b00001000001000, //'!' - added to map - 0b00001000000010, //'"' - added to map - 0b1001101001110, //'#' - 0b1001101101101, //'$' - 0b10010000100100, //'%' - 0b110011011001, //'&' - 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' - 0b11111010000000, //'*' - 0b1001101000000, //'+' - 0b10000000000000, //',' - 0b101000000, //'-' - 0b10, //'.' - DEBUG: need to test - 0b10010000000000, //'/' - 0b111111, //'0' - 0b10000000110, //'1' - 0b101011011, //'2' - 0b101001111, //'3' - 0b101100110, //'4' - 0b101101101, //'5' - 0b101111101, //'6' - 0b1010000000001, //'7' - 0b101111111, //'8' - 0b101100111, //'9' - 0b1, //':' - DEBUG: need to test - 0b10001000000000, //';' - 0b110000000000, //'<' - 0b101001000, //'=' - 0b10000010000000, //'>' - 0b01001000000000, //':' - Added to map - 0b10001000000000, //';' - Added to map - 0b101110111, //'A' - 0b1001100001111, //'B' - 0b111001, //'C' - 0b1001000001111, //'D' - 0b101111001, //'E' - 0b101110001, //'F' - 0b100111101, //'G' - 0b101110110, //'H' - 0b1001000001001, //'I' - 0b11110, //'J' - 0b110001110000, //'K' - 0b111000, //'L' - 0b10010110110, //'M' - 0b100010110110, //'N' - 0b111111, //'O' - 0b101110011, //'P' - 0b100000111111, //'Q' - 0b100101110011, //'R' - 0b110001101, //'S' - 0b1001000000001, //'T' - 0b111110, //'U' - 0b10010000110000, //'V' - 0b10100000110110, //'W' - 0b10110010000000, //'X' - 0b1010010000000, //'Y' - 0b10010000001001, //'Z' - 0b111001, //'[' - 0b100010000000, //'\' - 0b1111, //']' - 0b10100000000000, //'^' - Added to map - 0b1000, //'_' - 0b10000000, //'`' - 0b101011111, //'a' - 0b100001111000, //'b' - 0b101011000, //'c' - 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' - 0b110001111, //'g' - 0b101110100, //'h' - 0b1000000000000, //'i' - 0b1110, //'j' - 0b1111000000000, //'k' - 0b1001000000000, //'l' - 0b1000101010100, //'m' - 0b100001010000, //'n' - 0b101011100, //'o' - 0b10001110001, //'p' - 0b100101100011, //'q' - 0b1010000, //'r' - 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' - 0b10000000010000, //'v' - 0b10100000010100, //'w' - 0b10110010000000, //'x' - 0b1100001110, //'y' - 0b10010000001001, //'z' - 0b10000011001001, //'{' - 0b1001000000000, //'|' - 0b110100001001, //'}' - 0b00000101010010, //'~' - Added to map - 0b11111111111111, //Unknown character (DEL or RUBOUT) -}; - //Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { @@ -660,10 +662,12 @@ void HT16K33::printChar(uint8_t displayChar, uint8_t digit) // if (characterPosition > sizeof(alphanumeric_segs)) // characterPosition = sizeof(alphanumeric_segs) - 1; //Unknown char - illuminateChar(alphanumeric_segs[characterPosition], digit); + uint16_t segmentsToTurnOn = getSegmentsToTurnOn(characterPosition); + + illuminateChar(segmentsToTurnOn, digit); } -//Update the lookup table of segments for a particular character +//Update the list to define a new segments display for a particular character bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) { bool result = false; @@ -671,16 +675,66 @@ bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) //Check to see if character is within range of displayable ASCII characters if (displayChar >= '!' && displayChar <= '~') { - //Get the index of character in map and update its 14-bit segment value - uint16_t characterPosition = displayChar - '!' + 1; - - //Mask the input segment value to 14 bits only - alphanumeric_segs[characterPosition] = (segmentsToTurnOn & 0x3FFF); - - //We're all good - result = true; - } - return result; + //Get the index of character in table and update its 14-bit segment value + uint16_t characterPosition = displayChar - '!' + 1; + + //Create a new character definition + struct CharDef * pNewCharDef = calloc(1, sizeof(CharDef)); + + //Set the position to the table index + pNewCharDef -> position = characterPosition; + //Mask the segment value to 14 bits only + pNewCharDef -> segments = segmentsToTurnOn & 0x3FFF; + //New definition always goes at the end of the list + pNewCharDef -> next = NULL; + + //If list is empty set it to the new item + if (pCharDefList == NULL) + { + pCharDefList = pNewCharDef; + } + else + { + //Otherwise go to the end of the list and add it there + struct CharDef * pTail = pCharDefList; + + while(pTail->next != NULL) + { + pTail = pTail->next; + } + + pTail->next = pNewCharDef; + } + //We added the definition so we're all good + result = true; + } + return result; +} + +//Get the character map from the definition list or default table +uint16_t HT16K33::getSegmentsToTurnOn(uint8_t charPos) +{ + uint16_t segments = 0; + //pointer to a defined character in list + struct CharDef * pDefChar = pCharDefList; + + //Search the chacters list for a match + while(pDefChar && (pDefChar->position != charPos)) + { + pDefChar = pDefChar -> next; + } + + //If we found a match return that value + if (pDefChar != NULL) + { + segments = pDefChar -> segments; + } + //Otherwise get the value from the table + else + { + segments = pgm_read_word_near(alphanumeric_segs + charPos); + } + return segments; } /* diff --git a/src/SparkFun_Alphanumeric_Display.h b/src/SparkFun_Alphanumeric_Display.h index 201df5b..e20d71b 100644 --- a/src/SparkFun_Alphanumeric_Display.h +++ b/src/SparkFun_Alphanumeric_Display.h @@ -81,6 +81,13 @@ typedef enum ALPHA_CMD_DIMMING_SETUP = 0b11100000, } alpha_command_t; +//Structure for defining new character displays +struct CharDef { + uint8_t position; + int16_t segments; + struct CharDef * next; +}; + // class HT16K33 class HT16K33 : public Print { @@ -101,6 +108,9 @@ class HT16K33 : public Print uint8_t displayRAM[16 * 4]; char displayContent[4 * 4 + 1] = ""; + //Linked List of character definitions + struct CharDef * pCharDefList = NULL; + public: //Device status bool begin(uint8_t addressLeft = DEFAULT_ADDRESS, @@ -140,6 +150,7 @@ class HT16K33 : public Print //Define Character Segment Map bool defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn); + uint16_t getSegmentsToTurnOn (uint8_t charPos); //Colon and decimal bool decimalOn(); From 83a71a2a8473c145431708864b4ce1263d7244e4 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Sun, 3 May 2020 15:06:20 -0400 Subject: [PATCH 09/12] Updated comment --- src/SparkFun_Alphanumeric_Display.cpp | 1138 ++++++++++++------------- 1 file changed, 569 insertions(+), 569 deletions(-) diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index 4878a08..6cb11c2 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -19,9 +19,9 @@ the ADR1/ADR0 pins the address has been seen to change. The best way around this to do a isConnected check before updateRAM() is sent to the driver IC. Development environment specifics: - IDE: Arduino 1.8.9 - Hardware Platform: Arduino Uno - Alphanumeric Display Breakout Version: 1.0.0 + IDE: Arduino 1.8.9 + Hardware Platform: Arduino Uno + Alphanumeric Display Breakout Version: 1.0.0 This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! @@ -37,103 +37,103 @@ Distributed as-is; no warranty is given. //This is the lookup table of segments for various characters static const uint16_t PROGMEM alphanumeric_segs[96]{ - //nmlkjihgfedcba - 0b00000000000000, //' ' (space) - 0b00001000001000, //'!' - added to map - 0b00001000000010, //'"' - added to map - 0b1001101001110, //'#' - 0b1001101101101, //'$' - 0b10010000100100, //'%' - 0b110011011001, //'&' - 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' - 0b11111010000000, //'*' - 0b1001101000000, //'+' - 0b10000000000000, //',' - 0b101000000, //'-' - 0b00000000000000, //'.' - changed to blank - 0b10010000000000, //'/' - 0b111111, //'0' - 0b10000000110, //'1' - 0b101011011, //'2' - 0b101001111, //'3' - 0b101100110, //'4' - 0b101101101, //'5' - 0b101111101, //'6' - 0b1010000000001, //'7' - 0b101111111, //'8' - 0b101100111, //'9' - 0b00000000000000, //':' - changed to blank - 0b10001000000000, //';' - 0b110000000000, //'<' - 0b101001000, //'=' - 0b01000010000000, //'>' + //nmlkjihgfedcba + 0b00000000000000, //' ' (space) + 0b00001000001000, //'!' - added to map + 0b00001000000010, //'"' - added to map + 0b1001101001110, //'#' + 0b1001101101101, //'$' + 0b10010000100100, //'%' + 0b110011011001, //'&' + 0b1000000000, //''' + 0b111001, //'(' + 0b1111, //')' + 0b11111010000000, //'*' + 0b1001101000000, //'+' + 0b10000000000000, //',' + 0b101000000, //'-' + 0b00000000000000, //'.' - changed to blank + 0b10010000000000, //'/' + 0b111111, //'0' + 0b10000000110, //'1' + 0b101011011, //'2' + 0b101001111, //'3' + 0b101100110, //'4' + 0b101101101, //'5' + 0b101111101, //'6' + 0b1010000000001, //'7' + 0b101111111, //'8' + 0b101100111, //'9' + 0b00000000000000, //':' - changed to blank + 0b10001000000000, //';' + 0b110000000000, //'<' + 0b101001000, //'=' + 0b01000010000000, //'>' 0b01000100000011, //'?' - Added to map - 0b00001100111011, //'@' - Added to map - 0b101110111, //'A' - 0b1001100001111, //'B' - 0b111001, //'C' - 0b1001000001111, //'D' - 0b101111001, //'E' - 0b101110001, //'F' - 0b100111101, //'G' - 0b101110110, //'H' - 0b1001000001001, //'I' - 0b11110, //'J' - 0b110001110000, //'K' - 0b111000, //'L' - 0b10010110110, //'M' - 0b100010110110, //'N' - 0b111111, //'O' - 0b101110011, //'P' - 0b100000111111, //'Q' - 0b100101110011, //'R' - 0b110001101, //'S' - 0b1001000000001, //'T' - 0b111110, //'U' - 0b10010000110000, //'V' - 0b10100000110110, //'W' - 0b10110010000000, //'X' - 0b1010010000000, //'Y' - 0b10010000001001, //'Z' - 0b111001, //'[' - 0b100010000000, //'\' - 0b1111, //']' + 0b00001100111011, //'@' - Added to map + 0b101110111, //'A' + 0b1001100001111, //'B' + 0b111001, //'C' + 0b1001000001111, //'D' + 0b101111001, //'E' + 0b101110001, //'F' + 0b100111101, //'G' + 0b101110110, //'H' + 0b1001000001001, //'I' + 0b11110, //'J' + 0b110001110000, //'K' + 0b111000, //'L' + 0b10010110110, //'M' + 0b100010110110, //'N' + 0b111111, //'O' + 0b101110011, //'P' + 0b100000111111, //'Q' + 0b100101110011, //'R' + 0b110001101, //'S' + 0b1001000000001, //'T' + 0b111110, //'U' + 0b10010000110000, //'V' + 0b10100000110110, //'W' + 0b10110010000000, //'X' + 0b1010010000000, //'Y' + 0b10010000001001, //'Z' + 0b111001, //'[' + 0b100010000000, //'\' + 0b1111, //']' 0b10100000000000, //'^' - Added to map - 0b1000, //'_' - 0b10000000, //'`' - 0b101011111, //'a' - 0b100001111000, //'b' - 0b101011000, //'c' - 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' - 0b110001111, //'g' - 0b101110100, //'h' - 0b1000000000000, //'i' - 0b1110, //'j' - 0b1111000000000, //'k' - 0b1001000000000, //'l' - 0b1000101010100, //'m' - 0b100001010000, //'n' - 0b101011100, //'o' - 0b10001110001, //'p' - 0b100101100011, //'q' - 0b1010000, //'r' - 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' - 0b10000000010000, //'v' - 0b10100000010100, //'w' - 0b10110010000000, //'x' - 0b1100001110, //'y' - 0b10010000001001, //'z' - 0b10000011001001, //'{' - 0b1001000000000, //'|' - 0b110100001001, //'}' - 0b00000101010010, //'~' - Added to map - 0b11111111111111, //Unknown character (DEL or RUBOUT) + 0b1000, //'_' + 0b10000000, //'`' + 0b101011111, //'a' + 0b100001111000, //'b' + 0b101011000, //'c' + 0b10000100001110, //'d' + 0b1111001, //'e' + 0b1110001, //'f' + 0b110001111, //'g' + 0b101110100, //'h' + 0b1000000000000, //'i' + 0b1110, //'j' + 0b1111000000000, //'k' + 0b1001000000000, //'l' + 0b1000101010100, //'m' + 0b100001010000, //'n' + 0b101011100, //'o' + 0b10001110001, //'p' + 0b100101100011, //'q' + 0b1010000, //'r' + 0b110001101, //'s' + 0b1111000, //'t' + 0b11100, //'u' + 0b10000000010000, //'v' + 0b10100000010100, //'w' + 0b10110010000000, //'x' + 0b1100001110, //'y' + 0b10010000001001, //'z' + 0b10000011001001, //'{' + 0b1001000000000, //'|' + 0b110100001001, //'}' + 0b00000101010010, //'~' - Added to map + 0b11111111111111, //Unknown character (DEL or RUBOUT) }; /*--------------------------- Device Status----------------------------------*/ @@ -141,229 +141,229 @@ static const uint16_t PROGMEM alphanumeric_segs[96]{ bool HT16K33::begin(uint8_t addressLeft, uint8_t addressLeftCenter, uint8_t addressRightCenter, uint8_t addressRight, TwoWire &wirePort) { - _deviceAddressLeft = addressLeft; //grab the address of the alphanumeric - _deviceAddressLeftCenter = addressLeftCenter; //grab the address of the alphanumeric - _deviceAddressRightCenter = addressRightCenter; //grab the address of the alphanumeric - _deviceAddressRight = addressRight; //grab the address of the alphanumeric - - if (_deviceAddressRight != DEFAULT_NOTHING_ATTACHED) - numberOfDisplays = 4; - else if (_deviceAddressRightCenter != DEFAULT_NOTHING_ATTACHED) - numberOfDisplays = 3; - else if (_deviceAddressLeftCenter != DEFAULT_NOTHING_ATTACHED) - numberOfDisplays = 2; - else - numberOfDisplays = 1; - - //TODO: malloc more displayRAM - - _i2cPort = &wirePort; //Remember the user's setting - - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (isConnected(i) == false) - { - //Serial.println("Failed isConnected()"); - return false; - } - // if (checkDeviceID(i) == false) - // { - // Serial.println(i); - // Serial.println("Hello, I've failed checkDeviceID()"); - // return false; - // } - } - - if (initialize() == false) - { - //Serial.println("Failed initialize()"); - return false; - } - - if (clear() == false) //Clear all displays - { - //Serial.println("Failed clear()"); - return false; - } - - displayContent[4 * 4] = '\0'; //Terminate the array because we are doing direct prints - - return true; + _deviceAddressLeft = addressLeft; //grab the address of the alphanumeric + _deviceAddressLeftCenter = addressLeftCenter; //grab the address of the alphanumeric + _deviceAddressRightCenter = addressRightCenter; //grab the address of the alphanumeric + _deviceAddressRight = addressRight; //grab the address of the alphanumeric + + if (_deviceAddressRight != DEFAULT_NOTHING_ATTACHED) + numberOfDisplays = 4; + else if (_deviceAddressRightCenter != DEFAULT_NOTHING_ATTACHED) + numberOfDisplays = 3; + else if (_deviceAddressLeftCenter != DEFAULT_NOTHING_ATTACHED) + numberOfDisplays = 2; + else + numberOfDisplays = 1; + + //TODO: malloc more displayRAM + + _i2cPort = &wirePort; //Remember the user's setting + + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (isConnected(i) == false) + { + //Serial.println("Failed isConnected()"); + return false; + } + // if (checkDeviceID(i) == false) + // { + // Serial.println(i); + // Serial.println("Hello, I've failed checkDeviceID()"); + // return false; + // } + } + + if (initialize() == false) + { + //Serial.println("Failed initialize()"); + return false; + } + + if (clear() == false) //Clear all displays + { + //Serial.println("Failed clear()"); + return false; + } + + displayContent[4 * 4] = '\0'; //Terminate the array because we are doing direct prints + + return true; } //Check that all displays are responding //The Holtek IC sometimes fails to respond. This attempts multiple times before giving up. bool HT16K33::isConnected(uint8_t displayNumber) { - uint8_t triesBeforeGiveup = 20; - - for (uint8_t x = 0; x < triesBeforeGiveup; x++) - { - _i2cPort->beginTransmission(lookUpDisplayAddress(displayNumber)); - if (_i2cPort->endTransmission() == 0) - { - // if (x > 0) - // { - // Serial.print("isConnect successful"); - // Serial.print(" after "); - // Serial.print(x); - // Serial.print(" tries"); - // Serial.println(); - // } - return true; - } - - delay(1); - } - return false; + uint8_t triesBeforeGiveup = 20; + + for (uint8_t x = 0; x < triesBeforeGiveup; x++) + { + _i2cPort->beginTransmission(lookUpDisplayAddress(displayNumber)); + if (_i2cPort->endTransmission() == 0) + { + // if (x > 0) + // { + // Serial.print("isConnect successful"); + // Serial.print(" after "); + // Serial.print(x); + // Serial.print(" tries"); + // Serial.println(); + // } + return true; + } + + delay(1); + } + return false; } bool HT16K33::initialize() { - //Turn on system clock of all displays - if (enableSystemClock() == false) - { - //Serial.println("Init: Failed enableSystemClock()"); - return false; - } - - //Set brightness of all displays to full brightness - if (setBrightness(16) == false) - { - //Serial.println("Init: Failed setBrightness()"); - return false; - } - - //Blinking set - blinking off - if (setBlinkRate(ALPHA_BLINK_RATE_NOBLINK) == false) - { - //Serial.println("Init: Failed setBlinkRate()"); - return false; - } - - //Turn on all displays - if (displayOn() == false) - { - //Serial.println("Init: Failed display on"); - return false; - } - - return true; + //Turn on system clock of all displays + if (enableSystemClock() == false) + { + //Serial.println("Init: Failed enableSystemClock()"); + return false; + } + + //Set brightness of all displays to full brightness + if (setBrightness(16) == false) + { + //Serial.println("Init: Failed setBrightness()"); + return false; + } + + //Blinking set - blinking off + if (setBlinkRate(ALPHA_BLINK_RATE_NOBLINK) == false) + { + //Serial.println("Init: Failed setBlinkRate()"); + return false; + } + + //Turn on all displays + if (displayOn() == false) + { + //Serial.println("Init: Failed display on"); + return false; + } + + return true; } // //Verify that all objects on I2C bus are alphanumeric displays // bool HT16K33::checkDeviceID(uint8_t displayNumber) // { -// uint8_t address = lookUpDisplayAddress(displayNumber); -// uint8_t test = 0xAA; -// uint8_t temp; -// //Turn off display - DEBUG: should it be ALL or ONE? -// singleDisplayOff(displayNumber); -// //Write 0xAA to register 0 -// writeRAM(address, 0, (uint8_t *)&test, 1); -// //Read it back, it should be 0xAA -// readRAM(address, 0, (uint8_t *)&temp, sizeof((uint8_t)temp)); -// if (temp != test) -// return false; -// //DEBUGGING: taking this out for now... can't call this write to ALL displays when we haven't initalized all displays yet! -// //Clear the write we just did -// // clear(); -// //Turn display back on -// singleDisplayOn(displayNumber); -// return true; +// uint8_t address = lookUpDisplayAddress(displayNumber); +// uint8_t test = 0xAA; +// uint8_t temp; +// //Turn off display - DEBUG: should it be ALL or ONE? +// singleDisplayOff(displayNumber); +// //Write 0xAA to register 0 +// writeRAM(address, 0, (uint8_t *)&test, 1); +// //Read it back, it should be 0xAA +// readRAM(address, 0, (uint8_t *)&temp, sizeof((uint8_t)temp)); +// if (temp != test) +// return false; +// //DEBUGGING: taking this out for now... can't call this write to ALL displays when we haven't initalized all displays yet! +// //Clear the write we just did +// // clear(); +// //Turn display back on +// singleDisplayOn(displayNumber); +// return true; // } bool HT16K33::enableSystemClock() { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (enableSystemClockSingle(i) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (enableSystemClockSingle(i) == false) + status = false; + } + return status; } bool HT16K33::disableSystemClock() { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (enableSystemClockSingle(i) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (enableSystemClockSingle(i) == false) + status = false; + } + return status; } bool HT16K33::enableSystemClockSingle(uint8_t displayNumber) { - uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 1; //Enable system clock + uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 1; //Enable system clock - bool status = writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite); - delay(1); //Allow display to start - return (status); + bool status = writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite); + delay(1); //Allow display to start + return (status); } bool HT16K33::disableSystemClockSingle(uint8_t displayNumber) { - uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 0; //Standby mode + uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 0; //Standby mode - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } uint8_t HT16K33::lookUpDisplayAddress(uint8_t displayNumber) { - switch (displayNumber) - { - case 0: - return _deviceAddressLeft; - break; - case 1: - return _deviceAddressLeftCenter; - break; - case 2: - return _deviceAddressRightCenter; - break; - case 3: - return _deviceAddressRight; - break; - } - - return 0; //We shouldn't get here + switch (displayNumber) + { + case 0: + return _deviceAddressLeft; + break; + case 1: + return _deviceAddressLeftCenter; + break; + case 2: + return _deviceAddressRightCenter; + break; + case 3: + return _deviceAddressRight; + break; + } + + return 0; //We shouldn't get here } /*-------------------------- Display configuration functions ---------------------------*/ bool HT16K33::clear() { - //Clear the displayRAM array - for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) - displayRAM[i] = 0; + //Clear the displayRAM array + for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) + displayRAM[i] = 0; - digitPosition = 0; + digitPosition = 0; - return (updateDisplay()); + return (updateDisplay()); } //Duty valid between 1 and 16 bool HT16K33::setBrightness(uint8_t duty) { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (setBrightnessSingle(i, duty) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (setBrightnessSingle(i, duty) == false) + status = false; + } + return status; } bool HT16K33::setBrightnessSingle(uint8_t displayNumber, uint8_t duty) { - if (duty > 15) - duty = 15; //Error check + if (duty > 15) + duty = 15; //Error check - uint8_t dataToWrite = ALPHA_CMD_DIMMING_SETUP | duty; - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + uint8_t dataToWrite = ALPHA_CMD_DIMMING_SETUP | duty; + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } //Parameter "rate" in Hz @@ -371,208 +371,208 @@ bool HT16K33::setBrightnessSingle(uint8_t displayNumber, uint8_t duty) //Any other input to this function will result in steady alphanumeric display bool HT16K33::setBlinkRate(float rate) { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (setBlinkRateSingle(i, rate) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (setBlinkRateSingle(i, rate) == false) + status = false; + } + return status; } bool HT16K33::setBlinkRateSingle(uint8_t displayNumber, float rate) { - if (rate == 2) - { - blinkRate = ALPHA_BLINK_RATE_2HZ; - } - else if (rate == 1) - { - blinkRate = ALPHA_BLINK_RATE_1HZ; - } - else if (rate == 0.5) - { - blinkRate = ALPHA_BLINK_RATE_0_5HZ; - } - //default to no blink - else - { - blinkRate = ALPHA_BLINK_RATE_NOBLINK; - } - - uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + if (rate == 2) + { + blinkRate = ALPHA_BLINK_RATE_2HZ; + } + else if (rate == 1) + { + blinkRate = ALPHA_BLINK_RATE_1HZ; + } + else if (rate == 0.5) + { + blinkRate = ALPHA_BLINK_RATE_0_5HZ; + } + //default to no blink + else + { + blinkRate = ALPHA_BLINK_RATE_NOBLINK; + } + + uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } bool HT16K33::displayOnSingle(uint8_t displayNumber) { - return setDisplayOnOff(displayNumber, true); + return setDisplayOnOff(displayNumber, true); } bool HT16K33::displayOffSingle(uint8_t displayNumber) { - return setDisplayOnOff(displayNumber, false); + return setDisplayOnOff(displayNumber, false); } //Set or clear the display on/off bit of a given display number bool HT16K33::setDisplayOnOff(uint8_t displayNumber, bool turnOnDisplay) { - if (turnOnDisplay == true) - displayOnOff = ALPHA_DISPLAY_ON; - else - displayOnOff = ALPHA_DISPLAY_OFF; + if (turnOnDisplay == true) + displayOnOff = ALPHA_DISPLAY_ON; + else + displayOnOff = ALPHA_DISPLAY_OFF; - uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } //Turn on/off the entire display bool HT16K33::displayOn() { - bool status = true; + bool status = true; - displayOnOff = ALPHA_DISPLAY_ON; + displayOnOff = ALPHA_DISPLAY_ON; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (displayOnSingle(i) == false) - status = false; - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (displayOnSingle(i) == false) + status = false; + } - return status; + return status; } bool HT16K33::displayOff() { - bool status = true; + bool status = true; - displayOnOff = ALPHA_DISPLAY_OFF; + displayOnOff = ALPHA_DISPLAY_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (displayOffSingle(i) == false) - status = false; - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (displayOffSingle(i) == false) + status = false; + } - return status; + return status; } bool HT16K33::decimalOnSingle(uint8_t displayNumber) { - return setDecimalOnOff(displayNumber, true); + return setDecimalOnOff(displayNumber, true); } bool HT16K33::decimalOffSingle(uint8_t displayNumber) { - return setDecimalOnOff(displayNumber, false); + return setDecimalOnOff(displayNumber, false); } bool HT16K33::setDecimalOnOff(uint8_t displayNumber, bool turnOnDecimal) { - uint8_t adr = 0x03; - uint8_t dat; + uint8_t adr = 0x03; + uint8_t dat; - if (turnOnDecimal == true) - { - decimalOnOff = ALPHA_DECIMAL_ON; - dat = 0x01; - } - else - { - decimalOnOff = ALPHA_DECIMAL_OFF; - dat = 0x00; - } + if (turnOnDecimal == true) + { + decimalOnOff = ALPHA_DECIMAL_ON; + dat = 0x01; + } + else + { + decimalOnOff = ALPHA_DECIMAL_OFF; + dat = 0x00; + } - displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; - updateDisplay(); + displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; + updateDisplay(); } //Turn on/off the entire display bool HT16K33::decimalOn() { - bool status = true; + bool status = true; - decimalOnOff = ALPHA_DECIMAL_ON; + decimalOnOff = ALPHA_DECIMAL_ON; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (decimalOnSingle(i) == false) - status = false; - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (decimalOnSingle(i) == false) + status = false; + } - //Serial.println(status); - return status; + //Serial.println(status); + return status; } bool HT16K33::decimalOff() { - bool status = true; + bool status = true; - decimalOnOff = ALPHA_DECIMAL_OFF; + decimalOnOff = ALPHA_DECIMAL_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (decimalOffSingle(i) == false) - status = false; - } - return status; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (decimalOffSingle(i) == false) + status = false; + } + return status; } bool HT16K33::colonOnSingle(uint8_t displayNumber) { - return setColonOnOff(displayNumber, true); + return setColonOnOff(displayNumber, true); } bool HT16K33::colonOffSingle(uint8_t displayNumber) { - return setColonOnOff(displayNumber, false); + return setColonOnOff(displayNumber, false); } bool HT16K33::setColonOnOff(uint8_t displayNumber, bool turnOnColon) { - uint8_t adr = 0x01; - uint8_t dat; + uint8_t adr = 0x01; + uint8_t dat; - if (turnOnColon == true) - { - colonOnOff = ALPHA_COLON_ON; - dat = 0x01; - } - else - { - colonOnOff = ALPHA_COLON_OFF; - dat = 0x00; - } + if (turnOnColon == true) + { + colonOnOff = ALPHA_COLON_ON; + dat = 0x01; + } + else + { + colonOnOff = ALPHA_COLON_OFF; + dat = 0x00; + } - displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; - updateDisplay(); + displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; + updateDisplay(); } bool HT16K33::colonOn() { - bool status = true; + bool status = true; - colonOnOff = ALPHA_COLON_ON; + colonOnOff = ALPHA_COLON_ON; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (colonOnSingle(i) == false) - status = false; - } - return status; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (colonOnSingle(i) == false) + status = false; + } + return status; } bool HT16K33::colonOff() { - bool status = true; + bool status = true; - colonOnOff = ALPHA_COLON_OFF; + colonOnOff = ALPHA_COLON_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (colonOffSingle(i) == false) - status = false; - } - return status; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (colonOffSingle(i) == false) + status = false; + } + return status; } /*---------------------------- Light up functions ---------------------------------*/ @@ -580,108 +580,108 @@ bool HT16K33::colonOff() //Given a segment and a digit, set the matching bit within the RAM of the Holtek RAM set void HT16K33::illuminateSegment(uint8_t segment, uint8_t digit) { - uint8_t com; - uint8_t row; + uint8_t com; + uint8_t row; - com = segment - 'A'; //Convert the segment letter back to a number + com = segment - 'A'; //Convert the segment letter back to a number - if (com > 6) - com -= 7; - if (segment == 'I') - com = 0; - if (segment == 'H') - com = 1; + if (com > 6) + com -= 7; + if (segment == 'I') + com = 0; + if (segment == 'H') + com = 1; - row = digit % 4; //Convert digit (1 to 16) back to a relative position on a given display - if (segment > 'G') - row += 4; + row = digit % 4; //Convert digit (1 to 16) back to a relative position on a given display + if (segment > 'G') + row += 4; - uint8_t offset = digit / 4 * 16; - uint8_t adr = com * 2 + offset; + uint8_t offset = digit / 4 * 16; + uint8_t adr = com * 2 + offset; - //Determine the address - if (row > 7) - adr++; + //Determine the address + if (row > 7) + adr++; - //Determine the data bit - if (row > 7) - row -= 8; - uint8_t dat = 1 << row; + //Determine the data bit + if (row > 7) + row -= 8; + uint8_t dat = 1 << row; - //Temp DEBUGGING - clear segments that might affect A0/A1 - //dat &= 0b11111100; + //Temp DEBUGGING - clear segments that might affect A0/A1 + //dat &= 0b11111100; - // Serial.print("illSeg Digit: "); - // Serial.print(digit); - // Serial.print("\t row: "); - // Serial.print(row); - // Serial.print("\t com: "); - // Serial.print(com); - // Serial.print("\t adr: "); - // Serial.print(adr); - // Serial.println(); + // Serial.print("illSeg Digit: "); + // Serial.print(digit); + // Serial.print("\t row: "); + // Serial.print(row); + // Serial.print("\t com: "); + // Serial.print(com); + // Serial.print("\t adr: "); + // Serial.print(adr); + // Serial.println(); - displayRAM[adr] = displayRAM[adr] | dat; + displayRAM[adr] = displayRAM[adr] | dat; } //Given a binary set of segments and a digit, store this data into the RAM array void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) { - for (uint8_t i = 0; i < 14; i++) //There are 14 segments on this display - { - if ((segmentsToTurnOn >> i) & 0b1) - illuminateSegment('A' + i, digit); //Convert the segment number to a letter - } + for (uint8_t i = 0; i < 14; i++) //There are 14 segments on this display + { + if ((segmentsToTurnOn >> i) & 0b1) + illuminateSegment('A' + i, digit); //Convert the segment number to a letter + } } //Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { - //moved alphanumeric_segs array outside of function - uint16_t characterPosition = 65532; + //moved alphanumeric_segs array outside of function to PROGMEM + uint16_t characterPosition = 65532; - //space - if (displayChar == ' ') - characterPosition = 0; - //Printable Symbols - else if (displayChar >= '!' && displayChar <= '~') - { - characterPosition = displayChar - '!' + 1; - } + //space + if (displayChar == ' ') + characterPosition = 0; + //Printable Symbols + else if (displayChar >= '!' && displayChar <= '~') + { + characterPosition = displayChar - '!' + 1; + } - uint8_t dispNum = digitPosition / 4; - //Take care of special characters - if (characterPosition == 14) //'.' - decimalOnSingle(dispNum); - if (characterPosition == 26) //':' - colonOnSingle(dispNum); - if (characterPosition == 65532) //unknown character - characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; + uint8_t dispNum = digitPosition / 4; + //Take care of special characters + if (characterPosition == 14) //'.' + decimalOnSingle(dispNum); + if (characterPosition == 26) //':' + colonOnSingle(dispNum); + if (characterPosition == 65532) //unknown character + characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; - // //Error check - // if (characterPosition > sizeof(alphanumeric_segs)) - // characterPosition = sizeof(alphanumeric_segs) - 1; //Unknown char + // //Error check + // if (characterPosition > sizeof(alphanumeric_segs)) + // characterPosition = sizeof(alphanumeric_segs) - 1; //Unknown char - uint16_t segmentsToTurnOn = getSegmentsToTurnOn(characterPosition); + uint16_t segmentsToTurnOn = getSegmentsToTurnOn(characterPosition); - illuminateChar(segmentsToTurnOn, digit); + illuminateChar(segmentsToTurnOn, digit); } //Update the list to define a new segments display for a particular character bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) { - bool result = false; + bool result = false; - //Check to see if character is within range of displayable ASCII characters - if (displayChar >= '!' && displayChar <= '~') - { - //Get the index of character in table and update its 14-bit segment value - uint16_t characterPosition = displayChar - '!' + 1; + //Check to see if character is within range of displayable ASCII characters + if (displayChar >= '!' && displayChar <= '~') + { + //Get the index of character in table and update its 14-bit segment value + uint16_t characterPosition = displayChar - '!' + 1; //Create a new character definition struct CharDef * pNewCharDef = calloc(1, sizeof(CharDef)); - //Set the position to the table index + //Set the position to the table index pNewCharDef -> position = characterPosition; //Mask the segment value to 14 bits only pNewCharDef -> segments = segmentsToTurnOn & 0x3FFF; @@ -691,7 +691,7 @@ bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) //If list is empty set it to the new item if (pCharDefList == NULL) { - pCharDefList = pNewCharDef; + pCharDefList = pNewCharDef; } else { @@ -705,8 +705,8 @@ bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) pTail->next = pNewCharDef; } - //We added the definition so we're all good - result = true; + //We added the definition so we're all good + result = true; } return result; } @@ -743,16 +743,16 @@ uint16_t HT16K33::getSegmentsToTurnOn(uint8_t charPos) */ size_t HT16K33::write(uint8_t b) { - //If user wants to print '.' or ':', don't increment the digitPosition! - if (b == '.' | b == ':') - printChar(b, 0); - else - { - printChar(b, digitPosition++); - digitPosition %= (numberOfDisplays * 4); //Convert displays to number of digits - } + //If user wants to print '.' or ':', don't increment the digitPosition! + if (b == '.' | b == ':') + printChar(b, 0); + else + { + printChar(b, digitPosition++); + digitPosition %= (numberOfDisplays * 4); //Convert displays to number of digits + } - return (updateDisplay()); //Send RAM buffer over I2C bus + return (updateDisplay()); //Send RAM buffer over I2C bus } /* @@ -761,171 +761,171 @@ size_t HT16K33::write(uint8_t b) */ size_t HT16K33::write(const uint8_t *buffer, size_t size) { - size_t n = size; - uint8_t buff; - - //Clear the displayRAM array - for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) - displayRAM[i] = 0; - - digitPosition = 0; - - while (size--) - { - buff = *buffer++; - //For special characters like '.' or ':', do not increment the digitPosition - if (buff == '.') - printChar('.', 0); - else if (buff == ':') - printChar(':', 0); - else - { - printChar(buff, digitPosition); - displayContent[digitPosition] = buff; //Record to internal array - - digitPosition++; - digitPosition %= (numberOfDisplays * 4); - } - } + size_t n = size; + uint8_t buff; + + //Clear the displayRAM array + for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) + displayRAM[i] = 0; + + digitPosition = 0; + + while (size--) + { + buff = *buffer++; + //For special characters like '.' or ':', do not increment the digitPosition + if (buff == '.') + printChar('.', 0); + else if (buff == ':') + printChar(':', 0); + else + { + printChar(buff, digitPosition); + displayContent[digitPosition] = buff; //Record to internal array + + digitPosition++; + digitPosition %= (numberOfDisplays * 4); + } + } - updateDisplay(); //Send RAM buffer over I2C bus + updateDisplay(); //Send RAM buffer over I2C bus - return n; + return n; } //Write a string to the display size_t HT16K33::write(const char *str) { - if (str == NULL) - return 0; - return write((const uint8_t *)str, strlen(str)); + if (str == NULL) + return 0; + return write((const uint8_t *)str, strlen(str)); } //Push the contents of displayRAM out to the various displays in 16 byte chunks bool HT16K33::updateDisplay() { - //printRAM(); + //printRAM(); - bool status = true; + bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (writeRAM(lookUpDisplayAddress(i), 0, (uint8_t *)(displayRAM + (i * 16)), 16) == false) - { - //Serial.print("updateDisplay fail at display 0x"); - //Serial.println(lookUpDisplayAddress(i), HEX); - status = false; - } - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (writeRAM(lookUpDisplayAddress(i), 0, (uint8_t *)(displayRAM + (i * 16)), 16) == false) + { + //Serial.print("updateDisplay fail at display 0x"); + //Serial.println(lookUpDisplayAddress(i), HEX); + status = false; + } + } - return status; + return status; } //Shift the display content to the right one digit bool HT16K33::shiftRight(uint8_t shiftAmt) { - for (uint8_t x = (4 * numberOfDisplays) - shiftAmt; x >= shiftAmt; x--) - { - displayContent[x] = displayContent[x - shiftAmt]; - } + for (uint8_t x = (4 * numberOfDisplays) - shiftAmt; x >= shiftAmt; x--) + { + displayContent[x] = displayContent[x - shiftAmt]; + } - //Clear the leading characters - for (uint8_t x = 0; x < shiftAmt; x++) - { - if (x + shiftAmt > (4 * numberOfDisplays)) - break; //Error check + //Clear the leading characters + for (uint8_t x = 0; x < shiftAmt; x++) + { + if (x + shiftAmt > (4 * numberOfDisplays)) + break; //Error check - displayContent[0 + x] = ' '; - } + displayContent[0 + x] = ' '; + } - return (print(displayContent)); + return (print(displayContent)); } //Shift the display content to the left one digit bool HT16K33::shiftLeft(uint8_t shiftAmt) { - for (int x = 0; x < 4 * numberOfDisplays; x++) - { - if (x + shiftAmt > (4 * numberOfDisplays)) - break; //Error check - displayContent[x] = displayContent[x + shiftAmt]; - } + for (int x = 0; x < 4 * numberOfDisplays; x++) + { + if (x + shiftAmt > (4 * numberOfDisplays)) + break; //Error check + displayContent[x] = displayContent[x + shiftAmt]; + } - //Clear the trailing characters - for (int x = 0; x < shiftAmt; x++) - { - if (4 * numberOfDisplays - 1 - x < 0) - break; //Error check + //Clear the trailing characters + for (int x = 0; x < shiftAmt; x++) + { + if (4 * numberOfDisplays - 1 - x < 0) + break; //Error check - displayContent[4 * numberOfDisplays - 1 - x] = ' '; - } + displayContent[4 * numberOfDisplays - 1 - x] = ' '; + } - return (print(displayContent)); + return (print(displayContent)); } /*----------------------- Internal I2C Abstraction -----------------------------*/ bool HT16K33::readRAM(uint8_t address, uint8_t reg, uint8_t *buff, uint8_t buffSize) { - uint8_t displayNum = 0; - if (address == _deviceAddressLeftCenter) - displayNum = 1; - else if (address == _deviceAddressRightCenter) - displayNum = 2; - else if (address == _deviceAddressRight) - displayNum = 3; - isConnected(displayNum); //Wait until display is ready - - _i2cPort->beginTransmission(address); - _i2cPort->write(reg); - _i2cPort->endTransmission(false); - - if (_i2cPort->requestFrom(address, buffSize) > 0) - { - for (uint8_t i = 0; i < buffSize; i++) - buff[i] = _i2cPort->read(); - return true; - } + uint8_t displayNum = 0; + if (address == _deviceAddressLeftCenter) + displayNum = 1; + else if (address == _deviceAddressRightCenter) + displayNum = 2; + else if (address == _deviceAddressRight) + displayNum = 3; + isConnected(displayNum); //Wait until display is ready + + _i2cPort->beginTransmission(address); + _i2cPort->write(reg); + _i2cPort->endTransmission(false); + + if (_i2cPort->requestFrom(address, buffSize) > 0) + { + for (uint8_t i = 0; i < buffSize; i++) + buff[i] = _i2cPort->read(); + return true; + } - return false; + return false; } // //Overloaded function declaration // //Use when reading just one byte of data // bool HT16K33::read(uint8_t reg, uint8_t data) // { -// return (read(reg, (uint8_t *)&data, (uint8_t)sizeof(data))); +// return (read(reg, (uint8_t *)&data, (uint8_t)sizeof(data))); // } //Write the contents of the RAM array out to the Holtek IC //After much testing, it bool HT16K33::writeRAM(uint8_t address, uint8_t reg, uint8_t *buff, uint8_t buffSize) { - uint8_t displayNum = 0; - if (address == _deviceAddressLeftCenter) - displayNum = 1; - else if (address == _deviceAddressRightCenter) - displayNum = 2; - else if (address == _deviceAddressRight) - displayNum = 3; - //isConnected(displayNum); //Wait until display is ready + uint8_t displayNum = 0; + if (address == _deviceAddressLeftCenter) + displayNum = 1; + else if (address == _deviceAddressRightCenter) + displayNum = 2; + else if (address == _deviceAddressRight) + displayNum = 3; + //isConnected(displayNum); //Wait until display is ready - _i2cPort->beginTransmission(address); - _i2cPort->write(reg); + _i2cPort->beginTransmission(address); + _i2cPort->write(reg); - for (uint8_t i = 0; i < buffSize; i++) - _i2cPort->write(buff[i]); + for (uint8_t i = 0; i < buffSize; i++) + _i2cPort->write(buff[i]); - if (_i2cPort->endTransmission() == 0) - return true; + if (_i2cPort->endTransmission() == 0) + return true; - return false; + return false; } //Write a single byte to the display. This is often a command byte. //The address of the data to write is contained in the first four bits of dataToWrite bool HT16K33::writeRAM(uint8_t address, uint8_t dataToWrite) { - uint8_t temp = 0; - return (writeRAM(address, dataToWrite, (uint8_t *)&temp, 0)); + uint8_t temp = 0; + return (writeRAM(address, dataToWrite, (uint8_t *)&temp, 0)); } From f8c3682477aeb31d333ecc5896e443841b3b3b92 Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Sun, 3 May 2020 15:11:26 -0400 Subject: [PATCH 10/12] Revert "Updated comment" This reverts commit 83a71a2a8473c145431708864b4ce1263d7244e4. --- src/SparkFun_Alphanumeric_Display.cpp | 1138 ++++++++++++------------- 1 file changed, 569 insertions(+), 569 deletions(-) diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index 6cb11c2..4878a08 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -19,9 +19,9 @@ the ADR1/ADR0 pins the address has been seen to change. The best way around this to do a isConnected check before updateRAM() is sent to the driver IC. Development environment specifics: - IDE: Arduino 1.8.9 - Hardware Platform: Arduino Uno - Alphanumeric Display Breakout Version: 1.0.0 + IDE: Arduino 1.8.9 + Hardware Platform: Arduino Uno + Alphanumeric Display Breakout Version: 1.0.0 This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! @@ -37,103 +37,103 @@ Distributed as-is; no warranty is given. //This is the lookup table of segments for various characters static const uint16_t PROGMEM alphanumeric_segs[96]{ - //nmlkjihgfedcba - 0b00000000000000, //' ' (space) - 0b00001000001000, //'!' - added to map - 0b00001000000010, //'"' - added to map - 0b1001101001110, //'#' - 0b1001101101101, //'$' - 0b10010000100100, //'%' - 0b110011011001, //'&' - 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' - 0b11111010000000, //'*' - 0b1001101000000, //'+' - 0b10000000000000, //',' - 0b101000000, //'-' - 0b00000000000000, //'.' - changed to blank - 0b10010000000000, //'/' - 0b111111, //'0' - 0b10000000110, //'1' - 0b101011011, //'2' - 0b101001111, //'3' - 0b101100110, //'4' - 0b101101101, //'5' - 0b101111101, //'6' - 0b1010000000001, //'7' - 0b101111111, //'8' - 0b101100111, //'9' - 0b00000000000000, //':' - changed to blank - 0b10001000000000, //';' - 0b110000000000, //'<' - 0b101001000, //'=' - 0b01000010000000, //'>' + //nmlkjihgfedcba + 0b00000000000000, //' ' (space) + 0b00001000001000, //'!' - added to map + 0b00001000000010, //'"' - added to map + 0b1001101001110, //'#' + 0b1001101101101, //'$' + 0b10010000100100, //'%' + 0b110011011001, //'&' + 0b1000000000, //''' + 0b111001, //'(' + 0b1111, //')' + 0b11111010000000, //'*' + 0b1001101000000, //'+' + 0b10000000000000, //',' + 0b101000000, //'-' + 0b00000000000000, //'.' - changed to blank + 0b10010000000000, //'/' + 0b111111, //'0' + 0b10000000110, //'1' + 0b101011011, //'2' + 0b101001111, //'3' + 0b101100110, //'4' + 0b101101101, //'5' + 0b101111101, //'6' + 0b1010000000001, //'7' + 0b101111111, //'8' + 0b101100111, //'9' + 0b00000000000000, //':' - changed to blank + 0b10001000000000, //';' + 0b110000000000, //'<' + 0b101001000, //'=' + 0b01000010000000, //'>' 0b01000100000011, //'?' - Added to map - 0b00001100111011, //'@' - Added to map - 0b101110111, //'A' - 0b1001100001111, //'B' - 0b111001, //'C' - 0b1001000001111, //'D' - 0b101111001, //'E' - 0b101110001, //'F' - 0b100111101, //'G' - 0b101110110, //'H' - 0b1001000001001, //'I' - 0b11110, //'J' - 0b110001110000, //'K' - 0b111000, //'L' - 0b10010110110, //'M' - 0b100010110110, //'N' - 0b111111, //'O' - 0b101110011, //'P' - 0b100000111111, //'Q' - 0b100101110011, //'R' - 0b110001101, //'S' - 0b1001000000001, //'T' - 0b111110, //'U' - 0b10010000110000, //'V' - 0b10100000110110, //'W' - 0b10110010000000, //'X' - 0b1010010000000, //'Y' - 0b10010000001001, //'Z' - 0b111001, //'[' - 0b100010000000, //'\' - 0b1111, //']' + 0b00001100111011, //'@' - Added to map + 0b101110111, //'A' + 0b1001100001111, //'B' + 0b111001, //'C' + 0b1001000001111, //'D' + 0b101111001, //'E' + 0b101110001, //'F' + 0b100111101, //'G' + 0b101110110, //'H' + 0b1001000001001, //'I' + 0b11110, //'J' + 0b110001110000, //'K' + 0b111000, //'L' + 0b10010110110, //'M' + 0b100010110110, //'N' + 0b111111, //'O' + 0b101110011, //'P' + 0b100000111111, //'Q' + 0b100101110011, //'R' + 0b110001101, //'S' + 0b1001000000001, //'T' + 0b111110, //'U' + 0b10010000110000, //'V' + 0b10100000110110, //'W' + 0b10110010000000, //'X' + 0b1010010000000, //'Y' + 0b10010000001001, //'Z' + 0b111001, //'[' + 0b100010000000, //'\' + 0b1111, //']' 0b10100000000000, //'^' - Added to map - 0b1000, //'_' - 0b10000000, //'`' - 0b101011111, //'a' - 0b100001111000, //'b' - 0b101011000, //'c' - 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' - 0b110001111, //'g' - 0b101110100, //'h' - 0b1000000000000, //'i' - 0b1110, //'j' - 0b1111000000000, //'k' - 0b1001000000000, //'l' - 0b1000101010100, //'m' - 0b100001010000, //'n' - 0b101011100, //'o' - 0b10001110001, //'p' - 0b100101100011, //'q' - 0b1010000, //'r' - 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' - 0b10000000010000, //'v' - 0b10100000010100, //'w' - 0b10110010000000, //'x' - 0b1100001110, //'y' - 0b10010000001001, //'z' - 0b10000011001001, //'{' - 0b1001000000000, //'|' - 0b110100001001, //'}' - 0b00000101010010, //'~' - Added to map - 0b11111111111111, //Unknown character (DEL or RUBOUT) + 0b1000, //'_' + 0b10000000, //'`' + 0b101011111, //'a' + 0b100001111000, //'b' + 0b101011000, //'c' + 0b10000100001110, //'d' + 0b1111001, //'e' + 0b1110001, //'f' + 0b110001111, //'g' + 0b101110100, //'h' + 0b1000000000000, //'i' + 0b1110, //'j' + 0b1111000000000, //'k' + 0b1001000000000, //'l' + 0b1000101010100, //'m' + 0b100001010000, //'n' + 0b101011100, //'o' + 0b10001110001, //'p' + 0b100101100011, //'q' + 0b1010000, //'r' + 0b110001101, //'s' + 0b1111000, //'t' + 0b11100, //'u' + 0b10000000010000, //'v' + 0b10100000010100, //'w' + 0b10110010000000, //'x' + 0b1100001110, //'y' + 0b10010000001001, //'z' + 0b10000011001001, //'{' + 0b1001000000000, //'|' + 0b110100001001, //'}' + 0b00000101010010, //'~' - Added to map + 0b11111111111111, //Unknown character (DEL or RUBOUT) }; /*--------------------------- Device Status----------------------------------*/ @@ -141,229 +141,229 @@ static const uint16_t PROGMEM alphanumeric_segs[96]{ bool HT16K33::begin(uint8_t addressLeft, uint8_t addressLeftCenter, uint8_t addressRightCenter, uint8_t addressRight, TwoWire &wirePort) { - _deviceAddressLeft = addressLeft; //grab the address of the alphanumeric - _deviceAddressLeftCenter = addressLeftCenter; //grab the address of the alphanumeric - _deviceAddressRightCenter = addressRightCenter; //grab the address of the alphanumeric - _deviceAddressRight = addressRight; //grab the address of the alphanumeric - - if (_deviceAddressRight != DEFAULT_NOTHING_ATTACHED) - numberOfDisplays = 4; - else if (_deviceAddressRightCenter != DEFAULT_NOTHING_ATTACHED) - numberOfDisplays = 3; - else if (_deviceAddressLeftCenter != DEFAULT_NOTHING_ATTACHED) - numberOfDisplays = 2; - else - numberOfDisplays = 1; - - //TODO: malloc more displayRAM - - _i2cPort = &wirePort; //Remember the user's setting - - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (isConnected(i) == false) - { - //Serial.println("Failed isConnected()"); - return false; - } - // if (checkDeviceID(i) == false) - // { - // Serial.println(i); - // Serial.println("Hello, I've failed checkDeviceID()"); - // return false; - // } - } - - if (initialize() == false) - { - //Serial.println("Failed initialize()"); - return false; - } - - if (clear() == false) //Clear all displays - { - //Serial.println("Failed clear()"); - return false; - } - - displayContent[4 * 4] = '\0'; //Terminate the array because we are doing direct prints - - return true; + _deviceAddressLeft = addressLeft; //grab the address of the alphanumeric + _deviceAddressLeftCenter = addressLeftCenter; //grab the address of the alphanumeric + _deviceAddressRightCenter = addressRightCenter; //grab the address of the alphanumeric + _deviceAddressRight = addressRight; //grab the address of the alphanumeric + + if (_deviceAddressRight != DEFAULT_NOTHING_ATTACHED) + numberOfDisplays = 4; + else if (_deviceAddressRightCenter != DEFAULT_NOTHING_ATTACHED) + numberOfDisplays = 3; + else if (_deviceAddressLeftCenter != DEFAULT_NOTHING_ATTACHED) + numberOfDisplays = 2; + else + numberOfDisplays = 1; + + //TODO: malloc more displayRAM + + _i2cPort = &wirePort; //Remember the user's setting + + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (isConnected(i) == false) + { + //Serial.println("Failed isConnected()"); + return false; + } + // if (checkDeviceID(i) == false) + // { + // Serial.println(i); + // Serial.println("Hello, I've failed checkDeviceID()"); + // return false; + // } + } + + if (initialize() == false) + { + //Serial.println("Failed initialize()"); + return false; + } + + if (clear() == false) //Clear all displays + { + //Serial.println("Failed clear()"); + return false; + } + + displayContent[4 * 4] = '\0'; //Terminate the array because we are doing direct prints + + return true; } //Check that all displays are responding //The Holtek IC sometimes fails to respond. This attempts multiple times before giving up. bool HT16K33::isConnected(uint8_t displayNumber) { - uint8_t triesBeforeGiveup = 20; - - for (uint8_t x = 0; x < triesBeforeGiveup; x++) - { - _i2cPort->beginTransmission(lookUpDisplayAddress(displayNumber)); - if (_i2cPort->endTransmission() == 0) - { - // if (x > 0) - // { - // Serial.print("isConnect successful"); - // Serial.print(" after "); - // Serial.print(x); - // Serial.print(" tries"); - // Serial.println(); - // } - return true; - } - - delay(1); - } - return false; + uint8_t triesBeforeGiveup = 20; + + for (uint8_t x = 0; x < triesBeforeGiveup; x++) + { + _i2cPort->beginTransmission(lookUpDisplayAddress(displayNumber)); + if (_i2cPort->endTransmission() == 0) + { + // if (x > 0) + // { + // Serial.print("isConnect successful"); + // Serial.print(" after "); + // Serial.print(x); + // Serial.print(" tries"); + // Serial.println(); + // } + return true; + } + + delay(1); + } + return false; } bool HT16K33::initialize() { - //Turn on system clock of all displays - if (enableSystemClock() == false) - { - //Serial.println("Init: Failed enableSystemClock()"); - return false; - } - - //Set brightness of all displays to full brightness - if (setBrightness(16) == false) - { - //Serial.println("Init: Failed setBrightness()"); - return false; - } - - //Blinking set - blinking off - if (setBlinkRate(ALPHA_BLINK_RATE_NOBLINK) == false) - { - //Serial.println("Init: Failed setBlinkRate()"); - return false; - } - - //Turn on all displays - if (displayOn() == false) - { - //Serial.println("Init: Failed display on"); - return false; - } - - return true; + //Turn on system clock of all displays + if (enableSystemClock() == false) + { + //Serial.println("Init: Failed enableSystemClock()"); + return false; + } + + //Set brightness of all displays to full brightness + if (setBrightness(16) == false) + { + //Serial.println("Init: Failed setBrightness()"); + return false; + } + + //Blinking set - blinking off + if (setBlinkRate(ALPHA_BLINK_RATE_NOBLINK) == false) + { + //Serial.println("Init: Failed setBlinkRate()"); + return false; + } + + //Turn on all displays + if (displayOn() == false) + { + //Serial.println("Init: Failed display on"); + return false; + } + + return true; } // //Verify that all objects on I2C bus are alphanumeric displays // bool HT16K33::checkDeviceID(uint8_t displayNumber) // { -// uint8_t address = lookUpDisplayAddress(displayNumber); -// uint8_t test = 0xAA; -// uint8_t temp; -// //Turn off display - DEBUG: should it be ALL or ONE? -// singleDisplayOff(displayNumber); -// //Write 0xAA to register 0 -// writeRAM(address, 0, (uint8_t *)&test, 1); -// //Read it back, it should be 0xAA -// readRAM(address, 0, (uint8_t *)&temp, sizeof((uint8_t)temp)); -// if (temp != test) -// return false; -// //DEBUGGING: taking this out for now... can't call this write to ALL displays when we haven't initalized all displays yet! -// //Clear the write we just did -// // clear(); -// //Turn display back on -// singleDisplayOn(displayNumber); -// return true; +// uint8_t address = lookUpDisplayAddress(displayNumber); +// uint8_t test = 0xAA; +// uint8_t temp; +// //Turn off display - DEBUG: should it be ALL or ONE? +// singleDisplayOff(displayNumber); +// //Write 0xAA to register 0 +// writeRAM(address, 0, (uint8_t *)&test, 1); +// //Read it back, it should be 0xAA +// readRAM(address, 0, (uint8_t *)&temp, sizeof((uint8_t)temp)); +// if (temp != test) +// return false; +// //DEBUGGING: taking this out for now... can't call this write to ALL displays when we haven't initalized all displays yet! +// //Clear the write we just did +// // clear(); +// //Turn display back on +// singleDisplayOn(displayNumber); +// return true; // } bool HT16K33::enableSystemClock() { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (enableSystemClockSingle(i) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (enableSystemClockSingle(i) == false) + status = false; + } + return status; } bool HT16K33::disableSystemClock() { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (enableSystemClockSingle(i) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (enableSystemClockSingle(i) == false) + status = false; + } + return status; } bool HT16K33::enableSystemClockSingle(uint8_t displayNumber) { - uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 1; //Enable system clock + uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 1; //Enable system clock - bool status = writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite); - delay(1); //Allow display to start - return (status); + bool status = writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite); + delay(1); //Allow display to start + return (status); } bool HT16K33::disableSystemClockSingle(uint8_t displayNumber) { - uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 0; //Standby mode + uint8_t dataToWrite = ALPHA_CMD_SYSTEM_SETUP | 0; //Standby mode - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } uint8_t HT16K33::lookUpDisplayAddress(uint8_t displayNumber) { - switch (displayNumber) - { - case 0: - return _deviceAddressLeft; - break; - case 1: - return _deviceAddressLeftCenter; - break; - case 2: - return _deviceAddressRightCenter; - break; - case 3: - return _deviceAddressRight; - break; - } - - return 0; //We shouldn't get here + switch (displayNumber) + { + case 0: + return _deviceAddressLeft; + break; + case 1: + return _deviceAddressLeftCenter; + break; + case 2: + return _deviceAddressRightCenter; + break; + case 3: + return _deviceAddressRight; + break; + } + + return 0; //We shouldn't get here } /*-------------------------- Display configuration functions ---------------------------*/ bool HT16K33::clear() { - //Clear the displayRAM array - for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) - displayRAM[i] = 0; + //Clear the displayRAM array + for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) + displayRAM[i] = 0; - digitPosition = 0; + digitPosition = 0; - return (updateDisplay()); + return (updateDisplay()); } //Duty valid between 1 and 16 bool HT16K33::setBrightness(uint8_t duty) { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (setBrightnessSingle(i, duty) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (setBrightnessSingle(i, duty) == false) + status = false; + } + return status; } bool HT16K33::setBrightnessSingle(uint8_t displayNumber, uint8_t duty) { - if (duty > 15) - duty = 15; //Error check + if (duty > 15) + duty = 15; //Error check - uint8_t dataToWrite = ALPHA_CMD_DIMMING_SETUP | duty; - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + uint8_t dataToWrite = ALPHA_CMD_DIMMING_SETUP | duty; + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } //Parameter "rate" in Hz @@ -371,208 +371,208 @@ bool HT16K33::setBrightnessSingle(uint8_t displayNumber, uint8_t duty) //Any other input to this function will result in steady alphanumeric display bool HT16K33::setBlinkRate(float rate) { - bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (setBlinkRateSingle(i, rate) == false) - status = false; - } - return status; + bool status = true; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (setBlinkRateSingle(i, rate) == false) + status = false; + } + return status; } bool HT16K33::setBlinkRateSingle(uint8_t displayNumber, float rate) { - if (rate == 2) - { - blinkRate = ALPHA_BLINK_RATE_2HZ; - } - else if (rate == 1) - { - blinkRate = ALPHA_BLINK_RATE_1HZ; - } - else if (rate == 0.5) - { - blinkRate = ALPHA_BLINK_RATE_0_5HZ; - } - //default to no blink - else - { - blinkRate = ALPHA_BLINK_RATE_NOBLINK; - } - - uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + if (rate == 2) + { + blinkRate = ALPHA_BLINK_RATE_2HZ; + } + else if (rate == 1) + { + blinkRate = ALPHA_BLINK_RATE_1HZ; + } + else if (rate == 0.5) + { + blinkRate = ALPHA_BLINK_RATE_0_5HZ; + } + //default to no blink + else + { + blinkRate = ALPHA_BLINK_RATE_NOBLINK; + } + + uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } bool HT16K33::displayOnSingle(uint8_t displayNumber) { - return setDisplayOnOff(displayNumber, true); + return setDisplayOnOff(displayNumber, true); } bool HT16K33::displayOffSingle(uint8_t displayNumber) { - return setDisplayOnOff(displayNumber, false); + return setDisplayOnOff(displayNumber, false); } //Set or clear the display on/off bit of a given display number bool HT16K33::setDisplayOnOff(uint8_t displayNumber, bool turnOnDisplay) { - if (turnOnDisplay == true) - displayOnOff = ALPHA_DISPLAY_ON; - else - displayOnOff = ALPHA_DISPLAY_OFF; + if (turnOnDisplay == true) + displayOnOff = ALPHA_DISPLAY_ON; + else + displayOnOff = ALPHA_DISPLAY_OFF; - uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; - return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); + uint8_t dataToWrite = ALPHA_CMD_DISPLAY_SETUP | (blinkRate << 1) | displayOnOff; + return (writeRAM(lookUpDisplayAddress(displayNumber), dataToWrite)); } //Turn on/off the entire display bool HT16K33::displayOn() { - bool status = true; + bool status = true; - displayOnOff = ALPHA_DISPLAY_ON; + displayOnOff = ALPHA_DISPLAY_ON; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (displayOnSingle(i) == false) - status = false; - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (displayOnSingle(i) == false) + status = false; + } - return status; + return status; } bool HT16K33::displayOff() { - bool status = true; + bool status = true; - displayOnOff = ALPHA_DISPLAY_OFF; + displayOnOff = ALPHA_DISPLAY_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (displayOffSingle(i) == false) - status = false; - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (displayOffSingle(i) == false) + status = false; + } - return status; + return status; } bool HT16K33::decimalOnSingle(uint8_t displayNumber) { - return setDecimalOnOff(displayNumber, true); + return setDecimalOnOff(displayNumber, true); } bool HT16K33::decimalOffSingle(uint8_t displayNumber) { - return setDecimalOnOff(displayNumber, false); + return setDecimalOnOff(displayNumber, false); } bool HT16K33::setDecimalOnOff(uint8_t displayNumber, bool turnOnDecimal) { - uint8_t adr = 0x03; - uint8_t dat; + uint8_t adr = 0x03; + uint8_t dat; - if (turnOnDecimal == true) - { - decimalOnOff = ALPHA_DECIMAL_ON; - dat = 0x01; - } - else - { - decimalOnOff = ALPHA_DECIMAL_OFF; - dat = 0x00; - } + if (turnOnDecimal == true) + { + decimalOnOff = ALPHA_DECIMAL_ON; + dat = 0x01; + } + else + { + decimalOnOff = ALPHA_DECIMAL_OFF; + dat = 0x00; + } - displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; - updateDisplay(); + displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; + updateDisplay(); } //Turn on/off the entire display bool HT16K33::decimalOn() { - bool status = true; + bool status = true; - decimalOnOff = ALPHA_DECIMAL_ON; + decimalOnOff = ALPHA_DECIMAL_ON; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (decimalOnSingle(i) == false) - status = false; - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (decimalOnSingle(i) == false) + status = false; + } - //Serial.println(status); - return status; + //Serial.println(status); + return status; } bool HT16K33::decimalOff() { - bool status = true; + bool status = true; - decimalOnOff = ALPHA_DECIMAL_OFF; + decimalOnOff = ALPHA_DECIMAL_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (decimalOffSingle(i) == false) - status = false; - } - return status; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (decimalOffSingle(i) == false) + status = false; + } + return status; } bool HT16K33::colonOnSingle(uint8_t displayNumber) { - return setColonOnOff(displayNumber, true); + return setColonOnOff(displayNumber, true); } bool HT16K33::colonOffSingle(uint8_t displayNumber) { - return setColonOnOff(displayNumber, false); + return setColonOnOff(displayNumber, false); } bool HT16K33::setColonOnOff(uint8_t displayNumber, bool turnOnColon) { - uint8_t adr = 0x01; - uint8_t dat; + uint8_t adr = 0x01; + uint8_t dat; - if (turnOnColon == true) - { - colonOnOff = ALPHA_COLON_ON; - dat = 0x01; - } - else - { - colonOnOff = ALPHA_COLON_OFF; - dat = 0x00; - } + if (turnOnColon == true) + { + colonOnOff = ALPHA_COLON_ON; + dat = 0x01; + } + else + { + colonOnOff = ALPHA_COLON_OFF; + dat = 0x00; + } - displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; - updateDisplay(); + displayRAM[adr + displayNumber * 16] = displayRAM[adr + displayNumber * 16] | dat; + updateDisplay(); } bool HT16K33::colonOn() { - bool status = true; + bool status = true; - colonOnOff = ALPHA_COLON_ON; + colonOnOff = ALPHA_COLON_ON; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (colonOnSingle(i) == false) - status = false; - } - return status; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (colonOnSingle(i) == false) + status = false; + } + return status; } bool HT16K33::colonOff() { - bool status = true; + bool status = true; - colonOnOff = ALPHA_COLON_OFF; + colonOnOff = ALPHA_COLON_OFF; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (colonOffSingle(i) == false) - status = false; - } - return status; + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (colonOffSingle(i) == false) + status = false; + } + return status; } /*---------------------------- Light up functions ---------------------------------*/ @@ -580,108 +580,108 @@ bool HT16K33::colonOff() //Given a segment and a digit, set the matching bit within the RAM of the Holtek RAM set void HT16K33::illuminateSegment(uint8_t segment, uint8_t digit) { - uint8_t com; - uint8_t row; + uint8_t com; + uint8_t row; - com = segment - 'A'; //Convert the segment letter back to a number + com = segment - 'A'; //Convert the segment letter back to a number - if (com > 6) - com -= 7; - if (segment == 'I') - com = 0; - if (segment == 'H') - com = 1; + if (com > 6) + com -= 7; + if (segment == 'I') + com = 0; + if (segment == 'H') + com = 1; - row = digit % 4; //Convert digit (1 to 16) back to a relative position on a given display - if (segment > 'G') - row += 4; + row = digit % 4; //Convert digit (1 to 16) back to a relative position on a given display + if (segment > 'G') + row += 4; - uint8_t offset = digit / 4 * 16; - uint8_t adr = com * 2 + offset; + uint8_t offset = digit / 4 * 16; + uint8_t adr = com * 2 + offset; - //Determine the address - if (row > 7) - adr++; + //Determine the address + if (row > 7) + adr++; - //Determine the data bit - if (row > 7) - row -= 8; - uint8_t dat = 1 << row; + //Determine the data bit + if (row > 7) + row -= 8; + uint8_t dat = 1 << row; - //Temp DEBUGGING - clear segments that might affect A0/A1 - //dat &= 0b11111100; + //Temp DEBUGGING - clear segments that might affect A0/A1 + //dat &= 0b11111100; - // Serial.print("illSeg Digit: "); - // Serial.print(digit); - // Serial.print("\t row: "); - // Serial.print(row); - // Serial.print("\t com: "); - // Serial.print(com); - // Serial.print("\t adr: "); - // Serial.print(adr); - // Serial.println(); + // Serial.print("illSeg Digit: "); + // Serial.print(digit); + // Serial.print("\t row: "); + // Serial.print(row); + // Serial.print("\t com: "); + // Serial.print(com); + // Serial.print("\t adr: "); + // Serial.print(adr); + // Serial.println(); - displayRAM[adr] = displayRAM[adr] | dat; + displayRAM[adr] = displayRAM[adr] | dat; } //Given a binary set of segments and a digit, store this data into the RAM array void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) { - for (uint8_t i = 0; i < 14; i++) //There are 14 segments on this display - { - if ((segmentsToTurnOn >> i) & 0b1) - illuminateSegment('A' + i, digit); //Convert the segment number to a letter - } + for (uint8_t i = 0; i < 14; i++) //There are 14 segments on this display + { + if ((segmentsToTurnOn >> i) & 0b1) + illuminateSegment('A' + i, digit); //Convert the segment number to a letter + } } //Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { - //moved alphanumeric_segs array outside of function to PROGMEM - uint16_t characterPosition = 65532; + //moved alphanumeric_segs array outside of function + uint16_t characterPosition = 65532; - //space - if (displayChar == ' ') - characterPosition = 0; - //Printable Symbols - else if (displayChar >= '!' && displayChar <= '~') - { - characterPosition = displayChar - '!' + 1; - } + //space + if (displayChar == ' ') + characterPosition = 0; + //Printable Symbols + else if (displayChar >= '!' && displayChar <= '~') + { + characterPosition = displayChar - '!' + 1; + } - uint8_t dispNum = digitPosition / 4; - //Take care of special characters - if (characterPosition == 14) //'.' - decimalOnSingle(dispNum); - if (characterPosition == 26) //':' - colonOnSingle(dispNum); - if (characterPosition == 65532) //unknown character - characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; + uint8_t dispNum = digitPosition / 4; + //Take care of special characters + if (characterPosition == 14) //'.' + decimalOnSingle(dispNum); + if (characterPosition == 26) //':' + colonOnSingle(dispNum); + if (characterPosition == 65532) //unknown character + characterPosition = SFE_ALPHANUM_UNKNOWN_CHAR; - // //Error check - // if (characterPosition > sizeof(alphanumeric_segs)) - // characterPosition = sizeof(alphanumeric_segs) - 1; //Unknown char + // //Error check + // if (characterPosition > sizeof(alphanumeric_segs)) + // characterPosition = sizeof(alphanumeric_segs) - 1; //Unknown char - uint16_t segmentsToTurnOn = getSegmentsToTurnOn(characterPosition); + uint16_t segmentsToTurnOn = getSegmentsToTurnOn(characterPosition); - illuminateChar(segmentsToTurnOn, digit); + illuminateChar(segmentsToTurnOn, digit); } //Update the list to define a new segments display for a particular character bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) { - bool result = false; + bool result = false; - //Check to see if character is within range of displayable ASCII characters - if (displayChar >= '!' && displayChar <= '~') - { - //Get the index of character in table and update its 14-bit segment value - uint16_t characterPosition = displayChar - '!' + 1; + //Check to see if character is within range of displayable ASCII characters + if (displayChar >= '!' && displayChar <= '~') + { + //Get the index of character in table and update its 14-bit segment value + uint16_t characterPosition = displayChar - '!' + 1; //Create a new character definition struct CharDef * pNewCharDef = calloc(1, sizeof(CharDef)); - //Set the position to the table index + //Set the position to the table index pNewCharDef -> position = characterPosition; //Mask the segment value to 14 bits only pNewCharDef -> segments = segmentsToTurnOn & 0x3FFF; @@ -691,7 +691,7 @@ bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) //If list is empty set it to the new item if (pCharDefList == NULL) { - pCharDefList = pNewCharDef; + pCharDefList = pNewCharDef; } else { @@ -705,8 +705,8 @@ bool HT16K33::defineChar(uint8_t displayChar, uint16_t segmentsToTurnOn) pTail->next = pNewCharDef; } - //We added the definition so we're all good - result = true; + //We added the definition so we're all good + result = true; } return result; } @@ -743,16 +743,16 @@ uint16_t HT16K33::getSegmentsToTurnOn(uint8_t charPos) */ size_t HT16K33::write(uint8_t b) { - //If user wants to print '.' or ':', don't increment the digitPosition! - if (b == '.' | b == ':') - printChar(b, 0); - else - { - printChar(b, digitPosition++); - digitPosition %= (numberOfDisplays * 4); //Convert displays to number of digits - } + //If user wants to print '.' or ':', don't increment the digitPosition! + if (b == '.' | b == ':') + printChar(b, 0); + else + { + printChar(b, digitPosition++); + digitPosition %= (numberOfDisplays * 4); //Convert displays to number of digits + } - return (updateDisplay()); //Send RAM buffer over I2C bus + return (updateDisplay()); //Send RAM buffer over I2C bus } /* @@ -761,171 +761,171 @@ size_t HT16K33::write(uint8_t b) */ size_t HT16K33::write(const uint8_t *buffer, size_t size) { - size_t n = size; - uint8_t buff; - - //Clear the displayRAM array - for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) - displayRAM[i] = 0; - - digitPosition = 0; - - while (size--) - { - buff = *buffer++; - //For special characters like '.' or ':', do not increment the digitPosition - if (buff == '.') - printChar('.', 0); - else if (buff == ':') - printChar(':', 0); - else - { - printChar(buff, digitPosition); - displayContent[digitPosition] = buff; //Record to internal array - - digitPosition++; - digitPosition %= (numberOfDisplays * 4); - } - } + size_t n = size; + uint8_t buff; + + //Clear the displayRAM array + for (uint8_t i = 0; i < 16 * numberOfDisplays; i++) + displayRAM[i] = 0; + + digitPosition = 0; + + while (size--) + { + buff = *buffer++; + //For special characters like '.' or ':', do not increment the digitPosition + if (buff == '.') + printChar('.', 0); + else if (buff == ':') + printChar(':', 0); + else + { + printChar(buff, digitPosition); + displayContent[digitPosition] = buff; //Record to internal array - updateDisplay(); //Send RAM buffer over I2C bus + digitPosition++; + digitPosition %= (numberOfDisplays * 4); + } + } - return n; + updateDisplay(); //Send RAM buffer over I2C bus + + return n; } //Write a string to the display size_t HT16K33::write(const char *str) { - if (str == NULL) - return 0; - return write((const uint8_t *)str, strlen(str)); + if (str == NULL) + return 0; + return write((const uint8_t *)str, strlen(str)); } //Push the contents of displayRAM out to the various displays in 16 byte chunks bool HT16K33::updateDisplay() { - //printRAM(); + //printRAM(); - bool status = true; + bool status = true; - for (uint8_t i = 0; i < numberOfDisplays; i++) - { - if (writeRAM(lookUpDisplayAddress(i), 0, (uint8_t *)(displayRAM + (i * 16)), 16) == false) - { - //Serial.print("updateDisplay fail at display 0x"); - //Serial.println(lookUpDisplayAddress(i), HEX); - status = false; - } - } + for (uint8_t i = 0; i < numberOfDisplays; i++) + { + if (writeRAM(lookUpDisplayAddress(i), 0, (uint8_t *)(displayRAM + (i * 16)), 16) == false) + { + //Serial.print("updateDisplay fail at display 0x"); + //Serial.println(lookUpDisplayAddress(i), HEX); + status = false; + } + } - return status; + return status; } //Shift the display content to the right one digit bool HT16K33::shiftRight(uint8_t shiftAmt) { - for (uint8_t x = (4 * numberOfDisplays) - shiftAmt; x >= shiftAmt; x--) - { - displayContent[x] = displayContent[x - shiftAmt]; - } + for (uint8_t x = (4 * numberOfDisplays) - shiftAmt; x >= shiftAmt; x--) + { + displayContent[x] = displayContent[x - shiftAmt]; + } - //Clear the leading characters - for (uint8_t x = 0; x < shiftAmt; x++) - { - if (x + shiftAmt > (4 * numberOfDisplays)) - break; //Error check + //Clear the leading characters + for (uint8_t x = 0; x < shiftAmt; x++) + { + if (x + shiftAmt > (4 * numberOfDisplays)) + break; //Error check - displayContent[0 + x] = ' '; - } + displayContent[0 + x] = ' '; + } - return (print(displayContent)); + return (print(displayContent)); } //Shift the display content to the left one digit bool HT16K33::shiftLeft(uint8_t shiftAmt) { - for (int x = 0; x < 4 * numberOfDisplays; x++) - { - if (x + shiftAmt > (4 * numberOfDisplays)) - break; //Error check - displayContent[x] = displayContent[x + shiftAmt]; - } + for (int x = 0; x < 4 * numberOfDisplays; x++) + { + if (x + shiftAmt > (4 * numberOfDisplays)) + break; //Error check + displayContent[x] = displayContent[x + shiftAmt]; + } - //Clear the trailing characters - for (int x = 0; x < shiftAmt; x++) - { - if (4 * numberOfDisplays - 1 - x < 0) - break; //Error check + //Clear the trailing characters + for (int x = 0; x < shiftAmt; x++) + { + if (4 * numberOfDisplays - 1 - x < 0) + break; //Error check - displayContent[4 * numberOfDisplays - 1 - x] = ' '; - } + displayContent[4 * numberOfDisplays - 1 - x] = ' '; + } - return (print(displayContent)); + return (print(displayContent)); } /*----------------------- Internal I2C Abstraction -----------------------------*/ bool HT16K33::readRAM(uint8_t address, uint8_t reg, uint8_t *buff, uint8_t buffSize) { - uint8_t displayNum = 0; - if (address == _deviceAddressLeftCenter) - displayNum = 1; - else if (address == _deviceAddressRightCenter) - displayNum = 2; - else if (address == _deviceAddressRight) - displayNum = 3; - isConnected(displayNum); //Wait until display is ready - - _i2cPort->beginTransmission(address); - _i2cPort->write(reg); - _i2cPort->endTransmission(false); - - if (_i2cPort->requestFrom(address, buffSize) > 0) - { - for (uint8_t i = 0; i < buffSize; i++) - buff[i] = _i2cPort->read(); - return true; - } + uint8_t displayNum = 0; + if (address == _deviceAddressLeftCenter) + displayNum = 1; + else if (address == _deviceAddressRightCenter) + displayNum = 2; + else if (address == _deviceAddressRight) + displayNum = 3; + isConnected(displayNum); //Wait until display is ready + + _i2cPort->beginTransmission(address); + _i2cPort->write(reg); + _i2cPort->endTransmission(false); + + if (_i2cPort->requestFrom(address, buffSize) > 0) + { + for (uint8_t i = 0; i < buffSize; i++) + buff[i] = _i2cPort->read(); + return true; + } - return false; + return false; } // //Overloaded function declaration // //Use when reading just one byte of data // bool HT16K33::read(uint8_t reg, uint8_t data) // { -// return (read(reg, (uint8_t *)&data, (uint8_t)sizeof(data))); +// return (read(reg, (uint8_t *)&data, (uint8_t)sizeof(data))); // } //Write the contents of the RAM array out to the Holtek IC //After much testing, it bool HT16K33::writeRAM(uint8_t address, uint8_t reg, uint8_t *buff, uint8_t buffSize) { - uint8_t displayNum = 0; - if (address == _deviceAddressLeftCenter) - displayNum = 1; - else if (address == _deviceAddressRightCenter) - displayNum = 2; - else if (address == _deviceAddressRight) - displayNum = 3; - //isConnected(displayNum); //Wait until display is ready + uint8_t displayNum = 0; + if (address == _deviceAddressLeftCenter) + displayNum = 1; + else if (address == _deviceAddressRightCenter) + displayNum = 2; + else if (address == _deviceAddressRight) + displayNum = 3; + //isConnected(displayNum); //Wait until display is ready - _i2cPort->beginTransmission(address); - _i2cPort->write(reg); + _i2cPort->beginTransmission(address); + _i2cPort->write(reg); - for (uint8_t i = 0; i < buffSize; i++) - _i2cPort->write(buff[i]); + for (uint8_t i = 0; i < buffSize; i++) + _i2cPort->write(buff[i]); - if (_i2cPort->endTransmission() == 0) - return true; + if (_i2cPort->endTransmission() == 0) + return true; - return false; + return false; } //Write a single byte to the display. This is often a command byte. //The address of the data to write is contained in the first four bits of dataToWrite bool HT16K33::writeRAM(uint8_t address, uint8_t dataToWrite) { - uint8_t temp = 0; - return (writeRAM(address, dataToWrite, (uint8_t *)&temp, 0)); + uint8_t temp = 0; + return (writeRAM(address, dataToWrite, (uint8_t *)&temp, 0)); } From f0a2636f69a20c043ad83031356a6c1045343f9e Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Sun, 3 May 2020 15:19:59 -0400 Subject: [PATCH 11/12] Updated comment, pretty printed table --- src/SparkFun_Alphanumeric_Display.cpp | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/SparkFun_Alphanumeric_Display.cpp b/src/SparkFun_Alphanumeric_Display.cpp index 4878a08..b92ce28 100644 --- a/src/SparkFun_Alphanumeric_Display.cpp +++ b/src/SparkFun_Alphanumeric_Display.cpp @@ -46,15 +46,15 @@ static const uint16_t PROGMEM alphanumeric_segs[96]{ 0b10010000100100, //'%' 0b110011011001, //'&' 0b1000000000, //''' - 0b111001, //'(' - 0b1111, //')' + 0b111001, //'(' + 0b1111, //')' 0b11111010000000, //'*' 0b1001101000000, //'+' 0b10000000000000, //',' 0b101000000, //'-' 0b00000000000000, //'.' - changed to blank 0b10010000000000, //'/' - 0b111111, //'0' + 0b111111, //'0' 0b10000000110, //'1' 0b101011011, //'2' 0b101001111, //'3' @@ -73,33 +73,33 @@ static const uint16_t PROGMEM alphanumeric_segs[96]{ 0b00001100111011, //'@' - Added to map 0b101110111, //'A' 0b1001100001111, //'B' - 0b111001, //'C' + 0b111001, //'C' 0b1001000001111, //'D' 0b101111001, //'E' 0b101110001, //'F' 0b100111101, //'G' 0b101110110, //'H' 0b1001000001001, //'I' - 0b11110, //'J' + 0b11110, //'J' 0b110001110000, //'K' - 0b111000, //'L' + 0b111000, //'L' 0b10010110110, //'M' 0b100010110110, //'N' - 0b111111, //'O' + 0b111111, //'O' 0b101110011, //'P' 0b100000111111, //'Q' 0b100101110011, //'R' 0b110001101, //'S' 0b1001000000001, //'T' - 0b111110, //'U' + 0b111110, //'U' 0b10010000110000, //'V' 0b10100000110110, //'W' 0b10110010000000, //'X' 0b1010010000000, //'Y' 0b10010000001001, //'Z' - 0b111001, //'[' + 0b111001, //'[' 0b100010000000, //'\' - 0b1111, //']' + 0b1111, //']' 0b10100000000000, //'^' - Added to map 0b1000, //'_' 0b10000000, //'`' @@ -107,12 +107,12 @@ static const uint16_t PROGMEM alphanumeric_segs[96]{ 0b100001111000, //'b' 0b101011000, //'c' 0b10000100001110, //'d' - 0b1111001, //'e' - 0b1110001, //'f' + 0b1111001, //'e' + 0b1110001, //'f' 0b110001111, //'g' 0b101110100, //'h' 0b1000000000000, //'i' - 0b1110, //'j' + 0b1110, //'j' 0b1111000000000, //'k' 0b1001000000000, //'l' 0b1000101010100, //'m' @@ -120,10 +120,10 @@ static const uint16_t PROGMEM alphanumeric_segs[96]{ 0b101011100, //'o' 0b10001110001, //'p' 0b100101100011, //'q' - 0b1010000, //'r' + 0b1010000, //'r' 0b110001101, //'s' - 0b1111000, //'t' - 0b11100, //'u' + 0b1111000, //'t' + 0b11100, //'u' 0b10000000010000, //'v' 0b10100000010100, //'w' 0b10110010000000, //'x' @@ -637,7 +637,7 @@ void HT16K33::illuminateChar(uint16_t segmentsToTurnOn, uint8_t digit) //Show a character on display void HT16K33::printChar(uint8_t displayChar, uint8_t digit) { - //moved alphanumeric_segs array outside of function + //moved alphanumeric_segs array to PROGMEM uint16_t characterPosition = 65532; //space From 453f68ae2b68f30d16e93534f432927ff284a9bc Mon Sep 17 00:00:00 2001 From: "fourstix@gmail.com" Date: Fri, 15 May 2020 19:56:15 -0400 Subject: [PATCH 12/12] Updated version to 1.1.1 per Spearkfun request --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 3b6f24b..1b4bcc1 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun Qwiic Alphanumeric Display Arduino Library -version=v1.0.1 +version=v1.1.1 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=A library to drive the Holtek HT16K33 LED Driver with an Alphanumeric Display.