Changed display lib and added support for upto 6 digits (limit for TM1637)

This commit is contained in:
Ajith Vasudevan 2021-02-16 17:42:49 +05:30
parent c80d19ad92
commit 11852fe549
53 changed files with 3228 additions and 3363 deletions

View File

@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -1,136 +0,0 @@
# TM1637 Tiny Display #
[![arduino-library-badge](https://www.ardu-badge.com/badge/TM1637TinyDisplay.svg?)](https://www.ardu-badge.com/TM1637TinyDisplay)
[![Build Status](https://travis-ci.org/jasonacox/TM1637TinyDisplay.svg?branch=master)](https://travis-ci.org/github/jasonacox/TM1637TinyDisplay)
Arduino Library for the TM1637 Based LED Display Module
## Description
This is an Arduino library for 4-digit 7-segment display modules based on the TM1637 chip.
Connect the TM1637 display CLK and DIO pins to your Arduino GPIO pins, include this library, initialize TM1637TinyDisplay and call easy to use functions like showNumber(), showString(), showLevel() and showAnimation(). Display will scroll text for larger strings. Functions support screen splitting for easy number + text formatting. Library also runs well on tiny controllers including the ATtiny85.
## Hardware
![TM1637](examples/tm1637.png)
Display modules based on the TM1637 chip are available from [HiLetgo](https://www.amazon.com/gp/product/B01DKISMXK/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1), [DX](https://dx.com/p/0-36-led-4-digit-display-module-for-arduino-black-blue-works-with-official-arduino-boards-254978) and [SeeedStudio](https://www.digikey.com/products/en?keywords=tm1637).
![TM1637](examples/tm1637back.png)
The display has four connectors:
* CLK - Clock - attach to any GPIO output
* DIO - Data - attach to any GPIO output
* VCC - Power 5v
* GND - Ground
Power Note: Steady clean power is important for circuit stability. If you are seeing display artifacts during high frequency updates or animation sequences, you may be experiencing power fluctuations that are impacting signal timing and communication with the TM1637. This is especially true with standalone microprocessor applications that lack any power conditioning (e.g. ATtiny85). A polarized 100uF electrolytic capacitor inserted across VCC and GND can help smooth out the spikes.
Decimals and Colons: Some TM1637 displays come equipped with a middle colon LED (as shown above) as used in digital clocks but with no decimal points. Some displays come with decimal point LEDS for each digit. Some come with both but often the decimal point LEDs are not connected. These extra LEDs are activated by setting the upper bit (0x80) for the digit next to the dot. This library will handle setting that for you via the showNumber() function when you specify floating point numbers or via the showNumberDec() function where you can set the decimal point manually.
## Installation
This library is available via the Arduino IDE. Install this library via `Tools`, `Manage Libraries`, search for "TM1637TinyDisplay" and click `Install`.
Alternatively, you can install this manually by cloning this repo into your Arduino library folder (e.g. `~/Documents/Arduino/libraries`).
## Usage
The library provides a single class named TM1637TinyDisplay with the following functions:
* `showNumber` - Display an integer and floating point numbers (positive or negative)
* `showNumberDec` - Display a number with ability to manually set decimal points or colon
* `showNumberHex` - Display a number in hexadecimal format and set decimal point or colon
* `showString` - Display a ASCII string of text with optional scrolling for long strings
* `showLevel` - Use display LEDs to simulate a level indicator (vertical or horizontal)
* `showAnimation` - Display a sequence of frames to render an animation
* `setSegments` - Directly set the value of the LED segments in each digit
* `setBrightness` - Sets the brightness of the display
* `setScrolldelay` - Sets the speed for text scrolling
PROGMEM functions: Large string or animation data can be left in Flash instead of being loaded in to SRAM to save memory.
* `showAnimation_P` - Display a sequence of frames to render an animation (in PROGMEM)
* `showString_P` - Display a ASCII string of text with optional scrolling for long strings (in PROGMEM)
## Example Code
```cpp
#include <Arduino.h>
#include <TM1637TinyDisplay.h>
// Define Digital Pins
#define CLK 1
#define DIO 2
// Initialize TM1637TinyDisplay
TM1637TinyDisplay display(CLK, DIO);
void setup() {
display.setBrightness(0x0f);
}
void loop() {
// Say Hello
display.showString("HELLO");
delay(500);
// Clear Screen
display.clear();
// We can count!
for (int x = -100; x <= 100; x++) {
display.showNumber(x);
}
// Level indicator
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, false);
delay(20);
}
for (int x = 100; x >= 0; x = x - 10) {
display.showLevel(x, false);
delay(20);
}
// Split screen for temperature
display.showString("\xB0", 1, 3); // Degree Mark, length=1, position=3 (right)
for (int x = -90; x < 200; x++) {
display.showNumber(x, false, 3, 0); // Number, length=3, position=0 (left)
delay(10);
}
// The end
display.showString("End");
delay(1000);
}
```
Refer to [TM1637TinyDisplay.h](TM1637TinyDisplay.h) for information on available functions. See also [Examples](examples) for more demonstration.
## Animation and Animator Tool
The showAnimation() function projects a sequence of frames (patterns) onto the display. This works by defining the animation sequence through a multi-dimensional array of patterns.
You can use the included javascript based interactive [7-Segment LED Animator Tool](https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html) to help build your animation. The source code is in the [Examples](examples) folder. This tool will let you set up the LED sequences you want, save each frame and copy the final code (a static array) directly into your sketch to use for the `showAnimation(data, frames, timing)` function. Here is an example:
```cpp
// Data from Animator Tool
const uint8_t ANIMATION[12][4] = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 6
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 7
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 8
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 9
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 10
{ 0x10, 0x00, 0x00, 0x00 } // Frame 11
};
// Display Animation sequence
display.showAnimation(ANIMATION, FRAMES(ANIMATION), TIME_MS(50));
```
## References and Credit
* This library is based on the great work by Avishay Orpaz - https://github.com/avishorp/TM1637
* SevenSegmentTM1637 Arduino Library by Bram Harmsen - https://github.com/bremme/arduino-tm1637
* Arduino - https://playground.arduino.cc/Main/TM1637/

View File

@ -1,20 +0,0 @@
# Release Notes for TM1637TinyDisplay
## v1.0.0
- Initial Release.
## v1.1.0
- Added interactive [Animator Tool](https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html) to create frame data for the showAnimation() function.
- Added demo sketch to showcase functions and animation features.
## v1.1.1
- Added yield() call to example Demo sketch for esp8266 watchdog timer.
## v1.2.0
- Added floating number support to showNumber() for TM1637 displays with decimal points.
## v1.3.0
- Converted global digitToSegment[] and asciiToSegment[] lookup tables to PROGMEM space to save RAM.
- Fixed comparison between signed and unsigned integer expressions warning #5
- Saves ~1.5kB in the ATtiny85 example by using showNumber() instead of sprintf() #6
- Fixed implicit case fallthrough and signed/unsigned comparison warnings #7

View File

@ -1,603 +0,0 @@
// TM1637 Tiny Display
// Arduino tiny library for TM1637 LED Display
//
// Author: Jason A. Cox - @jasonacox - https://github.com/jasonacox
// Date: 27 June 2020
//
// Based on TM1637Display library at https://github.com/avishorp/TM1637
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
}
#include <TM1637TinyDisplay.h>
#include <Arduino.h>
#define TM1637_I2C_COMM1 0x40
#define TM1637_I2C_COMM2 0xC0
#define TM1637_I2C_COMM3 0x80
//
// A
// ---
// F | | B
// -G-
// E | | C
// ---
// D
const uint8_t digitToSegment[] PROGMEM = {
// XGFEDCBA
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
0b01110111, // A
0b01111100, // b
0b00111001, // C
0b01011110, // d
0b01111001, // E
0b01110001 // F
};
// ASCII Map - Index 0 starts at ASCII 32
const uint8_t asciiToSegment[] PROGMEM = {
0b00000000, // 032 (Space)
0b00110000, // 033 !
0b00100010, // 034 "
0b01000001, // 035 #
0b01101101, // 036 $
0b01010010, // 037 %
0b01111100, // 038 &
0b00100000, // 039 '
0b00111001, // 040 (
0b00001111, // 041 )
0b00100001, // 042 *
0b01110000, // 043 +
0b00001000, // 044 ,
0b01000000, // 045 -
0b00001000, // 046 .
0b01010010, // 047 /
0b00111111, // 048 0
0b00000110, // 049 1
0b01011011, // 050 2
0b01001111, // 051 3
0b01100110, // 052 4
0b01101101, // 053 5
0b01111101, // 054 6
0b00000111, // 055 7
0b01111111, // 056 8
0b01101111, // 057 9
0b01001000, // 058 :
0b01001000, // 059 ;
0b00111001, // 060 <
0b01001000, // 061 =
0b00001111, // 062 >
0b01010011, // 063 ?
0b01011111, // 064 @
0b01110111, // 065 A
0b01111100, // 066 B
0b00111001, // 067 C
0b01011110, // 068 D
0b01111001, // 069 E
0b01110001, // 070 F
0b00111101, // 071 G
0b01110110, // 072 H
0b00000110, // 073 I
0b00011110, // 074 J
0b01110110, // 075 K
0b00111000, // 076 L
0b00010101, // 077 M
0b00110111, // 078 N
0b00111111, // 079 O
0b01110011, // 080 P
0b01100111, // 081 Q
0b00110001, // 082 R
0b01101101, // 083 S
0b01111000, // 084 T
0b00111110, // 085 U
0b00011100, // 086 V
0b00101010, // 087 W
0b01110110, // 088 X
0b01101110, // 089 Y
0b01011011, // 090 Z
0b00111001, // 091 [
0b01100100, // 092 (backslash)
0b00001111, // 093 ]
0b00100011, // 094 ^
0b00001000, // 095 _
0b00100000, // 096 `
0b01110111, // 097 a
0b01111100, // 098 b
0b01011000, // 099 c
0b01011110, // 100 d
0b01111001, // 101 e
0b01110001, // 102 f
0b01101111, // 103 g
0b01110100, // 104 h
0b00000100, // 105 i
0b00011110, // 106 j
0b01110110, // 107 k
0b00011000, // 108 l
0b00010101, // 109 m
0b01010100, // 110 n
0b01011100, // 111 o
0b01110011, // 112 p
0b01100111, // 113 q
0b01010000, // 114 r
0b01101101, // 115 s
0b01111000, // 116 t
0b00011100, // 117 u
0b00011100, // 118 v
0b00101010, // 119 w
0b01110110, // 120 x
0b01101110, // 121 y
0b01011011, // 122 z
0b00111001, // 123 {
0b00110000, // 124 |
0b00001111, // 125 }
0b01000000, // 126 ~
0b00000000 // 127 
};
static const uint8_t minusSegments = 0b01000000;
static const uint8_t degreeSegments = 0b01100011;
TM1637TinyDisplay::TM1637TinyDisplay(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay, unsigned int scrollDelay)
{
// Copy the pin numbers
m_pinClk = pinClk;
m_pinDIO = pinDIO;
m_bitDelay = bitDelay;
m_scrollDelay = scrollDelay;
// Set the pin direction and default value.
// Both pins are set as inputs, allowing the pull-up resistors to pull them up
pinMode(m_pinClk, INPUT);
pinMode(m_pinDIO,INPUT);
digitalWrite(m_pinClk, LOW);
digitalWrite(m_pinDIO, LOW);
}
void TM1637TinyDisplay::setBrightness(uint8_t brightness, bool on)
{
m_brightness = (brightness & 0x07) | (on? 0x08 : 0x00);
}
void TM1637TinyDisplay::setScrolldelay(unsigned int scrollDelay)
{
m_scrollDelay = scrollDelay;
}
void TM1637TinyDisplay::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos)
{
// Write COMM1
start();
writeByte(TM1637_I2C_COMM1);
stop();
// Write COMM2 + first digit address
start();
writeByte(TM1637_I2C_COMM2 + (pos & 0x03));
// Write the data bytes
for (uint8_t k=0; k < length; k++)
writeByte(segments[k]);
stop();
// Write COMM3 + brightness
start();
writeByte(TM1637_I2C_COMM3 + (m_brightness & 0x0f));
stop();
}
void TM1637TinyDisplay::clear()
{
uint8_t data[] = { 0, 0, 0, 0 };
setSegments(data);
}
void TM1637TinyDisplay::showNumber(int num, bool leading_zero, uint8_t length, uint8_t pos)
{
showNumberDec(num, 0, leading_zero, length, pos);
}
void TM1637TinyDisplay::showNumber(double num, uint8_t decimal_length, uint8_t length, uint8_t pos)
{
int num_len = 0;
int inum = abs((int)num);
int decimal_places = 0;
double value = 0.0;
bool negative = false;
bool leading_zero = false;
uint8_t digits[4] = {0,0,0,0}; // output array to render
// determine length of whole number part of num
while(inum != 0) {
inum = inum / 10;
num_len++;
}
if(num < 0) {
num_len++; // make space for negative
negative = true;
}
if(abs(num)<1) {
num_len++; // make space for 0. prefix
leading_zero = true;
}
// make sure we can display number otherwise show overflow
if(num_len > length) {
showString("----", length, pos); // overflow symbol
return;
}
// how many decimal places can we show?
decimal_places = length - num_len;
if(decimal_places > decimal_length) {
decimal_places = decimal_length;
}
// construct whole number representation of num
value = num;
for(int x=0; x < decimal_places; x++) {
value = value * 10.00;
}
if(num>0) value = value + 0.5; // round up
if(num<0) value = value - 0.5; // round down
inum = abs((int)value);
// render display array
if (inum == 0 && !leading_zero) {
digits[length-1] = encodeDigit(0);
}
else {
int decimal_pos = length - 1 - decimal_places + pos;
for(int i = length-1; i >= 0; --i) {
uint8_t digit = inum % 10;
if (digit == 0 && inum == 0 &&
(leading_zero == false || (i < decimal_pos))
)
// Blank out any leading zeros except for 0.x case
digits[i] = 0;
else
digits[i] = encodeDigit(digit);
if(i == decimal_pos && decimal_length > 0) {
digits[i] += 0b10000000; // add decimal point
}
inum /= 10;
}
}
// add negative sign for negative number
if(negative) {
digits[pos] = minusSegments;
}
setSegments(digits, length, pos);
}
void TM1637TinyDisplay::showNumberDec(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 TM1637TinyDisplay::showNumberHex(uint16_t num, uint8_t dots, bool leading_zero,
uint8_t length, uint8_t pos)
{
showNumberBaseEx(16, num, dots, leading_zero, length, pos);
}
void TM1637TinyDisplay::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;
}
uint8_t digits[4];
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 {
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;
}
num /= base;
}
}
if(dots != 0) {
showDots(dots, digits);
}
setSegments(digits, length, pos);
}
void TM1637TinyDisplay::showString(const char s[], uint8_t length, uint8_t pos)
{
uint8_t digits[4] = {0,0,0,0};
if (strlen(s) <= 4) {
switch (strlen(s)) {
case 4:
digits[3] = encodeASCII(s[3]);
// fall through
case 3:
digits[2] = encodeASCII(s[2]);
// fall through
case 2:
digits[1] = encodeASCII(s[1]);
// fall through
case 1:
digits[0] = encodeASCII(s[0]);
// fall through
case 0:
setSegments(digits, length, pos);
}
}
if (strlen(s) > 4) {
// Scroll text on display if too long
for (int x = 0; x < 3; x++) { // Scroll message on
digits[0] = digits[1];
digits[1] = digits[2];
digits[2] = digits[3];
digits[3] = encodeASCII(s[x]);
setSegments(digits, length, pos);
delay(m_scrollDelay);
}
for (size_t x = 3; x < strlen(s); x++) { // Scroll through string
digits[0] = encodeASCII(s[x - 3]);
digits[1] = encodeASCII(s[x - 2]);
digits[2] = encodeASCII(s[x - 1]);
digits[3] = encodeASCII(s[x]);
setSegments(digits, length, pos);
delay(m_scrollDelay);
}
for (int x = 0; x < 4; x++) { // Scroll message off
digits[0] = digits[1];
digits[1] = digits[2];
digits[2] = digits[3];
digits[3] = 0;
setSegments(digits, length, pos);
delay(m_scrollDelay);
}
}
}
void TM1637TinyDisplay::showString_P(const char s[], uint8_t length, uint8_t pos)
{
uint8_t digits[4] = {0,0,0,0};
if (strlen_P(s) <= 4) {
switch (strlen_P(s)) {
case 4:
digits[3] = encodeASCII(pgm_read_byte(&s[3]));
// fall through
case 3:
digits[2] = encodeASCII(pgm_read_byte(&s[2]));
// fall through
case 2:
digits[1] = encodeASCII(pgm_read_byte(&s[1]));
// fall through
case 1:
digits[0] = encodeASCII(pgm_read_byte(&s[0]));
// fall through
case 0:
setSegments(digits, length, pos);
}
}
else {
// Scroll text on display if too long
for (int x = 0; x < 3; x++) { // Scroll message on
digits[0] = digits[1];
digits[1] = digits[2];
digits[2] = digits[3];
digits[3] = encodeASCII(pgm_read_byte(&s[x]));
setSegments(digits, length, pos);
delay(m_scrollDelay);
}
for (size_t x = 3; x < strlen_P(s); x++) { // Scroll through string
digits[0] = encodeASCII(pgm_read_byte(&s[x - 3]));
digits[1] = encodeASCII(pgm_read_byte(&s[x - 2]));
digits[2] = encodeASCII(pgm_read_byte(&s[x - 1]));
digits[3] = encodeASCII(pgm_read_byte(&s[x]));
setSegments(digits, length, pos);
delay(m_scrollDelay);
}
for (int x = 0; x < 4; x++) { // Scroll message off
digits[0] = digits[1];
digits[1] = digits[2];
digits[2] = digits[3];
digits[3] = 0;
setSegments(digits, length, pos);
delay(m_scrollDelay);
}
}
}
void TM1637TinyDisplay::showLevel(unsigned int level, bool horizontal)
{
uint8_t digits[4] = {0,0,0,0};
uint8_t digit = 0b00000000;
if(level>100) level=100;
if(horizontal) {
// Must fit within 3 bars
int bars = (int)((level*3)/100.0);
if(bars == 0 && level > 0) bars = 1; // Only level=0 turns off display
switch(bars) {
case 1:
digit = 0b00001000;
break;
case 2:
digit = 0b01001000;
break;
case 3:
digit = 0b01001001;
break;
default: // Keep at zero
break;
}
for(int x = 0; x < 4; x++) {
digits[x] = digit;
}
}
else {
// Must fit within 8 bars
int bars = (int)((level*8)/100.0);
if(bars == 0 && level > 0) bars = 1;
for(int x = 0; x<4; x++) { // for each digit
int left = bars-(x*2);
if(left > 1) digits[x] = 0b00110110;
if(left == 1) digits[x] = 0b00110000;
}
}
setSegments(digits);
}
void TM1637TinyDisplay::showAnimation(const uint8_t data[][4], unsigned int frames, unsigned int ms)
{
// Animation sequence
for (unsigned int x = 0; x < frames; x++) {
setSegments(data[x]);
delay(ms);
}
}
void TM1637TinyDisplay::showAnimation_P(const uint8_t data[][4], unsigned int frames, unsigned int ms)
{
// Animation sequence for data stored in PROGMEM flash memory
uint8_t digits[4] = {0,0,0,0};
for (unsigned int x = 0; x < frames; x++) {
for(unsigned int a = 0; a < 4; a++) {
digits[a] = pgm_read_byte(&(data[x][a]));
}
setSegments(digits);
delay(ms);
}
}
void TM1637TinyDisplay::bitDelay()
{
delayMicroseconds(m_bitDelay);
}
void TM1637TinyDisplay::start()
{
pinMode(m_pinDIO, OUTPUT);
bitDelay();
}
void TM1637TinyDisplay::stop()
{
pinMode(m_pinDIO, OUTPUT);
bitDelay();
pinMode(m_pinClk, INPUT);
bitDelay();
pinMode(m_pinDIO, INPUT);
bitDelay();
}
bool TM1637TinyDisplay::writeByte(uint8_t b)
{
uint8_t data = b;
// 8 Data Bits
for(uint8_t i = 0; i < 8; i++) {
// CLK low
pinMode(m_pinClk, OUTPUT);
bitDelay();
// Set data bit
if (data & 0x01)
pinMode(m_pinDIO, INPUT);
else
pinMode(m_pinDIO, OUTPUT);
bitDelay();
// CLK high
pinMode(m_pinClk, INPUT);
bitDelay();
data = data >> 1;
}
// Wait for acknowledge
// CLK to zero
pinMode(m_pinClk, OUTPUT);
pinMode(m_pinDIO, INPUT);
bitDelay();
// CLK to high
pinMode(m_pinClk, INPUT);
bitDelay();
uint8_t ack = digitalRead(m_pinDIO);
if (ack == 0)
pinMode(m_pinDIO, OUTPUT);
bitDelay();
pinMode(m_pinClk, OUTPUT);
bitDelay();
return ack;
}
void TM1637TinyDisplay::showDots(uint8_t dots, uint8_t* digits)
{
for(int i = 0; i < 4; ++i)
{
digits[i] |= (dots & 0x80);
dots <<= 1;
}
}
uint8_t TM1637TinyDisplay::encodeDigit(uint8_t digit)
{
// return digitToSegment[digit & 0x0f] using PROGMEM
return pgm_read_byte(digitToSegment + (digit & 0x0f));
}
uint8_t TM1637TinyDisplay::encodeASCII(uint8_t chr)
{
if(chr == 176) return degreeSegments; // Degree mark
if(chr > 127 || chr < 32) return 0; // Blank
// return asciiToSegment[chr - 32] using PROGMEM
return pgm_read_byte(asciiToSegment + (chr - 32));
}

View File

@ -1,316 +0,0 @@
// TM1637 Tiny Display
// Arduino tiny library for TM1637 LED Display
//
// Author: Jason A. Cox - @jasonacox - https://github.com/jasonacox
// Date: 27 June 2020
//
// Based on TM1637Display library at https://github.com/avishorp/TM1637
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef __TM1637TINYDISPLAY__
#define __TM1637TINYDISPLAY__
// Include PROGMEM Support
#include <inttypes.h>
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#define pgm_read_byte(addr) \
(*(const unsigned char *)(addr)) // workaround for non-AVR
#endif
#define SEG_A 0b00000001
#define SEG_B 0b00000010
#define SEG_C 0b00000100
#define SEG_D 0b00001000
#define SEG_E 0b00010000
#define SEG_F 0b00100000
#define SEG_G 0b01000000
#define SEG_DP 0b10000000
#define BRIGHT_LOW 0x00
#define BRIGHT_0 0x00
#define BRIGHT_1 0x01
#define BRIGHT_2 0x02
#define BRIGHT_3 0x03
#define BRIGHT_4 0x04
#define BRIGHT_5 0x05
#define BRIGHT_6 0x06
#define BRIGHT_7 0x07
#define BRIGHT_HIGH 0x0f
#define ON 1
#define OFF 0
#define DEFAULT_BIT_DELAY 100
#define DEFAULT_SCROLL_DELAY 100
#define FRAMES(a) sizeof(a)/4
#define TIME_MS(t) t
#define TIME_S(t) t*1000
class TM1637TinyDisplay {
public:
//! Initialize a TM1637TinyDisplay object, setting the clock and
//! data pins.
//!
//! @param pinClk - The number of the digital pin connected to the clock pin of the module
//! @param pinDIO - The number of the digital pin connected to the DIO pin of the module
//! @param bitDelay - The delay, in microseconds, between bit transition on the serial
//! bus connected to the display
TM1637TinyDisplay(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay = DEFAULT_BIT_DELAY, unsigned int scrollDelay = DEFAULT_SCROLL_DELAY);
//! Sets the brightness of the display.
//!
//! The setting takes effect when a command is given to change the data being
//! displayed.
//!
//! @param brightness A number from 0 (lowest brightness) to 7 (highest brightness)
//! @param on Turn display on or off
void setBrightness(uint8_t brightness, bool on = true);
//! Sets the delay used to scroll string text (in ms).
//!
//! The setting takes effect when a showString() command send an argument with over
//! four characters.
//!
//! @param scrollDelay A number in milliseconds (default is 200)
void setScrolldelay(unsigned int scrollDelay = 200);
//! Display arbitrary data on the module
//!
//! This function receives raw segment values as input and displays them. The segment data
//! is given as a byte array, each byte corresponding to a single digit. Within each byte,
//! bit 0 is segment A, bit 1 is segment B etc.
//! The function may either set the entire display or any desirable part on its own. The first
//! digit is given by the @ref pos argument with 0 being the leftmost digit. The @ref length
//! argument is the number of digits to be set. Other digits are not affected.
//!
//! @param segments An array of size @ref length containing the raw segment values
//! @param length The number of digits to be modified
//! @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);
//! Clear the display
void clear();
//! Display a decimal number
//!
//! Display 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. 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 showNumber(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
//! Display a decimal number with floating point
//!
//! Display the given argument as a decimal number. Decimal point will only show up on displays
//! that support decimal point.
//!
//! @param num The number to be shown
//! @param decimal_length Format to show only this number of digits after the decimal point.
//! NOTE: Anything over 4 will do best fit.
//! @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 showNumber(double num, uint8_t decimal_length = 4, uint8_t length = 4, uint8_t pos = 0);
//! Display a decimal number, with dot control
//!
//! Display 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)
//! * 0000. (0b00010000)
//! * 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 showNumberDec(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
//!
//! Display 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
//! 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)
//! * 0000. (0b00010000)
//! * 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
//! @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 showNumberHex(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
//!
//! The method accepts a number between 0 - 15 and converts it to the
//! code required to display the number on a 7 segment display.
//! Numbers between 10-15 are converted to hexadecimal digits (A-F)
//!
//! @param digit A number between 0 to 15
//! @return A code representing the 7 segment image of the digit (LSB - segment A;
//! bit 6 - segment G; bit 7 - always zero)
uint8_t encodeDigit(uint8_t digit);
//! Display a string
//!
//! Display the given string and if more than 4 characters, will scroll message on display
//!
//! @param s The string to be shown
//! @param scrollDelay The delay, in microseconds to wait before scrolling to next frame
//! @param length The number of digits to set.
//! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
//! The _P function is for reading PROGMEM read-only flash memory space instead of RAM
void showString(const char s[], uint8_t length = 4, uint8_t pos = 0);
//! Display a string (PROGMEM space)
//!
//! Display the given string and if more than 4 characters, will scroll message on display
//! This function is for reading PROGMEM read-only flash memory space instead of RAM
//!
//! @param s The string to be shown
//! @param scrollDelay The delay, in microseconds to wait before scrolling to next frame
//! @param length The number of digits to set.
//! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
//! The _P function is for reading PROGMEM read-only flash memory space instead of RAM
void showString_P(const char s[], uint8_t length = 4, uint8_t pos = 0);
//! Display a Level Indicator (both orientations)
//!
//! Illumiate LEDs to provide a visual indicator of level (horizontal or vertical orientation)
//!
//! @param level A value between 0 and 100 (representing percentage)
//! @param horizontal Boolean (true/false) where true = horizontal, false = vertical
void showLevel(unsigned int level = 100, bool horizontal = true);
//! Display a sequence of raw LED segment data to create an animation
//!
//! Play thorugh an array of raw LED segment data to create a moving pattern.
//!
//! const uint8_t Example[2][4] =
//! {
//! { // frame 1
//! 0b00001000, // digit 1
//! 0b00000000, // digit 2
//! 0b00000000, // digit 3
//! 0b00000000 // digit 4
//! },
//! { // frame 2
//! 0b00000000, // digit 1
//! 0b00001000, // digit 2
//! 0b00000000, // digit 3
//! 0b00000000 // digit 4
//! }
//! }
//! @param data A multi-dimensional array containing the LED segment - data[frames][4]
//! @param frames Number of frames in the sequence to animate
//! @param ms Time to delay between each frame
//! The _P function is for reading PROGMEM read-only flash memory space instead of RAM
void showAnimation(const uint8_t data[][4], unsigned int frames = 0, unsigned int ms = 10);
//! Display a sequence of raw LED segment data to create an animation (PROGMEM)
//!
//! Play thorugh an array of raw LED segment data to create a moving pattern.
//! This function is for reading PROGMEM read-only flash memory space instead of RAM
//!
//! const uint8_t Example[2][4] =
//! {
//! { // frame 1
//! 0b00001000, // digit 1
//! 0b00000000, // digit 2
//! 0b00000000, // digit 3
//! 0b00000000 // digit 4
//! },
//! { // frame 2
//! 0b00000000, // digit 1
//! 0b00001000, // digit 2
//! 0b00000000, // digit 3
//! 0b00000000 // digit 4
//! }
//! }
//! @param data A multi-dimensional array containing the LED segment - data[frames][4]
//! @param frames Number of frames in the sequence to animate
//! @param ms Time to delay between each frame
void showAnimation_P(const uint8_t data[][4], unsigned int frames = 0, unsigned int ms = 10);
//! Translate a single ASCII character into 7 segment code
//!
//! The method accepts a number between 0 - 255 and converts it to the
//! code required to display the number on a 7 segment display.
//! ASCII Characters between 0-32 and 128-255 are blank.
//!
//! @param chr A character ASCII value
//! @return A code representing the 7 segment image of the digit (LSB - segment A;
//! bit 6 - segment G; bit 7 - always zero)
uint8_t encodeASCII(uint8_t chr);
protected:
void bitDelay();
void start();
void stop();
bool writeByte(uint8_t b);
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;
uint8_t m_pinDIO;
uint8_t m_brightness;
unsigned int m_bitDelay;
unsigned int m_scrollDelay;
};
#endif // __TM1637TINYDISPLAY__

View File

@ -1 +0,0 @@
theme: jekyll-theme-cayman

View File

@ -1,638 +0,0 @@
<!--
7-Segment LED Display Animator Tool
Author: Jason A. Cox - @jasonacox - https://github.com/jasonacox
https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html
Description:
This tool will allow the user to visually toggle on/off LEDs in a 4-digit
7-segment display to create a pattern. It will show the hexadecimal and binary
value for the pattern. The user can then SAVE the pattern as a frame in an
animation sequence which will show up in the "Animation Data" section below
the controls. The user can then PLAY back the animation on the display. Once
complete, the user can COPY the code to their clipboard and paste the data
into their sketch. Designed for the Arduino TM1637TinyDisplay library available
for download in the Arduino IDE or via GitHub:
https://github.com/jasonacox/TM1637TinyDisplay
Date: 1 July 2020
-->
<html>
<head>
<style>
div {
font:14px Arial, Serif;
}
#digitPane {
background-color: black;
width: 600px;
text-align: center;
border:1px solid #4e4e4e;
}
.off {
fill: #320000;
}
.on {
fill: red;
}
#readings {
display: inline-block;
width: 120px;
margin-left: 20px;
font:14px Arial, Serif;
text-align: center;
margin-top: 5px;
margin-bottom: 5px;
}
#valuePane {
width: 600px;
margin-left: 0px;
background-color: #d3d3d3;
border:1px solid #4e4e4e;
}
#codeOutput {
/* height:100px; */
width:588px;
margin-top: 5px;
margin-left: 5px;
margin-bottom: 5px;
border:1px solid #4e4e4e;
font:15px Arial, Serif;
/* overflow:auto; uncomment to turn on scrolling */
background-color: white;
}
#controls {
display: inline-block;
width: 600;
text-align: center;
margin-top: 5px;
margin-bottom: 5px;
}
#controls2 {
display: inline-block;
width: 600;
margin-left: 20px;
text-align: left;
margin-top: 5px;
}
#controlsleft {
display: inline-block;
width: 200;
margin-left: 10px;
text-align: left;
}
#controlsright {
display: inline-block;
width: 350;
margin-right: 10px;
text-align: right;
}
#instructions {
display: inline-block;
width: 600;
margin-left: 20px;
text-align: left;
margin-bottom: 20px;
margin-top: 10px;
}
#datacontrols {
display: inline-block;
width: 560;
margin-left: 20px;
text-align: left;
background-color: white;
}
#outputblock {
width: 600px;
margin-left: 0px;
margin-top: 10px;
background-color: salmon;
border:1px solid #4e4e4e;
}
#help {
width: 560;
text-align: left;
}
.highlight
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 18px;
background: yellow;
z-index: -1;
display: none;
}
/* 7-segment LED Binary Data
|--A--|
F B
|--G--|
E C
|--D--|
H - Decimal
HGFEDCBA
0b00000000
*/
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<h1>7-Segment LED Display Animator</h1>
<div id="digitPane">
<svg xmlns="http://www.w3.org/2000/svg" width="140px" height="200px" viewBox="2 -2 10 22">
<g class="digit1">
<polygon id="a" class="off" points=" 1, 1 2, 0 8, 0 9, 1 8, 2 2, 2"/>
<polygon id="b" class="off" points=" 9, 1 10, 2 10, 8 9, 9 8, 8 8, 2"/>
<polygon id="c" class="off" points=" 9, 9 10,10 10,16 9,17 8,16 8,10"/>
<polygon id="d" class="off" points=" 9,17 8,18 2,18 1,17 2,16 8,16"/>
<polygon id="e" class="off" points=" 1,17 0,16 0,10 1, 9 2,10 2,16"/>
<polygon id="f" class="off" points=" 1, 9 0, 8 0, 2 1, 1 2, 2 2, 8"/>
<polygon id="g" class="off" points=" 1, 9 2, 8 8, 8 9, 9 8,10 2,10"/>
<polygon id="h" class="off" points=" 11,16 13,16 13,18 11,18"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="140px" height="200px" viewBox="2 -2 10 22">
<g class="digit2">
<polygon id="a" class="off" points=" 1, 1 2, 0 8, 0 9, 1 8, 2 2, 2"/>
<polygon id="b" class="off" points=" 9, 1 10, 2 10, 8 9, 9 8, 8 8, 2"/>
<polygon id="c" class="off" points=" 9, 9 10,10 10,16 9,17 8,16 8,10"/>
<polygon id="d" class="off" points=" 9,17 8,18 2,18 1,17 2,16 8,16"/>
<polygon id="e" class="off" points=" 1,17 0,16 0,10 1, 9 2,10 2,16"/>
<polygon id="f" class="off" points=" 1, 9 0, 8 0, 2 1, 1 2, 2 2, 8"/>
<polygon id="g" class="off" points=" 1, 9 2, 8 8, 8 9, 9 8,10 2,10"/>
<polygon id="h" class="off" points=" 11,16 13,16 13,18 11,18"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="140px" height="200px" viewBox="2 -2 10 22">
<g class="digit3">
<polygon id="a" class="off" points=" 1, 1 2, 0 8, 0 9, 1 8, 2 2, 2"/>
<polygon id="b" class="off" points=" 9, 1 10, 2 10, 8 9, 9 8, 8 8, 2"/>
<polygon id="c" class="off" points=" 9, 9 10,10 10,16 9,17 8,16 8,10"/>
<polygon id="d" class="off" points=" 9,17 8,18 2,18 1,17 2,16 8,16"/>
<polygon id="e" class="off" points=" 1,17 0,16 0,10 1, 9 2,10 2,16"/>
<polygon id="f" class="off" points=" 1, 9 0, 8 0, 2 1, 1 2, 2 2, 8"/>
<polygon id="g" class="off" points=" 1, 9 2, 8 8, 8 9, 9 8,10 2,10"/>
<polygon id="h" class="off" points=" 11,16 13,16 13,18 11,18"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="140px" height="200px" viewBox="2 -2 10 22">
<g class="digit4">
<polygon id="a" class="off" points=" 1, 1 2, 0 8, 0 9, 1 8, 2 2, 2"/>
<polygon id="b" class="off" points=" 9, 1 10, 2 10, 8 9, 9 8, 8 8, 2"/>
<polygon id="c" class="off" points=" 9, 9 10,10 10,16 9,17 8,16 8,10"/>
<polygon id="d" class="off" points=" 9,17 8,18 2,18 1,17 2,16 8,16"/>
<polygon id="e" class="off" points=" 1,17 0,16 0,10 1, 9 2,10 2,16"/>
<polygon id="f" class="off" points=" 1, 9 0, 8 0, 2 1, 1 2, 2 2, 8"/>
<polygon id="g" class="off" points=" 1, 9 2, 8 8, 8 9, 9 8,10 2,10"/>
<polygon id="h" class="off" points=" 11,16 13,16 13,18 11,18"/>
</g>
</svg>
</div>
<div id="valuePane">
<div id="readings">
<div id="val1">Digit 1</div>
<div id="hex1">HEX</div>
<div id="bin1">BIN</div>
</div>
<div id="readings">
<div id="val2">Digit 2</div>
<div id="hex2">HEX</div>
<div id="bin2">BIN</div>
</div>
<div id="readings">
<div id="val3">Digit 3</div>
<div id="hex3">HEX</div>
<div id="bin3">BIN</div>
</div>
<div id="readings">
<div id="val4">Digit 4</div>
<div id="hex4">HEX</div>
<div id="bin4">BIN</div>
</div>
<div id="controls">
<button onclick="saveFrame()">Save Frame</button>
<button onclick="playAnimation()">Playback Animation</button>
<button onclick="clearDisplay()">Clear</button> |
<button onclick="updateFrame()" id="frame">Frame = 0</button>
<button onclick="updateSpeed()" id="delay">Delay = 100</button>
<button onclick="toggleMap()" id="map">HGFEDCBA</button>
</div>
</div>
<div id="instructions">
<div id="help"><b>Instructions:</b> Click segments above to toggle LED state and
click "Save" to record frame. Data for the
animation will be generated below. Click the "Copy Code" button and paste
the data definition into your sketch. See Arduino library
<a href="https://github.com/jasonacox/TM1637TinyDisplay" target="_blank" >TM1637TinyDisplay</a>.
</div>
</div>
<br>
<div id="outputblock">
<div id="controls2">
<div id="controlsleft"><b>Animation Data</b></div>
<div id="controlsright">
<button onclick="copyCode()">Copy Code</button>
<button onclick="if(confirmErase('This will clear current animation - Proceed?')) clearData()">Clear Data</button>
<button onclick="formatData()">Format Data</button>
<button onclick="if(confirmErase('This will replace current animation - Proceed?')) exampleData()">Example</button>
</div>
</div>
<pre id="codeOutput" contentEditable="true">
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 0</pre>
</div>
<script>
// Globals //
var delayTime = 100; // Time between animation frames in ms
var currentFrame = 0; // TODO - Allow editing of frames
var HGFEDCBA = true; // Binary Map - True=HGFEDCBA and False=ABCDEFGH
// Functions //
// Popup to ask user msg to confirm
function confirmErase(msg) {
console.log("size: " + $('#codeOutput').text().length);
if($('#codeOutput').text().length > 39) {
return(window.confirm(msg));
}
else return(true);
}
// Flip binary order to change mapping
function flipByte(digitbin) {
var ret = 0b00000000;
console.log("digitbin: ".concat(digitbin," ret: ", ret));
if((digitbin & 0b00000001)>0) ret += 0b10000000;
if((digitbin & 0b00000010)>0) ret += 0b01000000;
if((digitbin & 0b00000100)>0) ret += 0b00100000;
if((digitbin & 0b00001000)>0) ret += 0b00010000;
if((digitbin & 0b00010000)>0) ret += 0b00001000;
if((digitbin & 0b00100000)>0) ret += 0b00000100;
if((digitbin & 0b01000000)>0) ret += 0b00000010;
if((digitbin & 0b10000000)>0) ret += 0b00000001;
return(ret);
}
// Toggle binary order for segment map
function toggleMap() {
if(HGFEDCBA) {
HGFEDCBA = false;
$('#map').text("ABCDEFGH");
}
else {
HGFEDCBA = true;
$('#map').text("HGFEDCBA");
}
formatData(true);
updateValues();
}
// Refresh button frame number indicator to last frame
function updateFrame() {
formatData();
var last = lastFrame();
showFrame(last);
}
// Toggle through speed options
function updateSpeed() {
switch(delayTime) {
case 200:
delayTime = 100;
break;
case 100:
delayTime = 50;
break;
case 50:
delayTime = 25;
break;
case 25:
delayTime = 500;
break;
default:
delayTime = 200;
break;
}
$('#delay').text("Delay = ".concat(delayTime.toString()));
}
// Copy animation data to users clipboard
function textToClipboard (text) {
var dummy = document.createElement("textarea");
dummy.setAttribute('readonly', '');
dummy.style.position = 'absolute';
dummy.style.left = '-9999px';
document.body.appendChild(dummy);
dummy.value = text;
dummy.select();
document.execCommand("copy");
document.body.removeChild(dummy);
}
// Generate code from animation data and update code output div
function copyCode() {
formatData();
var frame = 0;
var frameNum = lastFrame() + 1;
var buffer = "/* Animation Data - ";
if(HGFEDCBA) buffer = buffer + "HGFEDCBA Map */\n";
else buffer = buffer + "ABCDEFGH Map */\n";
buffer = buffer.concat("const uint8_t ANIMATION[",frameNum,"][4] = {");
// Copy data into code format and add to clipboard
var lines = $('#codeOutput').text().split("\n");
while(frame < lines.length) {
// Each frames to buffer
var line = lines[frame];
if(frame == (lines.length-1)) {
buffer = buffer.concat("\n ",line.replace("},","} "));
}
else if(line.length > 19) {
buffer = buffer.concat("\n ",line);
}
frame++;
}
buffer = buffer.concat("\n};");
console.log(buffer);
textToClipboard(buffer);
$('#codeOutput').text((buffer.concat(" ")).trim());
$("#outputblock").css("background-color","green");
}
// Erase all animation data
function clearData() {
$('#codeOutput').text('');
$('#frame').text("Frame = 0");
$("#outputblock").css("background-color","salmon");
}
// Load en example animation
function exampleData() {
var data = " { 0x08, 0x00, 0x00, 0x00 },\n { 0x00, 0x08, 0x00, 0x00 },\n { 0x00, 0x00, 0x08, 0x00 },\n { 0x00, 0x00, 0x00, 0x08 },\n { 0x00, 0x00, 0x00, 0x04 },\n { 0x00, 0x00, 0x00, 0x02 },\n { 0x00, 0x00, 0x00, 0x01 },\n { 0x00, 0x00, 0x01, 0x00 },\n { 0x00, 0x01, 0x00, 0x00 },\n { 0x01, 0x00, 0x00, 0x00 },\n { 0x20, 0x00, 0x00, 0x00 },\n { 0x10, 0x00, 0x00, 0x00 },";
$('#codeOutput').text(data);
$("#outputblock").css("background-color","salmon");
formatData(!HGFEDCBA);
}
// Return the value of digit dig
function grabValue(dig) {
// Compute binary value based on segment LEDs
var digitbin = 0;
if($(dig.concat(" #a")).attr("class") == "on") digitbin += 0b00000001;
if($(dig.concat(" #b")).attr("class") == "on") digitbin += 0b00000010;
if($(dig.concat(" #c")).attr("class") == "on") digitbin += 0b00000100;
if($(dig.concat(" #d")).attr("class") == "on") digitbin += 0b00001000;
if($(dig.concat(" #e")).attr("class") == "on") digitbin += 0b00010000;
if($(dig.concat(" #f")).attr("class") == "on") digitbin += 0b00100000;
if($(dig.concat(" #g")).attr("class") == "on") digitbin += 0b01000000;
if($(dig.concat(" #h")).attr("class") == "on") digitbin += 0b10000000;
// Note: the svg LED segment values use HGFEDCBA map
if(!HGFEDCBA) return(flipByte(digitbin)); // flip if ABCDEFGH map
else return(digitbin);
}
// Clear all digits
function clearDisplay(){
resetZero(".digit1");
resetZero(".digit2");
resetZero(".digit3");
resetZero(".digit4");
var frameNum = lastFrame() + 1;
$('#frame').text("Frame = ".concat(frameNum.toString()));
$("#outputblock").css("background-color","salmon");
}
// Clear a single digit dig
function resetZero(dig) {
$(dig.concat(" #a")).attr("class","off");
$(dig.concat(" #b")).attr("class","off");
$(dig.concat(" #c")).attr("class","off");
$(dig.concat(" #d")).attr("class","off");
$(dig.concat(" #e")).attr("class","off");
$(dig.concat(" #f")).attr("class","off");
$(dig.concat(" #g")).attr("class","off");
$(dig.concat(" #h")).attr("class","off");
}
// Set digit dig segment LEDs based on d
function setDigit(dig, d) {
resetZero(dig);
var digitbin = d;
// Note: the svg LED segment values always use HGFEDCBA map
if(!HGFEDCBA) digitbin = flipByte(d); // flip if ABCDEFGH
if((digitbin & 0b00000001) > 0)
$(dig.concat(" #a")).attr("class","on");
if((digitbin & 0b00000010) > 0)
$(dig.concat(" #b")).attr("class","on");
if((digitbin & 0b00000100) > 0)
$(dig.concat(" #c")).attr("class","on");
if((digitbin & 0b00001000) > 0)
$(dig.concat(" #d")).attr("class","on");
if((digitbin & 0b00010000) > 0)
$(dig.concat(" #e")).attr("class","on");
if((digitbin & 0b00100000) > 0)
$(dig.concat(" #f")).attr("class","on");
if((digitbin & 0b01000000) > 0)
$(dig.concat(" #g")).attr("class","on");
if((digitbin & 0b10000000) > 0)
$(dig.concat(" #h")).attr("class","on");
updateValues();
}
// Compute digit values and display values below digits
function updateValues() {
digit1bin = grabValue(".digit1");
$('#hex1').html('0x'.concat(digit1bin.toString(16).padStart(2, '0')));
$('#bin1').html('0b'.concat(digit1bin.toString(2).padStart(8, '0')));
digit2bin = grabValue(".digit2");
$('#hex2').html('0x'.concat(digit2bin.toString(16).padStart(2, '0')));
$('#bin2').html('0b'.concat(digit2bin.toString(2).padStart(8, '0')));
digit3bin = grabValue(".digit3");
$('#hex3').html('0x'.concat(digit3bin.toString(16).padStart(2, '0')));
$('#bin3').html('0b'.concat(digit3bin.toString(2).padStart(8, '0')));
digit4bin = grabValue(".digit4");
$('#hex4').html('0x'.concat(digit4bin.toString(16).padStart(2, '0')));
$('#bin4').html('0b'.concat(digit4bin.toString(2).padStart(8, '0')));
}
// Capture digit values as a new frame and add to animation data
function saveFrame() {
formatData(); // Clean up data before adding new frame
var frameNum = lastFrame() + 1;
var d1 = '0x'.concat(grabValue(".digit1").toString(16).padStart(2, '0'));
var d2 = '0x'.concat(grabValue(".digit2").toString(16).padStart(2, '0'));
var d3 = '0x'.concat(grabValue(".digit3").toString(16).padStart(2, '0'));
var d4 = '0x'.concat(grabValue(".digit4").toString(16).padStart(2, '0'));
var output = $('#codeOutput').text();
if(output.length > 19) output = output + "\n";
else frameNum = 0;
$('#codeOutput').text(''.concat(output,"{ ",d1,", ",d2,", ",d3,", ",d4," }, // Frame ",frameNum.toString()));
$('#frame').text("Frame = ".concat(frameNum.toString()));
}
// Return the number of frames
function lastFrame() {
var lines = $('#codeOutput').text().split("\n");
return(lines.length - 1);
}
// Playback the animation data on digits
function playAnimation() {
formatData(); // clean up data first
var frame = 0;
var lines = $('#codeOutput').text().split("\n");
var step = 1;
var tick = setInterval(function() {
if(frame == (lines.length-1)) { clearInterval(tick) };
var line = lines[frame];
if(line.length > 19) {
$('#frame').text("Frame = ".concat(frame.toString()));
var fields = line.replace("{","").replace("}","").split(",");
if(fields.length >= 4) {
var d1 = parseInt(fields[0].trim());
var d2 = parseInt(fields[1].trim());
var d3 = parseInt(fields[2].trim());
var d4 = parseInt(fields[3].trim());
console.log("Frame: ".concat(frame," - Valid Data: ",d1," ",d2," ", d3," ", d4));
setDigit(".digit1", d1);
setDigit(".digit2", d2);
setDigit(".digit3", d3);
setDigit(".digit4", d4);
}
else console.log("Frame: ".concat(frame," - Invalid Data"));
}
else {
console.log("Frame: ".concat(frame," - Invalid Data"));
}
frame++;
}, delayTime);
}
// Clean up the animation data
function formatData(flip = false) {
var frame = 0;
var lines = $('#codeOutput').text().split("\n");
var step = 1;
var buffer = [];
var dirty = false;
while(frame < lines.length) {
var line = lines[frame];
if(line.length > 19) {
var fields = line.replace("{","").replace("}","").split(",");
if(fields.length >= 4) {
var d1 = parseInt(fields[0].trim());
var d2 = parseInt(fields[1].trim());
var d3 = parseInt(fields[2].trim());
var d4 = parseInt(fields[3].trim());
if(isNaN(d1)) d1=0;
if(isNaN(d2)) d2=0;
if(isNaN(d3)) d3=0;
if(isNaN(d4)) d4=0;
if(flip) {
d1 = flipByte(d1);
d2 = flipByte(d2);
d3 = flipByte(d3);
d4 = flipByte(d4);
}
var nd1 = '0x'.concat(d1.toString(16).padStart(2, '0'));
var nd2 = '0x'.concat(d2.toString(16).padStart(2, '0'));
var nd3 = '0x'.concat(d3.toString(16).padStart(2, '0'));
var nd4 = '0x'.concat(d4.toString(16).padStart(2, '0'));
buffer = "".concat(buffer,"{ ",nd1,", ",nd2,", ",nd3,", ",nd4," }, // Frame ",frame.toString());
if(frame < (lines.length-1)) buffer = buffer + "\n";
}
else {
console.log("Format Frame: ".concat(frame," - Invalid Field Number"));
dirty = true;
}
}
else {
console.log("Format Frame: ".concat(frame," - Data Missing"));
}
frame++;
}
$('#codeOutput').text((" ".concat(buffer)).trim());
$('#frame').text("Frame = ".concat(lastFrame().toString()));
$("#outputblock").css("background-color","salmon");
if(dirty) formatData(); // We threw away lines during formatting, run again
}
// Load a single frame into digits
function showFrame(frame) {
var lines = $('#codeOutput').text().split("\n");
if((lines.length-1)<frame) return;
var line = lines[frame];
if(line.length > 19) {
$('#frame').text("Frame = ".concat(frame.toString()));
var fields = line.replace("{","").replace("}","").split(",");
if(fields.length >= 4) {
var d1 = parseInt(fields[0].trim());
var d2 = parseInt(fields[1].trim());
var d3 = parseInt(fields[2].trim());
var d4 = parseInt(fields[3].trim());
setDigit(".digit1", d1);
setDigit(".digit2", d2);
setDigit(".digit3", d3);
setDigit(".digit4", d4);
}
else console.log("Frame: ".concat(frame," - Invalid Data"));
}
else {
console.log("Frame: ".concat(frame," - Invalid Data"));
}
}
// Warn user before leaving page
$(window).bind('beforeunload', function(e){
if($('#codeOutput').text().length > 39) {
return("Animation data will be lost - Proceed?");
}
else e=null;
});
// Detect user interactions
$(document).ready(function() {
// Intercept LED mouse clicks and toggle LED
$(".digit1 polygon").click(function() {
var sSegClass = $(this).attr("class") === "off" ? "on" : "off";
$(this).attr("class", sSegClass);
updateValues();
});
$(".digit2 polygon").click(function() {
var sSegClass = $(this).attr("class") === "off" ? "on" : "off";
$(this).attr("class", sSegClass);
updateValues();
});
$(".digit3 polygon").click(function() {
var sSegClass = $(this).attr("class") === "off" ? "on" : "off";
$(this).attr("class", sSegClass);
updateValues();
});
$(".digit4 polygon").click(function() {
var sSegClass = $(this).attr("class") === "off" ? "on" : "off";
$(this).attr("class", sSegClass);
updateValues();
});
// Intercept mouse clicks in output section and load frame selected
$( "#codeOutput" ).mousedown(function( event ) {
var line = parseInt(event.offsetY/17);
console.log("Line: "+ line);
showFrame(line);
});
});
updateValues();
</script>
</body>
</html>

View File

@ -1,402 +0,0 @@
// TM1637TinyDisplay DEMO Sketch for ATtiny85
// This is a demo sketch for the Arduino TM1637TinyDisplay LED Display library
// Designed for small memory processors like the ATtiny85
//
// Author: Jason A. Cox - @jasonacox
// Date: 2 July 2020
//
// Based on TM1637Display library at https://github.com/avishorp/TM1637
//
// Includes
#include <Arduino.h>
#include <TM1637TinyDisplay.h>
#include <avr/pgmspace.h>
// Define Digital Pins
#define CLK 4
#define DIO 5
// Initialize TM1637TinyDisplay
TM1637TinyDisplay display(CLK, DIO);
// Animation data below was created with the Animator Tool located here:
// https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html
// To save RAM space, we store the animation sequences in PROGMEM read-only flash memory.
// This requires using the showAnimation_P() function to read from PROGMEM memory space.
const uint8_t ANIMATION1[40][4] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 1
{ 0x40, 0x01, 0x00, 0x00 }, // Frame 2
{ 0x08, 0x40, 0x00, 0x01 }, // Frame 3
{ 0x00, 0x08, 0x01, 0x40 }, // Frame 4
{ 0x01, 0x00, 0x40, 0x08 }, // Frame 5
{ 0x40, 0x01, 0x08, 0x00 }, // Frame 6
{ 0x08, 0x40, 0x00, 0x01 }, // Frame 7
{ 0x00, 0x08, 0x01, 0x40 }, // Frame 8
{ 0x01, 0x01, 0x40, 0x08 }, // Frame 9
{ 0x40, 0x40, 0x09, 0x00 }, // Frame 10
{ 0x08, 0x08, 0x40, 0x01 }, // Frame 11
{ 0x01, 0x00, 0x08, 0x40 }, // Frame 12
{ 0x40, 0x01, 0x00, 0x08 }, // Frame 13
{ 0x08, 0x40, 0x01, 0x00 }, // Frame 14
{ 0x01, 0x09, 0x41, 0x01 }, // Frame 15
{ 0x40, 0x40, 0x48, 0x40 }, // Frame 16
{ 0x08, 0x08, 0x08, 0x08 }, // Frame 17
{ 0x1c, 0x1c, 0x1c, 0x1c }, // Frame 18
{ 0x3e, 0x3e, 0x3e, 0x3e }, // Frame 19
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 20
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 21
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 22
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 23
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 24
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 25
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 26
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 27
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 28
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 29
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 30
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 31
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 32
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 33
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 34
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 35
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 36
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 37
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 38
{ 0x3f, 0x3f, 0x3f, 0x3f } // Frame 39
};
const uint8_t ANIMATION2[33][4] PROGMEM = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 6
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 7
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 8
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 9
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 10
{ 0x10, 0x00, 0x00, 0x00 }, // Frame 11
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 12
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 13
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 14
{ 0x00, 0x00, 0x04, 0x00 }, // Frame 15
{ 0x00, 0x00, 0x02, 0x00 }, // Frame 16
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 17
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 18
{ 0x00, 0x20, 0x00, 0x00 }, // Frame 19
{ 0x00, 0x10, 0x00, 0x00 }, // Frame 20
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 21
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 22
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 23
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 24
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 25
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 26
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 27
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 28
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 29
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 30
{ 0x10, 0x00, 0x00, 0x00 }, // Frame 31
{ 0x00, 0x00, 0x00, 0x00 } // Frame 32
};
const uint8_t ANIMATION3[218][4] PROGMEM = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x40, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x01, 0x40, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x01, 0x40, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x01, 0x40 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 6
{ 0x63, 0x00, 0x00, 0x00 }, // Frame 7
{ 0x00, 0x5c, 0x00, 0x00 }, // Frame 8
{ 0x00, 0x00, 0x63, 0x00 }, // Frame 9
{ 0x00, 0x00, 0x00, 0x5c }, // Frame 10
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 11
{ 0x01, 0x01, 0x01, 0x01 }, // Frame 12
{ 0x41, 0x41, 0x41, 0x41 }, // Frame 13
{ 0x49, 0x49, 0x49, 0x49 }, // Frame 14
{ 0x79, 0x49, 0x49, 0x49 }, // Frame 15
{ 0x7f, 0x49, 0x49, 0x49 }, // Frame 16
{ 0x7f, 0x79, 0x49, 0x49 }, // Frame 17
{ 0x7f, 0x7f, 0x49, 0x49 }, // Frame 18
{ 0x7f, 0x7f, 0x79, 0x49 }, // Frame 19
{ 0x7f, 0x7f, 0x7f, 0x49 }, // Frame 20
{ 0x7f, 0x7f, 0x7f, 0x79 }, // Frame 21
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 22
{ 0x3f, 0x7f, 0x7f, 0x7f }, // Frame 23
{ 0x3f, 0x3f, 0x7f, 0x7f }, // Frame 24
{ 0x3f, 0x3f, 0x3f, 0x7f }, // Frame 25
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 26
{ 0x1e, 0x3f, 0x3f, 0x3f }, // Frame 27
{ 0x0c, 0x3f, 0x3f, 0x3f }, // Frame 28
{ 0x00, 0x1e, 0x3f, 0x3f }, // Frame 29
{ 0x00, 0x0c, 0x3f, 0x3f }, // Frame 30
{ 0x00, 0x00, 0x1e, 0x3f }, // Frame 31
{ 0x00, 0x00, 0x0c, 0x3f }, // Frame 32
{ 0x00, 0x00, 0x00, 0x1e }, // Frame 33
{ 0x00, 0x00, 0x00, 0x0c }, // Frame 34
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 35
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 36
{ 0x00, 0x00, 0x00, 0x10 }, // Frame 37
{ 0x00, 0x00, 0x00, 0x20 }, // Frame 38
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 39
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 40
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 41
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 42
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 43
{ 0x00, 0x00, 0x10, 0x00 }, // Frame 44
{ 0x00, 0x00, 0x20, 0x00 }, // Frame 45
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 46
{ 0x00, 0x00, 0x02, 0x00 }, // Frame 47
{ 0x00, 0x00, 0x04, 0x00 }, // Frame 48
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 49
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 50
{ 0x00, 0x10, 0x00, 0x00 }, // Frame 51
{ 0x00, 0x20, 0x00, 0x00 }, // Frame 52
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 53
{ 0x00, 0x02, 0x00, 0x00 }, // Frame 54
{ 0x00, 0x04, 0x00, 0x00 }, // Frame 55
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 56
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 57
{ 0x10, 0x00, 0x00, 0x00 }, // Frame 58
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 59
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 60
{ 0x02, 0x00, 0x00, 0x00 }, // Frame 61
{ 0x04, 0x00, 0x00, 0x00 }, // Frame 62
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 63
{ 0x18, 0x00, 0x00, 0x00 }, // Frame 64
{ 0x38, 0x00, 0x00, 0x00 }, // Frame 65
{ 0x39, 0x00, 0x00, 0x00 }, // Frame 66
{ 0x39, 0x01, 0x00, 0x00 }, // Frame 67
{ 0x39, 0x01, 0x01, 0x00 }, // Frame 68
{ 0x39, 0x01, 0x01, 0x01 }, // Frame 69
{ 0x39, 0x01, 0x01, 0x03 }, // Frame 70
{ 0x39, 0x01, 0x01, 0x07 }, // Frame 71
{ 0x39, 0x01, 0x01, 0x0f }, // Frame 72
{ 0x39, 0x01, 0x09, 0x0f }, // Frame 73
{ 0x39, 0x09, 0x09, 0x0f }, // Frame 74
{ 0x06, 0x09, 0x09, 0x30 }, // Frame 75
{ 0x00, 0x39, 0x0f, 0x00 }, // Frame 76
{ 0x00, 0x06, 0x30, 0x00 }, // Frame 77
{ 0x00, 0x46, 0x70, 0x00 }, // Frame 78
{ 0x40, 0x06, 0x30, 0x40 }, // Frame 79
{ 0x30, 0x06, 0x30, 0x06 }, // Frame 80
{ 0x30, 0x30, 0x06, 0x06 }, // Frame 81
{ 0x36, 0x00, 0x00, 0x36 }, // Frame 82
{ 0x30, 0x00, 0x00, 0x06 }, // Frame 83
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 84
{ 0x4c, 0x00, 0x00, 0x00 }, // Frame 85
{ 0x00, 0x4c, 0x00, 0x00 }, // Frame 86
{ 0x00, 0x00, 0x4c, 0x00 }, // Frame 87
{ 0x00, 0x00, 0x00, 0x4c }, // Frame 88
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 89
{ 0x00, 0x00, 0x00, 0x61 }, // Frame 90
{ 0x00, 0x00, 0x61, 0x00 }, // Frame 91
{ 0x00, 0x61, 0x00, 0x00 }, // Frame 92
{ 0x61, 0x00, 0x00, 0x00 }, // Frame 93
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 94
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 95
{ 0x00, 0x00, 0x5c, 0x00 }, // Frame 96
{ 0x00, 0x08, 0x7f, 0x08 }, // Frame 97
{ 0x00, 0x0c, 0x7f, 0x18 }, // Frame 98
{ 0x00, 0x5e, 0x7f, 0x7c }, // Frame 99
{ 0x08, 0x7f, 0x7f, 0x7f }, // Frame 100
{ 0x0c, 0x7f, 0x7f, 0x7f }, // Frame 101
{ 0x5e, 0x7f, 0x7f, 0x7f }, // Frame 102
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 103
{ 0x7e, 0x7e, 0x7e, 0x7e }, // Frame 104
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 105
{ 0x77, 0x77, 0x77, 0x77 }, // Frame 106
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 107
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 108
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 109
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 110
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 111
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 112
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 113
{ 0x3f, 0x3f, 0x3f, 0x39 }, // Frame 114
{ 0x3f, 0x3f, 0x3f, 0x30 }, // Frame 115
{ 0x3f, 0x3f, 0x3f, 0x00 }, // Frame 116
{ 0x3f, 0x3f, 0x39, 0x00 }, // Frame 117
{ 0x3f, 0x3f, 0x30, 0x00 }, // Frame 118
{ 0x3f, 0x3f, 0x00, 0x00 }, // Frame 119
{ 0x3f, 0x39, 0x00, 0x00 }, // Frame 120
{ 0x3f, 0x30, 0x00, 0x00 }, // Frame 121
{ 0x3f, 0x00, 0x00, 0x00 }, // Frame 122
{ 0x39, 0x00, 0x00, 0x00 }, // Frame 123
{ 0x30, 0x00, 0x00, 0x00 }, // Frame 124
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 125
{ 0x38, 0x00, 0x00, 0x00 }, // Frame 126
{ 0x3f, 0x38, 0x00, 0x00 }, // Frame 127
{ 0x38, 0x3f, 0x38, 0x00 }, // Frame 128
{ 0x00, 0x38, 0x3f, 0x38 }, // Frame 129
{ 0x00, 0x00, 0x38, 0x3f }, // Frame 130
{ 0x00, 0x00, 0x00, 0x38 }, // Frame 131
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 132
{ 0x40, 0x00, 0x00, 0x00 }, // Frame 133
{ 0x00, 0x40, 0x00, 0x00 }, // Frame 134
{ 0x00, 0x00, 0x40, 0x00 }, // Frame 135
{ 0x00, 0x00, 0x00, 0x46 }, // Frame 136
{ 0x00, 0x00, 0x00, 0x39 }, // Frame 137
{ 0x40, 0x00, 0x06, 0x09 }, // Frame 138
{ 0x00, 0x40, 0x39, 0x09 }, // Frame 139
{ 0x40, 0x06, 0x09, 0x09 }, // Frame 140
{ 0x00, 0x39, 0x09, 0x09 }, // Frame 141
{ 0x46, 0x09, 0x09, 0x09 }, // Frame 142
{ 0x39, 0x09, 0x09, 0x09 }, // Frame 143
{ 0x09, 0x09, 0x09, 0x0f }, // Frame 144
{ 0x09, 0x09, 0x09, 0x79 }, // Frame 145
{ 0x09, 0x09, 0x0f, 0x00 }, // Frame 146
{ 0x09, 0x09, 0x79, 0x00 }, // Frame 147
{ 0x09, 0x0f, 0x09, 0x00 }, // Frame 148
{ 0x09, 0x79, 0x00, 0x00 }, // Frame 149
{ 0x0f, 0x09, 0x00, 0x00 }, // Frame 150
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 151
{ 0x30, 0x00, 0x00, 0x00 }, // Frame 152
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 153
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 154
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 155
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 156
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 157
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 158
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 159
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 160
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 161
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 162
{ 0x00, 0x00, 0x00, 0x6d }, // Frame 163
{ 0x00, 0x00, 0x6d, 0x73 }, // Frame 164
{ 0x00, 0x6d, 0x73, 0x77 }, // Frame 165
{ 0x6d, 0x73, 0x77, 0x39 }, // Frame 166
{ 0x73, 0x77, 0x39, 0x79 }, // Frame 167
{ 0x77, 0x39, 0x79, 0x00 }, // Frame 168
{ 0x39, 0x79, 0x00, 0x00 }, // Frame 169
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 170
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 171
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 172
{ 0x00, 0x79, 0x00, 0x00 }, // Frame 173
{ 0x00, 0x00, 0x79, 0x00 }, // Frame 174
{ 0x00, 0x00, 0x00, 0x79 }, // Frame 175
{ 0x10, 0x00, 0x00, 0x79 }, // Frame 176
{ 0x74, 0x00, 0x00, 0x79 }, // Frame 177
{ 0x00, 0x74, 0x00, 0x79 }, // Frame 178
{ 0x00, 0x00, 0x74, 0x79 }, // Frame 179
{ 0x78, 0x00, 0x74, 0x79 }, // Frame 180
{ 0x00, 0x78, 0x74, 0x79 }, // Frame 181
{ 0x00, 0x78, 0x74, 0x79 }, // Frame 182
{ 0x00, 0x78, 0x74, 0x79 }, // Frame 183
{ 0x78, 0x74, 0x79, 0x00 }, // Frame 184
{ 0x74, 0x79, 0x00, 0x00 }, // Frame 185
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 186
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 187
{ 0x79, 0x00, 0x00, 0x04 }, // Frame 188
{ 0x79, 0x00, 0x00, 0x54 }, // Frame 189
{ 0x79, 0x00, 0x54, 0x00 }, // Frame 190
{ 0x79, 0x54, 0x00, 0x00 }, // Frame 191
{ 0x79, 0x54, 0x00, 0x04 }, // Frame 192
{ 0x79, 0x54, 0x00, 0x5e }, // Frame 193
{ 0x79, 0x54, 0x04, 0x30 }, // Frame 194
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 195
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 196
{ 0x79, 0x55, 0x5e, 0x02 }, // Frame 197
{ 0x79, 0x54, 0x5e, 0x10 }, // Frame 198
{ 0xf9, 0x54, 0x5e, 0x20 }, // Frame 199
{ 0x79, 0xd4, 0x5e, 0x08 }, // Frame 200
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 201
{ 0x69, 0x54, 0x5e, 0x00 }, // Frame 202
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 203
{ 0x79, 0x54, 0x1e, 0x00 }, // Frame 204
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 205
{ 0x79, 0x14, 0x5e, 0x00 }, // Frame 206
{ 0x68, 0x14, 0x5e, 0x00 }, // Frame 207
{ 0x68, 0x14, 0x1e, 0x00 }, // Frame 208
{ 0x68, 0x14, 0x16, 0x00 }, // Frame 209
{ 0x68, 0x04, 0x16, 0x00 }, // Frame 210
{ 0x28, 0x04, 0x16, 0x00 }, // Frame 211
{ 0x28, 0x04, 0x14, 0x00 }, // Frame 212
{ 0x08, 0x04, 0x14, 0x00 }, // Frame 213
{ 0x08, 0x04, 0x04, 0x00 }, // Frame 214
{ 0x00, 0x04, 0x04, 0x00 }, // Frame 215
{ 0x00, 0x00, 0x04, 0x00 }, // Frame 216
{ 0x00, 0x00, 0x00, 0x00 } // Frame 217
};
const PROGMEM char FlashString[] = "Flash Test - 1234567890"; // Must be globally defined for PROGMEM space
const PROGMEM char FlashString2[] = "good";
void setup() {
display.setBrightness(BRIGHT_7);
}
void loop() {
// Say Hello
display.showString("HELLO");
delay(500);
// Clear Screen
display.clear();
// We can count!
for (int x = -100; x <= 100; x++) {
display.showNumber(x);
}
// Demo Brightness Levels
for (int x = 0; x < 8; x++) {
display.setBrightness(x);
display.showString("On ");
display.showNumber(x, false, 1, 3);
delay(1000);
}
// Demo Horizontal Level Meter
for (int count = 0; count < 3; count++) {
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, true);
delay(20);
}
for (int x = 100; x >= 0; x = x - 10) {
display.showLevel(x, true);
delay(20);
}
}
// Demo Vertical Level Meter
for (int count = 0; count < 3; count++) {
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, false);
delay(20);
}
for (int x = 100; x >= 0; x = x - 10) {
display.showLevel(x, false);
delay(20);
}
}
delay(1000);
// Demo split screen for temperature
display.showString("\xB0", 1, 3); // Degree Mark, length=1, position=3 (right)
for (int x = -50; x < 150; x++) {
display.showNumber(x, false, 3, 0); // Number, length=3, position=0 (left)
delay(10);
}
delay(1000);
// Test PROGMEM flash memory
display.showString_P(FlashString);
delay(1000);
display.showString_P(FlashString2);
delay(1000);
// Animation sequences - All in PROGMEM flash memory
display.clear();
display.showAnimation_P(ANIMATION1, FRAMES(ANIMATION1), TIME_MS(50));
display.showAnimation_P(ANIMATION2, FRAMES(ANIMATION2), TIME_MS(50));
display.showAnimation_P(ANIMATION3, FRAMES(ANIMATION3), TIME_MS(50));
delay(1000);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

View File

@ -1,65 +0,0 @@
# TM1637TinyDisplay Examples
## Test Sketch
The [TM1637Test.ino](TM1637Test/TM1637Test.ino) sketch will test the library functions.
## Demo Sketch
The [TM1637Demo.ino](TM1637Demo/TM1637Demo.ino) sketch will demonstrate the library functions
and play an extended set of animation sequences. The animations were built with the [Animator Tool](https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html) referenced below.
## Animation
### 7-Segment LED Display Animator Tool
![Animator Tool](AnimatorToolThumb.png)
This tool will allow the user to visually toggle on/off LEDs in a 4-digit
7-segment display to create a pattern. It calculates the hexadecimal and binary
values for the pattern. You can SAVE the pattern as a frame in an
animation sequence which will show up in the "Animation Data" section below
the controls. To see the animation, press the PLAYBACK button. Once
complete, press the COPY button to copy the code to your clipboard and paste the data
into your sketch.
[https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html](https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html)
### Animation showAnimation() Function
The showAnimation() function projects a sequence of frames (patterns) onto the display. This works by provide the function a multi-dimensional array of patterns.
As mentioned above, you can use the javascript based interactive [7-Segment LED Animator Tool](https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html) to help build your animation. The source code is in this single-file HTML: [7-segment-animator.html](7-segment-animator.html) which you can run from your local file system or a website. This tool will let you set up the LED sequences you want, save each frame and copy the final code (a static array) directly into your sketch to use for the `showAnimation(data, frames, timing)` function. Here is an example implementation:
```cpp
#include <Arduino.h>
#include <TM1637TinyDisplay.h>
// Define Digital Pins
#define CLK 4
#define DIO 5
// Initialize TM1637TinyDisplay
TM1637TinyDisplay display(CLK, DIO);
// Data from Animator Tool
const uint8_t ANIMATION[12][4] = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 6
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 7
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 8
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 9
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 10
{ 0x10, 0x00, 0x00, 0x00 } // Frame 11
};
void setup() {
display.setBrightness(0x0f);
}
void loop() {
// Display Animation sequence
display.showAnimation(ANIMATION, FRAMES(ANIMATION), TIME_MS(50));
}
```

View File

@ -1,400 +0,0 @@
// TM1637TinyDisplay DEMO Sketch
// This is a demo sketch for the Arduino TM1637TinyDisplay LED Display library
//
// Author: Jason A. Cox - @jasonacox
// Date: 2 July 2020
//
// Includes
#include <Arduino.h>
#include <TM1637TinyDisplay.h>
// Define Digital Pins
#define CLK 4
#define DIO 5
// Initialize TM1637TinyDisplay
TM1637TinyDisplay display(CLK, DIO);
// Animations created with Tool https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html
const uint8_t ANIMATION1[40][4] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 1
{ 0x40, 0x01, 0x00, 0x00 }, // Frame 2
{ 0x08, 0x40, 0x00, 0x01 }, // Frame 3
{ 0x00, 0x08, 0x01, 0x40 }, // Frame 4
{ 0x01, 0x00, 0x40, 0x08 }, // Frame 5
{ 0x40, 0x01, 0x08, 0x00 }, // Frame 6
{ 0x08, 0x40, 0x00, 0x01 }, // Frame 7
{ 0x00, 0x08, 0x01, 0x40 }, // Frame 8
{ 0x01, 0x01, 0x40, 0x08 }, // Frame 9
{ 0x40, 0x40, 0x09, 0x00 }, // Frame 10
{ 0x08, 0x08, 0x40, 0x01 }, // Frame 11
{ 0x01, 0x00, 0x08, 0x40 }, // Frame 12
{ 0x40, 0x01, 0x00, 0x08 }, // Frame 13
{ 0x08, 0x40, 0x01, 0x00 }, // Frame 14
{ 0x01, 0x09, 0x41, 0x01 }, // Frame 15
{ 0x40, 0x40, 0x48, 0x40 }, // Frame 16
{ 0x08, 0x08, 0x08, 0x08 }, // Frame 17
{ 0x1c, 0x1c, 0x1c, 0x1c }, // Frame 18
{ 0x3e, 0x3e, 0x3e, 0x3e }, // Frame 19
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 20
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 21
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 22
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 23
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 24
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 25
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 26
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 27
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 28
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 29
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 30
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 31
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 32
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 33
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 34
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 35
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 36
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 37
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 38
{ 0x3f, 0x3f, 0x3f, 0x3f } // Frame 39
};
const uint8_t ANIMATION2[33][4] PROGMEM = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 6
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 7
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 8
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 9
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 10
{ 0x10, 0x00, 0x00, 0x00 }, // Frame 11
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 12
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 13
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 14
{ 0x00, 0x00, 0x04, 0x00 }, // Frame 15
{ 0x00, 0x00, 0x02, 0x00 }, // Frame 16
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 17
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 18
{ 0x00, 0x20, 0x00, 0x00 }, // Frame 19
{ 0x00, 0x10, 0x00, 0x00 }, // Frame 20
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 21
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 22
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 23
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 24
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 25
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 26
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 27
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 28
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 29
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 30
{ 0x10, 0x00, 0x00, 0x00 }, // Frame 31
{ 0x00, 0x00, 0x00, 0x00 } // Frame 32
};
const uint8_t ANIMATION3[218][4] PROGMEM = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x40, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x01, 0x40, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x01, 0x40, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x01, 0x40 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 6
{ 0x63, 0x00, 0x00, 0x00 }, // Frame 7
{ 0x00, 0x5c, 0x00, 0x00 }, // Frame 8
{ 0x00, 0x00, 0x63, 0x00 }, // Frame 9
{ 0x00, 0x00, 0x00, 0x5c }, // Frame 10
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 11
{ 0x01, 0x01, 0x01, 0x01 }, // Frame 12
{ 0x41, 0x41, 0x41, 0x41 }, // Frame 13
{ 0x49, 0x49, 0x49, 0x49 }, // Frame 14
{ 0x79, 0x49, 0x49, 0x49 }, // Frame 15
{ 0x7f, 0x49, 0x49, 0x49 }, // Frame 16
{ 0x7f, 0x79, 0x49, 0x49 }, // Frame 17
{ 0x7f, 0x7f, 0x49, 0x49 }, // Frame 18
{ 0x7f, 0x7f, 0x79, 0x49 }, // Frame 19
{ 0x7f, 0x7f, 0x7f, 0x49 }, // Frame 20
{ 0x7f, 0x7f, 0x7f, 0x79 }, // Frame 21
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 22
{ 0x3f, 0x7f, 0x7f, 0x7f }, // Frame 23
{ 0x3f, 0x3f, 0x7f, 0x7f }, // Frame 24
{ 0x3f, 0x3f, 0x3f, 0x7f }, // Frame 25
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 26
{ 0x1e, 0x3f, 0x3f, 0x3f }, // Frame 27
{ 0x0c, 0x3f, 0x3f, 0x3f }, // Frame 28
{ 0x00, 0x1e, 0x3f, 0x3f }, // Frame 29
{ 0x00, 0x0c, 0x3f, 0x3f }, // Frame 30
{ 0x00, 0x00, 0x1e, 0x3f }, // Frame 31
{ 0x00, 0x00, 0x0c, 0x3f }, // Frame 32
{ 0x00, 0x00, 0x00, 0x1e }, // Frame 33
{ 0x00, 0x00, 0x00, 0x0c }, // Frame 34
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 35
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 36
{ 0x00, 0x00, 0x00, 0x10 }, // Frame 37
{ 0x00, 0x00, 0x00, 0x20 }, // Frame 38
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 39
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 40
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 41
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 42
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 43
{ 0x00, 0x00, 0x10, 0x00 }, // Frame 44
{ 0x00, 0x00, 0x20, 0x00 }, // Frame 45
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 46
{ 0x00, 0x00, 0x02, 0x00 }, // Frame 47
{ 0x00, 0x00, 0x04, 0x00 }, // Frame 48
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 49
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 50
{ 0x00, 0x10, 0x00, 0x00 }, // Frame 51
{ 0x00, 0x20, 0x00, 0x00 }, // Frame 52
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 53
{ 0x00, 0x02, 0x00, 0x00 }, // Frame 54
{ 0x00, 0x04, 0x00, 0x00 }, // Frame 55
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 56
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 57
{ 0x10, 0x00, 0x00, 0x00 }, // Frame 58
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 59
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 60
{ 0x02, 0x00, 0x00, 0x00 }, // Frame 61
{ 0x04, 0x00, 0x00, 0x00 }, // Frame 62
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 63
{ 0x18, 0x00, 0x00, 0x00 }, // Frame 64
{ 0x38, 0x00, 0x00, 0x00 }, // Frame 65
{ 0x39, 0x00, 0x00, 0x00 }, // Frame 66
{ 0x39, 0x01, 0x00, 0x00 }, // Frame 67
{ 0x39, 0x01, 0x01, 0x00 }, // Frame 68
{ 0x39, 0x01, 0x01, 0x01 }, // Frame 69
{ 0x39, 0x01, 0x01, 0x03 }, // Frame 70
{ 0x39, 0x01, 0x01, 0x07 }, // Frame 71
{ 0x39, 0x01, 0x01, 0x0f }, // Frame 72
{ 0x39, 0x01, 0x09, 0x0f }, // Frame 73
{ 0x39, 0x09, 0x09, 0x0f }, // Frame 74
{ 0x06, 0x09, 0x09, 0x30 }, // Frame 75
{ 0x00, 0x39, 0x0f, 0x00 }, // Frame 76
{ 0x00, 0x06, 0x30, 0x00 }, // Frame 77
{ 0x00, 0x46, 0x70, 0x00 }, // Frame 78
{ 0x40, 0x06, 0x30, 0x40 }, // Frame 79
{ 0x30, 0x06, 0x30, 0x06 }, // Frame 80
{ 0x30, 0x30, 0x06, 0x06 }, // Frame 81
{ 0x36, 0x00, 0x00, 0x36 }, // Frame 82
{ 0x30, 0x00, 0x00, 0x06 }, // Frame 83
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 84
{ 0x4c, 0x00, 0x00, 0x00 }, // Frame 85
{ 0x00, 0x4c, 0x00, 0x00 }, // Frame 86
{ 0x00, 0x00, 0x4c, 0x00 }, // Frame 87
{ 0x00, 0x00, 0x00, 0x4c }, // Frame 88
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 89
{ 0x00, 0x00, 0x00, 0x61 }, // Frame 90
{ 0x00, 0x00, 0x61, 0x00 }, // Frame 91
{ 0x00, 0x61, 0x00, 0x00 }, // Frame 92
{ 0x61, 0x00, 0x00, 0x00 }, // Frame 93
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 94
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 95
{ 0x00, 0x00, 0x5c, 0x00 }, // Frame 96
{ 0x00, 0x08, 0x7f, 0x08 }, // Frame 97
{ 0x00, 0x0c, 0x7f, 0x18 }, // Frame 98
{ 0x00, 0x5e, 0x7f, 0x7c }, // Frame 99
{ 0x08, 0x7f, 0x7f, 0x7f }, // Frame 100
{ 0x0c, 0x7f, 0x7f, 0x7f }, // Frame 101
{ 0x5e, 0x7f, 0x7f, 0x7f }, // Frame 102
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 103
{ 0x7e, 0x7e, 0x7e, 0x7e }, // Frame 104
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 105
{ 0x77, 0x77, 0x77, 0x77 }, // Frame 106
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 107
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 108
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 109
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 110
{ 0x7f, 0x7f, 0x7f, 0x7f }, // Frame 111
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 112
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 113
{ 0x3f, 0x3f, 0x3f, 0x39 }, // Frame 114
{ 0x3f, 0x3f, 0x3f, 0x30 }, // Frame 115
{ 0x3f, 0x3f, 0x3f, 0x00 }, // Frame 116
{ 0x3f, 0x3f, 0x39, 0x00 }, // Frame 117
{ 0x3f, 0x3f, 0x30, 0x00 }, // Frame 118
{ 0x3f, 0x3f, 0x00, 0x00 }, // Frame 119
{ 0x3f, 0x39, 0x00, 0x00 }, // Frame 120
{ 0x3f, 0x30, 0x00, 0x00 }, // Frame 121
{ 0x3f, 0x00, 0x00, 0x00 }, // Frame 122
{ 0x39, 0x00, 0x00, 0x00 }, // Frame 123
{ 0x30, 0x00, 0x00, 0x00 }, // Frame 124
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 125
{ 0x38, 0x00, 0x00, 0x00 }, // Frame 126
{ 0x3f, 0x38, 0x00, 0x00 }, // Frame 127
{ 0x38, 0x3f, 0x38, 0x00 }, // Frame 128
{ 0x00, 0x38, 0x3f, 0x38 }, // Frame 129
{ 0x00, 0x00, 0x38, 0x3f }, // Frame 130
{ 0x00, 0x00, 0x00, 0x38 }, // Frame 131
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 132
{ 0x40, 0x00, 0x00, 0x00 }, // Frame 133
{ 0x00, 0x40, 0x00, 0x00 }, // Frame 134
{ 0x00, 0x00, 0x40, 0x00 }, // Frame 135
{ 0x00, 0x00, 0x00, 0x46 }, // Frame 136
{ 0x00, 0x00, 0x00, 0x39 }, // Frame 137
{ 0x40, 0x00, 0x06, 0x09 }, // Frame 138
{ 0x00, 0x40, 0x39, 0x09 }, // Frame 139
{ 0x40, 0x06, 0x09, 0x09 }, // Frame 140
{ 0x00, 0x39, 0x09, 0x09 }, // Frame 141
{ 0x46, 0x09, 0x09, 0x09 }, // Frame 142
{ 0x39, 0x09, 0x09, 0x09 }, // Frame 143
{ 0x09, 0x09, 0x09, 0x0f }, // Frame 144
{ 0x09, 0x09, 0x09, 0x79 }, // Frame 145
{ 0x09, 0x09, 0x0f, 0x00 }, // Frame 146
{ 0x09, 0x09, 0x79, 0x00 }, // Frame 147
{ 0x09, 0x0f, 0x09, 0x00 }, // Frame 148
{ 0x09, 0x79, 0x00, 0x00 }, // Frame 149
{ 0x0f, 0x09, 0x00, 0x00 }, // Frame 150
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 151
{ 0x30, 0x00, 0x00, 0x00 }, // Frame 152
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 153
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 154
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 155
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 156
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 157
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 158
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 159
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 160
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 161
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 162
{ 0x00, 0x00, 0x00, 0x6d }, // Frame 163
{ 0x00, 0x00, 0x6d, 0x73 }, // Frame 164
{ 0x00, 0x6d, 0x73, 0x77 }, // Frame 165
{ 0x6d, 0x73, 0x77, 0x39 }, // Frame 166
{ 0x73, 0x77, 0x39, 0x79 }, // Frame 167
{ 0x77, 0x39, 0x79, 0x00 }, // Frame 168
{ 0x39, 0x79, 0x00, 0x00 }, // Frame 169
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 170
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 171
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 172
{ 0x00, 0x79, 0x00, 0x00 }, // Frame 173
{ 0x00, 0x00, 0x79, 0x00 }, // Frame 174
{ 0x00, 0x00, 0x00, 0x79 }, // Frame 175
{ 0x10, 0x00, 0x00, 0x79 }, // Frame 176
{ 0x74, 0x00, 0x00, 0x79 }, // Frame 177
{ 0x00, 0x74, 0x00, 0x79 }, // Frame 178
{ 0x00, 0x00, 0x74, 0x79 }, // Frame 179
{ 0x78, 0x00, 0x74, 0x79 }, // Frame 180
{ 0x00, 0x78, 0x74, 0x79 }, // Frame 181
{ 0x00, 0x78, 0x74, 0x79 }, // Frame 182
{ 0x00, 0x78, 0x74, 0x79 }, // Frame 183
{ 0x78, 0x74, 0x79, 0x00 }, // Frame 184
{ 0x74, 0x79, 0x00, 0x00 }, // Frame 185
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 186
{ 0x79, 0x00, 0x00, 0x00 }, // Frame 187
{ 0x79, 0x00, 0x00, 0x04 }, // Frame 188
{ 0x79, 0x00, 0x00, 0x54 }, // Frame 189
{ 0x79, 0x00, 0x54, 0x00 }, // Frame 190
{ 0x79, 0x54, 0x00, 0x00 }, // Frame 191
{ 0x79, 0x54, 0x00, 0x04 }, // Frame 192
{ 0x79, 0x54, 0x00, 0x5e }, // Frame 193
{ 0x79, 0x54, 0x04, 0x30 }, // Frame 194
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 195
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 196
{ 0x79, 0x55, 0x5e, 0x02 }, // Frame 197
{ 0x79, 0x54, 0x5e, 0x10 }, // Frame 198
{ 0xf9, 0x54, 0x5e, 0x20 }, // Frame 199
{ 0x79, 0xd4, 0x5e, 0x08 }, // Frame 200
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 201
{ 0x69, 0x54, 0x5e, 0x00 }, // Frame 202
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 203
{ 0x79, 0x54, 0x1e, 0x00 }, // Frame 204
{ 0x79, 0x54, 0x5e, 0x00 }, // Frame 205
{ 0x79, 0x14, 0x5e, 0x00 }, // Frame 206
{ 0x68, 0x14, 0x5e, 0x00 }, // Frame 207
{ 0x68, 0x14, 0x1e, 0x00 }, // Frame 208
{ 0x68, 0x14, 0x16, 0x00 }, // Frame 209
{ 0x68, 0x04, 0x16, 0x00 }, // Frame 210
{ 0x28, 0x04, 0x16, 0x00 }, // Frame 211
{ 0x28, 0x04, 0x14, 0x00 }, // Frame 212
{ 0x08, 0x04, 0x14, 0x00 }, // Frame 213
{ 0x08, 0x04, 0x04, 0x00 }, // Frame 214
{ 0x00, 0x04, 0x04, 0x00 }, // Frame 215
{ 0x00, 0x00, 0x04, 0x00 }, // Frame 216
{ 0x00, 0x00, 0x00, 0x00 } // Frame 217
};
void setup() {
display.setBrightness(BRIGHT_7);
display.showNumber(1234);
delay(1000);
}
void loop() {
// Say Hello
display.showString("HELLO");
delay(500);
// Clear Screen
display.clear();
// We can count!
for (int x = -110; x <= 100; x++) {
display.showNumber(x);
yield(); // Keep watchdog timer happy
}
delay(500);
for (int x = -100; x < 100; x = x + 1) {
display.showNumber((float)x / 10.0);
yield(); // Keep watchdog timer happy
}
delay(500);
// Demo Brightness Levels
char string[10];
for (int x = 0; x < 8; x++) {
display.setBrightness(x);
sprintf(string, "On %d", x);
display.showString(string);
delay(1000);
}
// Demo Horizontal Level Meter
for (int count = 0; count < 3; count++) {
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, true);
delay(20);
}
for (int x = 100; x >= 0; x = x - 10) {
display.showLevel(x, true);
delay(20);
}
}
// Demo Vertical Level Meter
for (int count = 0; count < 3; count++) {
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, false);
delay(20);
}
for (int x = 100; x >= 0; x = x - 10) {
display.showLevel(x, false);
delay(20);
}
}
delay(1000);
// Demo split screen for temperature
display.showString("\xB0", 1, 3); // Degree Mark, length=1, position=3 (right)
for (int x = -90; x < 200; x++) {
display.showNumber(x, false, 3, 0); // Number, length=3, position=0 (left)
delay(10);
}
delay(1000);
// Animation sequences - All in PROGMEM flash memory
display.clear();
display.showString("For Fun");
delay(1000);
display.showAnimation_P(ANIMATION1, FRAMES(ANIMATION1), TIME_MS(50));
display.showAnimation_P(ANIMATION2, FRAMES(ANIMATION2), TIME_MS(50));
display.showAnimation_P(ANIMATION3, FRAMES(ANIMATION3), TIME_MS(50));
delay(5000);
}

View File

@ -1,313 +0,0 @@
// TM1637TinyDisplay TEST Sketch
// This is a test sketch for the Arduino TM1637TinyDisplay LED Display library
//
// Author: Jason A. Cox - @jasonacox - https://github.com/jasonacox
// Date: 2 July 2020
//
// Based on TM1637Display library at https://github.com/avishorp/TM1637
//
// Includes
#include <Arduino.h>
#include <TM1637TinyDisplay.h>
// Module connection pins (Digital Pins)
#define CLK 4
#define DIO 5
// The amount of time (in milliseconds) between tests
#define TEST_DELAY 1000
// Example of manually defining a display pattern
const uint8_t SEG_DONE[] = {
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O
SEG_C | SEG_E | SEG_G, // n
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G // E
};
// Example animation sequence for showAnimation() Test
// Built with 7-Segment Animator Tool
// https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html
const uint8_t ANIMATION[12][4] = {
{ 0x08, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x00, 0x08, 0x00, 0x00 }, // Frame 1
{ 0x00, 0x00, 0x08, 0x00 }, // Frame 2
{ 0x00, 0x00, 0x00, 0x08 }, // Frame 3
{ 0x00, 0x00, 0x00, 0x04 }, // Frame 4
{ 0x00, 0x00, 0x00, 0x02 }, // Frame 5
{ 0x00, 0x00, 0x00, 0x01 }, // Frame 6
{ 0x00, 0x00, 0x01, 0x00 }, // Frame 7
{ 0x00, 0x01, 0x00, 0x00 }, // Frame 8
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 9
{ 0x20, 0x00, 0x00, 0x00 }, // Frame 10
{ 0x10, 0x00, 0x00, 0x00 } // Frame 11
};
// To save RAM space, we can store the animation sequences in PROGMEM read-only flash memory.
// This requires using the showAnimation_P() function to read from PROGMEM memory space.
const uint8_t ANIMATION2[40][4] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 0
{ 0x01, 0x00, 0x00, 0x00 }, // Frame 1
{ 0x40, 0x01, 0x00, 0x00 }, // Frame 2
{ 0x08, 0x40, 0x00, 0x01 }, // Frame 3
{ 0x00, 0x08, 0x01, 0x40 }, // Frame 4
{ 0x01, 0x00, 0x40, 0x08 }, // Frame 5
{ 0x40, 0x01, 0x08, 0x00 }, // Frame 6
{ 0x08, 0x40, 0x00, 0x01 }, // Frame 7
{ 0x00, 0x08, 0x01, 0x40 }, // Frame 8
{ 0x01, 0x01, 0x40, 0x08 }, // Frame 9
{ 0x40, 0x40, 0x09, 0x00 }, // Frame 10
{ 0x08, 0x08, 0x40, 0x01 }, // Frame 11
{ 0x01, 0x00, 0x08, 0x40 }, // Frame 12
{ 0x40, 0x01, 0x00, 0x08 }, // Frame 13
{ 0x08, 0x40, 0x01, 0x00 }, // Frame 14
{ 0x01, 0x09, 0x41, 0x01 }, // Frame 15
{ 0x40, 0x40, 0x48, 0x40 }, // Frame 16
{ 0x08, 0x08, 0x08, 0x08 }, // Frame 17
{ 0x1c, 0x1c, 0x1c, 0x1c }, // Frame 18
{ 0x3e, 0x3e, 0x3e, 0x3e }, // Frame 19
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 20
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 21
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 22
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 23
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 24
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 25
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 26
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 27
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 28
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 29
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 30
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 31
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 32
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 33
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 34
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 35
{ 0x00, 0x00, 0x00, 0x00 }, // Frame 36
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 37
{ 0x3f, 0x3f, 0x3f, 0x3f }, // Frame 38
{ 0x3f, 0x3f, 0x3f, 0x3f } // Frame 39
};
// Text string constants can be stored in PROGMEM read-only flash memory.
// This requires using the showString_P() function to read from PROGMEM memory space.
// PROGMEM space strings are globally defined.
const PROGMEM char FlashString[] = "Flash Test - 1234567890";
const PROGMEM char FlashString2[] = "good";
TM1637TinyDisplay display(CLK, DIO);
void setup()
{
}
void loop()
{
int k;
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff }; // Test Pattern - All
uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 }; // Test Pattern - Blank
display.setBrightness(BRIGHT_HIGH);
// Announce Testing
display.showString("Test");
delay(TEST_DELAY);
// All segments on
display.setSegments(data);
delay(TEST_DELAY);
// Test setting different digits
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);
// Test display splitting with position
display.clear();
display.setSegments(data + 2, 2, 2); // Length 2, Position 2
delay(TEST_DELAY);
display.clear();
display.setSegments(data + 2, 2, 1); // Length 2, Position 1
delay(TEST_DELAY);
display.clear();
display.setSegments(data + 1, 3, 1); // Length 3, Position 1
delay(TEST_DELAY);
// Test decimal numbers with/without leading zeros in different positions
display.showNumber(0, false); // Expect: ___0
delay(TEST_DELAY);
display.showNumber(0, true); // Expect: 0000
delay(TEST_DELAY);
display.showNumber(1, false); // Expect: ___1
delay(TEST_DELAY);
display.showNumber(1, true); // Expect: 0001
delay(TEST_DELAY);
display.showNumber(301, false); // Expect: _301
delay(TEST_DELAY);
display.showNumber(301, true); // Expect: 0301
delay(TEST_DELAY);
display.clear();
display.showNumber(14, false, 2, 1); // Expect: _14_
delay(TEST_DELAY);
display.clear();
display.showNumber(4, true, 2, 2); // Expect: __04
delay(TEST_DELAY);
display.showNumber(-1, false); // Expect: __-1
delay(TEST_DELAY);
display.showNumber(-12); // Expect: _-12
delay(TEST_DELAY);
display.showNumber(-999); // Expect: -999
delay(TEST_DELAY);
display.clear();
display.showNumber(-5, false, 3, 0); // Expect: _-5_
delay(TEST_DELAY);
display.showNumberHex(0xf1af); // Expect: f1Af
delay(TEST_DELAY);
display.showNumberHex(0x2c); // Expect: __2C
delay(TEST_DELAY);
display.showNumberHex(0xd1, 0, true); // Expect: 00d1
delay(TEST_DELAY);
display.clear();
display.showNumberHex(0xd1, 0, true, 2); // Expect: d1__
delay(TEST_DELAY);
// Floating point tests
display.showNumber(1.234); // Floating point number
delay(TEST_DELAY);
display.showNumber(1.234, 2); // Format to 2 decimal places
delay(TEST_DELAY);
display.showNumber(-1.234); // Negative floating point number
delay(TEST_DELAY);
display.showNumber(-0.5); // Zero prefix floating point number
delay(TEST_DELAY);
display.showNumber(0.4);
delay(TEST_DELAY);
display.showNumber(1005.3);
delay(TEST_DELAY);
display.showNumber(10005.3); // Overflow test
delay(TEST_DELAY);
display.showNumber(0.52345, 1);
delay(TEST_DELAY);
display.showNumber(0.255, 2); // Test rounding up
delay(TEST_DELAY);
display.showString("\xB0", 1, 3); // Test with suffix
display.showNumber(12.3, 4, 3, 0);
delay(TEST_DELAY);
for (int x = -100; x < 100; x = x + 1) { // Count
display.showNumber((float)x / 10.0);
}
// Test all the dots
for (k = 0; k <= 4; k++) {
display.showNumberDec(0, (0x80 >> k), true);
delay(TEST_DELAY);
}
// Test Brightness Levels
for (k = 0; k < 4; k++)
data[k] = 0xff;
for (k = 0; k < 7; k++) {
display.setBrightness(k);
display.setSegments(data);
delay(TEST_DELAY);
}
// Test Display On/Off
for (k = 0; k < 4; k++) {
display.setBrightness(7, false); // Turn off
display.setSegments(data);
delay(TEST_DELAY);
display.setBrightness(7, true); // Turn on
display.setSegments(data);
delay(TEST_DELAY);
}
// Test Horizontal Level Meter
for (int count = 0; count < 3; count++) {
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, true);
delay(20);
}
for (int x = 100; x > 0; x = x - 10) {
display.showLevel(x, true);
delay(20);
}
}
// Test Vertical Level Meter
for (int count = 0; count < 3; count++) {
for (int x = 0; x <= 100; x = x + 10) {
display.showLevel(x, false);
delay(20);
}
for (int x = 100; x > 0; x = x - 10) {
display.showLevel(x, false);
delay(20);
}
}
// Test Numbers and Strings Using Positions
display.clear();
char degree[] = "\xB0";
display.showString(degree, 1, 3); // Position 3 (right) and 1 char length
for (int x = -50; x < 150; x++) {
display.showNumber(x, false, 3, 0); // Postion 0 (left) and 3 char length
delay(10);
}
delay(TEST_DELAY);
// Test String Display
display.clear();
display.showString("String Test 1234"); // Test literal string
delay(TEST_DELAY);
display.clear();
char stringb[10]; // Test dynamic string
sprintf(stringb, "25%cC", '\xB0'); // Display 25 + degree symbol + C
display.showString(stringb);
delay(TEST_DELAY);
display.clear(); // Long string test
display.showString("abcdefghijklmnopqrstuvwxyz.-=ABCDEFGHIJKLMNOPQRSTUVWXYZ");
delay(TEST_DELAY);
// Test Strings in PROGMEM flash memory
display.showString_P(FlashString);
delay(1000);
display.showString_P(FlashString2);
delay(1000);
// Animation Sequence Test in SRAM - Run 3 times
display.clear();
for (int count = 0; count < 3; count++) {
display.showAnimation(ANIMATION, FRAMES(ANIMATION), TIME_MS(10));
}
display.clear();
delay(TEST_DELAY);
// Animation Sequence Test in PROGMEM flash memory
display.clear();
display.showAnimation_P(ANIMATION2, FRAMES(ANIMATION2), TIME_MS(50));
// Done!
display.clear();
display.showString("The");
delay(TEST_DELAY);
display.showString("End");
delay(TEST_DELAY);
display.setSegments(SEG_DONE);
delay(TEST_DELAY * 5);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

View File

@ -1,65 +0,0 @@
#######################################
# Datatypes (KEYWORD1)
#######################################
TM1637TinyDisplay KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
setBrightness KEYWORD2
setSegments KEYWORD2
setScrolldelay KEYWORD2
clear KEYWORD2
showNumber KEYWORD2
showLevel KEYWORD2
showString KEYWORD2
showString_P KEYWORD2
showAnimation KEYWORD2
showAnimation_P KEYWORD2
showNumberDec KEYWORD2
showNumberHex KEYWORD2
encodeDigit KEYWORD2
encodeASCII KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
SEG_A LITERAL1
SEG_B LITERAL1
SEG_C LITERAL1
SEG_D LITERAL1
SEG_E LITERAL1
SEG_F LITERAL1
SEG_G LITERAL1
SEG_DP LITERAL1
digitToSegment LITERAL1
asciiToSegment LITERAL1
minusSegments LITERAL1
degreeSegments LITERAL1
BRIGHT_LOW LITERAL1
BRIGHT_0 LITERAL1
BRIGHT_1 LITERAL1
BRIGHT_2 LITERAL1
BRIGHT_3 LITERAL1
BRIGHT_4 LITERAL1
BRIGHT_5 LITERAL1
BRIGHT_6 LITERAL1
BRIGHT_7 LITERAL1
BRIGHT_8 LITERAL1
BRIGHT_HIGH LITERAL1
ON LITERAL1
OFF LITERAL1
#######################################
# Macros (LITERAL1)
#######################################
FRAMES LITERAL1
TIME_MS LITERAL1
TIME_S LITERAL1

View File

@ -1,15 +0,0 @@
{
"name": "TM1637TinyDisplay",
"keywords": "TM1637, tiny, LED, display",
"description": "A simple library to display numbers, text and animation on a 4-digit 7-segment TM1637 based display module.",
"repository": {
"type": "git",
"url": "https://github.com/jasonacox/TM1637TinyDisplay.git"
},
"authors": {
"name": "Jason Cox",
"url": "https://jasonacox.com"
},
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,10 +0,0 @@
name=TM1637TinyDisplay
version=1.3.0
author=Jason Cox <jason@jasonacox.com>
maintainer=Jason Cox <jason@jasonacox.com>
sentence=A simple library to display numbers, text and animation on a 4-digit 7-segment TM1637 based display module.
paragraph=Connect the TM1637 display CLK and DIO pins to your Arduino GPIO pins, include this library, initialize TM1637TinyDisplay and call easy to use functions like showNumber(), showString(), showLevel() and showAnimation(). Display will scroll text for larger strings. Functions support screen splitting for easy number + text formatting. Runs well on tiny controllers including the ATtiny85.
category=Display
url=https://github.com/jasonacox/TM1637TinyDisplay
architectures=*
includes=TM1637TinyDisplay.h

6
lib/lib_display/arduino-tm1637/.gitignore vendored Executable file
View File

@ -0,0 +1,6 @@
build
libraries
sketches
/.project
*.h.gch
.vscode

View File

@ -0,0 +1,17 @@
language: c
before_install:
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
- sleep 3
- export DISPLAY=:1.0
- wget https://downloads.arduino.cc/arduino-1.8.12-linux64.tar.xz
- tar xf arduino-1.8.12-linux64.tar.xz
- sudo mv arduino-1.8.12 /usr/local/share/arduino
- sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
install:
- ln -s $PWD /usr/local/share/arduino/libraries/SevenSegmentTM1637
script:
- arduino --verify --board arduino:avr:uno --pref sketchbook.path="$PWD" $PWD/examples/Basic/Basic.ino
notifications:
email:
on_success: change
on_failure: change

View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -0,0 +1,150 @@
# SevenSegmentTM1637 Arduino Library
* master&nbsp;&nbsp;[![Build Status](https://travis-ci.org/bremme/arduino-tm1637.svg?branch=master)](https://travis-ci.org/bremme/arduino-tm1637)
* develop&nbsp;[![Build Status](https://travis-ci.org/bremme/arduino-tm1637.svg?branch=develop)](https://travis-ci.org/bremme/arduino-tm1637)
Arduino library for controlling a TM163x based 7-segment display module. These modules are sold under various names by various suppliers. For example:
* [Seed Studio: Grove 4 digit display](http://www.seeedstudio.com/depot/grove-4digit-display-p-1198.html)
* [Ebay: 4 Bits Digital Tube LED TM1637](http://www.ebay.com/sch/i.html?_odkw=4+Bits+Digital+Tube+LED&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.X4+Bits+Digital+Tube+LED+TM1637.TRS0&_nkw=4+Bits+Digital+Tube+LED+TM1637&_sacat=0)
* [DealExtreme: LED 4-Digit Display Module](http://www.dx.com/s/TM1637)
They come in different sizes, colors and there is a clock (with a colon) and decimal (with four decimal dots) display variant. But the most common one is the red 0.36" clock version, this is also the cheapest one (you can get those for about $1.50). I've written this library using the above module, if I get my hands on any of the other variants I might add some specific code, for example to print floats on the decimal version.
![TM1637](extras/img/TM1637-4-digit-colon.jpg)
# Hardware setup
| TM1637 PIN | Arduino PIN | Description |
|------------|------------------|---------------------|
| CLK | Any digital pin | Clock |
| DIO | Any digital pin | Digital output |
| VCC | 5V | Supply voltage |
| GND | GND | Ground |
# Installation
Like any other Arduino library this library is installed by copying the files into a directory on the Arduino IDE search path. Most common is to put all files in a director in `your sketch folder/libraries/SevenSegmentTM1637/`. See [installing additional Arduino libraries](https://www.arduino.cc/en/Guide/Libraries) for more information.
# Usage
This library uses the [LCD API v1.0](http://playground.arduino.cc/Code/LCDAPI) so you can use the same functions/methods using this library as any lcd library which conforms to the LCD API. Furthermore this library (like described in the LCD API) inherent the Print class (See [Serial.print()](https://www.arduino.cc/en/Serial/Print) and for more details [Print.h](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.h)). This means that you can use all Print class functions/methods like you're used to when you're doing `Serial.print("Something")` or `Serial.print(128, BIN)` for example.
## Basic methods
* `SevenSegmentTM1637(clkPin, dioPin)`Creates a display object
* `init()` Initializes the display
* `print(value)` Prints anything to the display (e.g. a string, number..)
* `clear()` Clears the display (and resets cursor)
* `home()` Resets cursor
* `setCursor(row, col)` Set the cursor to specified position
* `setBacklight(value)` Sets the brightness of the display
* `on()` Turn the display on (set brightness to default)
* `off()` Turns the display off (set brightness to zero)
* `blink()` Blinks what ever is on the display
* `setColonOn(bool)` Sets the colon in the middle of the display
* `setPrintDelay(time)` Sets the delay when printing more than 4 characters
## Advanced methods
* `encode()` Encodes a single digit, single char or char array (C string)
* `printRaw()` Prints raw byte(s) to the display
* `command()` Sends one or more raw byte commands to the display
## Low level methods
* `comStart()` Serial communication start command
* `comWriteByte(bytes)` Serial communication send byte command
* `comAck()` Serial communication get acknowledged command
* `comStop()` Serial communication stop command
If you still want or need more functionality, I've included two super classes:
* `SevenSegmentExtended()` Extends the base class with more usefull functions.
* `SevenSegmentFun()` Even more extensions for fun.
If you use any of these super classes, you will also get all the basic, advanced and low level methods as well. If you use the fun class extension you will get the extended class methods as well.
## Extended class extra methods
* `SevenSegmentExtended(clkPin, dioPin)` Creates a display object
* `printTime(hour, min, [blink], [blinkDelay])` Prints the time to the display
* `printTime(time, [blink], [blinkDelay])` Prints the time to the display
* `printDualCounter(leftValue, rightValue)` Prints two digits to the display
## Fun class extra methods
* `SevenSegmentFun(clkPin, dioPin)` Creates a display object
* `printLevelVertical(level, [leftToRight])` Print 0-100% (2 steps per digit) vertical level e.g. volume, battery
* `printLevelVertical(level, leftToRight, symbol)` Print 0-100% (1 step per digit) vertical level using custom symbol
* `printLevelHorizontal(levels[])` Prints 4 horizontal levels e.g. equalizer
* `scrollingText()` Prints text and (keeps) scrolling
* `snake()` Classic snake demo
* `nightrider()` Nightrider Kit demo
* `bombTimer()` Count down a (bomb) timer
* `bouncingBall()` Bouncing ball demo
For more extended information on what arguments all above functions accept and return see the header files of the classes (SevenSegmentTM1637.h, SevenSegmentExtended.h and SevenSegmentFun.h).
# Trouble shooting
* Some boards might not have enough power on their 5V pin. In that case try to use an external 5V power supply. People reported that the ESP8266 might be one of those boards.
# Todo
* Refactor library to make it more modular and support more chips
+ Add support for all TM16xx chips (most should already work)
+ Add support for MAX7219 displays
+ Add support for TM74HC595 displays
# Changelog
+ 09-07-2020 version 1.1.1
+ Bug fixes
+ fixed a typo in SevenSegmentFun.h file
+ 04-07-2020 version 1.1.0
+ Improved `printLevelVertical()` using [pablo-lp](https://github.com/pablo-lp) suggestions
+ The default `printLevelVertical()` can diplay twice the number of levels now (e.g. 9 levels for a defaulf 4 digit display)
+ Add configurable blink delay when using the `printTime` methods (thanks to [simoneluconi](https://github.com/simoneluconi))
+ Added a new `printNumber()` method to make it easier to print right aligned numbers
+ Thanks [dan2600](https://github.com/dan2600), [Bilick88](https://github.com/Bilick88), [jasonacox](https://github.com/jasonacox) for your suggestions.
+ Bug fixes
+ Merge PR from [berendkleinhaneveld](https://github.com/berendkleinhaneveld) to fix some compiler warnings
+ Merge PR from [facelessloser](https://github.com/facelessloser) Remove some `Serial.prinln()` calls
+ Merge PR from [RAnders00](https://github.com/RAnders00) Fix incorrect repsonse from `comReadByte()`
+ Merge PR from [per1234](https://github.com/per1234) Use correct separator in `keywords.txt`
+ 04-11-2016 version 1.0.4
+ Fixed bombTimer not counting down to zero (thanks to [foons](https://github.com/fooons) for opening an issue)
* 22-05-2016 version 1.0.3
+ add support for all AVR MCU's (thanks to [per1234](https://github.com/per1234))
* 08-05-2016 version 1.0.2
+ fixed digitalHigh() macro for non AVR boards (thanks to [per1234](https://github.com/per1234))
* 28-09-2015 version 1.0.1
+ fixed folder structure to comply with Arduino library 1.5 rev 2 specifications
* 28-09-2015 version 1.0.0
+ First release
# Note
I spend quite a bit of time to build this library. I hope it will be useful to others. I decided to publish it, although there still might be small bugs. If you find one, just let me know and I will try to fix it. If you have any other suggestion, don't hesitate to contact me.
# Sources
I've looked at many sources while constructing this library, bassicly all alternative Arduino TM1637 libraries and some AVR TM1637 libraries. While doing so I've found some really nice improvements compared to other implementations. For example, most libraries use a really low clock speed (~50us), I've tested with clock speeds as low as 1us and the chip still seems to respond well. Furthermore, from the (Chinese) datasheet it seems that you always have to perform three operation when communicating with the IC; set some configuration, set the address and send 1-4 digit data and set the display brightness. I've found out that this is not the case, you can do all of those separately if you want.
Still without all these fine examples it would have taken me a lot more time to figure out the inner workings of this IC!
Sources:
* http://blog.3d-logic.com/2015/01/21/arduino-and-the-tm1637-4-digit-seven-segment-display/
* http://www.arduino.md/hardware/lcd-and-leds/0-36-led-display-4-digit-red/
* https://brainy-bits.com/tutorials/4-bits-7-segment-led-display-with-arduino/
#### Keywords
People will probably Google for keywords when looking for a driver, so here are some:
```TM1637 TM1636 library Arduino Led Driver 4 Digit Bits Digital LED Tube module LCD API Print.h Print class API display LCD AVR Atmega```

View File

@ -0,0 +1,100 @@
#include "SevenSegmentAsciiMap.h"
// store an ASCII Map in PROGMEM (Flash memory)
const uint8_t AsciiMap::map[] PROGMEM = {
TM1637_CHAR_SPACE,
TM1637_CHAR_EXC,
TM1637_CHAR_D_QUOTE,
TM1637_CHAR_POUND,
TM1637_CHAR_DOLLAR,
TM1637_CHAR_PERC,
TM1637_CHAR_AMP,
TM1637_CHAR_S_QUOTE,
TM1637_CHAR_L_BRACKET,
TM1637_CHAR_R_BRACKET,
TM1637_CHAR_STAR,
TM1637_CHAR_PLUS,
TM1637_CHAR_COMMA,
TM1637_CHAR_MIN,
TM1637_CHAR_DOT,
TM1637_CHAR_F_SLASH,
TM1637_CHAR_0, // 48 (ASCII)
TM1637_CHAR_1,
TM1637_CHAR_2,
TM1637_CHAR_3,
TM1637_CHAR_4,
TM1637_CHAR_5,
TM1637_CHAR_6,
TM1637_CHAR_7,
TM1637_CHAR_8,
TM1637_CHAR_9,
TM1637_CHAR_COLON,
TM1637_CHAR_S_COLON,
TM1637_CHAR_LESS,
TM1637_CHAR_EQUAL,
TM1637_CHAR_GREAT,
TM1637_CHAR_QUEST,
TM1637_CHAR_AT,
TM1637_CHAR_A, // 65 (ASCII)
TM1637_CHAR_B,
TM1637_CHAR_C,
TM1637_CHAR_D,
TM1637_CHAR_E,
TM1637_CHAR_F,
TM1637_CHAR_G,
TM1637_CHAR_H,
TM1637_CHAR_I,
TM1637_CHAR_J,
TM1637_CHAR_K,
TM1637_CHAR_L,
TM1637_CHAR_M,
TM1637_CHAR_N,
TM1637_CHAR_O,
TM1637_CHAR_P,
TM1637_CHAR_Q,
TM1637_CHAR_R,
TM1637_CHAR_S,
TM1637_CHAR_T,
TM1637_CHAR_U,
TM1637_CHAR_V,
TM1637_CHAR_W,
TM1637_CHAR_X,
TM1637_CHAR_Y,
TM1637_CHAR_Z,
TM1637_CHAR_L_S_BRACKET, // 91 (ASCII)
TM1637_CHAR_B_SLASH,
TM1637_CHAR_R_S_BRACKET,
TM1637_CHAR_A_CIRCUM,
TM1637_CHAR_UNDERSCORE,
TM1637_CHAR_A_GRAVE, // 96 (ASCII)
TM1637_CHAR_a,
TM1637_CHAR_b,
TM1637_CHAR_c,
TM1637_CHAR_d,
TM1637_CHAR_e,
TM1637_CHAR_f,
TM1637_CHAR_g,
TM1637_CHAR_h,
TM1637_CHAR_i,
TM1637_CHAR_j,
TM1637_CHAR_k,
TM1637_CHAR_l,
TM1637_CHAR_m,
TM1637_CHAR_n,
TM1637_CHAR_o,
TM1637_CHAR_p,
TM1637_CHAR_q,
TM1637_CHAR_r,
TM1637_CHAR_s,
TM1637_CHAR_t,
TM1637_CHAR_u,
TM1637_CHAR_v,
TM1637_CHAR_w,
TM1637_CHAR_x,
TM1637_CHAR_y,
TM1637_CHAR_z,
TM1637_CHAR_L_ACCON, // 123 (ASCII)
TM1637_CHAR_BAR,
TM1637_CHAR_R_ACCON,
TM1637_CHAR_TILDE // 126 (ASCII)
};

View File

@ -0,0 +1,109 @@
#ifndef SevenSegmentAsciiMap_H
#define SevenSegmentAsciiMap_H
#include <Arduino.h>
// ASCII MAPPINGS
#define TM1637_CHAR_SPACE B00000000 // 32 (ASCII)
#define TM1637_CHAR_EXC B00000110
#define TM1637_CHAR_D_QUOTE B00100010
#define TM1637_CHAR_POUND B01110110
#define TM1637_CHAR_DOLLAR B01101101
#define TM1637_CHAR_PERC B00100100
#define TM1637_CHAR_AMP B01111111
#define TM1637_CHAR_S_QUOTE B00100000
#define TM1637_CHAR_L_BRACKET B00111001
#define TM1637_CHAR_R_BRACKET B00001111
#define TM1637_CHAR_STAR B01011100
#define TM1637_CHAR_PLUS B01010000
#define TM1637_CHAR_COMMA B00010000
#define TM1637_CHAR_MIN B01000000
#define TM1637_CHAR_DOT B00001000
#define TM1637_CHAR_F_SLASH B00000110
#define TM1637_CHAR_0 B00111111 // 48
#define TM1637_CHAR_1 B00000110
#define TM1637_CHAR_2 B01011011
#define TM1637_CHAR_3 B01001111
#define TM1637_CHAR_4 B01100110
#define TM1637_CHAR_5 B01101101
#define TM1637_CHAR_6 B01111101
#define TM1637_CHAR_7 B00000111
#define TM1637_CHAR_8 B01111111
#define TM1637_CHAR_9 B01101111
#define TM1637_CHAR_COLON B00110000
#define TM1637_CHAR_S_COLON B00110000
#define TM1637_CHAR_LESS B01011000
#define TM1637_CHAR_EQUAL B01001000
#define TM1637_CHAR_GREAT B01001100
#define TM1637_CHAR_QUEST B01010011
#define TM1637_CHAR_AT B01011111
#define TM1637_CHAR_A B01110111 // 65 (ASCII)
#define TM1637_CHAR_B B01111111
#define TM1637_CHAR_C B00111001
#define TM1637_CHAR_D TM1637_CHAR_d
#define TM1637_CHAR_E B01111001
#define TM1637_CHAR_F B01110001
#define TM1637_CHAR_G B00111101
#define TM1637_CHAR_H B01110110
#define TM1637_CHAR_I B00000110
#define TM1637_CHAR_J B00001110
#define TM1637_CHAR_K B01110101
#define TM1637_CHAR_L B00111000
#define TM1637_CHAR_M B00010101
#define TM1637_CHAR_N B00110111
#define TM1637_CHAR_O B00111111
#define TM1637_CHAR_P B01110011
#define TM1637_CHAR_Q B01100111
#define TM1637_CHAR_R B00110011
#define TM1637_CHAR_S B01101101
#define TM1637_CHAR_T TM1637_CHAR_t
#define TM1637_CHAR_U B00111110
#define TM1637_CHAR_V B00011100
#define TM1637_CHAR_W B00101010
#define TM1637_CHAR_X TM1637_CHAR_H
#define TM1637_CHAR_Y B01101110
#define TM1637_CHAR_Z B01011011
#define TM1637_CHAR_L_S_BRACKET B00111001 // 91 (ASCII)
#define TM1637_CHAR_B_SLASH B00110000
#define TM1637_CHAR_R_S_BRACKET B00001111
#define TM1637_CHAR_A_CIRCUM B00010011
#define TM1637_CHAR_UNDERSCORE B00001000
#define TM1637_CHAR_A_GRAVE B00010000
#define TM1637_CHAR_a B01011111 // 97 (ASCII)
#define TM1637_CHAR_b B01111100
#define TM1637_CHAR_c B01011000
#define TM1637_CHAR_d B01011110
#define TM1637_CHAR_e B01111011
#define TM1637_CHAR_f TM1637_CHAR_F
#define TM1637_CHAR_g B01101111
#define TM1637_CHAR_h B01110100
#define TM1637_CHAR_i B00000100
#define TM1637_CHAR_j B00001100
#define TM1637_CHAR_k TM1637_CHAR_K
#define TM1637_CHAR_l B00110000
#define TM1637_CHAR_m TM1637_CHAR_M
#define TM1637_CHAR_n B01010100
#define TM1637_CHAR_o B01011100
#define TM1637_CHAR_p TM1637_CHAR_P
#define TM1637_CHAR_q TM1637_CHAR_Q
#define TM1637_CHAR_r B01010000
#define TM1637_CHAR_s TM1637_CHAR_S
#define TM1637_CHAR_t B01111000
#define TM1637_CHAR_u B00011100
#define TM1637_CHAR_v B00011100
#define TM1637_CHAR_w TM1637_CHAR_W
#define TM1637_CHAR_x TM1637_CHAR_X
#define TM1637_CHAR_y B01100110
#define TM1637_CHAR_z TM1637_CHAR_Z
#define TM1637_CHAR_L_ACCON B01111001 // 123 (ASCII)
#define TM1637_CHAR_BAR B00000110
#define TM1637_CHAR_R_ACCON B01001111
#define TM1637_CHAR_TILDE B01000000 // 126 (ASCII)
class AsciiMap {
public:
const static uint8_t map[96];
};
// static const uint8_t asciiMap[96];
#endif

View File

@ -0,0 +1,140 @@
#include "SevenSegmentExtended.h"
SevenSegmentExtended::SevenSegmentExtended(uint8_t pinClk, uint8_t pinDIO) :
SevenSegmentTM1637(pinClk, pinDIO)
{ };
void SevenSegmentExtended::printTime(uint16_t t, bool blink, uint16_t blinkDelay) {
uint16_t max = 2359;
t = ( t > max)?max:t;
uint8_t hour = t / 100;
t -= (hour * 100);
uint8_t min = t;
printTime(hour, min, blink);
};
void SevenSegmentExtended::printTime(uint8_t hour, uint8_t min, bool blink, uint16_t blinkDelay) {
bool colonWasOn = getColonOn();
setColonOn(true);
uint8_t buffer[4];
buffer[0] = encode(int16_t(hour / 10));
buffer[1] = encode(int16_t(hour % 10));
buffer[2] = encode(int16_t(min / 10));
buffer[3] = encode(int16_t(min % 10));
printRaw(buffer, 4, 0);
// turn colon off and on again
if (blink) {
delay(blinkDelay);
setColonOn(false);
printRaw(buffer[1],1);
delay(blinkDelay);
setColonOn(true);
printRaw(buffer[1],1);
}
setColonOn(colonWasOn);
};
void SevenSegmentExtended::printNumber(int16_t number, bool zeroPadding, bool rollOver, bool alignRight) {
const int16_t maxNumber = 9999;
const int16_t minNumber = -999;
bool positive = true;
// get and store sign
if (number < 0) {
positive = false;
};
// roll over if rollOver is set to true
if (rollOver == true) {
if (positive == true) {
number = number % int16_t(10000);
} else {
number = -1 * ((-1 * number) % 1000);
}
// limit number by default
} else {
number = number > maxNumber?maxNumber:number;
number = number < minNumber?minNumber:number;
}
// clear the display first
clear();
// align left is the default behavior, just forward to print
if (alignRight == false) {
print(number);
return;
}
if (positive == false) {
number *= -1;
print("-");
}
if (number > 999) {
setCursor(0, 0);
} else if (number > 99) {
if (zeroPadding == true) {print('0');}
setCursor(0, 1);
} else if (number > 9) {
if (zeroPadding == true) {print(F("00"));}
setCursor(0, 2);
} else {
if (zeroPadding == true) {print(F("000"));}
setCursor(0, 3);
};
print(number);
};
// positive counter 0..99, negative counter 0..-9
void SevenSegmentExtended::printDualCounter(int8_t leftCounter, int8_t rightCounter, bool zeroPadding) {
int8_t max = 99;
int8_t min = -9;
uint8_t zeroByte = encode('0');
leftCounter = (leftCounter > max)?max:leftCounter;
leftCounter = (leftCounter < min)?min:leftCounter;
rightCounter = (rightCounter > max)?max:rightCounter;
rightCounter = (rightCounter < min)?min:rightCounter;
bool colonWasOn = getColonOn(); // get current state
setColonOn(true); // turn on the colon
home(); // set cursor to zero
if ( leftCounter < 10 && leftCounter >= 0) {
if ( zeroPadding ) {
printRaw(zeroByte,1);
setCursor(0,1);
} else {
// print colon
printRaw(TM1637_COLON_BIT,1);
};
};
print(leftCounter);
if ( rightCounter < 10 && rightCounter >= 0) {
if ( zeroPadding ) {
printRaw(zeroByte,2);
}
uint8_t pos = 2;
printRaw(0,pos);
setCursor(0,3);
} else {
setCursor(0,2);
}
print(rightCounter);
// set to previous state
setColonOn(colonWasOn);
};

View File

@ -0,0 +1,44 @@
#ifndef SevenSegmentExtended_H
#define SevenSegmentExtended_H
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include "SevenSegmentTM1637.h"
class SevenSegmentExtended : public SevenSegmentTM1637 {
public:
SevenSegmentExtended(uint8_t pinClk, uint8_t pinDIO);
/* Prints given time to the display
@param [in] hour hours or minutes
@param [in] min minutes or seconds
*/
void printTime(uint8_t hour, uint8_t min, bool blink = false, uint16_t blinkDelay = TM1637_DEFAULT_CLOCK_BLINK_DELAY);
/* Prints given time to the display
@param [in] t time given as an int, e.g. 1643 prints 16:43
*/
void printTime(uint16_t t, bool blink = false, uint16_t blinkDelay = TM1637_DEFAULT_CLOCK_BLINK_DELAY);
/* Prints a number and aligns it (right by default)
Can print both positive and negative numbers. When the the number is larger then 9999
it will roll over to 0, the same happens for a negative number smaller then -999.
@param [in] number the number to print to the display
@param [in] alignRight (optional) set to true to alightright (default)
@param [in] rollOver (optional) set to true make the number rollover*/
void printNumber(int16_t number, bool zeroPadding = false, bool rollOver = false, bool alignRight = true);
/* Print two one or two digit numbers to the display
* Prints a number to the left and right of the display
*
@param [in] leftCounter the number on the left side of the display
@param [in] rightcounter the numnber on the right side of the display
@param [in] zeroPadding optional: pad counters with zero
*/
void printDualCounter(int8_t leftCounter, int8_t rightCounter, bool zeroPadding = false);
};
#endif

View File

@ -0,0 +1,254 @@
#include "SevenSegmentFun.h"
const PROGMEM uint8_t levelVerticalMap[4] = {
TM1637_CHAR_HOR_LEVEL_0,
TM1637_CHAR_HOR_LEVEL_1,
TM1637_CHAR_HOR_LEVEL_2,
TM1637_CHAR_HOR_LEVEL_3
};
SevenSegmentFun::SevenSegmentFun(uint8_t pinClk, uint8_t pinDIO) :
SevenSegmentExtended(pinClk, pinDIO)
{
randomSeed(analogRead(0));
};
// 9 levels ( 0, 12.5, 25, 37.4, 50, 62.5, 75.0, 87.5, 100)
void SevenSegmentFun::printLevelVertical(uint8_t level, bool leftToRight) {
level = (level > 100?100:level);
float levelScale = (100 / (TM1637_MAX_COLOM * 2.0));
uint8_t barsOn = float(level) / levelScale;
uint8_t d = leftToRight == true?0:TM1637_MAX_COLOM-1;
for (uint8_t i=0; i < TM1637_MAX_COLOM; i++) {
if (barsOn - (2 * (i + 1)) >= 0) {
_rawBuffer[d] = TM1637_CHAR_VERT_LEVEL_II;
} else if (barsOn - (2 * (i + 1)) >= 1) {
_rawBuffer[d] = (leftToRight == true)?TM1637_CHAR_VERT_LEVEL_I0:TM1637_CHAR_VERT_LEVEL_0I;
} else {
_rawBuffer[d] = 0;
}
if (leftToRight == true) {d++;}
else {d--;};
};
printRaw(_rawBuffer, TM1637_MAX_COLOM, 0);
};
void SevenSegmentFun::printLevelVertical(uint8_t level, bool leftToRight, uint8_t symbol) {
level /= (100 / TM1637_MAX_COLOM);
level = (level > TM1637_MAX_COLOM)?TM1637_MAX_COLOM:level;
for( uint8_t i=0; i < TM1637_MAX_COLOM;i++) {
if ( ( i < level && leftToRight ) || ( i >= ( TM1637_MAX_COLOM - level ) && !leftToRight) ) {
_rawBuffer[i] = symbol;
} else {
_rawBuffer[i] = 0;
}
};
printRaw(_rawBuffer, TM1637_MAX_COLOM, 0);
};
void SevenSegmentFun::nightrider(uint8_t repeats, uint16_t d, uint8_t symbol) {
uint8_t buffer[((TM1637_MAX_COLOM * 2) - 1)] = {0, };
for ( uint8_t i= 0; i < ((TM1637_MAX_COLOM * 2) - 1); i++) {
if ( i == (TM1637_MAX_COLOM - 1) ) {
buffer[i] = symbol;
} else {
buffer[i] = 0;
}
};
for( int8_t r=0; r < repeats; r++) {
for (int8_t i = (TM1637_MAX_COLOM - 1); i > 0; i--) {
printRaw( &buffer[i],4,0);
delay(d);
};
for ( int8_t i = 0; i < (TM1637_MAX_COLOM - 1); i++) {
printRaw( &buffer[i], TM1637_MAX_COLOM, 0);
delay(d);
};
}
}
// 5 levels ( 0, 33, 66, 100)
void SevenSegmentFun::printLevelHorizontal( uint8_t levels[4] ) {
for (uint8_t i=0; i < TM1637_MAX_COLOM;i++) {
levels[i] /= (100 / 3);
levels[i] = ( levels[i] > 3)?3:levels[i];
_rawBuffer[i] = pgm_read_byte_near(levelVerticalMap + levels[i]);
};
printRaw(_rawBuffer, TM1637_MAX_COLOM, 0);
}
void SevenSegmentFun::scrollingText(const char* str, uint8_t repeats) {
uint8_t buffer[TM1637_MAX_CHARS];
size_t length = encode(&buffer[3], str, TM1637_MAX_CHARS);
uint8_t paddingBegin = TM1637_MAX_COLOM - 1;
uint8_t totalPadding = (2 * paddingBegin) + 1;
// padd with three spaces in front
for(uint8_t i=0; i < paddingBegin; i++) {
buffer[i] = 0;
};
// padd with four spaces at the end (empty scree)
for(uint8_t i = length + paddingBegin; i < length + totalPadding ; i++) {
buffer[i] = 0;
};
for( ; repeats != 0; repeats--) {
printRaw(buffer, length + totalPadding);
if ( repeats > 250 ) { // more than 250 -> forever
repeats++;
}
};
}
void SevenSegmentFun::snake(uint8_t repeats, uint16_t d) {
uint8_t outerEdges = (4 * TM1637_MAX_LINES) + (TM1637_MAX_COLOM * 2);
uint8_t widthEdged = (TM1637_MAX_COLOM * 2);
// number of repeats/rounds
for ( uint8_t r=0; r < repeats; r++) {
// 12 steps for all outer edges
for (uint8_t i=0; i < outerEdges; i++) {
for (uint8_t j=0; j < TM1637_MAX_COLOM; j++) {
// set segments
// top edges
if ( i == j) {
_rawBuffer[j] =TM1637_CHAR_SNAKE_0;
}
// top right edge
else if ( i == TM1637_MAX_COLOM && j == 3) {
_rawBuffer[j] =TM1637_CHAR_SNAKE_1;
}
// bottom left edge
else if ( i == (TM1637_MAX_COLOM + 1) && j == 3) {
_rawBuffer[j] =TM1637_CHAR_SNAKE_2;
}
// bottom edges
else if ( i + j == (widthEdged + 1) ) {
_rawBuffer[j] =TM1637_CHAR_SNAKE_3;
}
// bottom left edge
else if ( i == (widthEdged + 2) && j == 0) {
_rawBuffer[j] =TM1637_CHAR_SNAKE_4;
}
// top left edge
else if ( i == (widthEdged + 3) && j == 0) {
_rawBuffer[j] =TM1637_CHAR_SNAKE_5;
} else {
_rawBuffer[j] = 0;
};
};
printRaw(_rawBuffer, 4, 0);
delay(d);
}
};
}
void SevenSegmentFun::bombTimer(uint8_t hours, uint8_t min, uint16_t speed) {
// maximum speed is 60000 -> 1min per ms
speed = (speed > 60000)?60000:speed;
uint16_t d = 60000 / speed;
// copy start minute
int8_t m = min;
int8_t h;
for ( h=hours; h >= 0; h--) {
for ( ; m >= 0; m--) {
printTime((uint8_t)h, (uint8_t)m);
delay(d);
};
m = 59; // reset minute timer
};
blink();
};
void SevenSegmentFun::bombTimer(uint8_t hours, uint8_t min, uint16_t speed, char* str) {
bombTimer(hours, min, speed);
print(str);
blink();
};
void SevenSegmentFun::bouncingBall(uint16_t moves, uint16_t d, bool runForever) {
int8_t wallRight = TM1637_MAX_COLOM - 1;
int8_t wallBottom = TM1637_MAX_LINES;
// start at top left
int8_t x = 0; int8_t y = 0;
int8_t newX; int8_t newY;
// default speed is 1 x right and 2 y down
int8_t vx = 1; int8_t vy = 1;
bool flipVx = false; bool flipVy = false;
// print initial state
printBall(x, y);
for ( ; moves != 0; moves--) {
newX = x + vx;
newY = y + vy;
// check if ball has hit the wall
if (newX > wallRight || newX < 0 ) {
vx = vx * -1;
newX = x + vx;
// random flip other direction as well
flipVy = (random(3) == 1);
};
if ( newY > wallBottom || newY < 0) {
vy = vy * -1;
newY = y + vy;
// random flip other direction as well
flipVx = (random(3) == 1);
};
if ( flipVy ) {
newY = y;
} else if ( flipVx ) {
newX = x;
};
// set new coordinates
x = newX; y = newY;
printBall(x, y);
delay(d);
if (runForever) {
moves++;
};
};
}
void SevenSegmentFun::printBall( const int8_t x, const int8_t y ) {
// uint8_t buffer[4] = {0,0,0,0};
// buffer[x] = (y > 0)?TM1637_CHAR_BALL_LOW:TM1637_CHAR_BALL_HIGH;
// printRaw(buffer);
uint8_t symbol = (y > 0)?TM1637_CHAR_BALL_LOW:TM1637_CHAR_BALL_HIGH;
print4Bit(x, y, symbol);
};
void SevenSegmentFun::print4Bit( const uint8_t x, const uint8_t y, uint8_t symbol) {
uint8_t buffer[4] = {0,0,0,0};
buffer[x] = symbol;
printRaw(buffer);
}

View File

@ -0,0 +1,65 @@
#ifndef SevenSegmentFun_H
#define SevenSegmentFun_H
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
// COMPILE TIME USER CONFIG ////////////////////////////////////////////////////
#define TM1637_SNAKE_DEFAULT_DELAY 50 // Snake step delay ms
#define TM1637_BOUNCING_BALL_DEFAULT_DELAY 100 // Bouncing ball delay ms
#define TM1637_NIGHTRIDER_DEFAULT_DELAY 200 // Nightrider delay ms
//
// A
// ---
// * F | | B
// X -G-
// * E | | C
// ---
// D
// X defines the colon (dots) and only applies to byte 1 (second from left)
// BXGFEDCBA
#define TM1637_CHAR_VERT_LEVEL_I0 B00110000 // | one bar left
#define TM1637_CHAR_VERT_LEVEL_0I B00000110 // | one bar right
#define TM1637_CHAR_VERT_LEVEL_II B00110110 // || two bars
#define TM1637_CHAR_HOR_LEVEL_0 B00000000
#define TM1637_CHAR_HOR_LEVEL_1 B00001000
#define TM1637_CHAR_HOR_LEVEL_2 B01001000
#define TM1637_CHAR_HOR_LEVEL_3 B01001001
#define TM1637_CHAR_SNAKE_0 B00000001
#define TM1637_CHAR_SNAKE_1 B00000010
#define TM1637_CHAR_SNAKE_2 B00000100
#define TM1637_CHAR_SNAKE_3 B00001000
#define TM1637_CHAR_SNAKE_4 B00010000
#define TM1637_CHAR_SNAKE_5 B00100000
#define TM1637_CHAR_BALL_HIGH B01100011
#define TM1637_CHAR_BALL_LOW B01011100
class SevenSegmentFun : public SevenSegmentExtended {
public:
SevenSegmentFun(uint8_t pinClk, uint8_t pinDIO);
void printLevelVertical(uint8_t level, bool leftToRight = true);
void printLevelVertical(uint8_t level, bool leftToRight, uint8_t symbol);
void printLevelHorizontal(uint8_t levels[4]);
void scrollingText(const char* str, uint8_t repeats);
void snake(uint8_t repeats = 1, uint16_t d = TM1637_SNAKE_DEFAULT_DELAY);
void nightrider(uint8_t repeats = 10, uint16_t d = TM1637_NIGHTRIDER_DEFAULT_DELAY, uint8_t symbol = TM1637_CHAR_VERT_LEVEL_II);
void bombTimer(uint8_t hours, uint8_t min, uint16_t speed = 60);
void bombTimer(uint8_t hours, uint8_t min, uint16_t speed, char* str);
void bouncingBall(uint16_t moves, uint16_t d, bool runForever = false);
void printBall(const int8_t x, const int8_t y);
void print4Bit(const uint8_t x, const uint8_t y, uint8_t symbol);
private:
};
#endif

View File

@ -0,0 +1,434 @@
#include "SevenSegmentTM1637.h"
SevenSegmentTM1637::SevenSegmentTM1637(uint8_t pinClk, uint8_t pinDIO) :
_pinClk(pinClk),
_pinDIO(pinDIO)
{
// setup pins
pinAsOutput(_pinClk);
pinAsOutput(_pinDIO);
digitalHigh(_pinClk);
digitalHigh(_pinDIO);
// setup defaults
setCursor(0, TM1637_DEFAULT_CURSOR_POS);
setPrintDelay(TM1637_DEFAULT_PRINT_DELAY);
setColonOn(TM1637_DEFAULT_COLON_ON);
setBacklight(TM1637_DEFAULT_BACKLIGHT);
// write command SET_DATA (Command1) Defaults
command(
TM1637_COM_SET_DATA |
TM1637_SET_DATA_WRITE |
TM1637_SET_DATA_A_ADDR |
TM1637_SET_DATA_M_NORM
);
};
// Print API ///////////////////////////////////////////////////////////////////
// single byte
size_t SevenSegmentTM1637::write(uint8_t byte) {
TM1637_DEBUG_PRINT(F("write byte:\t")); TM1637_DEBUG_PRINTLN((char)byte);
size_t n = 0;
if ( _cursorPos == _numCols ) {
shiftLeft(_rawBuffer, _numCols);
_rawBuffer[_cursorPos] = encode( (char)byte );
// buffer, length, position
printRaw( _rawBuffer, _numCols, 0);
++n;
};
if (_cursorPos < _numCols) {
_rawBuffer[_cursorPos] = encode( (char)byte );
// buffer, length, position
printRaw( _rawBuffer, _cursorPos+1, 0);
setCursor(1, _cursorPos + 1);
++n;
}
return n;
}
// null terminated char array
size_t SevenSegmentTM1637::write(const char* str) {
TM1637_DEBUG_PRINT(F("write char*:\t")); TM1637_DEBUG_PRINTLN(str);
uint8_t encodedBytes[4];
encode(encodedBytes, str, 4);
uint8_t i =4;
while( str[i] != '\0' ) {
printRaw(encodedBytes);
shiftLeft(encodedBytes, 4);
encodedBytes[3] = encode( str[i] );
i++;
if ( i == TM1637_MAX_CHARS) {
break;
}
}
return i;
};
// byte array with length
size_t SevenSegmentTM1637::write(const uint8_t* buffer, size_t size) {
TM1637_DEBUG_PRINT(F("write uint8_t*:\t("));
for(size_t i=0; i < size; i++) {
TM1637_DEBUG_PRINT((char)buffer[i]);
TM1637_DEBUG_PRINT(i == size -1?F(""):F(", "));
}
TM1637_DEBUG_PRINT(F(") "));
TM1637_DEBUG_PRINT(size);
uint8_t encodedBytes[TM1637_MAX_CHARS];
if ( size > TM1637_MAX_CHARS) {
size = TM1637_MAX_CHARS;
}
size_t length = encode(encodedBytes, buffer, size);
TM1637_DEBUG_PRINT(F(" (")); TM1637_DEBUG_PRINT(length); TM1637_DEBUG_PRINT(F(", "));
TM1637_DEBUG_PRINT(_cursorPos); TM1637_DEBUG_PRINTLN(F(")"));
printRaw(encodedBytes, length, _cursorPos);
return length;
};
// Liquid cristal API
void SevenSegmentTM1637::begin(uint8_t cols, uint8_t rows) {
_numCols = cols;
_numRows = rows;
clear();
};
void SevenSegmentTM1637::init(uint8_t cols, uint8_t rows) {
begin(cols, rows);
}
void SevenSegmentTM1637::clear(void) {
uint8_t rawBytes[4] = {0,0,0,0};
printRaw(rawBytes);
home();
};
void SevenSegmentTM1637::home(void) {
setCursor(0, 0);
};
void SevenSegmentTM1637::setCursor(uint8_t row, uint8_t col) {
col = (col > TM1637_MAX_COLOM -1)?TM1637_MAX_COLOM-1:col;
_cursorPos = col;
};
void SevenSegmentTM1637::setBacklight(uint8_t value) {
value = (value > 100 )?100:value; // 0..100 brightness
// Store the backlight value
_backLightValue = value;
// scale backlight value to 0..8
value /= 10; // 0..10
value = (value > 8 )? 8:value; // only 8 levels and off
uint8_t cmd = TM1637_COM_SET_DISPLAY;;
switch ( value ) {
case 0:
cmd |= TM1637_SET_DISPLAY_OFF;
break;
case 1:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_1;
break;
case 2:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_2;
break;
case 3:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_4;
break;
case 4:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_10;
break;
case 5:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_11;
break;
case 6:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_12;
break;
case 7:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_13;
break;
case 8:
cmd |= TM1637_SET_DISPLAY_ON | TM1637_SET_DISPLAY_14;
break;
};
#if TM1637_DEBUG
bool ack = command(cmd);
TM1637_DEBUG_PRINT(F("SET_DISPLAY:\t")); TM1637_DEBUG_PRINTLN((
cmd
), BIN);
TM1637_DEBUG_PRINT(F("Acknowledged:\t")); TM1637_DEBUG_PRINTLN(ack);
#else
command(cmd);
#endif
};
void SevenSegmentTM1637::setContrast(uint8_t value) {
setBacklight(value);
}
void SevenSegmentTM1637::on(void) {
setBacklight(TM1637_DEFAULT_BACKLIGHT);
};
void SevenSegmentTM1637::off(void) {
setBacklight(0);
clear();
};
// SevenSegmentTM1637 public methods
void SevenSegmentTM1637::blink(uint8_t blinkDelay, uint8_t repeats, uint8_t maxBacklight, uint8_t minBacklight) {
for (uint8_t i=0; i < repeats; i++) {
setBacklight(minBacklight); // turn backlight off
delay(blinkDelay);
setBacklight(maxBacklight); // turn backlight on
delay(blinkDelay);
}
// restore backlight
setBacklight(_backLightValue);
}
void SevenSegmentTM1637::setPrintDelay(uint16_t printDelay) {
_printDelay = printDelay;
};
bool SevenSegmentTM1637::getColonOn(void) {
return (_colonOn);
};
void SevenSegmentTM1637::setColonOn(bool setToOn) {
_colonOn = setToOn;
}
void SevenSegmentTM1637::printRaw(uint8_t rawByte, uint8_t position) {
uint8_t cmd[2];
cmd[0] = TM1637_COM_SET_ADR | position;
cmd[1] = rawByte;
if (position == 1) { cmd[1]|=(_colonOn)?TM1637_COLON_BIT:0; };
command(cmd, 2);
};
void SevenSegmentTM1637::printRaw(const uint8_t* rawBytes, size_t length, uint8_t position) {
// if fits on display
if ( (length + position) <= _numCols) {
uint8_t cmd[5] = {0, };
cmd[0] = TM1637_COM_SET_ADR | (position & B111); // sets address
memcpy(&cmd[1], rawBytes, length); // copy bytes
// do we have to print a colon?
if ( position < 2 ) { // printing after position 2 has never a colon
if ( position == 0 && length >= 2) {
// second index is the colon
cmd[2] |= (_colonOn)?TM1637_COLON_BIT:0;
} else {
// first index is the colon
cmd[1] |= (_colonOn)?TM1637_COLON_BIT:0;
}
}
// TM1637_DEBUG_PRINT(F("ADDR :\t")); TM1637_DEBUG_PRINTLN(cmd[0],BIN);
// TM1637_DEBUG_PRINT(F("DATA0:\t")); TM1637_DEBUG_PRINTLN(cmd[1],BIN);
command(cmd, length+1); // send to display
}
// does not fit on display, need to print with delay
else {
// First print 1-4 characters
uint8_t numtoPrint = _numCols - position;
printRaw(rawBytes, numtoPrint, position);
delay(_printDelay);
// keep printing 4 characters till done
uint8_t remaining = length - numtoPrint + 3;
uint8_t i = 1;
while( remaining >= _numCols) {
printRaw(&rawBytes[i], _numCols, 0);
delay(_printDelay);
remaining--;
i++;
};
}
};
// Helpers
uint8_t SevenSegmentTM1637::encode(char c) {
if ( c < ' ') { // 32 (ASCII)
return 0;
}
return pgm_read_byte_near(AsciiMap::map + c - ' ');
};
uint8_t SevenSegmentTM1637::encode(int16_t d) {
// can only encode single digit
if ( d > 9 || d < 0) {
return 0;
};
return pgm_read_byte_near(AsciiMap::map + d + '0' - ' ');
};
size_t SevenSegmentTM1637::encode(uint8_t* buffer, const char* str, size_t bufferSize) {
size_t i;
for (i=0; i < bufferSize; i++) {
if (str[i] == '\0' ) {
return i;
}
buffer[i] = encode( str[i] );
};
return i;
}
size_t SevenSegmentTM1637::encode(uint8_t* buffer, const uint8_t* byteArr, size_t bufferSize) {
size_t i;
for (i=0; i < bufferSize; i++) {
buffer[i] = encode( (char)byteArr[i] );
};
return i;
}
void SevenSegmentTM1637::shiftLeft(uint8_t* buffer, size_t length) {
for (uint8_t i=0; i < length ; i++) {
buffer[i] = buffer[i+1];
}
}
// SevenSegmentTM1637 LOW LEVEL
bool SevenSegmentTM1637::command(uint8_t cmd) const{
return command(_pinClk, _pinDIO, cmd);
};
bool SevenSegmentTM1637::command(uint8_t pinClk, uint8_t pinDIO, uint8_t cmd) {
comStart(pinClk, pinDIO);
comWriteByte(pinClk, pinDIO,cmd);
bool acknowledged = comAck(pinClk, pinDIO);
comStop(pinClk, pinDIO);
return acknowledged;
}
bool SevenSegmentTM1637::command(const uint8_t* commands, uint8_t length) const {
return command(_pinClk, _pinDIO, commands, length);
};
bool SevenSegmentTM1637::command(uint8_t pinClk, uint8_t pinDIO, const uint8_t* commands, uint8_t length) {
bool acknowledged = true;
comStart(pinClk, pinDIO);
for (uint8_t i=0; i < length;i++) {
comWriteByte(pinClk, pinDIO, commands[i]);
acknowledged &= comAck(pinClk, pinDIO);
};
comStop(pinClk, pinDIO);
return acknowledged;
}
uint8_t SevenSegmentTM1637::comReadByte(void) const {
uint8_t readKey = 0;
comStart();
comWriteByte(TM1637_COM_SET_DATA | TM1637_SET_DATA_READ);
comAck();
pinAsInput(_pinDIO);
digitalHigh(_pinDIO);
delayMicroseconds(5);
for ( uint8_t i=0; i < 8; i++) {
readKey >>= 1;
digitalLow(_pinClk);
delayMicroseconds(30);
digitalHigh(_pinClk);
if ( isHigh(_pinDIO) ) {
readKey = readKey | B10000000;
};
delayMicroseconds(30);
};
pinAsOutput(_pinDIO);
comAck();
comStop();
return readKey;
};
void SevenSegmentTM1637::comWriteByte(uint8_t command) const{
comWriteByte(_pinClk, _pinDIO, command);
};
void SevenSegmentTM1637::comWriteByte(uint8_t pinClk, uint8_t pinDIO, uint8_t command) {
// CLK in bits
for ( uint8_t i=0; i < 8; i++) {
digitalLow(pinClk); // CLK LOW
if ( command & B1) {
digitalHigh(pinDIO);// DIO HIGH
} else {
digitalLow(pinDIO); // DIO LOW
}
delayMicroseconds(TM1637_CLK_DELAY_US);
command >>= 1;
digitalHigh(pinClk); // CLK HIGH
delayMicroseconds(TM1637_CLK_DELAY_US);
};
}
void SevenSegmentTM1637::comStart(void) const {
comStart(_pinClk, _pinDIO);
};
void SevenSegmentTM1637::comStart(uint8_t pinClk, uint8_t pinDIO) {
digitalHigh(pinDIO); // DIO HIGH
digitalHigh(pinClk); // CLK HIGH
delayMicroseconds(TM1637_CLK_DELAY_US);
digitalLow(pinDIO); // DIO LOW
}
void SevenSegmentTM1637::comStop(void) const {
comStop(_pinClk, _pinDIO);
};
void SevenSegmentTM1637::comStop(uint8_t pinClk, uint8_t pinDIO) {
digitalLow(pinClk); // CLK LOW
delayMicroseconds(TM1637_CLK_DELAY_US);
digitalLow(pinDIO); // DIO LOW
delayMicroseconds(TM1637_CLK_DELAY_US);
digitalHigh(pinClk); // CLK HIGH
delayMicroseconds(TM1637_CLK_DELAY_US);
digitalHigh(pinDIO); // DIO HIGH
}
bool SevenSegmentTM1637::comAck(void) const {
return comAck(_pinClk, _pinDIO);
};
bool SevenSegmentTM1637::comAck(uint8_t pinClk, uint8_t pinDIO) {
bool acknowledged = false;
digitalLow(pinClk); // CLK LOW
pinAsInputPullUp(pinDIO); // DIO INPUT PULLUP (state==HIGH)
delayMicroseconds(TM1637_CLK_DELAY_US);
acknowledged = isLow(pinDIO);// Ack should pull the pin low again
digitalHigh(pinClk); // CLK HIGH
delayMicroseconds(TM1637_CLK_DELAY_US);
digitalLow(pinClk); // CLK LOW
pinAsOutput(pinDIO);
return acknowledged;
}

View File

@ -0,0 +1,347 @@
/*
SevenSegmentTM1637 - class to control a 4 digit seven segment display with a TM1636 or TM1637 driver IC
Created by Bram Harmsen, September 25, 2015
Released into the public domain.
Licence: GNU GENERAL PUBLIC LICENSE V2.0
# Changelog
v1.0 25-10-2015
v1.1 04-07-2020
*/
#ifndef SevenSegmentTM1637_H
#define SevenSegmentTM1637_H
#include <Arduino.h>
#include "SevenSegmentAsciiMap.h"
// COMPILE TIME USER CONFIG ////////////////////////////////////////////////////
#define TM1637_DEBUG false // true for serial debugging
#define TM1637_BEGIN_DELAY 500 // ms
#define TM1637_PRINT_BUFFER_SIZE 128 // lower if you don't need it
// Default values //////////////////////////////////////////////////////////////
#define TM1637_DEFAULT_PRINT_DELAY 300 // 300 ms delay between characters
#define TM1637_DEFAULT_BLINK_DELAY 50 // ms
#define TM1637_DEFAULT_CLOCK_BLINK_DELAY 500 // the default delay for when using printTime
#define TM1637_DEFAULT_BLINK_REPEAT 10
#define TM1637_DEFAULT_CURSOR_POS 0 // 0-MAX-1 (e.g 3)
#define TM1637_DEFAULT_COLON_ON false //
#define TM1637_DEFAULT_BACKLIGHT 100 // 0..100
#define TM1637_MAX_LINES 1 // number of display lines
#define TM1637_MAX_COLOM 4 // number of coloms (digits)
#define TM1637_MAX_CHARS 128
// PROGRAM CONFIG (ONLY CHANGE WHEN YOU KNOW WHAT YOU RE DOING:)////////////////
#define TM1637_CLK_DELAY_US 5 // clock delay for communication
// mine works with 1us, perhaps increase if display does not function ( tested upto 1ms)
// COMMANDS ////////////////////////////////////////////////////////////////////
#define TM1637_COM_SET_DATA B01000000 // 0x40 (1) Data set
#define TM1637_COM_SET_ADR B11000000 // 0xC0 (2) Address command set
#define TM1637_COM_SET_DISPLAY B10000000 // 0x80 (3) Display control command set
// Data set (1) (use logical OR to contruct complete command)
#define TM1637_SET_DATA_WRITE B00000000 // Write data to the display register
#define TM1637_SET_DATA_READ B00000010 // Read the key scan data
#define TM1637_SET_DATA_A_ADDR B00000000 // Automatic address increment
#define TM1637_SET_DATA_F_ADDR B00000100 // Fixed address
#define TM1637_SET_DATA_M_NORM B00000000 // Normal mode
#define TM1637_SET_DATA_M_TEST B00100000 // Test mode
// Address settings (2) (use logical OR to contruct complete command)
#define TM1637_SET_ADR_00H B0000000 // addr 00
#define TM1637_SET_ADR_01H B0000001 // addr 01
#define TM1637_SET_ADR_02H B0000010 // addr 02
#define TM1637_SET_ADR_03H B0000011 // addr 03
#define TM1637_SET_ADR_04H B0000100 // addr 04 (only TM1637)
#define TM1637_SET_ADR_05H B0000101 // addr 05 (only TM1637)
// The command is used to set the display register address; if the address is set to 0C4H or higher, the data is ignored, until the effective address is set; when the power is on, the default is set to 00H address.
// Display control command set (use logical OR to consruct complete command)
#define TM1637_SET_DISPLAY_1 B0000000 // Pulse width 1/16 (0.0625) (0)
#define TM1637_SET_DISPLAY_2 B0000001 // Pulse width 2/16 (0.0625) (1)
#define TM1637_SET_DISPLAY_4 B0000010 // Pulse width 4/16 (0.0625) (2)
#define TM1637_SET_DISPLAY_10 B0000011 // Pulse width 10/16 (0.0625) (3)
#define TM1637_SET_DISPLAY_11 B0000100 // Pulse width 11/16 (0.0625) (4)
#define TM1637_SET_DISPLAY_12 B0000101 // Pulse width 12/16 (0.0625) (5)
#define TM1637_SET_DISPLAY_13 B0000110 // Pulse width 13/16 (0.0625) (6)
#define TM1637_SET_DISPLAY_14 B0000111 // Pulse width 14/16 (0.0625) (7)
#define TM1637_SET_DISPLAY_OFF B0000000 // OFF
#define TM1637_SET_DISPLAY_ON B0001000 // ON
// there are a total of 8 brighness values, plus off
// PROTOCOL SPECIFICATION
/*
* Structure
* START COMMAND ACK STOP set config or display
* START ADR_CMD DATA ACK STOP sets single digit
* START ADR_CMD DATA0 .. DATAN ACK STOP sets multiple digits when in auto mode
*
* There are basicly three things you can do:
* 1. Set some configuration values
* - read/write mode, auto/manual address, normal/test mode
* 2. Set a (starting) address followed by 1 or N data bytes
* 3. Set the display brightness (pwm) 0-7 and on or off
*
* From the datasheet it might seem that you always have to perform all three commands; setting configuration, setting address and data bytes and display. I'v tested this and this is not true. You can just set only one of these three. But ofcourse you have to make sure that your configuration is set properly. For example if you haven't set the configuration to automatic addresses, you can't just send out 4 data bytes, it won't work. Simlilair, if your display is off and you write some data to it, it won't display. On the other hand most default setting are what you want most of the time.
*/
class SevenSegmentTM1637 : public Print {
public:
// LIQUID CRISTAL API ///////////////////////////////////////////////////////
// See http://playground.arduino.cc/Code/LCDAPI for more details.
/* Constructor
@param [in] pinClk clock pin (any digital pin)
@param [in] pinDIO digital output pin (any digital pin)
*/
SevenSegmentTM1637(uint8_t pinClk, uint8_t pinDIO);
/* Initializes the display
* Initializes the display, sets some text and blinks the display
@param [in] cols optional: number of coloms (digits)
@param [in] rows optional: number of rows
*/
void init(uint8_t cols = TM1637_MAX_COLOM, uint8_t rows = TM1637_MAX_LINES);
/* Implemented for compatibility, see begin() above */
void begin(uint8_t cols = TM1637_MAX_COLOM, uint8_t rows = TM1637_MAX_LINES);
// Print class inheritance ///////////////////////////////////////////////////
// See https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.h for more details
/* This library inherent the Print class, this means that all regular print function can be used. For example:
* printing a number: print(78)
* printint a number in BIN, OCT, HEX..: print(78, BIN)
* printing a float: print(2.85)
* printing a PROGMEM c string: print(F("Arduino"))
*
* Also the more low level write() function can be used. (Actually all print function eventually call one of these write methods, every class that wants to inherent from the Print class needs to implement these)
*/
size_t write(uint8_t byte);
size_t write(const char* str);
size_t write(const uint8_t* buffer, size_t size);
/* Clears the display
* Writes zero to all digits and segments, display off.
*/
void clear(void);
/* Sets the cursor position to zero
*/
void home(void);
/* Sets the cursor position to a specfic position
*
@param [in] col colomn (position)
*/
void setCursor(uint8_t row, uint8_t col);
// Liquid cristal optional //////////////////////////////////////////////////
/* Sets the display backlight
* The display has 8 PWM modes and an off mode. The function accepts a value from 0 to 100, where 80-100 are the same; full brighness.
@param [in] value brightness value (0..80(100))
*/
void setBacklight(uint8_t value);
/* Sets the display contrast (identical to brightness)
* This function is mainly for compatibility with the LCD API
*/
void setContrast(uint8_t value);
/* Turns the display ON
* Identical to setting the brightness to the default value.
*/
void on(void);
/* Turns the display ON
* Identical to setting the brightness to zero and clearing the display.
*/
void off(void);
// SevenSegmentTM1637 METHODS ///////////////////////////////////////////////
/* Blink the last printed text
*
@param [in] blinkDelay optional: blink delay in ms
@param [in] repeats optional: number of blink repeats
*/
void blink(uint8_t blinkDelay = TM1637_DEFAULT_BLINK_DELAY, uint8_t repeats = TM1637_DEFAULT_BLINK_REPEAT, uint8_t maxBacklight=100, uint8_t minBacklight=0);
// getters and setters ///////////////////////////////////////////////////////
/* Turn the colon on or off
* When turing the colon on, the next displayed text/numbers will have a colon
@param [in] setToOn sets the colon to on or off
*/
void setColonOn(bool setToOn);
/* Get the currrent colon setting
*/
bool getColonOn(void);
/* Sets the delay for scrolling text
* When printing more than four characters/ the display will scroll, this setting determines the scrolling speed in ms
@param [in] printDelay the print delay in ms
*/
void setPrintDelay(uint16_t printDelay);
// helpers //////////////////////////////////////////////////////////////////
/* Encodes a character to sevensegment binairy
*
@param [in] c a character to encode
*/
uint8_t encode(char c);
/* Encodes a single digit to sevensegment binairy
*
@param [in] d a digit to encode
*/
uint8_t encode(int16_t d);
/* Encodes a null terminated c string (char array) to sevensegment binairy
*
@param [out] buffer holds the encodes char array
@param [in] str the c string to encode
@param [in] bufferSize the size/length of the buffer
*/
size_t encode(uint8_t* buffer, const char* str, size_t bufferSize);
/* Encodes a byte array to sevensegment binairy
*
@param [out] buffer holds the encodes char array
@param [in] byteArr the byte array to encode
@param [in] bufferSize the size/length of the buffer
*/
size_t encode(uint8_t* buffer, const uint8_t* byteArr, size_t arrSize);
/* Shift an array one position to the left
@param [out] buffer the buffer to be shifted
@param [in] length the length to the buffer
*/
void shiftLeft(uint8_t* buffer, size_t length);
// SevenSegmentTM1637 low level methods (use when you know what you're doing)
/* Prints raw (encoded) bytes to the display
* A
* ___
* * F | | B
* X -G-
* * E | | C
* ___
* D
* Bit: 76543210
* Segment: XGFEDCBA
*
* For example to print an H, you would set bits BCEFG, this gives B01110110 in binary or 118 in decimal or 0x76 in HEX.
* Bit 7 (X) only applies to the second digit and sets the colon
*/
/* Print raw (binary encodes) bytes to the display
@param [in] rawBytes Array of raw bytes
@param [in] length optional: length to print to display
@param [in] position optional: Start position
*/
void printRaw(const uint8_t* rawBytes, size_t length = 4, uint8_t position = 0);
/* Print raw (binary encodes) bytes to the display
@param [in] rawByte Raw byte
@param [in] position optional: Start position
*/
void printRaw(uint8_t rawByte, uint8_t position);
/* Write command to IC TM1637
@param [in] cmd command to send
@return acknowledged? command was (successful) acknowledged
*/
bool command(uint8_t cmd) const;
bool command(const uint8_t* command, uint8_t length) const;
/* Read bytes from IC TM1637
* The IC also can read the state of a keypad? TODO untested
*/
uint8_t comReadByte(void) const;
/* Write a single command to the display
@param [in] cmd command to send
*/
void comWriteByte(uint8_t command) const;
/* Send start signal
* Send the start signal for serial communication
*/
void comStart(void) const;
/* Send stop signal
* Send the stop signal for serial communication
*/
void comStop(void) const;
/* Get command acknowledged
* Get acknowledge signal (command was succesful received)
*/
bool comAck(void) const;
/* Static version of low level function
* If using more than one display, this saves some space since these methods will be shared among all instances/objects of the class
*/
static bool command(uint8_t pinClk, uint8_t pinDIO, uint8_t cmd);
static bool command(uint8_t pinClk, uint8_t pinDIO, const uint8_t* command, uint8_t length);
static void comStart(uint8_t pinClk, uint8_t pinDIO);
static void comWriteByte(uint8_t pinClk, uint8_t pinDIO, uint8_t command);
static bool comAck(uint8_t pinClk, uint8_t pinDIO);
static void comStop(uint8_t pinClk, uint8_t pinDIO);
protected:
const uint8_t _pinClk; // clock pin
const uint8_t _pinDIO; // digital out pin
uint8_t _numCols; // number of columns
uint8_t _numRows; // number of rows
uint8_t _backLightValue; // brightness of the display (0..100)
uint8_t _cursorPos; // current cursor position
uint16_t _printDelay; // print delay in ms (multiple chars)
uint8_t _colonOn; // colon bit if set
uint8_t _rawBuffer[TM1637_MAX_COLOM];// hold the last chars printed to display
};
#define TM1637_COLON_BIT B10000000
// debug macros for debugging
#if TM1637_DEBUG
#define TM1637_DEBUG_BEGIN(x) Serial.begin(x)
#define TM1637_DEBUG_PRINT(...) Serial.print(__VA_ARGS__)
#define TM1637_DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
#define TM1637_DEBUG_WRITE(x) Serial.write(x)
#define TM1637_DEBUG_MESSAGE(...) \
Serial.print(millis()); \
Serial.print(F("\t")); \
Serial.print(__VA_ARGS__);
#define TM1637_DEBUG_MESSAGELN(...) \
TM1637_DEBUG_MESSAGE(__VA_ARGS__) \
Serial.println();
#else
#define TM1637_DEBUG_BEGIN(x)
#define TM1637_DEBUG_PRINT(...)
#define TM1637_DEBUG_PRINTLN(...)
#define TM1637_DEBUG_WRITE(x)
#define TM1637_DEBUG_MESSAGE(x)
#define TM1637_DEBUG_MESSAGELN(x)
#endif
// arduino:standard variant direct port access macros for more speed ( communication is ~us)
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8A__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
#define portOfPin(P) \
( ((P) >= 0 && (P) < 8)? &PORTD:( ((P) > 7 && (P) < 14) ? &PORTB: &PORTC ) )
#define ddrOfPin(P) \
( ((P) >= 0 && (P) < 8)? &DDRD: ( ((P) > 7 && (P) < 14) ? &DDRB: &DDRC ) )
#define pinOfPin(P) \
( ((P) >= 0 && (P) < 8)? &PIND: ( ((P) > 7 && (P) < 14) ? &PINB: &PINC ) )
#define pinIndex(P) ( (uint8_t)( P > 13 ? P-14: P&7 ) )
#define pinMask(P) ( (uint8_t)( 1 << pinIndex(P) ) )
#define pinAsInput(P) *(ddrOfPin(P) ) &= ~pinMask(P)
#define pinAsInputPullUp(P) *(ddrOfPin(P) ) &= ~pinMask(P);digitalHigh(P)
#define pinAsOutput(P) *(ddrOfPin(P) ) |= pinMask(P)
#define digitalLow(P) *(portOfPin(P)) &= ~pinMask(P)
#define digitalHigh(P) *(portOfPin(P)) |= pinMask(P)
#define isHigh(P) ( ( *( pinOfPin(P) ) & pinMask(P) ) > 0 )
#define isLow(P) ( ( *( pinOfPin(P) ) & pinMask(P) ) == 0 )
#define digitalState(P) ((uint8_t)isHigh(P))
#else
#define pinAsOutput(P) pinMode(P, OUTPUT)
#define pinAsInput(P) pinMode(P, INPUT)
#define pinAsInputPullUp(P) pinMode(P, INPUT_PULLUP)
#define digitalLow(P) digitalWrite(P, LOW)
#define digitalHigh(P) digitalWrite(P, HIGH)
#define isHigh(P) (digitalRead(P) == 1)
#define isLow(P) (digitalRead(P) == 0)
#define digitalState(P) digitalRead(P)
#endif
#endif

View File

@ -0,0 +1,57 @@
/*
Basic usage example
Demonstrated some of the basic functionality of the library. Initialize the display,
set the backlight brightness, print some text, count from 0 to 100 and
print and blink some text.
Note: make sure to set your serial monitor to line end: NEW LINE!
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 25 September 2015
By Bram Harmsen
https://github.com/bremme/arduino-tm1637
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentTM1637 display(PIN_CLK, PIN_DIO);
// run setup code
void setup() {
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
display.begin(); // initializes the display
display.setBacklight(100); // set the brightness to 100 %
display.print("INIT"); // display INIT on the display
delay(1000); // wait 1000 ms
};
// run loop (forever)
void loop() {
display.print("LOOP"); // display LOOP on the display
delay(1000); // wait 1000 ms
display.print("COUNTING SOME DIGITS");// print COUNTING SOME DIGITS
display.clear(); // clear the display
for (uint8_t i=0; i < 100; i++) { // loop from 0 to 100
display.print(i); // display loop counter
delay(100); // wait 100 ms
};
display.clear(); // clear the display
display.print("SUCC"); // print SUCC for success
display.blink(); // blink SUCC
delay(1000); // wait 1000 ms
};

View File

@ -0,0 +1,53 @@
/*
Clock example example (Extended class example)
Display a clock on the display. For this demo you can add a speed multiplier to make the clock run faster. For a real clock you want to use a delay of 1 min or even use a Real Time Clock module (RTC)
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 25 September 2015
By Bram Harmsen
https://github.com/bremme/arduino-tm1637
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentExtended display(PIN_CLK, PIN_DIO);
const unsigned int clockSpeed = 10000; // speed up clock for demo
// run setup code
void setup() {
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
display.begin(); // initializes the display
display.setBacklight(100); // set the brightness to 100 %
delay(1000); // wait 1000 ms
};
// run loop (forever)
void loop() {
byte hours = 14; // initialize hours
byte minutes = 39; // initialize minutes
for ( ; hours < 24; hours++) { // count hours up to 24
for ( ; minutes < 60; minutes++) { // count minutes up to 59
display.printTime(hours, minutes, true); // display time
delay(60000 / clockSpeed); // clock delay ms
};
minutes = 0; // reset minutes
};
};

View File

@ -0,0 +1,114 @@
/*
Dual counter example (Extended class example)
You could do many things with a dual counter. This example demoonstrates a scoreboard. Two players rol a dice every round, the player with the highest score wins the round. The number of rounds won are displayed on the scoreboard. Once one of the players reaches a maximum score the game is over. At the end of the game a player won message or draw will be displayed.
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 25 September 2015
By Bram Harmsen
https://github.com/bremme/arduino-tm1637
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentExtended display(PIN_CLK, PIN_DIO);
// sets the maximum score for the game
const byte maxScore = 10;
// run setup code
void setup() {
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
display.begin(); // initializes the display
display.setBacklight(100); // set the brightness to 100 %
delay(1000); // wait 1000 ms
randomSeed(analogRead(0)); // get a random seed for throwing dices
};
// run loop (forever)
void loop() {
byte playerOneScore = 0; // initialize player one score
byte playerTwoScore = 0; // initialize player two score
bool gameEnd = false; // initialize gameEnd?
display.print("START NEW GAME "); // Start a new round
delay(500); // delay 1000 ms
display.clear(); // clear the display
while( !gameEnd ) { // play till the end of the game
byte playerOneTurn = rollDice(); // player one rolls a dice
byte playerTwoTurn = rollDice(); // player two rolls a dice
if ( playerOneTurn > playerTwoTurn ) { // player one had a higher dice
playerOneScore++; // increase player one's score
} else if ( playerOneTurn < playerTwoTurn ){
playerTwoScore++; // increase player two's score
} else { // player one and two had same score
display.clear();
display.print("SAME");
display.blink();
display.clear();
}
// update scoreboard
display.printDualCounter(playerOneScore, playerTwoScore);
delay(500);
// check if game has ended (player one or two's score >= maxScore)
if ( (playerOneScore >= maxScore || playerTwoScore >= maxScore) ) {
gameEnd = true; // game has ended
printGameEnd(); // print end game message
break; // break from while loop (jump out)
};
};
// check who won
if ( playerOneScore > playerTwoScore ) {
printPlayerWon(1); // player one won
} else if ( playerOneScore < playerTwoScore ){
printPlayerWon(2); // player two won
} else {
display.clear(); display.print("DRAW"); // draw
display.blink(); display.clear();
};
};
// roll a dice: random rumber fom 0 to 5 + 1 = 0 to 6
byte rollDice() {
return (random(6) + 1);
}
// print winning player message
void printPlayerWon(byte player) {
display.clear();
char winText[] = "PLAYER x WON ";
winText[7] = (char)player + '0';
display.print(winText);
delay(500);
display.clear();
};
// print end game message
void printGameEnd(void) {
display.clear();
display.print("GAME END ");
display.blink();
delay(500);
};

View File

@ -0,0 +1,139 @@
/*
Fun Print all example
This is a demonstration off a lot of the possibilities of the Fun superclass
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 25 September 2015
By Bram Harmsen
https://github.com/bremme/arduino-tm1637
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
#include "SevenSegmentFun.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentFun display(PIN_CLK, PIN_DIO);
// run setup code
void setup() {
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
display.begin(); // initializes the display
display.setBacklight(100); // set the brightness to 100 %
delay(1000); // wait 1000 ms
};
// run loop (forever)
void loop() {
// vertical level (e.g. audio volume)
introDuceNextDemo("AUDIO VOLUME DEMO");
audioVolume();
// bouncing ball
introDuceNextDemo("BOUNCING BALL DEMO");
unsigned int numMoves = 100; unsigned int timeDelay = 100;
display.bouncingBall(numMoves, timeDelay);
// scrolling text
introDuceNextDemo("SCROLLING TEXT DEMO");
byte repeats = 2;
display.scrollingText("ARDUINO TM1637 FUN", repeats);
// nightrider
introDuceNextDemo("REMEMBER KIT? NIGHTRIDER DEMO");
repeats = 4;
display.nightrider(repeats);
// snake
introDuceNextDemo("SNAKE DEMO");
display.snake(repeats);
// horizontal level (e.g equalizer)
introDuceNextDemo("EQUALIZER DEMO");
equalizer();
// bomb timer
introDuceNextDemo("GET READY FOR THE BOMB");
byte hours = 5; byte min = 16; unsigned int speed = 10000;
display.bombTimer(hours, min, speed, " RUN ");
delay(1000);;
};
// Demo for displaying a vertical level, for example audio volume, battery charge etc.
void audioVolume() {
for (byte repeats=0; repeats < 2; repeats++) {
for (byte level=0; level < 125; level+=25) {
display.printLevelVertical(level);
delay(200);
};
for (byte level=100; level != 0; level-=25) {
display.printLevelVertical(level);
delay(200);
};
}
// maybe try another symbol instead of default | |
byte symbol = display.encode((byte)0);
bool leftToRight = false; // print the other direction
for (byte repeats=0; repeats < 2; repeats++) {
for (byte level=0; level < 125; level+=25) {
display.printLevelVertical(level, leftToRight, symbol);
delay(200);
if ( level == 100 ) {
display.blink();
}
};
for (byte level=100; level != 0; level-=25) {
display.printLevelVertical(level, leftToRight, symbol);
delay(200);
};
}
// 0, 25, 50, 75, 100
}
void equalizer() {
// initialize horizontal level counters
char i,j,k,l;
byte levels[4];
// repeat 5 times
for ( byte r=0; r < 4; r++) {
// increae i and k, decrease j and l
for (i=0,j=100,k=0,l=100; i <= 100; i+=33, j-=33, k+=33, l-=33) {
levels[0] = i; levels[1] = j; levels[2] = k; levels[3] = l;
display.printLevelHorizontal(levels);
delay(100);
}
// increae j and l, decrease i and k
for (i=100,j=0,k=100,l=0; i >= 0; i-=33, j+=33, k-=33, l+=33) {
levels[0] = i; levels[1] = j; levels[2] = k; levels[3] = l;
display.printLevelHorizontal(levels);
delay(100);
}
}
}
void introDuceNextDemo(char* str) {
display.print(str);
delay(500);
}

View File

@ -0,0 +1,52 @@
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
#include "SevenSegmentFun.h"
// define clock and digital input pins
#define PIN_CLK 4
#define PIN_DIO 5
// initialize TM1637 Display objects
SevenSegmentFun display(PIN_CLK, PIN_DIO);
void setup() {
// initialize the display
display.begin();
}
void loop() {
// increase level from 0 to 100
for (uint8_t i=0; i <= 100; i+=25) {
display.printLevelVertical(i);
delay(100);
};
// decrease level from 100 to 0
for (int8_t i=100; i >=0; i-=25) {
display.printLevelVertical(i);
delay(100);
}
// initialize horizontal level counters
int8_t i,j,k,l;
uint8_t levels[4];
// repeat 5 times
for ( uint8_t r=0; r < 4; r++) {
// increae i and k, decrease j and l
for (i=0,j=100,k=0,l=100; i <= 100; i+=33, j-=33, k+=33, l-=33) {
levels[0] = i; levels[1] = j; levels[2] = k; levels[3] = l;
display.printLevelHorizontal(levels);
delay(100);
}
// increae j and l, decrease i and k
for (i=100,j=0,k=100,l=0; i >= 0; i-=33, j+=33, k-=33, l+=33) {
levels[0] = i; levels[1] = j; levels[2] = k; levels[3] = l;
display.printLevelHorizontal(levels);
delay(100);
}
}
}

View File

@ -0,0 +1,111 @@
/*
Low level (advanced) example
In this example the display is controlled by the low level command function.
See SevenSegmentTM1637.h for more details on how the protocol actually works and which commands it accepts.
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 25 September 2015
By Bram Harmsen
https://github.com/bremme/arduino-tm1637
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentTM1637 display(PIN_CLK, PIN_DIO);
// run setup code
void setup() {
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
};
void loop() {
// set brightness
uint8_t setDisplayCmd = B10000000; // bit 6,7
uint8_t brightnessBits = B111; // bit 0,1,2 (7 = max)
uint8_t displayOnBit = B1000; // bit 3
// construct complete command
uint8_t command = setDisplayCmd | brightnessBits | displayOnBit;
// turn display on and set brightness to max (7)
bool ack = display.command(command);
// print acknowledged?
Serial.println(ack);
// write init to display using automatic address
uint8_t setDataCmd = B01000000; // bit 6,7
ack = display.command(setDataCmd);
Serial.println(ack);
uint8_t setAddrCmd = B11000000; // bit 6,7 set addr to 0
uint8_t dataI = B00000110; // I
uint8_t dataN = B00110111; // N
uint8_t dataT = B01111000; // T
uint8_t commands[5];
commands[0] = setAddrCmd;
commands[1] = dataI;
commands[2] = dataN;
commands[3] = dataI;
commands[4] = dataT;
ack = display.command(commands, 5);
Serial.println(ack);
delay(1000);
// dim display
brightnessBits = B001; // bit 0,1,2 level=1;
command = setDisplayCmd | brightnessBits | displayOnBit;
display.command(command);
delay(1000);
// set back to full brightness
brightnessBits = B111; // bit 0,1,2 (7 = max)
command = setDisplayCmd | brightnessBits | displayOnBit;
display.command(command);
delay(1000);
// write characters to display in non auto mode
setDataCmd |= 1 << 2; // bit 2 control auto/manual address
ack = display.command(setDataCmd);
Serial.println(ack);
commands[1] = B01110111;
commands[2] = B01111111;
commands[3] = B00111001;
commands[4] = B01011110;
for (uint8_t i = 1; i < 5; i++) {
commands[1] = commands[i]; // set character
display.command(commands, 2); // write character to display
commands[0]++; // increase address
}
delay(1000);
// set back to auto address mode
setDataCmd &= ~(1 << 2); // bit 2 control auto/manual address
ack = display.command(setDataCmd);
Serial.println(ack);
// clear display
commands[0] = setAddrCmd;
commands[1] = 0; commands[2] = 0;commands[3] = 0; commands[4] = 0;
// clear display
display.command(commands, 5);
delay(1000);
}

View File

@ -0,0 +1,76 @@
/*
Printing numbers example
Demonstrate a couple different ways nubers can be printed: positive, negative,
with padding and with rollover.
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 22 June 2020
By Bram Harmsen
https://github.com/bremme/arduino-tm1637
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentExtended display(PIN_CLK, PIN_DIO);
// run setup code
void setup() {
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
display.begin(); // initializes the display
display.setBacklight(100); // set the brightness to 100 %
display.print("INIT"); // display INIT on the display
delay(1000); // wait 1000 ms
};
// run loop (forever)
void loop() {
// print positive numbers
display.print("PRINT POSITIVE NUMBERS");
delay(1000); // wait 1000 ms
for (int16_t number=0; number < 2000; number++) {
display.printNumber(number);
delay(1);
};
// print negative numbers
display.print("PRINT NEGATIVE NUMBERS");
delay(1000); // wait 1000 ms
for (int16_t number=0; number > -999; number--) {
display.printNumber(number);
delay(2);
};
// print with positive with zero padding
display.print("PRINT POSITIVE NUMBERS WITH PADDING");
delay(1000); // wait 1000 ms
for (int16_t number=0; number < 2000; number++) {
display.printNumber(number, true);
delay(1);
};
// print with rollover (e.g. 10000 -> 0, 10001 -> 1)
display.print("PRINT POSITIVE NUMBERS WITH ROLLOVER");
delay(1000); // wait 1000 ms
for (int16_t number=0; number < 20000; number+=250) {
display.printNumber(number, false, true);
delay(50);
};
};

View File

@ -0,0 +1,79 @@
/*
Serial Print example
Prints text typed to the Serial Monitor on the display. Connect an Arduino to a TM1637 4 digit 7-segment display. Connect the wires as descibed below. Run the sketch and open the Serial Monitor. Set the the speed to 9600 baud, set the line ending to Newline. Now type some text and press enter, the text will be displayed on the 7-segment display.
Note: make sure to set your serial monitor to line end: NEW LINE!
The circuit:
* connect TM1637 pin CLK to Arduino pin D4
* connect TM1637 pin DIO to Arduino pin D5
* connect TM1637 pin Vcc to Arduino pin 5V
* connect TM1637 pin GND to Arduino pin GND
Created 25 September 2015
By Bram Harmsen
http://url/of/online/tutorial.cc
*/
// include the SevenSegmentTM1637 library
#include "SevenSegmentTM1637.h"
/* initialize global TM1637 Display object
* The constructor takes two arguments, the number of the clock pin and the digital output pin:
* SevenSegmentTM1637(byte pinCLK, byte pinDIO);
*/
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentTM1637 display(PIN_CLK, PIN_DIO);
// define a fixed buffer size for receiving characters via Serial
const byte BUFFER_SIZE = 128;
char serialBuffer[BUFFER_SIZE]; // initialize global serial buffer
// run setup code
void setup() {
display.begin(); // initializes the display
Serial.begin(9600); // initializes the Serial connection @ 9600 baud
Serial.println(F("Enter some text followed by ENTER"));
Serial.println(F("also make sure to set the line ending to Newline (\\n)"));
};
// run loop (forever)
void loop() {
// if received new serial data, print to display
if ( receivedSerialString() ) {
display.print(serialBuffer); // Print received serial data to display
Serial.print(F("Echo:\t")); // Echo serial data back to Serial Monitor
Serial.println(serialBuffer);
};
};
// Read in bytes from Serial Monitor and return true is ether the serialBuffer is full or a Newline character is received
bool receivedSerialString() {
static unsigned int i=0; // init static counter to keep track of count
while( Serial.available() ) { // check if new data arrived
if ( i == BUFFER_SIZE-1) { // if buffer is full RETURN true
serialBuffer[i] = '\0'; // add termination char
i = 0;
Serial.println(F("Buffer full!"));
return true;
};
char c = Serial.read(); // read new char from serial port
if ( c == '\n') { // if new line RETURN true
serialBuffer[i] = '\0'; // add termination char
i = 0;
return true;
} else {
serialBuffer[i] = c; // add received character to buffer
}
i++; // increase counter
};
return false; // default RETURN false
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -0,0 +1,56 @@
#######################################
# Syntax Coloring Map For SevenSegmentTM1637
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SevenSegmentTM1637 KEYWORD1
SevenSegmentExtended KEYWORD1
SevenSegmentFun KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
init KEYWORD2
begin KEYWORD2
write KEYWORD2
clear KEYWORD2
home KEYWORD2
setCursor KEYWORD2
setBacklight KEYWORD2
setContrast KEYWORD2
on KEYWORD2
off KEYWORD2
blink KEYWORD2
setColonOn KEYWORD2
getColonOn KEYWORD2
setPrintDelay KEYWORD2
encode KEYWORD2
shiftLeft KEYWORD2
printRaw KEYWORD2
command KEYWORD2
comReadByte KEYWORD2
comWriteByte KEYWORD2
comStart KEYWORD2
comStop KEYWORD2
comAck KEYWORD2
printTime KEYWORD2
printNumber KEYWORD2
printDualCounter KEYWORD2
printLevelVertical KEYWORD2
printLevelHorizontal KEYWORD2
scrollingText KEYWORD2
snake KEYWORD2
nightrider KEYWORD2
bombTimer KEYWORD2
bouchingBall KEYWORD2
printBall KEYWORD2
print4Bit KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,9 @@
name=SevenSegmentTM1637
version=1.1.0
author=Bram Harmsen <bramharmsen@gmail.com>
maintainer=Bram Harmsen <bramharmsen@gmail.com>
sentence=Library for using a 4 digit seven segment display with TM1636 or TM1637 driver IC
paragraph=Extensive library for controlling a 4 digit seven segment display. This library inherent the Print class and uses the LCDAPI 1.0. For example you can use all normal Print methods like: print() and println(). From the LCDAPI among others begin(), clear(), home(), setCursor() and setBacklight() are implementend. On top of these regular functionality a segerate fun class which adds more features can be used. For example a bombtimer(), nightrider() and bouncingBall() method can be used when using the fun class.
category=Display
url=https://github.com/bremme/arduino-tm1637
architectures=*

View File

@ -78,6 +78,11 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log
#define D_CMND_DISP_SCROLLDELAY "ScrollDelay"
#define D_CMND_DISP_CLOCK "Clock"
#define D_CMND_DISP_TEXTNC "TextNC" // NC - "No Clear"
#define D_CMND_DISP_SETLEDS "SetLEDs"
#define D_CMND_DISP_SETLED "SetLED"
#define D_CMND_DISP_BUTTONS "Buttons"
#define D_CMND_DISP_SCROLLTEXT "ScrollText"
enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND,
@ -91,10 +96,10 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E
#ifdef USE_UFILESYS
,FUNC_DISPLAY_BATCH
#endif
, FUNC_DISPLAY_NUMBER, FUNC_DISPLAY_FLOAT,
FUNC_DISPLAY_NUMBERNC, FUNC_DISPLAY_FLOATNC, FUNC_DISPLAY_BRIGHTNESS, FUNC_DISPLAY_RAW,
FUNC_DISPLAY_LEVEL, FUNC_DISPLAY_SEVENSEG_TEXT, FUNC_DISPLAY_SEVENSEG_TEXTNC,
FUNC_DISPLAY_SCROLLDELAY, FUNC_DISPLAY_CLOCK
, FUNC_DISPLAY_NUMBER, FUNC_DISPLAY_FLOAT, FUNC_DISPLAY_NUMBERNC, FUNC_DISPLAY_FLOATNC,
FUNC_DISPLAY_BRIGHTNESS, FUNC_DISPLAY_RAW, FUNC_DISPLAY_LEVEL, FUNC_DISPLAY_SEVENSEG_TEXT, FUNC_DISPLAY_SEVENSEG_TEXTNC,
FUNC_DISPLAY_SCROLLDELAY, FUNC_DISPLAY_CLOCK, FUNC_DISPLAY_SETLEDS, FUNC_DISPLAY_SETLED,
FUNC_DISPLAY_BUTTONS, FUNC_DISPLAY_SCROLLTEXT
};
enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FULL };
@ -106,10 +111,10 @@ const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix
#ifdef USE_UFILESYS
"|" D_CMND_DISP_BATCH
#endif
"|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|"
"|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|"
D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|"
D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC;
D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SETLEDS "|" D_CMND_DISP_SETLED "|"
D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT
;
void (* const DisplayCommand[])(void) PROGMEM = {
@ -119,8 +124,10 @@ void (* const DisplayCommand[])(void) PROGMEM = {
#ifdef USE_UFILESYS
,&CmndDisplayBatch
#endif
, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayBrightness, &CmndDisplayRaw,
&CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC
, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC,
&CmndDisplayBrightness, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC,
&CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplaySetLEDs, &CmndDisplaySetLED,
&CmndDisplayButtons, &CmndDisplayScrollText
};
char *dsp_str;
@ -1682,6 +1689,19 @@ void CmndDisplayBlinkrate(void)
ResponseCmndNumber(XdrvMailbox.payload);
}
#ifdef USE_UFILESYS
void CmndDisplayBatch(void) {
if (XdrvMailbox.data_len > 0) {
if (!Settings.display_mode) {
Display_Text_From_File(XdrvMailbox.data);
}
ResponseCmndChar(XdrvMailbox.data);
}
}
#endif
void CmndDisplayClear(void)
{
if (!renderer)
@ -1728,7 +1748,7 @@ void CmndDisplayBrightness(void)
result = XdspCall(FUNC_DISPLAY_BRIGHTNESS);
}
if(result) ResponseCmndNumber(XdrvMailbox.payload);
ResponseCmndNumber(XdrvMailbox.payload);
else ResponseCmndChar(XdrvMailbox.data);
}
void CmndDisplayRaw(void)
@ -1746,7 +1766,7 @@ void CmndDisplayLevel(void)
result = XdspCall(FUNC_DISPLAY_LEVEL);
}
if(result) ResponseCmndNumber(XdrvMailbox.payload);
ResponseCmndNumber(XdrvMailbox.payload);
else ResponseCmndChar(XdrvMailbox.data);
}
void CmndDisplaySevensegText(void)
@ -1788,20 +1808,53 @@ void CmndDisplayClock(void)
}
ResponseCmndNumber(XdrvMailbox.payload);
}
#ifdef USE_UFILESYS
void CmndDisplayBatch(void) {
if (XdrvMailbox.data_len > 0) {
if (!Settings.display_mode) {
Display_Text_From_File(XdrvMailbox.data);
}
ResponseCmndChar(XdrvMailbox.data);
void CmndDisplaySetLEDs(void)
{
bool result = false;
if (!renderer) {
result = XdspCall(FUNC_DISPLAY_SETLEDS);
}
if(result) ResponseCmndNumber(XdrvMailbox.payload);
else ResponseCmndChar(XdrvMailbox.data);
}
#endif
void CmndDisplaySetLED(void)
{
if (!renderer) {
XdspCall(FUNC_DISPLAY_SETLED);
}
ResponseCmndChar(XdrvMailbox.data);
}
void CmndDisplayButtons(void)
{
if (!renderer) {
XdspCall(FUNC_DISPLAY_BUTTONS);
}
ResponseCmndNumber(XdrvMailbox.payload);
}
void CmndDisplayScrollText(void)
{
bool result = false;
if (!renderer) {
result = XdspCall(FUNC_DISPLAY_SCROLLTEXT);
}
if(result) ResponseCmndNumber(XdrvMailbox.payload);
else ResponseCmndChar(XdrvMailbox.data);
}
void CmndDisplaySize(void)
{
#ifdef USE_DISPLAY_TM1637
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 6)) {
#else
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) {
#endif
Settings.display_size = XdrvMailbox.payload;
if (renderer) renderer->setTextSize(Settings.display_size);
//else DisplaySetSize(Settings.display_size);

View File

@ -1,5 +1,5 @@
/*
xdsp_15_tm1637.ino - Support for TM1637 seven-segment display for Tasmota
xdsp_15_tm1637.ino - Support for TM1637 seven-segment display (upto 6 digits) for Tasmota
Copyright (C) 2020 Ajith Vasudevan
@ -21,9 +21,10 @@
/*
This driver enables the display of numbers (both integers and floats) and basic text
on the inexpensive TM1637-based seven-segment module. Raw segments can also be displayed.
In addition, it is also possible to clear the display, set brightness (8 levels), display
a rudimentary bar graph, and a Clock.
on the inexpensive TM1637-based seven-segment modules (tested on both 4- and 6-digit variants).
Raw segments can also be displayed.
In addition, it is also possible to set brightness (8 levels), clear the display, scroll text, display
a rudimentary bar graph, and a Clock (12 hr and 24 hr).
To use, compile Tasmota with USE_DISPLAY and USE_DISPLAY_TM1637, or build the tasmota-display env.
@ -37,51 +38,94 @@
Once the device restarts the following "Display" commands become available:
DisplaySize size {1-6}
Sets the number of digits to use. This is typically set to the actual number of digits available
in the display module. command e.g., "DisplaySize 6"
DisplayClear
Blanks the display, command: "DisplayClear"
Clears the display, command: "DisplayClear"
DisplayNumber num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]]
Clears and then displays integer number (-999 to 9999). command e.g., "DisplayNumber 1234"
Control 'leading zeros', 'length' and 'position' with "DisplayNumber 1234, <leadingZeros>, <length>, <position>, <dot>"
'leading zeros' can be 1 or 0 (default), 'length' can be 1 to 4 (default), 'position' can be 0 (left-most) to 3 (right-most),
'dot' can be 0,(no dot), 1 (left-most) to 4 (right-most). See function description below for more details.
DisplayNumberNC num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]]
Display integer number as above, but without clearing first. e.g., "DisplayNumberNC 1234". Usage is same as above.
DisplayFloat num [,precision {0-4} [,length {1-4} [,position {0-3} ]]]
Clears and then displays float (with decimal point) (0.001 to 9999.) command e.g., "DisplayFloat 12.34"
DisplayNumber num [,position {0-(NUM_DIGITS-1))} [,leading_zeros {0|1} [,length {1-NUM_DIGITS}]]]
Clears and then displays number without decimal. command e.g., "DisplayNumber 1234"
Control 'leading zeros', 'length' and 'position' with "DisplayNumber 1234, <position>, <leadingZeros>, <length>"
'leading zeros' can be 1 or 0 (default), 'length' can be 1 to NUM_DIGITS, 'position' can be 0 (left-most) to NUM_DIGITS (right-most).
See function description below for more details.
DisplayFloatNC num [,precision {0-4} [,length {1-4} [,position {0-3} ]]]
DisplayNumberNC num [,position {0-(NUM_DIGITS-1))} [,leading_zeros {0|1} [,length {1-NUM_DIGITS}]]]
Display integer number as above, but without clearing first. e.g., "DisplayNumberNC 1234". Usage is same as above.
DisplayFloat num [,position {0-(NUM_DIGITS-1)} [,precision {0-NUM_DIGITS} [,length {1-NUM_DIGITS}]]]
Clears and then displays float (with decimal point) command e.g., "DisplayFloat 12.34"
See function description below for more details.
DisplayFloatNC num [,position {0-(NUM_DIGITS-1)} [,precision {0-NUM_DIGITS} [,length {1-NUM_DIGITS}]]]
Displays float (with decimal point) as above, but without clearing first. command e.g., "DisplayFloatNC 12.34"
See function description below for more details.
DisplayBrightness num {0-7}
Set brightness (1 to 7) command e.g., "DisplayBrightness 2" Note: Brightness takes effect only after a new display command is sent.
DisplayRaw num1, num2, num3, num4 [,length {1-4} [,position {0-3}] ]
Takes 4 comma-separated integers (0-255) and displays raw segments
Each 7-segment display unit is represented by an 8-bit(8th bit for decimap point) number.
For example, the command "DisplayRaw 255, 255, 255, 255" would display "[8.8.8.8.]"
DisplayBrightness num {0-8}
Set brightness (0 (off) to 8) command e.g., "DisplayBrightness 2"
DisplayRaw position {0-(NUM_DIGITS-1)},length {1-NUM_DIGITS}, num1 [, num2[, num3[, num4[, ...upto NUM_DIGITS numbers]]]]]
Takes upto NUM_DIGITS comma-separated integers (0-255) and displays raw segments. Each number represents a
7-segment digit. Each 8-bit number represents individual segments of a digit.
For example, the command "DisplayRaw 0, 4, 255, 255, 255, 255" would display "[8.8.8.8.]"
DisplayText text [, position {0-(NUM_DIGITS-1)} [,length {1-NUM_DIGITS}]]
Clears and then displays basic text. command e.g., "DisplayText ajith vasudevan"
Control 'length' and 'position' with "DisplayText <text>, <position>, <length>"
'length' can be 1 to NUM_DIGITS, 'position' can be 0 (left-most) to NUM_DIGITS-1 (right-most)
DisplayTextNC text [, position {0-NUM_DIGITS-1} [,length {1-NUM_DIGITS}]]
Clears first, then displays text. Usage is same as above.
DisplayScrollText text
Displays scrolling text.
DisplayScrollDelay delay {0-15} // default = 4
Sets the speed of text scroll. Smaller delay = faster scrolling.
DisplayLevel num {0-100}
Display a horizontal bar graph (0-100) command e.g., "DisplayLevel 50" will display [|||| ]
DisplayText text [, length {1-4} [, position {0-3}]]
Clears and then displays basic text (scrolls if > 4 characters) command e.g., "DisplayText ajith vasudevan"
Control 'length' and 'position' with "DisplayText <text>, <length>, <position>"
'length' can be 1 to 4 (default), 'position' can be 0 (left-most) to 3 (right-most)
Note: A caret sign '^' in the input text would be replaced by a "degrees" symbol. This is handy for displaying temperature!
Other Characters whose ASCII > 127 or ASCII < 32 would simply be blank.
DisplayTextNC text [, length {1-4} [, position {0-3}]]
Clear first, then display text. Usage is same as above.
DisplayScrollDelay delay_in_milliseconds // default = 200
Sets the speed of text scroll. Takes effect only after a new TEXT command is sent with 4 chars or more.
DisplayClock 1|2|0
Displays a clock.
Commands "DisplayClock 1" // 12 hr format
"DisplayClock 2" // 24 hr format
@ -100,30 +144,38 @@
\*********************************************************************************************/
#define XDSP_15 15
#include <TM1637TinyDisplay.h>
#include "SevenSegmentTM1637.h"
TM1637TinyDisplay *display;
SevenSegmentTM1637 *display;
bool showClock = false;
bool clock24 = false;
char tm[5];
char msg[60];
uint32_t NUM_DIGITS = 4;
uint32_t prev_num_digits = 4;
bool scroll = false;
uint32_t scrolldelay = 4;
uint32_t scrollindex = 0;
uint32_t iteration = 0;
#define BRIGHTNESS_MIN 0
#define BRIGHTNESS_MAX 7
#define BRIGHTNESS_MIN 0 // Display OFF
#define BRIGHTNESS_MAX 8
#define CMD_MAX_LEN 55
#define LEVEL_MIN 0
#define LEVEL_MAX 100
#define SCROLL_MAX_LEN 50
char scrolltext[CMD_MAX_LEN];
/*********************************************************************************************\
* Init function
\*********************************************************************************************/
bool TM1637Init(void) {
display = new TM1637TinyDisplay(Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI) );
display->setBrightness(BRIGHT_4);
display->clear();
display = new SevenSegmentTM1637(Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI) );
NUM_DIGITS = Settings.display_size ? Settings.display_size : 4;
display->begin(NUM_DIGITS, 1);
display->setBacklight(40);
clearDisplay();
if (!Settings.display_model) {
Settings.display_model = XDSP_15;
}
@ -133,116 +185,230 @@ bool TM1637Init(void) {
/*********************************************************************************************\
* Displays number with/without decimal, with/without leading zeros, specifying length, start-position
* and dot-position, optionally skipping clearing display before displaying the number.
* commands: DisplayNumber num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]]
* DisplayNumberNC num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]] // "NC" --> "No Clear"
* Displays number without decimal, with/without leading zeros, specifying start-position
* and length, optionally skipping clearing display before displaying the number.
* commands: DisplayNumber num [,position {0-(NUM_DIGITS-1)} [,leading_zeros {0|1} [,length {1-NUM_DIGITS}]]]
* DisplayNumberNC num [,position {0-(NUM_DIGITS-1)} [,leading_zeros {0|1} [,length {1-NUM_DIGITS}]]] // "NC" --> "No Clear"
\*********************************************************************************************/
bool CmndTM1637Number(bool clear) {
char sNum[CMD_MAX_LEN];
char sLeadingZero[CMD_MAX_LEN];
char sLength[CMD_MAX_LEN];
char sPos[CMD_MAX_LEN];
char sDot[CMD_MAX_LEN];
uint8_t dot = 0;
uint8_t length = 4;
uint8_t position = 0;
char sLeadingzeros[CMD_MAX_LEN];
char sPosition[CMD_MAX_LEN];
char sLength[CMD_MAX_LEN];
uint8_t length = 0;
bool leadingzeros = false;
uint32_t num;
uint8_t position = 0;
uint32_t num = 0;
switch (ArgC())
{
case 5 :
subStr(sDot, XdrvMailbox.data, ",", 5);
dot = atoi(sDot);
case 4 :
subStr(sPos, XdrvMailbox.data, ",", 4);
position = atoi(sPos);
case 3 :
subStr(sLength, XdrvMailbox.data, ",", 3);
subStr(sLength, XdrvMailbox.data, ",", 4);
length = atoi(sLength);
case 3 :
subStr(sLeadingzeros, XdrvMailbox.data, ",", 3);
leadingzeros = atoi(sLeadingzeros);
case 2 :
subStr(sLeadingZero, XdrvMailbox.data, ",", 2);
leadingzeros = atoi(sLeadingZero);
subStr(sPosition, XdrvMailbox.data, ",", 2);
position = atoi(sPosition);
case 1 :
subStr(sNum, XdrvMailbox.data, ",", 1);
num = atoi(Trim(sNum));
num = atof(sNum);
}
if(position > 3) position = 3;
if(position < 0) position = 0;
if((length <= 0) || (length > 4)) length = 4;
if((dot < 0) || (dot > 4)) dot = 0;
if((position < 0) || (position > (NUM_DIGITS-1))) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: num=%d"), num);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: position=%d"), position);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: leadingzeros=%d"), leadingzeros);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: position=%d"), position);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: dot=%d"), dot);
if(clear) display->clear();
if(!dot) display->showNumber(num, leadingzeros, length, position);
else display->showNumberDec(num, (1 << ( 8 - dot )), leadingzeros, length, position);
if(clear) clearDisplay();
char txt[30];
snprintf_P(txt, sizeof(txt), PSTR("%d"), num);
if(!length) length = strlen(txt);
if((length < 0) || (length > NUM_DIGITS)) length = NUM_DIGITS;
char pad = (leadingzeros ? '0': ' ');
uint32_t i = position;
uint8_t rawBytes[1];
rawBytes[0] = display->encode(pad);
for(; i<position + (length - strlen(txt)); i++) {
if(i>NUM_DIGITS) break;
display->printRaw(rawBytes, 1, i);
}
for(uint32_t j = 0; i< position + length; i++, j++) {
if(txt[j] == 0) break;
rawBytes[0] = display->encode(txt[j]);
if(i>NUM_DIGITS) break;
display->printRaw(rawBytes, 1, i);
}
return true;
}
/*********************************************************************************************\
* Displays number with decimal, specifying precision and length,
* Displays number with decimal, specifying position, precision and length,
* optionally skipping clearing display before displaying the number.
* commands: DisplayFloat num [,precision {0-4} [,length {1-4} [,position {0-3} ]]]
* DisplayFloatNC num [,precision {0-4} [,length {1-4} [,position {0-3} ]]] // "NC" --> "No Clear"
* commands: DisplayFloat num [,position {0-(NUM_DIGITS-1)} [,precision {0-NUM_DIGITS} [,length {1-NUM_DIGITS}]]]
* DisplayFloatNC num [,position {0-(NUM_DIGITS-1)} [,precision {0-NUM_DIGITS} [,length {1-NUM_DIGITS}]]] // "NC" --> "No Clear"
\*********************************************************************************************/
bool CmndTM1637Float(bool clear) {
char sNum[CMD_MAX_LEN];
char sPrecision[CMD_MAX_LEN];
char sPrecision[CMD_MAX_LEN];
char sPosition[CMD_MAX_LEN];
char sLength[CMD_MAX_LEN];
uint8_t length = 4;
uint8_t precision = 4;
uint8_t length = 0;
uint8_t precision = NUM_DIGITS;
uint8_t position = 0;
float fnum = 0.0f;
switch (ArgC())
{
case 3 :
subStr(sLength, XdrvMailbox.data, ",", 3);
case 4 :
subStr(sLength, XdrvMailbox.data, ",", 4);
length = atoi(sLength);
case 2 :
subStr(sPrecision, XdrvMailbox.data, ",", 2);
case 3 :
subStr(sPrecision, XdrvMailbox.data, ",", 3);
precision = atoi(sPrecision);
case 2 :
subStr(sPosition, XdrvMailbox.data, ",", 2);
position = atoi(sPosition);
case 1 :
subStr(sNum, XdrvMailbox.data, ",", 1);
fnum = atof(sNum);
}
if((precision < 0) || (precision > 4)) precision = 4;
if((length <= 0) || (length > 4)) length = 4;
if((position < 0) || (position > (NUM_DIGITS-1))) position = 0;
if((precision < 0) || (precision > NUM_DIGITS)) precision = NUM_DIGITS;
if(clear) clearDisplay();
char txt[30];
ext_snprintf_P(txt, sizeof(txt), PSTR("%*_f"), precision, &fnum);
if(!length) length = strlen(txt);
if((length <= 0) || (length > NUM_DIGITS)) length = NUM_DIGITS;
char s[30];
ext_snprintf_P(s, sizeof(s), PSTR("LOG: TM1637: num=%*_f"), 4, &fnum);
AddLog(LOG_LEVEL_DEBUG, PSTR("%s"), s);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: precision=%d"), precision);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
uint8_t rawBytes[1];
for(uint32_t i=0, j=0; i<length; i++, j++) {
if(txt[i] == 0) break;
rawBytes[0] = display->encode(txt[i]);
if(txt[i+1] == '.') {
rawBytes[0] = rawBytes[0] | 128;
i++;
length++;
}
if((j+position) > NUM_DIGITS) break;
display->printRaw(rawBytes, 1, j+position);
}
if(clear) display->clear();
display->showNumber(fnum, precision, length, 0);
return true;
}
/*********************************************************************************************\
* Clears the display
* Command: DisplayClear
\*********************************************************************************************/
// /*********************************************************************************************\
// * Clears the display
// * Command: DisplayClear
// \*********************************************************************************************/
bool CmndTM1637Clear(void) {
display->clear();
clearDisplay();
sprintf(msg, PSTR("Cleared"));
XdrvMailbox.data = msg;
return true;
}
void clearDisplay (void) {
unsigned char arr[] = {0};
AddLog(LOG_LEVEL_DEBUG, PSTR("Clearing digit %d"), NUM_DIGITS);
for(int i=0; i<NUM_DIGITS; i++) display->printRaw(arr, 1, i);
}
/*********************************************************************************************\
* Display scrolling text
* Command: DisplayScrollText text
\*********************************************************************************************/
bool CmndTM1637ScrollText(void) {
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: text=%s"), XdrvMailbox.data);
if(XdrvMailbox.data_len > SCROLL_MAX_LEN) {
snprintf(msg, sizeof(msg), PSTR("Text too long. Length should be less than %d"), SCROLL_MAX_LEN);
XdrvMailbox.data = msg;
return false;
} else {
snprintf(scrolltext, sizeof(scrolltext), PSTR("%s"), XdrvMailbox.data);
scrolltext[XdrvMailbox.data_len] = 0;
scrollindex = 0;
scroll = true;
return true;
}
}
/*********************************************************************************************\
* Sets the scroll delay for scrolling text.
* Command: DisplayScrollDelay delay {0-15} // default = 4
\*********************************************************************************************/
bool CmndTM1637ScrollDelay(void) {
if(scrolldelay<0) scrolldelay=0;
scrolldelay = XdrvMailbox.payload;
return true;
}
/*********************************************************************************************\
* Scrolls a given string. Called every 50ms
\*********************************************************************************************/
void scrollText(void) {
if(scroll) {
iteration++;
if(scrolldelay) iteration = iteration % scrolldelay;
else iteration = 0;
if(iteration) return;
if(scrollindex > strlen(scrolltext)) {
scroll = false;
scrollindex = 0;
return;
}
bool clr = false;
uint8_t rawBytes[1];
for(uint32_t i=0, j=scrollindex; i< strlen(scrolltext); i++, j++) {
if(i > (NUM_DIGITS-1)) break;
if(scrolltext[j] == 0) {clr = true;};
char charToDisp = (clr ? ' ' : scrolltext[j]);
rawBytes[0] = display->encode(charToDisp);
display->printRaw(rawBytes, 1, i);
}
scrollindex++;
}
}
/*********************************************************************************************\
* Displays a horizontal bar graph. Takes a percentage number (0-100) as input
* Command: DisplayLevel level {0-100}
@ -254,126 +420,166 @@ bool CmndTM1637Level(void) {
XdrvMailbox.data = msg;
return false;
}
display->showLevel(val, false);
uint8_t totalBars = 2*NUM_DIGITS;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: CmndTM1637Level totalBars=%d"), totalBars);
float barsToDisplay = totalBars * val / 100.0f;
char txt[5];
ext_snprintf_P(txt, sizeof(txt), PSTR("%*_f"), 1, &barsToDisplay);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: CmndTM1637Level barsToDisplay=%s"), txt);
char s[4];
ext_snprintf_P(s, sizeof(s), PSTR("%*_f"), 0, &barsToDisplay);
uint8_t numBars = atoi(s);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: CmndTM1637Level numBars=%d"), numBars);
clearDisplay();
uint8_t rawBytes[1];
for(int i=1; i<=numBars; i++) {
uint8_t digit = (i-1) / 2;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: CmndTM1637Level digit=%d"), digit);
uint8_t value = (((i%2) == 0) ? 54 : 48);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: CmndTM1637Level value=%d"), value);
rawBytes[0] = value;
display->printRaw(rawBytes, 1, digit);
}
return true;
}
/*********************************************************************************************\
* Display arbitrary data on the display module
* Command: DisplayRaw a, b, c, d [, length {1-4} [, position {0-3}] ]
* where a,b,c,d are 4 numbers in the range 0-255, representing a byte array,
* each byte corresponding to a single digit. Within each byte, bit 0 is segment A,
* Command: DisplayRaw position {0-(NUM_DIGITS-1)},length {1-NUM_DIGITS}, a [, b[, c[, d[...upto NUM_DIGITS]]]]
* where a,b,c,d... are upto NUM_DIGITS numbers in the range 0-255, each number (byte)
* corresponding to a single 7-segment digit. Within each byte, bit 0 is segment A,
* bit 1 is segment B etc. The function may either set the entire display
* or any desirable part using the length and position parameters.
* or any desired part using the length and position parameters.
\*********************************************************************************************/
bool CmndTM1637Raw(void) {
uint8_t DATA[4] = { 0, 0, 0, 0 };
uint8_t DATA[6] = { 0, 0, 0, 0, 0, 0 };
char as[CMD_MAX_LEN];
char bs[CMD_MAX_LEN];
char cs[CMD_MAX_LEN];
char ds[CMD_MAX_LEN];
char es[CMD_MAX_LEN];
char fs[CMD_MAX_LEN];
char sLength[CMD_MAX_LEN];
char sPos[CMD_MAX_LEN];
uint8_t a = 0;
uint8_t b = 0;
uint8_t c = 0;
uint8_t d = 0;
uint32_t position = 0;
uint32_t length = 4;
uint32_t length = 0;
switch (ArgC())
{
case 8 :
subStr(fs, XdrvMailbox.data, ",", 8);
DATA[5] = atoi(fs);
case 7 :
subStr(es, XdrvMailbox.data, ",", 7);
DATA[4] = atoi(es);
case 6 :
subStr(sPos, XdrvMailbox.data, ",", 6);
position = atoi(sPos);
subStr(ds, XdrvMailbox.data, ",", 6);
DATA[3] = atoi(ds);
case 5 :
subStr(sLength, XdrvMailbox.data, ",", 5);
length = atoi(sLength);
subStr(cs, XdrvMailbox.data, ",", 5);
DATA[2] = atoi(cs);
case 4 :
subStr(ds, XdrvMailbox.data, ",", 4);
d = atoi(ds);
subStr(bs, XdrvMailbox.data, ",", 4);
DATA[1] = atoi(bs);
case 3 :
subStr(cs, XdrvMailbox.data, ",", 3);
c = atoi(cs);
case 2 :
subStr(bs, XdrvMailbox.data, ",", 2);
b = atoi(bs);
case 1 :
subStr(as, XdrvMailbox.data, ",", 1);
a = atoi(as);
}
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: a=%d"), a);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: b=%d"), b);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: c=%d"), c);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: d=%d"), d);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: position=%d"), position);
DATA[0] = a;
DATA[1] = b;
DATA[2] = c;
DATA[3] = d;
display->setSegments(DATA, length, position);
return true;
}
/*********************************************************************************************\
* Display a given string. If more than 4 characters, will scroll message on display
* Text can be placed at arbitrary location on the display using the length and
* position parameters without affecting the rest of the display.
* Command: DisplayText text [, length {1-4} [, position {0-3}]]
\*********************************************************************************************/
bool CmndTM1637Text(bool clear) {
char sString[CMD_MAX_LEN + 1];
char sLength[CMD_MAX_LEN];
char sPos[CMD_MAX_LEN];
uint32_t position = 0;
uint32_t length = 4;
switch (ArgC())
{
case 3 :
subStr(sPos, XdrvMailbox.data, ",", 3);
position = atoi(sPos);
subStr(as, XdrvMailbox.data, ",", 3);
DATA[0] = atoi(as);
case 2 :
subStr(sLength, XdrvMailbox.data, ",", 2);
length = atoi(sLength);
case 1 :
subStr(sPos, XdrvMailbox.data, ",", 1);
position = atoi(sPos);
}
if(!length) length = ArgC() - 2;
if(length < 0 || length > NUM_DIGITS) length = NUM_DIGITS;
if(position < 0 || position > (NUM_DIGITS-1)) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: a=%d"), DATA[0]);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: b=%d"), DATA[1]);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: c=%d"), DATA[2]);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: d=%d"), DATA[3]);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: e=%d"), DATA[4]);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: f=%d"), DATA[5]);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: position=%d"), position);
uint8_t rawBytes[1];
for(uint32_t i=position; i<position+length; i++ ) {
if(i>(NUM_DIGITS-1)) break;
rawBytes[0] = DATA[i-position];
display->printRaw(rawBytes, 1, i);
}
return true;
}
/*********************************************************************************************\
* Display a given string.
* Text can be placed at arbitrary location on the display using the length and
* position parameters without affecting the rest of the display.
* Command: DisplayText text [, position {0-(NUM_DIGITS-1)} [,length {1-NUM_DIGITS}]]
\*********************************************************************************************/
bool CmndTM1637Text(bool clear) {
char sString[CMD_MAX_LEN + 1];
char sPosition[CMD_MAX_LEN];
char sLength[CMD_MAX_LEN];
uint8_t length = 0;
uint8_t position = 0;
switch (ArgC())
{
case 3 :
subStr(sLength, XdrvMailbox.data, ",", 3);
length = atoi(sLength);
case 2 :
subStr(sPosition, XdrvMailbox.data, ",", 2);
position = atoi(sPosition);
case 1 :
subStr(sString, XdrvMailbox.data, ",", 1);
}
if((length <= 0) || (length > 4)) length = 4;
if(position > 3) position = 3;
if(position < 0) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: string=%s"), sString);
if((position < 0) || (position > (NUM_DIGITS-1))) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: sString=%s"), sString);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: position=%d"), position);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: pos=%d"), position);
for(uint32_t i=0; i<strlen(sString); i++) { // replacing caret '^' with ASCII value for degrees symbol
if(sString[i] == '^') {
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: Found Caret at %d"), i);
sString[i] = 176;
}
if(clear) clearDisplay();
if(!length) length = strlen(sString);
if((length < 0) || (length > NUM_DIGITS)) length = NUM_DIGITS;
uint32_t i = position;
uint8_t rawBytes[1];
for(uint32_t j = 0; i< position + length; i++, j++) {
if(i > (NUM_DIGITS-1)) break;
if(sString[j] == 0) break;
rawBytes[0] = display->encode(sString[j]);
if(i>(NUM_DIGITS-1)) break;
display->printRaw(rawBytes, 1, i);
}
if(clear) display->clear();
display->showString_P(sString, length, position);
return true;
}
/*********************************************************************************************\
* Sets brightness of the display. The setting takes effect when a command is given
* to change the data being displayed.
* Command: DisplayBrightness {0-7}
* Sets brightness of the display.
* Command: DisplayBrightness {0-8} // 0 => off
\*********************************************************************************************/
bool CmndTM1637Brightness(void) {
@ -384,22 +590,11 @@ bool CmndTM1637Brightness(void) {
XdrvMailbox.data = msg;
return false;
}
display->setBrightness(val);
display->setBacklight(val*10);
return true;
}
/*********************************************************************************************\
* Sets the scroll frame delay when the display needs to scroll. The setting takes effect
* when a text display command sends an argument with over four characters.
* Command: DisplayScrollDelay delay_in_milliseconds // default = 200
\*********************************************************************************************/
bool CmndTM1637ScrollDelay(void) {
uint16_t val = XdrvMailbox.payload;
display->setScrolldelay(val);
return true;
}
/*********************************************************************************************\
* Displays a clock.
@ -419,7 +614,7 @@ bool CmndTM1637Clock(void) {
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: clock24=%d"), clock24);
if(!showClock) {
display->clear();
clearDisplay();
}
return true;
}
@ -448,9 +643,12 @@ void showTime() {
if(mn < 10) snprintf(tm, sizeof(tm), PSTR("%d0%d"), hr, mn);
else snprintf(tm, sizeof(tm), PSTR("%d%d"), hr, mn);
}
tm[4] = 0;
if((millis() % 1000) > 500) display->showNumberDec(atoi(tm), 64, clock24, 4, 0);
else display->showString_P(tm, 4, 0);
uint8_t rawBytes[1];
for(uint32_t i = 0; i< 4; i++) {
rawBytes[0] = display->encode(tm[i]);
if((millis() % 1000) > 500 && (i == 1)) rawBytes[0] = rawBytes[0] | 128;
display->printRaw(rawBytes, 1, i);
}
}
/*********************************************************************************************\
@ -458,6 +656,17 @@ void showTime() {
\*********************************************************************************************/
bool TM1637Cmd(uint8_t fn) {
bool result = false;
NUM_DIGITS = Settings.display_size;
if(prev_num_digits != NUM_DIGITS) { // Cleck for change of display size, and re-init the library
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: Size changed. Re-initializing library..."));
display = new SevenSegmentTM1637(Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI) );
display->begin(NUM_DIGITS, 1);
display->setBacklight(40);
clearDisplay();
prev_num_digits = NUM_DIGITS;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: Re-initialized library"));
}
if(XdrvMailbox.data_len > CMD_MAX_LEN) {
sprintf(msg, PSTR("Command text too long. Please limit it to %d characters"), CMD_MAX_LEN);
XdrvMailbox.data = msg;
@ -486,15 +695,18 @@ bool TM1637Cmd(uint8_t fn) {
case FUNC_DISPLAY_RAW:
result = CmndTM1637Raw();
break;
case FUNC_DISPLAY_LEVEL:
result = CmndTM1637Level();
break;
case FUNC_DISPLAY_SEVENSEG_TEXT:
result = CmndTM1637Text(true);
break;
case FUNC_DISPLAY_SEVENSEG_TEXTNC:
result = CmndTM1637Text(false);
break;
case FUNC_DISPLAY_LEVEL:
result = CmndTM1637Level();
break;
case FUNC_DISPLAY_SCROLLTEXT:
result = CmndTM1637ScrollText();
break;
case FUNC_DISPLAY_SCROLLDELAY:
result = CmndTM1637ScrollDelay();
break;
@ -528,11 +740,6 @@ bool Xdsp15(uint8_t function)
CmndTM1637Clear();
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: FUNC_DISPLAY_INIT"));
break;
// case FUNC_DISPLAY_DRAW_STRING:
// sprintf(msg, PSTR("For TM1637, please use DisplaySevenSegText instead of DisplayText"));
// XdrvMailbox.data = msg;
// result = true;
// break;
case FUNC_DISPLAY_SEVENSEG_TEXT:
case FUNC_DISPLAY_CLEAR:
case FUNC_DISPLAY_NUMBER:
@ -543,11 +750,13 @@ bool Xdsp15(uint8_t function)
case FUNC_DISPLAY_RAW:
case FUNC_DISPLAY_LEVEL:
case FUNC_DISPLAY_SEVENSEG_TEXTNC:
case FUNC_DISPLAY_SCROLLTEXT:
case FUNC_DISPLAY_SCROLLDELAY:
case FUNC_DISPLAY_CLOCK:
result = TM1637Cmd(function);
break;
case FUNC_DISPLAY_EVERY_50_MSECOND:
scrollText();
if(showClock) {
showTime();
}