Added support for TM1637 Seven-Segment Display

This commit is contained in:
Ajith Vasudevan 2021-02-09 13:16:16 +05:30
parent 4926222dd7
commit 977fe740e6
49 changed files with 3576 additions and 1 deletions

View File

@ -0,0 +1,165 @@
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

@ -0,0 +1,136 @@
# 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

@ -0,0 +1,20 @@
# 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

@ -0,0 +1,603 @@
// 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

@ -0,0 +1,316 @@
// 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

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

View File

@ -0,0 +1,638 @@
<!--
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

@ -0,0 +1,402 @@
// 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.

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -0,0 +1,65 @@
# 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

@ -0,0 +1,400 @@
// 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

@ -0,0 +1,313 @@
// 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.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

View File

@ -0,0 +1,65 @@
#######################################
# 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

@ -0,0 +1,15 @@
{
"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

@ -0,0 +1,10 @@
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

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -638,6 +638,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -635,6 +635,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -639,6 +639,8 @@
#define D_SENSOR_TM1638_CLK "TM16 CLK"
#define D_SENSOR_TM1638_DIO "TM16 DIO"
#define D_SENSOR_TM1638_STB "TM16 STB"
#define D_SENSOR_TM1637_CLK "TM1637 CLK"
#define D_SENSOR_TM1637_DIO "TM1637 DIO"
#define D_SENSOR_HX711_SCK "HX711 SCK"
#define D_SENSOR_HX711_DAT "HX711 DAT"
#define D_SENSOR_FTC532 "FTC532"

View File

@ -776,6 +776,7 @@
// -- Other sensors/drivers -----------------------
//#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
//#define USE_TM1637 // Add support for TM1637 seven-segment display (+1k code)
//#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
// #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)

View File

@ -320,6 +320,9 @@ void ResponseAppendFeatures(void)
#endif
#ifdef USE_TM1638
feature3 |= 0x80000000; // xsns_28_tm1638.ino
#endif
#ifdef USE_TM1637
feature3 |= 0x100000000; // xsns_85_tm1637.ino
#endif
}

View File

@ -761,6 +761,8 @@ bool MqttShowSensor(void)
for (uint32_t i = 0; i < MAX_SWITCHES; i++) {
#ifdef USE_TM1638
if (PinUsed(GPIO_SWT1, i) || (PinUsed(GPIO_TM16CLK) && PinUsed(GPIO_TM16DIO) && PinUsed(GPIO_TM16STB))) {
#elif defined(USE_TM1637)
if (PinUsed(GPIO_TM1637_CLK) && PinUsed(GPIO_TM1637_DIO)) {
#else
if (PinUsed(GPIO_SWT1, i)) {
#endif // USE_TM1638

View File

@ -202,6 +202,7 @@
#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
//#define USE_WIEGAND // Add support for 24/26/32/34 bit RFID Wiegand interface (D0/D1) (+1k7 code)
#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
#define USE_TM1637 // Add support for TM1637 seven-segment display
#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
//#define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)
//#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code)
@ -432,6 +433,7 @@
#undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI
#undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_TM1637 // Disable support for TM1637 seven-segment display
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer
@ -579,6 +581,7 @@
#undef USE_IR_REMOTE // Disable IR driver
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_TM1637 // Disable support for TM1637 seven-segment display
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer
@ -716,6 +719,7 @@
#undef USE_IR_REMOTE // Disable IR driver
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_TM1637 // Disable support for TM1637 seven-segment display
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer
@ -858,6 +862,7 @@
#undef USE_LMT01 // Disable support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
#undef USE_IR_REMOTE // Disable IR driver
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_TM1637 // Disable support for TM1637 seven-segment display
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer

View File

@ -53,6 +53,7 @@ enum UserSelectablePins {
GPIO_SDM120_TX, GPIO_SDM120_RX, // SDM120 Serial interface
GPIO_SDM630_TX, GPIO_SDM630_RX, // SDM630 Serial interface
GPIO_TM16CLK, GPIO_TM16DIO, GPIO_TM16STB, // TM1638 interface
GPIO_TM1637_CLK, GPIO_TM1637_DIO, // TM1637 interface
GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player
GPIO_HX711_SCK, GPIO_HX711_DAT, // HX711 Load Cell interface
GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin
@ -225,6 +226,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|"
D_SENSOR_SDM630_TX "|" D_SENSOR_SDM630_RX "|"
D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|"
D_SENSOR_TM1637_CLK "|" D_SENSOR_TM1637_DIO "|"
D_SENSOR_DFR562 "|"
D_SENSOR_HX711_SCK "|" D_SENSOR_HX711_DAT "|"
D_SENSOR_TX2X_TX "|"
@ -529,6 +531,14 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_TM16DIO), // TM1638 Data I/O
AGPIO(GPIO_TM16STB), // TM1638 Strobe
#endif
#ifdef USE_TM1637
AGPIO(GPIO_TM1637_CLK), // TM1637 Clock
AGPIO(GPIO_TM1637_DIO), // TM1637 Data I/O
#endif
#ifdef USE_TM1637
GPIO_TM1637_CLK, // TM1637 Clock
GPIO_TM1637_DIO, // TM1637 Data I/O
#endif
#ifdef USE_HX711
AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock
AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data

355
tasmota/xsns_85_tm1637.ino Normal file
View File

@ -0,0 +1,355 @@
/*
xsns_85_tm1637.ino - Support for TM1637 seven-segment display for Tasmota
Copyright (C) 2020 Ajith Vasudevan
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 3 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, see <http://www.gnu.org/licenses/>.
*/
/*
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 (7 levels) and display
a rudimentary bar graph.
To use, compile Tasmota with USE_DISPLAY_SEVENSEG and USE_TM1637
This adds the following
Pins:
* TM 1637 DIO
* TM 1637 CLK
Connect the TM1637 display module's DIO and CLK pins to any free GPIOs of the ESP8266 module
and assign the above pins accordingly, from Tasmota's GUI.
Once the device restarts the following commands become available:
* TM1637Clear
* TM1637Number
* TM1637Float
* TM1637Brightness
* TM1637Raw
* TM1637Level
* TM1637Text
The usage of these commands are explained in code comments below.
*/
#ifdef USE_DISPLAY_SEVENSEG
#ifdef USE_TM1637
/*********************************************************************************************\
* TM1637 support
\*********************************************************************************************/
#define XSNS_85 85
#include <TM1637TinyDisplay.h>
TM1637TinyDisplay *display;
bool defaultResponse = true;
bool isString = false;
char command[CMDSZ];
#define BRIGHTNESS_MIN 0
#define BRIGHTNESS_MAX 7
#define NUMBER_MIN -999
#define NUMBER_MAX 9999
#define FLOAT_MIN -999.0
#define FLOAT_MAX 9999.0
#define CMD_MAX_LEN 55
#define LEVEL_MIN 0
#define LEVEL_MAX 100
#define D_CMND_TM1637 "TM1637"
const char S_TM1637_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_TM1637 "%s\":%s}";
const char S_TM1637_COMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_TM1637 "%s\":\"%s\"}";
const char S_TM1637_RAWCOMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_TM1637 "%s\":\"%d,%d,%d,%d\"}";
const char S_TM1637_MESSAGE_SVALUE[] PROGMEM = "{\"" "\"%s\":\"%s\"}";
const char kTM1637_Commands[] PROGMEM = "Clear|Number|NumberC|Float|Brightness|Raw|Level|Text|TextC|ScrollDelay";
uint32_t len = strlen(D_CMND_TM1637);
enum TM1637_Commands { // commands useable in console/MQTT or rules
CMND_TM1637_CLEAR, // Blanks the display, command: "TM1637Clear"
CMND_TM1637_NUMBER, // Display integer number (-999 to 9999). command e.g., "TM1637Number 1234"
// Control 'leading zeros', 'length' and 'position' with "TM1637Number 1234, <leadingZeros>, <length>, <position>"
// '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)
CMND_TM1637_NUMBERC, // Clear first, then display integer number (-999 to 9999). Usage is same as above.
CMND_TM1637_FLOAT, // Display float (with decimal point) (0.001 to 9999.) command e.g., "TM1637Float 12.34"
CMND_TM1637_BRIGHTNESS, // Set brightness (1 to 7) command e.g., "TM1637Brightness 2" Note: Brightness takes effect only after a new display command is sent.
CMND_TM1637_RAW, // 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 "TM1637Raw 255, 255, 255, 255" would display "[8.8.8.8.]"
CMND_TM1637_LEVEL, // Display a horizontal bar graph (0-100) command e.g., "TM1637Level 50" will display [|||| ]
CMND_TM1637_TEXT, // Display basic text (scrolls if > 4 characters) command e.g., "TM1637Text ajith vasudevan"
// Control 'length' and 'position' with "TM1637Text abcd, <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.
CMND_TM1637_TEXTC, // Clear first, then display text. Usage is same as above.
CMND_TM1637_SCROLLDELAY // Sets the speed of text scroll. Takes effect only after a new TEXT command is sent with 4 chars or more.
};
bool TM1637Init(void) {
display = new TM1637TinyDisplay(Pin(GPIO_TM1637_CLK), Pin(GPIO_TM1637_DIO));
display->setBrightness(BRIGHT_5);
display->clear();
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: initialized"));
return true;
}
bool CmndTM1637Number(bool clear) {
char sNum[5]; char sLeadingZero[5]; char sLength[5]; char sPos[5];
subStr(sNum, XdrvMailbox.data, ",", 1);
subStr(sLeadingZero, XdrvMailbox.data, ",", 2);
subStr(sLength, XdrvMailbox.data, ",", 3);
subStr(sPos, XdrvMailbox.data, ",", 4);
uint32_t num = atoi(sNum);
bool leadingZero = atoi(sLeadingZero);
uint32_t length = atoi(sLength);
uint32_t pos = atoi(sPos);
if((length <= 0) || (length > 4)) length = 4;
if(pos > 4) pos = 4;
if(pos < 0) pos = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: num=%d"), num);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: leadingZero=%d"), leadingZero);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: pos=%d"), pos);
if(clear) display->clear();
display->showNumber(num, leadingZero, length, pos);
return true;
}
bool CmndTM1637Float(void) {
float val = atof(XdrvMailbox.data);
char msg[50];
if((val < FLOAT_MIN) || (val > FLOAT_MAX)) {
defaultResponse = false;
float fmin = FLOAT_MIN;
float fmax = FLOAT_MAX;
char msg[50];
ext_snprintf_P(msg, sizeof(msg), PSTR("Float should be in the range [%1_f, %1_f]"), &fmin, &fmax);
Response_P(S_TM1637_MESSAGE_SVALUE, "Error", msg);
return true;
}
display->showNumber(val);
return true;
}
bool CmndTM1637Clear(void) {
display->clear();
return true;
}
bool CmndTM1637Level(void) {
uint16_t val = XdrvMailbox.payload;
if((val < LEVEL_MIN) || (val > LEVEL_MAX)) {
defaultResponse = false;
char msg[45];
sprintf(msg, PSTR("Level should be a number in the range [%d, %d]"), LEVEL_MIN, LEVEL_MAX);
Response_P(S_TM1637_MESSAGE_SVALUE, "Error", msg);
return true;
}
display->showLevel(val, false);
return true;
}
bool CmndTM1637Raw(void) {
uint8_t DATA[1][4] = {
{ 0x00, 0x00, 0x00, 0x00 }
};
char a[5]; char b[5]; char c[5]; char d[5];
subStr(a, XdrvMailbox.data, ",", 1);
subStr(b, XdrvMailbox.data, ",", 2);
subStr(c, XdrvMailbox.data, ",", 3);
subStr(d, XdrvMailbox.data, ",", 4);
uint16_t a1 = atoi(a);
uint16_t b1 = atoi(b);
uint16_t c1 = atoi(c);
uint16_t d1 = atoi(d);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: a1=%d"), a1);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: b1=%d"), b1);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: c1=%d"), c1);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: d1=%d"), d1);
DATA[0][0] = a1;
DATA[0][1] = b1;
DATA[0][2] = c1;
DATA[0][3] = d1;
defaultResponse = false;
Response_P(S_TM1637_RAWCOMMAND_NVALUE, command, a1, b1, c1, d1);
display->showAnimation_P(DATA, FRAMES(DATA), TIME_MS(150));
return true;
}
bool CmndTM1637Text(bool clear) {
char sString[CMD_MAX_LEN + 1]; char sLength[5]; char sPos[5];
subStr(sString, XdrvMailbox.data, ",", 1);
subStr(sLength, XdrvMailbox.data, ",", 2);
subStr(sPos, XdrvMailbox.data, ",", 3);
uint32_t length = atoi(sLength);
uint32_t pos = atoi(sPos);
if((length <= 0) || (length > 4)) length = 4;
if(pos > 4) pos = 4;
if(pos < 0) pos = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: string=%s"), sString);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: pos=%d"), pos);
for(uint32_t i; i<strlen(sString); i++) { // replacing caret '^' with ASCII value for degrees symbol
if(sString[i] == '^') sString[i] = 176;
}
if(clear) display->clear();
display->showString_P(sString, length, pos);
return true;
}
bool CmndTM1637Brightness(void) {
uint16_t val = XdrvMailbox.payload;
if((val < BRIGHTNESS_MIN) || (val > BRIGHTNESS_MAX)) {
defaultResponse = false;
char msg[45];
sprintf(msg, PSTR("Brightness is a number in the range [%d, %d]"), BRIGHTNESS_MIN, BRIGHTNESS_MAX);
Response_P(S_TM1637_MESSAGE_SVALUE, "Error", msg);
return true;
}
display->setBrightness(val);
return true;
}
bool CmndTM1637ScrollDelay(void) {
uint16_t val = XdrvMailbox.payload;
if(val == 0) val = 200;
display->setScrolldelay(val);
return true;
}
bool TM1637Cmd(void) {
bool result = false;
uint32_t command_code = -1;
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_TM1637), len)) {
command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + len, kTM1637_Commands);
AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: command_code: %d params: %s"), command_code, XdrvMailbox.data);
}
if(command_code < 0) {
return result;
}
if(XdrvMailbox.data_len > CMD_MAX_LEN) {
char msg[45];
sprintf(msg, PSTR("Command too long. Should be less than %d characters long"), CMD_MAX_LEN);
Response_P(S_TM1637_MESSAGE_SVALUE, "Error", msg);
return result;
}
switch (command_code) {
case CMND_TM1637_CLEAR:
defaultResponse = false;
result = CmndTM1637Clear();
Response_P(S_TM1637_MESSAGE_SVALUE, "Message", "Cleared");
break;
case CMND_TM1637_NUMBER :
result = CmndTM1637Number(false);
break;
case CMND_TM1637_NUMBERC :
result = CmndTM1637Number(true);
break;
case CMND_TM1637_FLOAT :
result = CmndTM1637Float();
break;
case CMND_TM1637_BRIGHTNESS:
result = CmndTM1637Brightness();
break;
case CMND_TM1637_RAW:
isString = true;
result = CmndTM1637Raw();
break;
case CMND_TM1637_LEVEL:
result = CmndTM1637Level();
break;
case CMND_TM1637_TEXT:
isString = true;
result = CmndTM1637Text(false);
break;
case CMND_TM1637_TEXTC:
isString = true;
result = CmndTM1637Text(true);
break;
case CMND_TM1637_SCROLLDELAY:
isString = true;
result = CmndTM1637ScrollDelay();
break;
}
if(defaultResponse) {
if(isString) Response_P(S_TM1637_COMMAND_SVALUE, command, XdrvMailbox.data);
else Response_P(S_TM1637_COMMAND_NVALUE, command, XdrvMailbox.data);
}
return result;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xsns85(uint8_t function)
{
bool result = false;
if (PinUsed(GPIO_TM1637_CLK) && PinUsed(GPIO_TM1637_DIO)) {
switch (function) {
case FUNC_PRE_INIT:
TM1637Init(); // init
break;
case FUNC_COMMAND:
defaultResponse = true; // resetting value for new cmnd
isString = false; // resetting value for new cmmd
result = TM1637Cmd();
break;
}
}
return result;
}
#endif // USE_1637
#endif // USE_DISPLAY_SEVENSEG

View File

@ -209,7 +209,7 @@ a_features = [[
"USE_INA219","USE_SHT3X","USE_MHZ19","USE_TSL2561",
"USE_SENSEAIR","USE_PMS5003","USE_MGS","USE_NOVA_SDS",
"USE_SGP30","USE_SR04","USE_SDM120","USE_SI1145",
"USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638"
"USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638","USE_TM1637"
],[
"USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050",
"USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766",