Completely rework the number display functions

Add support for decimal negative and hexadecimal numbers.
This commit is contained in:
Avishay
2018-10-30 23:09:10 +02:00
parent 77a9adc788
commit c0cf42cf98
3 changed files with 144 additions and 76 deletions
+57 -25
View File
@@ -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);
+40 -9
View File
@@ -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;
+47 -42
View File
@@ -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);