diff --git a/TM1637Display.cpp b/TM1637Display.cpp index bad1785..e1c0f8d 100644 --- a/TM1637Display.cpp +++ b/TM1637Display.cpp @@ -100,6 +100,12 @@ void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_ stop(); } +void TM1637Display::clear() +{ + uint8_t data[] = { 0, 0, 0, 0 }; + setSegments(data); +} + void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, uint8_t pos) { showNumberDecEx(num, 0, leading_zero, length, pos); @@ -108,41 +114,67 @@ void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, ui void TM1637Display::showNumberDecEx(int num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos) { + showNumberBaseEx(num < 0? -10 : 10, num < 0? -num : num, dots, leading_zero, length, pos); +} + +void TM1637Display::showNumberHexEx(uint16_t num, uint8_t dots, bool leading_zero, + uint8_t length, uint8_t pos) +{ + showNumberBaseEx(16, num, dots, leading_zero, length, pos); +} + +void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bool leading_zero, + uint8_t length, uint8_t pos) +{ bool negative = false; + if (base < 0) { + base = -base; + negative = true; + } - if((num < 0) && (num > -1000)) //we gotta only 4 digits, can't display minus in case lower than -999 - { - negative = true; - num = -num; - } uint8_t digits[4]; - for(int i = 3; i >= 0; --i) - { - digits[i] = encodeDigit(num % 10); - num /= 10; - } + if (num == 0 && !leading_zero) { + // Singular case - take care separately + for(uint8_t i = 0; i < (length-1); i++) + digits[i] = 0; + digits[length-1] = encodeDigit(0); + } + else { + //uint8_t i = length-1; + //if (negative) { + // // Negative number, show the minus sign + // digits[i] = minusSegments; + // i--; + //} + + for(int i = length-1; i >= 0; --i) + { + uint8_t digit = num % base; + + if (digit == 0 && num == 0 && leading_zero == false) + // Leading zero is blank + digits[i] = 0; + else + digits[i] = encodeDigit(digit); + + if (digit == 0 && num == 0 && negative) { + digits[i] = minusSegments; + negative = false; + } - if(!leading_zero) - { - blankLeadingZeros(digits); - } + num /= base; + } - if(negative) - { - showMinus(digits); + if(dots != 0) + { + showDots(dots, digits); + } } - - if(dots != 0) - { - showDots(dots, digits); - } - - setSegments(digits + (4 - length), length, pos); + setSegments(digits, length, pos); } - void TM1637Display::bitDelay() { delayMicroseconds(100); diff --git a/TM1637Display.h b/TM1637Display.h index 0aba004..84c781c 100644 --- a/TM1637Display.h +++ b/TM1637Display.h @@ -60,23 +60,51 @@ public: //! @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); - //! Displayes a decimal number + //! Clear the display + void clear(); + + //! Display a decimal number //! - //! Dispalyes the given argument as a decimal number + //! Dispaly the given argument as a decimal number. //! //! @param num The number to be shown //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are - //! blank + //! blank. NOTE: leading zero is not supported with negative numbers. //! @param length The number of digits to set. The user must ensure that the number to be shown //! 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 most significant digit (0 - leftmost, 3 - rightmost) + //! @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); - //! Displayes a decimal number, with dot control + //! Display a decimal number, with dot control //! - //! Dispalyes the given argument as a decimal number. The dots between the digits (or colon) - //! can be individually controlled + //! Dispaly the given argument as a decimal number. The dots between the digits (or colon) + //! can be individually controlled. + //! + //! @param num The number to be shown + //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot + //! between the digits (or colon mark, as implemented by each module). i.e. + //! For displays with dots between each digit: + //! * 0.000 (0b10000000) + //! * 00.00 (0b01000000) + //! * 000.0 (0b00100000) + //! * 0.0.0.0 (0b11100000) + //! For displays with just a colon: + //! * 00:00 (0b01000000) + //! For displays with dots and colons colon: + //! * 0.0:0.0 (0b11100000) + //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are + //! blank. NOTE: leading zero is not supported with negative numbers. + //! @param length The number of digits to set. The user must ensure that the number to be shown + //! 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); + + //! Display a hexadecimal number, with dot control + //! + //! Dispaly the given argument as a hexadecimal number. The dots between the digits (or colon) + //! can be individually controlled. //! //! @param num The number to be shown //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot @@ -95,8 +123,8 @@ public: //! @param length The number of digits to set. The user must ensure that the number to be shown //! 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 least 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); + //! @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); //! Translate a single digit into 7 segment code //! @@ -121,6 +149,9 @@ protected: void blankLeadingZeros(uint8_t* digits); void showMinus(uint8_t* digits); 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); + private: uint8_t m_pinClk; diff --git a/examples/TM1637Test/TM1637Test.ino b/examples/TM1637Test/TM1637Test.ino index 8d70425..eb7c841 100644 --- a/examples/TM1637Test/TM1637Test.ino +++ b/examples/TM1637Test/TM1637Test.ino @@ -25,6 +25,7 @@ void loop() { int k; uint8_t data[] = { 0xff, 0xff, 0xff, 0xff }; + uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 }; display.setBrightness(0x0f); // All segments on @@ -32,60 +33,77 @@ void loop() delay(TEST_DELAY); // Selectively set different digits - data[0] = 0b01001001; + data[0] = display.encodeDigit(0); data[1] = display.encodeDigit(1); data[2] = display.encodeDigit(2); data[3] = display.encodeDigit(3); + 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 - bool lz = false; - for (uint8_t z = 0; z < 2; z++) { - for(k = 0; k < 10000; k += k*4 + 7) { - display.showNumberDec(k, lz); - delay(TEST_DELAY); - } - lz = true; - } - - // Show decimal number whose length is smaller than 4 - for(k = 0; k < 4; k++) - data[k] = 0; - display.setSegments(data); - + 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 <= 4; k++) { display.showNumberDecEx(0, (0x80 >> k), true); delay(TEST_DELAY); } - display.showNumberDec(153, false, 3, 1); - delay(TEST_DELAY); - display.showNumberDec(22, false, 2, 2); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 3); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 2); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 1); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 0); - delay(TEST_DELAY); - // Brightness Test for(k = 0; k < 4; k++) data[k] = 0xff; @@ -105,20 +123,7 @@ void loop() delay(TEST_DELAY); } - // Negative numbers - display.showNumberDec(-1); - delay(TEST_DELAY); - display.showNumberDec(-12); - delay(TEST_DELAY); - display.showNumberDec(-123); - delay(TEST_DELAY); - display.showNumberDec(-1, true); - delay(TEST_DELAY); - display.showNumberDec(-12, true); - delay(TEST_DELAY); - display.showNumberDec(-123, true); - delay(TEST_DELAY); - + // Done! display.setSegments(SEG_DONE);