From 383f98c2ba61c3b04708493b3aa3472ad5492657 Mon Sep 17 00:00:00 2001 From: Scott Lawrence Date: Tue, 20 Apr 2021 22:10:17 -0400 Subject: [PATCH] Added support for 6 digit displays with digit remapping --- TM1637Display.cpp | 29 +++- TM1637Display.h | 22 ++- .../TM1637_6digit_Test/TM1637_6digit_Test.ino | 146 ++++++++++++++++++ 3 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 examples/TM1637_6digit_Test/TM1637_6digit_Test.ino diff --git a/TM1637Display.cpp b/TM1637Display.cpp index eada692..4952bc6 100644 --- a/TM1637Display.cpp +++ b/TM1637Display.cpp @@ -58,12 +58,19 @@ const uint8_t digitToSegment[] = { static const uint8_t minusSegments = 0b01000000; -TM1637Display::TM1637Display(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay) +TM1637Display::TM1637Display( + uint8_t pinClk, + uint8_t pinDIO, + unsigned int bitDelay, + uint8_t digitCount, + uint8_t * digitRemap ) { // Copy the pin numbers m_pinClk = pinClk; m_pinDIO = pinDIO; m_bitDelay = bitDelay; + m_digitCount = digitCount; + m_digitRemap = digitRemap; // Set the pin direction and default value. // Both pins are set as inputs, allowing the pull-up resistors to pull them up @@ -80,6 +87,9 @@ void TM1637Display::setBrightness(uint8_t brightness, bool on) void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos) { + if( length == 255 ) { + length = m_digitCount; + } // Write COMM1 start(); writeByte(TM1637_I2C_COMM1); @@ -90,8 +100,14 @@ void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_ writeByte(TM1637_I2C_COMM2 + (pos & 0x03)); // Write the data bytes - for (uint8_t k=0; k < length; k++) - writeByte(segments[k]); + for (uint8_t k=0; k < length; k++) { + if( m_digitRemap == NULL ) { + writeByte(segments[k]); + } else { + + writeByte( segments[ m_digitRemap[k] ]); + } + } stop(); @@ -127,14 +143,17 @@ void TM1637Display::showNumberHexEx(uint16_t num, uint8_t dots, bool leading_zer void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos) { + if( length == 255 ) { + length = m_digitCount; + } + bool negative = false; if (base < 0) { base = -base; negative = true; } - - uint8_t digits[4]; + uint8_t digits[MAX_DIGIT_COUNT]; if (num == 0 && !leading_zero) { // Singular case - take care separately diff --git a/TM1637Display.h b/TM1637Display.h index f586c78..a34086b 100644 --- a/TM1637Display.h +++ b/TM1637Display.h @@ -30,6 +30,8 @@ #define DEFAULT_BIT_DELAY 100 +#define MAX_DIGIT_COUNT (6) // maximum that the TM1637 supports + class TM1637Display { public: @@ -40,7 +42,13 @@ class TM1637Display { //! @param pinDIO - The number of the digital pin connected to the DIO pin of the module //! @param bitDelay - The delay, in microseconds, between bit transition on the serial //! bus connected to the display - TM1637Display(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay = DEFAULT_BIT_DELAY); + //! @param digitCount - number of digits on the display (ie 4, 6) + TM1637Display( + uint8_t pinClk, + uint8_t pinDIO, + unsigned int bitDelay = DEFAULT_BIT_DELAY, + uint8_t digitCount = 4, + uint8_t * digitRemap = NULL); //! Sets the brightness of the display. //! @@ -63,7 +71,7 @@ class TM1637Display { //! @param segments An array of size @ref length containing the raw segment values //! @param length The number of digits to be modified //! @param pos The position from which to start the modification (0 - leftmost, 3 - rightmost) - void setSegments(const uint8_t segments[], uint8_t length = 4, uint8_t pos = 0); + void setSegments(const uint8_t segments[], uint8_t length = 255, uint8_t pos = 0); //! Clear the display void clear(); @@ -79,7 +87,7 @@ class TM1637Display { //! fits to the number of digits requested (for example, if two digits are to be displayed, //! the number must be between 0 to 99) //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost) - void showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); + void showNumberDec(int num, bool leading_zero = false, uint8_t length = 255, uint8_t pos = 0); //! Display a decimal number, with dot control //! @@ -104,7 +112,7 @@ class TM1637Display { //! fits to the number of digits requested (for example, if two digits are to be displayed, //! the number must be between 0 to 99) //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost) - void showNumberDecEx(int num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); + void showNumberDecEx(int num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 255, uint8_t pos = 0); //! Display a hexadecimal number, with dot control //! @@ -129,7 +137,7 @@ class TM1637Display { //! fits to the number of digits requested (for example, if two digits are to be displayed, //! the number must be between 0 to 99) //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost) - void showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); + void showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 255, uint8_t pos = 0); //! Translate a single digit into 7 segment code //! @@ -153,7 +161,7 @@ class TM1637Display { void showDots(uint8_t dots, uint8_t* digits); - void showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0); + void showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 255, uint8_t pos = 0); private: @@ -161,6 +169,8 @@ class TM1637Display { uint8_t m_pinDIO; uint8_t m_brightness; unsigned int m_bitDelay; + uint8_t m_digitCount; + uint8_t * m_digitRemap; }; #endif // __TM1637DISPLAY__ diff --git a/examples/TM1637_6digit_Test/TM1637_6digit_Test.ino b/examples/TM1637_6digit_Test/TM1637_6digit_Test.ino new file mode 100644 index 0000000..07bed96 --- /dev/null +++ b/examples/TM1637_6digit_Test/TM1637_6digit_Test.ino @@ -0,0 +1,146 @@ +#include +#include + +// Module connection pins (Digital Pins) +#define CLK 2 +#define DIO 3 + +// The amount of time (in milliseconds) between tests +#define TEST_DELAY 1000 + +const uint8_t SEG_DONE[] = { + SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d + SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O + SEG_C | SEG_E | SEG_G, // n + SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E + SEG_DP, // . + SEG_DP, // . + }; + + +const uint8_t digit_remapping[] = { 2, 1, 0, 5, 4, 3 }; + +TM1637Display display(CLK, DIO, DEFAULT_BIT_DELAY, 6, digit_remapping ); + +void setup() +{ +} + +void loop() +{ + int k; + uint8_t data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + //uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 }; + display.setBrightness(0x0f); + + // All segments on + display.setSegments(data); + delay(TEST_DELAY); + + // Selectively set different digits + data[0] = display.encodeDigit(0); + data[1] = display.encodeDigit(1); + data[2] = display.encodeDigit(2); + data[3] = display.encodeDigit(3); + data[4] = display.encodeDigit(4); + data[5] = display.encodeDigit(5); + display.setSegments(data); + delay(TEST_DELAY); + + /* + for(k = 3; k >= 0; k--) { + display.setSegments(data, 1, k); + delay(TEST_DELAY); + } + */ + + display.clear(); + display.setSegments(data+2, 2, 2); + delay(TEST_DELAY); + + display.clear(); + display.setSegments(data+2, 2, 1); + delay(TEST_DELAY); + + display.clear(); + display.setSegments(data+1, 3, 1); + delay(TEST_DELAY); + + + // Show decimal numbers with/without leading zeros + display.showNumberDec(0, false); // Expect: ___0 + delay(TEST_DELAY); + display.showNumberDec(0, true); // Expect: 0000 + delay(TEST_DELAY); + display.showNumberDec(1, false); // Expect: ___1 + delay(TEST_DELAY); + display.showNumberDec(1, true); // Expect: 0001 + delay(TEST_DELAY); + display.showNumberDec(301, false); // Expect: _301 + delay(TEST_DELAY); + display.showNumberDec(301, true); // Expect: 0301 + delay(TEST_DELAY); + display.clear(); + display.showNumberDec(14, false, 2, 1); // Expect: _14_ + delay(TEST_DELAY); + display.clear(); + display.showNumberDec(4, true, 2, 2); // Expect: __04 + delay(TEST_DELAY); + display.showNumberDec(-1, false); // Expect: __-1 + delay(TEST_DELAY); + display.showNumberDec(-12); // Expect: _-12 + delay(TEST_DELAY); + display.showNumberDec(-999); // Expect: -999 + delay(TEST_DELAY); + display.clear(); + display.showNumberDec(-5, false, 3, 0); // Expect: _-5_ + delay(TEST_DELAY); + display.showNumberHexEx(0xf1af); // Expect: f1Af + delay(TEST_DELAY); + display.showNumberHexEx(0x2c); // Expect: __2C + delay(TEST_DELAY); + display.showNumberHexEx(0xd1, 0, true); // Expect: 00d1 + delay(TEST_DELAY); + display.clear(); + display.showNumberHexEx(0xd1, 0, true, 2); // Expect: d1__ + delay(TEST_DELAY); + + // Run through all the dots + for(k=0; k <= 6; k++) { + display.showNumberDecEx(0, (0x80 >> k), true); + delay(TEST_DELAY); + } + + // Brightness Test + for(k = 0; k < 6; k++) + data[k] = 0xff; + + for(k = 0; k < 7; k++) { + display.setBrightness(k); + display.setSegments(data); + delay(TEST_DELAY/4); + } + + // On/Off test + for(k = 0; k < 4; k++) { + display.setBrightness(7, false); // Turn off + display.setSegments(data); + delay(TEST_DELAY/4); + display.setBrightness(7, true); // Turn on + display.setSegments(data); + delay(TEST_DELAY/4); + } + + + // Done! + while(1) { + display.setBrightness(7); + display.setSegments(SEG_DONE); + delay( TEST_DELAY/4 ); + + display.setBrightness(1); + display.setSegments(SEG_DONE); + delay( TEST_DELAY/4 ); + + } +}