Permalink
Browse files

Float/Double neg # fixes by John Archie

  • Loading branch information...
1 parent 2b23a5e commit df757206a45b1162e281fa902a0d959287f2aa06 @ladyada ladyada committed Aug 9, 2012
Showing with 69 additions and 104 deletions.
  1. +63 −101 Adafruit_LEDBackpack.cpp
  2. +6 −3 Adafruit_LEDBackpack.h
View
@@ -23,19 +23,16 @@
#include "Adafruit_GFX.h"
static const uint8_t numbertable[] = {
- 0x3F /* 0 */,
- 0x06 /* 1 */,
- 0x5B /* 2 */,
- 0x4F /* 3 */,
- 0x66 /* 4 */,
- 0x6D /* 5 */,
+ 0x3F, /* 0 */
+ 0x06, /* 1 */
+ 0x5B, /* 2 */
+ 0x4F, /* 3 */
+ 0x66, /* 4 */
+ 0x6D, /* 5 */
0x7D, /* 6 */
0x07, /* 7 */
0x7F, /* 8 */
0x6F, /* 9 */
-};
-
-const uint8_t alphatable[] = {
0x77, /* a */
0x7C, /* b */
0x39, /* C */
@@ -275,108 +272,73 @@ void Adafruit_7segment::writeDigitNum(uint8_t d, uint8_t num, boolean dot) {
writeDigitRaw(d, numbertable[num] | (dot << 7));
}
-void Adafruit_7segment::writeDigitAlpha(uint8_t d, uint8_t alph, boolean dot) {
- if (d > 4) return;
-
- writeDigitRaw(d, alphatable[alph] | (dot << 7));
-}
-
void Adafruit_7segment::print(long n, int base)
{
- if (base == 0) {
- write(n);
- } else if (base == 10) {
- if (n < 0) {
- print('-');
- n = -n;
- }
- printNumber(n, 10);
- } else {
- printNumber(n, base);
- }
+ printNumber(n, base);
}
-
-void Adafruit_7segment::printNumber(unsigned long n, uint8_t base)
+void Adafruit_7segment::printNumber(long n, uint8_t base)
{
- position = 0;
+ printFloat(n, 0, base);
+}
- unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
- unsigned long i = 0;
-
- if (n == 0) {
- writeDigitRaw(0, 0x0);
- writeDigitRaw(1, 0x0);
- writeDigitRaw(2, 0x0);
- writeDigitRaw(3, 0x0);
- writeDigitNum(4, 0);
- return;
- }
-
- while (n > 0) {
- buf[i++] = n % base;
- n /= base;
+void Adafruit_7segment::printFloat(double n, uint8_t fracDigits, uint8_t base)
+{
+ uint8_t numericDigits = 4; // available digits on display
+ boolean isNegative = false; // true if the number is negative
+
+ // is the number negative?
+ if(n < 0) {
+ isNegative = true; // need to draw sign later
+ --numericDigits; // the sign will take up one digit
+ n *= -1; // pretend the number is positive
}
-
- // we have i digits
-
- if (i > 4) { // too big!
- Serial.println("too long");
- writeDigitRaw(0, 0x40);
- writeDigitRaw(1, 0x40);
- writeDigitRaw(2, 0x00);
- writeDigitRaw(3, 0x40);
- writeDigitRaw(4, 0x40);
- return;
+
+ // calculate the factor required to shift all fractional digits
+ // into the integer part of the number
+ double toIntFactor = 1.0;
+ for(int i = 0; i < fracDigits; ++i) toIntFactor *= base;
+
+ // create integer containing digits to display by applying
+ // shifting factor and rounding adjustment
+ uint32_t displayNumber = n * toIntFactor + 0.5;
+
+ // calculate upper bound on displayNumber given
+ // available digits on display
+ uint32_t tooBig = 1;
+ for(int i = 0; i < numericDigits; ++i) tooBig *= base;
+
+ // if displayNumber is too large, try fewer fractional digits
+ while(displayNumber >= tooBig) {
+ --fracDigits;
+ toIntFactor /= base;
+ displayNumber = n * toIntFactor + 0.5;
}
- //Serial.println(i);
-
- clear();
-
- position = 4;
- for (uint8_t n=0; n<i; n++) {
- if (buf[n] < 10)
- writeDigitNum(position, buf[n]);
- else
- writeDigitAlpha(position, buf[n] - 10);
-
- position--;
- if (position == 2) position--;
+
+ // did toIntFactor shift the decimal off the display?
+ if (toIntFactor < 1) {
+ printError();
+ } else {
+ // otherwise, display the number
+ int8_t displayPos = 4;
+
+ for(uint8_t i = 0; displayNumber; ++i) {
+ boolean displayDecimal = (fracDigits != 0 && i == fracDigits);
+ writeDigitNum(displayPos--, displayNumber % base, displayDecimal);
+ if(displayPos == 2) writeDigitRaw(displayPos--, 0x00);
+ displayNumber /= base;
+ }
+
+ // display negative sign if negative
+ if(isNegative) writeDigitRaw(displayPos--, 0x40);
+
+ // clear remaining display positions
+ while(displayPos >= 0) writeDigitRaw(displayPos--, 0x00);
}
- position = 0;
}
-void Adafruit_7segment::printFloat(double number, uint8_t digits)
-{
- // Handle negative numbers
- if (number < 0.0)
- {
- print('-');
- number = -number;
+void Adafruit_7segment::printError(void) {
+ for(uint8_t i = 0; i < SEVENSEG_DIGITS; ++i) {
+ writeDigitRaw(i, (i == 2 ? 0x00 : 0x40));
}
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- for (uint8_t i=0; i<digits; ++i)
- rounding /= 10.0;
-
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits > 0)
- print('.');
-
- // Extract digits from the remainder one at a time
- while (digits-- > 0)
- {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
}
View
@@ -45,6 +45,9 @@
#define HT16K33_CMD_BRIGHTNESS 0x0E
+#define SEVENSEG_DIGITS 5
+
+
// this is the raw HT16K33 controller
class Adafruit_LEDBackpack {
public:
@@ -110,10 +113,10 @@ class Adafruit_7segment : public Adafruit_LEDBackpack {
void writeDigitRaw(uint8_t x, uint8_t bitmask);
void writeDigitNum(uint8_t x, uint8_t num, boolean dot = false);
- void writeDigitAlpha(uint8_t x, uint8_t num, boolean dot = false);
void drawColon(boolean state);
- void printNumber(unsigned long n, uint8_t base);
- void printFloat(double number, uint8_t digits);
+ void printNumber(long, uint8_t = 2);
+ void printFloat(double, uint8_t = 2, uint8_t = DEC);
+ void printError(void);
private:
uint8_t position;

0 comments on commit df75720

Please sign in to comment.