From e3af0a7ba2e3da490a866d44630163923faee696 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Thu, 3 Aug 2017 15:12:46 +0200 Subject: [PATCH] Fixed #3 Allow negative values --- Source/TODO | 19 -------- Source/res/digits.png | Bin 2301 -> 2321 bytes Source/res/digits.psd | Bin 65194 -> 65726 bytes Source/res/digits2code.py | 39 ++++++++++++---- Source/src/digits.c | 31 ++++++++----- Source/src/digits.h | 4 ++ Source/src/screen/counter.c | 86 ++++++++++++++++++++++++++++-------- Source/src/screen/counter.h | 12 ++++- 8 files changed, 134 insertions(+), 57 deletions(-) delete mode 100644 Source/TODO diff --git a/Source/TODO b/Source/TODO deleted file mode 100644 index 90757aa..0000000 --- a/Source/TODO +++ /dev/null @@ -1,19 +0,0 @@ -Code: - -x After turning off, turning on doesn't really respond well to the option button -- Store value in EEPROM (after a timeout) -- Long press shows menu with reset option (menu prevents accidental resets and can show battery voltage) - - -PCB: - -- Bigger pads for the +5V vias - - - - -Pin-out reminder: - -SW2 = - = pin 2, PB3 -SW3 = menu = pin 3, PB4 -SW1 = + = pin 6, PB1 \ No newline at end of file diff --git a/Source/res/digits.png b/Source/res/digits.png index d03dc462630270cbcb213a934baf4108df2e1188..d986c442431e5100c0a2ab04e5e4d19531a1f9ec 100644 GIT binary patch delta 1537 zcmV+c2LAc|5s?xhiBL{Q4GJ0x0000DNk~Le0005X0000$2m=5B0IeR!`qK|?S^MlwP|K{ZA-L_|hL zlQsi>f9ej(H~;_u22e~?MgRZ*00010!qa{L00l2eL_t(|+U%W6g5xjdb4uF_xQ|f&04&WMFv+Mri(_@4afe|(ZpzWfEsRkj4Jz3%NXmW1B=x@TpWxdCZ`;{G*Lny=Sxr;K~(5Kxr4d`SC8ZYQwI?O~z7fE6$?C5z9t7 zkbShCL>d01v{3#ndySi+Y}M#F=WVuX+9>&c>K4J?1f{z1l*+TCwQdyKg51k(_|Z2& zNnHEw4f;&IxFVzEK}4%O_0v#dlFGgz9dWd>)ZMb7mv^Uw(qg&R_Z27|e~=e8uj(I99O_EDP?Q5jhvx>&INns2=d5*9=hcXV4%wq2{<80;Jb`lP# zx~0o9<1Hu~B=t%7B9ze%4@gI|ic_qeG+R$^m#{OsPug}+rshwvvkr>}(WnnY83$0d zKt5ae#wclAuTuBg!@m60e+aj>$2jrlFGtB|bc!hR#V8*x{SK5`-s=7+_c5wlp>zsk zn!$F$^5;q9!UK^Kcpl1Xv;B|KMG5UaiZW+V=BJ^I8I&QRbYK7Jg?DrPDls}-Un^2X zdq6qk_R7mpKAth5w~R9WBPbxME$1 z&qvu|$tn(Rjk0y*e{a;U_3WT1d0)3GiUW|qExJv7Rx+{QWk#|$~=H_Y?YVOgN@VN1j@8YrftQ6A>ADx zVElnhuYUw^QPM5KNToF$bLRVbUMwd${FgBUDAVW!4iGjsXAZVD;QtkrOG% zQ*G&hH2;xn%npqKBHQgrhUM(pn;@IZZux`=()lF-Hm2LpM~ksy16biEi|(#VIVX~` nvJ`PzMbfe;roO)XM}PqU5rsd$Y6Cpt00000NkvXXu0mjfD)7UB delta 1491 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

9FF9*Wgr%1J@_@iX44_cPTO@v{QQ>Wd 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 diff --git a/Source/res/digits2code.py b/Source/res/digits2code.py index d64e77d..becf33c 100644 --- a/Source/res/digits2code.py +++ b/Source/res/digits2code.py @@ -74,23 +74,24 @@ while x < width: x += 1 digitWidth = x - startX - if digitWidth > maxWidth: + + # Only measure actual digits for the maximum, skip the minus sign + if len(digits) > 0 and digitWidth > maxWidth: maxWidth = digitWidth digits.append({ "start": startX, "stop": x, "width": digitWidth }) x += 1 -if len(digits) != 10: - print("Error: expected 10 digits, found", len(digits)) +if len(digits) != 11: + print("Error: expected 11 sections (minus sign + 10 digits), found", len(digits)) exit(2) rows = int(math.ceil(height / 8)) -print("Found 10 digits") -print(" character width :", maxWidth) -print(" rows per character :", rows) -print(" total bytes :", rows * maxWidth * 10) +print("Character width :", maxWidth) +print("Rows per character :", rows) +print("Total bytes :", rows * maxWidth * 10) output = open(OutputHeaderFile, "w") @@ -103,8 +104,12 @@ output.write("#define DigitWidth " + str(maxWidth) + "\n") output.write("#define DigitHeight " + str(height) + "\n") output.write("#define DigitRows " + str(rows) + "\n") output.write("#define DigitBytesPerChar " + str(rows * maxWidth) + "\n") +output.write("\n") +output.write("#define MinusSignWidth " + str(digits[0]["width"]) + "\n") +output.write("#define MinusSignBytes " + str(rows * digits[0]["width"]) + "\n") output.write("\n\n\n") output.write("extern const uint8_t Digits[] PROGMEM;\n") +output.write("extern const uint8_t MinusSign[] PROGMEM;\n") output.write("\n") output.write("#endif\n") output.close(); @@ -124,7 +129,7 @@ def outputColumn(value, isLast): # Generate byte array for each digit -for digitIndex in range(len(digits)): +for digitIndex in range(1, len(digits)): digit = digits[digitIndex] output.write(" // " + str(digitIndex) + "\n") @@ -150,7 +155,25 @@ for digitIndex in range(len(digits)): output.write("\n") output.write("\n") output.write("};\n") +output.write("\n"); + + +output.write("const uint8_t MinusSign[] PROGMEM = {\n") +digit = digits[0] + +for rowIndex in range(rows): + lastRow = rowIndex == rows - 1 + output.write(" ") + + # Output one column at a time + for x in range(digit["start"], digit["stop"]): + outputColumn(getColumnValue(x, rowIndex * 8), lastRow and x == digit["stop"] - 1) + + output.write("\n") + +output.write("};\n") output.close() + print("") print("Wrote output to", OutputHeaderFile, "and", OutputCodeFile) \ No newline at end of file diff --git a/Source/src/digits.c b/Source/src/digits.c index 2fe9d9b..f8cd4f7 100644 --- a/Source/src/digits.c +++ b/Source/src/digits.c @@ -1,7 +1,7 @@ #include "digits.h" const uint8_t Digits[] PROGMEM = { - // 0 + // 1 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x1f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, @@ -11,7 +11,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0x01, 0x0f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 1 + // 2 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x07, 0x0f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -21,7 +21,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 2 + // 3 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x0f, 0x0f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0f, 0x3f, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, @@ -31,7 +31,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x80, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x7f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x0f, 0x07, 0x01, 0x00, 0x00, 0x00, - // 3 + // 4 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0x1f, 0x1f, 0x1f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x87, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -41,7 +41,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x80, 0xe0, 0xf0, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 4 + // 5 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x7e, 0x3e, 0x1e, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xe0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -51,7 +51,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 5 + // 6 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0f, 0x0f, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -61,7 +61,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0xe0, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x3f, 0x3f, 0x1f, 0x0f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 6 + // 7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0x7c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -71,7 +71,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0x07, 0x1f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x1f, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x0f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 7 + // 8 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x0f, 0x0f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -81,7 +81,7 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0xe0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x1f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 8 + // 9 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf0, 0xf0, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, @@ -91,7 +91,7 @@ const uint8_t Digits[] PROGMEM = { 0x0f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x0f, 0x1f, 0x3f, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, - // 9 + // 10 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xc0, 0x00, @@ -102,3 +102,14 @@ const uint8_t Digits[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x38, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +const uint8_t MinusSign[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x38, + 0x07, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/Source/src/digits.h b/Source/src/digits.h index 2928187..c3e0b62 100644 --- a/Source/src/digits.h +++ b/Source/src/digits.h @@ -8,8 +8,12 @@ #define DigitRows 8 #define DigitBytesPerChar 328 +#define MinusSignWidth 19 +#define MinusSignBytes 152 + extern const uint8_t Digits[] PROGMEM; +extern const uint8_t MinusSign[] PROGMEM; #endif diff --git a/Source/src/screen/counter.c b/Source/src/screen/counter.c index 0d8c2e9..11f8e0e 100644 --- a/Source/src/screen/counter.c +++ b/Source/src/screen/counter.c @@ -5,13 +5,17 @@ #include "../buttons.h" -uint16_t lastDrawnCounter = 9999; -uint16_t counter = 0; +#define CounterMinValue -99 +#define CounterMaxValue 999 + +int16_t lastDrawnCounter = 9999; +int16_t counter = 0; // Forward declarations -void drawCounter(uint16_t value); +void drawCounter(); void drawDigit(uint8_t* column, uint8_t digit); +void drawMinusSign(uint8_t* column); void blankDigitColumn(uint8_t* column, uint8_t width); @@ -19,54 +23,75 @@ void handleCounterScreen() { if (button_is_pressed_or_repeated(&buttonUp)) { - if (counter < 999) + if (counter < CounterMaxValue) counter++; } else if (button_is_pressed_or_repeated(&buttonDown)) { - if (counter > 0) + if (counter > CounterMinValue) counter--; } if (counter != lastDrawnCounter || getScreenInvalidated()) { - drawCounter(counter); + drawCounter(); lastDrawnCounter = counter; } } -void drawCounter(uint16_t value) +void drawCounter() { - if (value > 999) value = 999; uint8_t column = DigitFullOffset; - if (value < 10) + if (counter < -9) { - // Single digit, blank left and right (prevents flicker) + // Two digit negative, blank left and right (minimizes flicker) and spacing + blankDigitColumn(&column, SpacingNegativeLeft2); + drawMinusSign(&column); + blankDigitColumn(&column, DigitSpacing); + + drawDigit(&column, (-counter) / 10); + blankDigitColumn(&column, DigitSpacing); + drawDigit(&column, (-counter) % 10); + + blankDigitColumn(&column, SpacingNegativeRight2); + } + else if (counter < 0) + { + // Single digit negative, similar + blankDigitColumn(&column, SpacingNegativeLeft1); + drawMinusSign(&column); + blankDigitColumn(&column, DigitSpacing); + drawDigit(&column, -counter); + blankDigitColumn(&column, SpacingNegativeRight1); + } + else if (counter < 10) + { + // Single digit, blank left and right only blankDigitColumn(&column, SpacingLeft1); - drawDigit(&column, value); + drawDigit(&column, counter); blankDigitColumn(&column, SpacingRight1); } - else if (value < 100) + else if (counter < 100) { - // Two digits, similar but also blank the spacing + // Two digits, you know the drill by now blankDigitColumn(&column, SpacingLeft2); - drawDigit(&column, value / 10); + drawDigit(&column, counter / 10); blankDigitColumn(&column, DigitSpacing); - drawDigit(&column, value % 10); + drawDigit(&column, counter % 10); blankDigitColumn(&column, SpacingRight2); } else { - // Three digits, you know the drill by now - drawDigit(&column, value / 100); + // Three digits + drawDigit(&column, counter / 100); blankDigitColumn(&column, DigitSpacing); - drawDigit(&column, (value % 100) / 10); + drawDigit(&column, (counter % 100) / 10); blankDigitColumn(&column, DigitSpacing); - drawDigit(&column, value % 10); + drawDigit(&column, counter % 10); } } @@ -96,6 +121,29 @@ void drawDigit(uint8_t* column, uint8_t digit) } +void drawMinusSign(uint8_t* column) +{ + uint8_t yEnd = DigitPage + DigitRows; + uint16_t bitmapOffset = 0; + + for (uint8_t y = DigitPage; y < yEnd; y++) + { + ssd1306_setpos(*column, y); + ssd1306_send_data_start(); + + for (uint8_t x = 0; x < MinusSignWidth; x++) + { + ssd1306_send_byte(pgm_read_byte(&MinusSign[bitmapOffset])); + bitmapOffset++; + } + + ssd1306_send_data_stop(); + } + + (*column) += MinusSignWidth; +} + + void blankDigitColumn(uint8_t* column, uint8_t width) { uint8_t yEnd = DigitPage + DigitRows; diff --git a/Source/src/screen/counter.h b/Source/src/screen/counter.h index bfb56fa..85324e2 100644 --- a/Source/src/screen/counter.h +++ b/Source/src/screen/counter.h @@ -22,12 +22,22 @@ #define DigitOffset2 ((DisplayWidth - DigitWidth2) / 2) #define SpacingLeft2 ((DigitFullWidth - DigitWidth2) / 2) #define SpacingRight2 (DigitFullWidth - DigitWidth2 - SpacingLeft2) -#define DigitWidth1 DigitWidth +#define DigitNegativeWidth2 (DigitWidth2 + MinusSignWidth + DigitSpacing) +#define DigitNegativeOffset2 ((DisplayWidth - DigitNegativeWidth2) / 2) +#define SpacingNegativeLeft2 ((DigitFullWidth - DigitNegativeWidth2) / 2) +#define SpacingNegativeRight2 (DigitFullWidth - DigitNegativeWidth2 - SpacingNegativeLeft2) + +#define DigitWidth1 DigitWidth #define DigitOffset1 ((DisplayWidth - DigitWidth1) / 2) #define SpacingLeft1 ((DigitFullWidth - DigitWidth1) / 2) #define SpacingRight1 (DigitFullWidth - DigitWidth1 - SpacingLeft1) +#define DigitNegativeWidth1 (DigitWidth + MinusSignWidth + DigitSpacing) +#define DigitNegativeOffset1 ((DisplayWidth - DigitNegativeWidth1) / 2) +#define SpacingNegativeLeft1 ((DigitFullWidth - DigitNegativeWidth1) / 2) +#define SpacingNegativeRight1 (DigitFullWidth - DigitNegativeWidth1 - SpacingNegativeLeft1) + extern void handleCounterScreen();