From 91e85881d87ed1d7c8beed8d941ac68e3cd7aec1 Mon Sep 17 00:00:00 2001 From: Jonathan Lindsey Date: Mon, 23 Oct 2023 07:57:42 -0500 Subject: [PATCH 1/4] Support leading zeros with negative numbers. --- TM1637Display.cpp | 11 ++--------- TM1637Display.h | 4 ++-- examples/TM1637Test/TM1637Test.ino | 2 ++ 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/TM1637Display.cpp b/TM1637Display.cpp index eada692..aeca518 100644 --- a/TM1637Display.cpp +++ b/TM1637Display.cpp @@ -143,24 +143,17 @@ void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bo 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) + if (digit == 0 && num == 0 && !leading_zero) // Leading zero is blank digits[i] = 0; else digits[i] = encodeDigit(digit); - if (digit == 0 && num == 0 && negative) { + if (digit == 0 && num == 0 && negative && (!leading_zero || i == 0)) { digits[i] = minusSegments; negative = false; } diff --git a/TM1637Display.h b/TM1637Display.h index f586c78..fcbfadc 100644 --- a/TM1637Display.h +++ b/TM1637Display.h @@ -74,7 +74,7 @@ class TM1637Display { //! //! @param num The number to be shown //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are - //! blank. NOTE: leading zero is not supported with negative numbers. + //! blank. //! @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) @@ -99,7 +99,7 @@ class TM1637Display { //! 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. + //! blank. //! @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) diff --git a/examples/TM1637Test/TM1637Test.ino b/examples/TM1637Test/TM1637Test.ino index d826d1a..ab82a67 100644 --- a/examples/TM1637Test/TM1637Test.ino +++ b/examples/TM1637Test/TM1637Test.ino @@ -73,6 +73,8 @@ void loop() delay(TEST_DELAY); display.showNumberDec(301, true); // Expect: 0301 delay(TEST_DELAY); + display.showNumberDec(-23, true); // Expect: -023 + delay(TEST_DELAY); display.clear(); display.showNumberDec(14, false, 2, 1); // Expect: _14_ delay(TEST_DELAY); From b132d789e00dadff5fe976b0a7d3da7126f6d9b2 Mon Sep 17 00:00:00 2001 From: Jonathan Lindsey Date: Mon, 23 Oct 2023 09:26:42 -0500 Subject: [PATCH 2/4] Add support for floating point numbers. --- README.md | 1 + TM1637Display.cpp | 18 ++++++++++++++ TM1637Display.h | 19 +++++++++++++++ examples/TM1637Test/TM1637Test.ino | 38 +++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 403028a..dfe5948 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ The library provides a single class named TM1637Display. An instance of this cla * `setSegments` - Set the raw value of the segments of each digit * `showNumberDec` - Display a decimal number +* `showNumberFloat` - Display a floating point number * `showNumberDecEx` - Display a decimal number with decimal points or colon * `setBrightness` - Sets the brightness of the display diff --git a/TM1637Display.cpp b/TM1637Display.cpp index aeca518..a921354 100644 --- a/TM1637Display.cpp +++ b/TM1637Display.cpp @@ -112,6 +112,24 @@ void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, ui showNumberDecEx(num, 0, leading_zero, length, pos); } +void TM1637Display::showNumberFloat(float num, DecimalType decimal_type, bool leading_zero) { + if (decimal_type == Colon) + { + const int COLON_SHIFT = 100; + + int num_int = round(num * COLON_SHIFT); + if (num_int < 10000 && num_int > -1000) + { + bool use_leading_zero = leading_zero || (-COLON_SHIFT < num_int && num_int < COLON_SHIFT); + showNumberDecEx(num_int, 0b01000000, use_leading_zero); + } + else + { + showNumberDec(round(num), leading_zero); + } + } +} + void TM1637Display::showNumberDecEx(int num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos) { diff --git a/TM1637Display.h b/TM1637Display.h index fcbfadc..966adcd 100644 --- a/TM1637Display.h +++ b/TM1637Display.h @@ -81,6 +81,25 @@ class TM1637Display { //! @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); + enum DecimalType { + Colon + }; + + //! Display a floating point number + //! + //! Display the given argument as a floating point number, displaying digits to the right of the + //! decimal point only when possible while prioritizing all digits to the left of the decimal + //! point, and given the limitations of 4 digit 7 segment displays. + //! + //! @param num The number to be shown + //! @param decimal_type Whether to use the colon or decimal points. + //! Note: For now only the colon is supported. + //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are + //! blank. + //! Note: When `-1 < num < 1` and `leading_zero` is false, superfluous leading zeros may be + //! shown. This behavior may change in the future. + void showNumberFloat(float num, DecimalType decimal_type, bool leading_zero = false); + //! Display a decimal number, with dot control //! //! Display the given argument as a decimal number. The dots between the digits (or colon) diff --git a/examples/TM1637Test/TM1637Test.ino b/examples/TM1637Test/TM1637Test.ino index ab82a67..8d59c47 100644 --- a/examples/TM1637Test/TM1637Test.ino +++ b/examples/TM1637Test/TM1637Test.ino @@ -90,6 +90,32 @@ void loop() display.clear(); display.showNumberDec(-5, false, 3, 0); // Expect: _-5_ delay(TEST_DELAY); + + // Floating point numbers use the colon when possible + display.showNumberFloat(12.34, TM1637Display::Colon); // Expect: 12:34 + delay(TEST_DELAY); + display.showNumberFloat(-12.34, TM1637Display::Colon); // Expect: _-12 + delay(TEST_DELAY); + display.showNumberFloat(99.996, TM1637Display::Colon); // Expect: _100 + delay(TEST_DELAY); + display.showNumberFloat(-9.996, TM1637Display::Colon); // Expect: _-10 + delay(TEST_DELAY); + display.showNumberFloat(0.996, TM1637Display::Colon); // Expect: _1:00 + delay(TEST_DELAY); + display.showNumberFloat(2.34, TM1637Display::Colon, false); // Expect: _2:34 + delay(TEST_DELAY); + display.showNumberFloat(2.34, TM1637Display::Colon, true); // Expect: 02:34 + delay(TEST_DELAY); + display.showNumberFloat(0.01, TM1637Display::Colon, true); // Expect: 00:01 + delay(TEST_DELAY); + display.showNumberFloat(0.02, TM1637Display::Colon, false); // Expect: 00:02 - Future: _0:02 + delay(TEST_DELAY); + display.showNumberFloat(-0.01, TM1637Display::Colon, true); // Expect: -0.01 + delay(TEST_DELAY); + display.showNumberFloat(-0.02, TM1637Display::Colon, false); // Expect: -0.02 + delay(TEST_DELAY); + + // Hexadecimal display.showNumberHexEx(0xf1af); // Expect: f1Af delay(TEST_DELAY); display.showNumberHexEx(0x2c); // Expect: __2C @@ -128,6 +154,16 @@ void loop() // Done! display.setSegments(SEG_DONE); + delay(TEST_DELAY); - while(1); + // Voltmeter + while(true) { + // Constants for Arduino Uno + const float RESOLUTION = 1023.0; // Max value for resolution + const float OPERATING_VOLTAGE = 5.0; + // If analog input pin is not connected, reading will fluctuate + float reading = (analogRead(0) / RESOLUTION) * OPERATING_VOLTAGE; + display.showNumberFloat(reading, TM1637Display::Colon); + delay(100); + } } From 0f4618004ca5ea0bef783db76a2e7d14dfc533c2 Mon Sep 17 00:00:00 2001 From: Jonathan Lindsey Date: Sun, 29 Oct 2023 23:04:03 -0500 Subject: [PATCH 3/4] Fix displaying 700.0 which had previously overflowed the int type internally. --- TM1637Display.cpp | 9 +++++---- examples/TM1637Test/TM1637Test.ino | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/TM1637Display.cpp b/TM1637Display.cpp index a921354..9d3b38c 100644 --- a/TM1637Display.cpp +++ b/TM1637Display.cpp @@ -117,11 +117,12 @@ void TM1637Display::showNumberFloat(float num, DecimalType decimal_type, bool le { const int COLON_SHIFT = 100; - int num_int = round(num * COLON_SHIFT); - if (num_int < 10000 && num_int > -1000) + int32_t num_long = round(num * COLON_SHIFT); // Need int32_t to store 700.0 shifted + if (num_long < 10000 && num_long > -1000) { - bool use_leading_zero = leading_zero || (-COLON_SHIFT < num_int && num_int < COLON_SHIFT); - showNumberDecEx(num_int, 0b01000000, use_leading_zero); + // In this case a int16_t could store the number but no need to explicitly convert it + bool use_leading_zero = leading_zero || (-COLON_SHIFT < num_long && num_long < COLON_SHIFT); + showNumberDecEx(num_long, 0b01000000, use_leading_zero); } else { diff --git a/examples/TM1637Test/TM1637Test.ino b/examples/TM1637Test/TM1637Test.ino index 8d59c47..1117cf7 100644 --- a/examples/TM1637Test/TM1637Test.ino +++ b/examples/TM1637Test/TM1637Test.ino @@ -100,6 +100,8 @@ void loop() delay(TEST_DELAY); display.showNumberFloat(-9.996, TM1637Display::Colon); // Expect: _-10 delay(TEST_DELAY); + display.showNumberFloat(700.6, TM1637Display::Colon); // Expect: _701 + delay(TEST_DELAY); display.showNumberFloat(0.996, TM1637Display::Colon); // Expect: _1:00 delay(TEST_DELAY); display.showNumberFloat(2.34, TM1637Display::Colon, false); // Expect: _2:34 From c4dfa24c13e1a90ac42bfd64bbfd18267ee26585 Mon Sep 17 00:00:00 2001 From: Jonathan Lindsey Date: Sun, 29 Oct 2023 23:13:45 -0500 Subject: [PATCH 4/4] Instead of a DecimalType enum, use the function name showNumberFloatColon. --- README.md | 2 +- TM1637Display.cpp | 27 ++++++++++++--------------- TM1637Display.h | 10 ++-------- examples/TM1637Test/TM1637Test.ino | 28 ++++++++++++++-------------- 4 files changed, 29 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index dfe5948..756e678 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The library provides a single class named TM1637Display. An instance of this cla * `setSegments` - Set the raw value of the segments of each digit * `showNumberDec` - Display a decimal number -* `showNumberFloat` - Display a floating point number +* `showNumberFloatColon` - Display a floating point number using a colon for the decimal point * `showNumberDecEx` - Display a decimal number with decimal points or colon * `setBrightness` - Sets the brightness of the display diff --git a/TM1637Display.cpp b/TM1637Display.cpp index 9d3b38c..3b32a22 100644 --- a/TM1637Display.cpp +++ b/TM1637Display.cpp @@ -112,22 +112,19 @@ void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, ui showNumberDecEx(num, 0, leading_zero, length, pos); } -void TM1637Display::showNumberFloat(float num, DecimalType decimal_type, bool leading_zero) { - if (decimal_type == Colon) - { - const int COLON_SHIFT = 100; +void TM1637Display::showNumberFloatColon(float num, bool leading_zero) { + const int COLON_SHIFT = 100; - int32_t num_long = round(num * COLON_SHIFT); // Need int32_t to store 700.0 shifted - if (num_long < 10000 && num_long > -1000) - { - // In this case a int16_t could store the number but no need to explicitly convert it - bool use_leading_zero = leading_zero || (-COLON_SHIFT < num_long && num_long < COLON_SHIFT); - showNumberDecEx(num_long, 0b01000000, use_leading_zero); - } - else - { - showNumberDec(round(num), leading_zero); - } + int32_t num_long = round(num * COLON_SHIFT); // Need int32_t to store 700.0 shifted + if (num_long < 10000 && num_long > -1000) + { + // In this case a int16_t could store the number but no need to explicitly convert it + bool use_leading_zero = leading_zero || (-COLON_SHIFT < num_long && num_long < COLON_SHIFT); + showNumberDecEx(num_long, 0b01000000, use_leading_zero); + } + else + { + showNumberDec(round(num), leading_zero); } } diff --git a/TM1637Display.h b/TM1637Display.h index 966adcd..9aaa6d6 100644 --- a/TM1637Display.h +++ b/TM1637Display.h @@ -81,24 +81,18 @@ class TM1637Display { //! @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); - enum DecimalType { - Colon - }; - - //! Display a floating point number + //! Display a floating point number using a colon for the decimal point //! //! Display the given argument as a floating point number, displaying digits to the right of the //! decimal point only when possible while prioritizing all digits to the left of the decimal //! point, and given the limitations of 4 digit 7 segment displays. //! //! @param num The number to be shown - //! @param decimal_type Whether to use the colon or decimal points. - //! Note: For now only the colon is supported. //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are //! blank. //! Note: When `-1 < num < 1` and `leading_zero` is false, superfluous leading zeros may be //! shown. This behavior may change in the future. - void showNumberFloat(float num, DecimalType decimal_type, bool leading_zero = false); + void showNumberFloatColon(float num, bool leading_zero = false); //! Display a decimal number, with dot control //! diff --git a/examples/TM1637Test/TM1637Test.ino b/examples/TM1637Test/TM1637Test.ino index 1117cf7..184a858 100644 --- a/examples/TM1637Test/TM1637Test.ino +++ b/examples/TM1637Test/TM1637Test.ino @@ -91,30 +91,30 @@ void loop() display.showNumberDec(-5, false, 3, 0); // Expect: _-5_ delay(TEST_DELAY); - // Floating point numbers use the colon when possible - display.showNumberFloat(12.34, TM1637Display::Colon); // Expect: 12:34 + // Show floating point numbers using the colon for a decimal point when possible + display.showNumberFloatColon(12.34); // Expect: 12:34 delay(TEST_DELAY); - display.showNumberFloat(-12.34, TM1637Display::Colon); // Expect: _-12 + display.showNumberFloatColon(-12.34); // Expect: _-12 delay(TEST_DELAY); - display.showNumberFloat(99.996, TM1637Display::Colon); // Expect: _100 + display.showNumberFloatColon(99.996); // Expect: _100 delay(TEST_DELAY); - display.showNumberFloat(-9.996, TM1637Display::Colon); // Expect: _-10 + display.showNumberFloatColon(-9.996); // Expect: _-10 delay(TEST_DELAY); - display.showNumberFloat(700.6, TM1637Display::Colon); // Expect: _701 + display.showNumberFloatColon(700.6); // Expect: _701 delay(TEST_DELAY); - display.showNumberFloat(0.996, TM1637Display::Colon); // Expect: _1:00 + display.showNumberFloatColon(0.996); // Expect: _1:00 delay(TEST_DELAY); - display.showNumberFloat(2.34, TM1637Display::Colon, false); // Expect: _2:34 + display.showNumberFloatColon(2.34, false); // Expect: _2:34 delay(TEST_DELAY); - display.showNumberFloat(2.34, TM1637Display::Colon, true); // Expect: 02:34 + display.showNumberFloatColon(2.34, true); // Expect: 02:34 delay(TEST_DELAY); - display.showNumberFloat(0.01, TM1637Display::Colon, true); // Expect: 00:01 + display.showNumberFloatColon(0.01, true); // Expect: 00:01 delay(TEST_DELAY); - display.showNumberFloat(0.02, TM1637Display::Colon, false); // Expect: 00:02 - Future: _0:02 + display.showNumberFloatColon(0.02, false); // Expect: 00:02 - Future: _0:02 delay(TEST_DELAY); - display.showNumberFloat(-0.01, TM1637Display::Colon, true); // Expect: -0.01 + display.showNumberFloatColon(-0.01, true); // Expect: -0.01 delay(TEST_DELAY); - display.showNumberFloat(-0.02, TM1637Display::Colon, false); // Expect: -0.02 + display.showNumberFloatColon(-0.02, false); // Expect: -0.02 delay(TEST_DELAY); // Hexadecimal @@ -165,7 +165,7 @@ void loop() const float OPERATING_VOLTAGE = 5.0; // If analog input pin is not connected, reading will fluctuate float reading = (analogRead(0) / RESOLUTION) * OPERATING_VOLTAGE; - display.showNumberFloat(reading, TM1637Display::Colon); + display.showNumberFloatColon(reading); delay(100); } }