mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-16 04:43:25 +00:00
tm1637: add support for tm1637 7-segment LED
This commit is contained in:
@@ -119,6 +119,8 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
|
tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
|
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
|
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
|
||||||
@@ -179,7 +181,7 @@ endif
|
|||||||
DRIVERS = $(wildcard */)
|
DRIVERS = $(wildcard */)
|
||||||
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
|
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
|
||||||
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
|
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
|
||||||
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx p1am tone
|
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx p1am tone tm1637
|
||||||
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
|
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
|
||||||
|
|
||||||
unit-test:
|
unit-test:
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/tm1637"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
tm := tm1637.New(machine.D2, machine.D3, 7) // clk, dio, brightness
|
||||||
|
tm.Configure()
|
||||||
|
|
||||||
|
tm.ClearDisplay()
|
||||||
|
|
||||||
|
tm.DisplayText([]byte("Tiny"))
|
||||||
|
time.Sleep(time.Millisecond * 1000)
|
||||||
|
|
||||||
|
tm.ClearDisplay()
|
||||||
|
|
||||||
|
tm.DisplayChr(byte('G'), 1)
|
||||||
|
tm.DisplayDigit(0, 2) // looks like O
|
||||||
|
time.Sleep(time.Millisecond * 1000)
|
||||||
|
|
||||||
|
tm.DisplayClock(12, 59, true)
|
||||||
|
|
||||||
|
for i := uint8(0); i < 8; i++ {
|
||||||
|
tm.Brightness(i)
|
||||||
|
time.Sleep(time.Millisecond * 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
i := int16(0)
|
||||||
|
for {
|
||||||
|
tm.DisplayNumber(i)
|
||||||
|
i++
|
||||||
|
time.Sleep(time.Millisecond * 50)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package tm1637
|
||||||
|
|
||||||
|
const (
|
||||||
|
TM1637_CMD1 = 0x40
|
||||||
|
TM1637_CMD2 = 0xC0
|
||||||
|
TM1637_CMD3 = 0x80
|
||||||
|
TM1637_DSP_ON = 0x08
|
||||||
|
TM1637_DELAY = uint8(10)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 7-segment characters encoding for 0-9, A-Z, a-z, blank, dash, star
|
||||||
|
var segments []byte = []byte{
|
||||||
|
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,
|
||||||
|
0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x3D, 0x76, 0x06, 0x1E,
|
||||||
|
0x76, 0x38, 0x55, 0x54, 0x3F, 0x73, 0x67, 0x50, 0x6D, 0x78,
|
||||||
|
0x3E, 0x1C, 0x2A, 0x76, 0x6E, 0x5B, 0x00, 0x40, 0x63}
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
// Package tm1637 provides a driver for the TM1637 4-digit 7-segment LED display.
|
||||||
|
//
|
||||||
|
// Datasheet: https://www.mcielectronics.cl/website_MCI/static/documents/Datasheet_TM1637.pdf
|
||||||
|
//
|
||||||
|
package tm1637
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device wraps the pins of the TM1637.
|
||||||
|
type Device struct {
|
||||||
|
clk machine.Pin
|
||||||
|
dio machine.Pin
|
||||||
|
brightness uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new TM1637 device.
|
||||||
|
func New(clk machine.Pin, dio machine.Pin, brightness uint8) Device {
|
||||||
|
return Device{clk: clk, dio: dio, brightness: brightness}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure sets up the pins.
|
||||||
|
func (d *Device) Configure() {
|
||||||
|
pinMode(d.clk, false)
|
||||||
|
pinMode(d.dio, false)
|
||||||
|
d.clk.Low() // required for future pull-down
|
||||||
|
d.dio.Low() // required for future pull-down
|
||||||
|
}
|
||||||
|
|
||||||
|
// Brightness sets the brightness of the display (0-7).
|
||||||
|
func (d *Device) Brightness(brightness uint8) {
|
||||||
|
if brightness > 7 {
|
||||||
|
brightness = 7
|
||||||
|
}
|
||||||
|
d.brightness = brightness
|
||||||
|
d.writeCmd()
|
||||||
|
d.writeDsp()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDisplay clears the display.
|
||||||
|
func (d *Device) ClearDisplay() {
|
||||||
|
d.writeData([]byte{0, 0, 0, 0}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayText shows a text on the display.
|
||||||
|
//
|
||||||
|
// Only the first 4 letters in the array text would be shown.
|
||||||
|
func (d *Device) DisplayText(text []byte) {
|
||||||
|
var sequences []byte
|
||||||
|
for i, t := range text {
|
||||||
|
if i > 3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sequences = append(sequences, encodeChr(t))
|
||||||
|
}
|
||||||
|
d.writeData(sequences, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayChr shows a single character (A-Z, a-z)
|
||||||
|
// on the display at position 0-3.
|
||||||
|
func (d *Device) DisplayChr(chr byte, pos uint8) {
|
||||||
|
if pos > 3 {
|
||||||
|
pos = 3
|
||||||
|
}
|
||||||
|
d.writeData([]byte{encodeChr(chr)}, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayNumber shows a number on the display.
|
||||||
|
//
|
||||||
|
// Only 4 rightmost digits of the number would be shown.
|
||||||
|
//
|
||||||
|
// For negative numbers, only -999 to -1 would be
|
||||||
|
// shown with a negaive sign.
|
||||||
|
func (d *Device) DisplayNumber(num int16) {
|
||||||
|
var sequences []byte
|
||||||
|
var start int16
|
||||||
|
if num < 0 {
|
||||||
|
sequences = append(sequences, segments[37])
|
||||||
|
num *= -1
|
||||||
|
start = 100
|
||||||
|
num %= 1000
|
||||||
|
} else {
|
||||||
|
start = 1000
|
||||||
|
num %= 10000
|
||||||
|
}
|
||||||
|
for i := start; i >= 1; i /= 10 {
|
||||||
|
if num >= i {
|
||||||
|
n := (num / int16(i)) % 10
|
||||||
|
sequences = append(sequences, segments[n])
|
||||||
|
} else {
|
||||||
|
if i == 1 && num == 0 {
|
||||||
|
sequences = append(sequences, segments[0])
|
||||||
|
} else {
|
||||||
|
sequences = append(sequences, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.writeData(sequences, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayDigit shows a single-digit number (0-9)
|
||||||
|
// at position 0-3.
|
||||||
|
func (d *Device) DisplayDigit(digit uint8, pos uint8) {
|
||||||
|
digit %= 10
|
||||||
|
d.writeData([]byte{segments[digit]}, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayClock allows you to display hour and minute numbers
|
||||||
|
// together with the colon on/off.
|
||||||
|
func (d *Device) DisplayClock(num1 uint8, num2 uint8, colon bool) {
|
||||||
|
var sequences []byte
|
||||||
|
num := []uint8{num1 % 100, num2 % 100}
|
||||||
|
for k := 0; k < 2; k++ {
|
||||||
|
for i := 10; i >= 1; i /= 10 {
|
||||||
|
n := (num[k] / uint8(i)) % 10
|
||||||
|
sequences = append(sequences, segments[n])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if colon {
|
||||||
|
sequences[1] |= 1 << 7
|
||||||
|
}
|
||||||
|
d.writeData(sequences, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeChr(c byte) byte {
|
||||||
|
r := rune(c)
|
||||||
|
switch {
|
||||||
|
case r == 32:
|
||||||
|
return segments[36] // space
|
||||||
|
case r == 42:
|
||||||
|
return segments[38] // star/degrees
|
||||||
|
case r == 45:
|
||||||
|
return segments[37] // dash
|
||||||
|
case r >= 65 && r <= 90:
|
||||||
|
return segments[r-55] // uppercase A-Z
|
||||||
|
case r >= 97 && r <= 122:
|
||||||
|
return segments[r-87] // lowercase a-z
|
||||||
|
case r >= 48 && r <= 57:
|
||||||
|
return segments[r-48] // 0-9
|
||||||
|
default:
|
||||||
|
return byte(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func delaytm() {
|
||||||
|
time.Sleep(time.Microsecond * time.Duration(TM1637_DELAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
func pinMode(pin machine.Pin, mode bool) {
|
||||||
|
// TM1637 has internal pull-up resistors for both CLK and DIO pins.
|
||||||
|
// Set them to input mode will pull them high,
|
||||||
|
// and set them to output mode will pull them down
|
||||||
|
// (since we did so in the beginning.)
|
||||||
|
// The High()/Low() method don't work on some boards.
|
||||||
|
if mode {
|
||||||
|
pin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
||||||
|
} else {
|
||||||
|
pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) start() {
|
||||||
|
pinMode(d.dio, false)
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.clk, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) stop() {
|
||||||
|
pinMode(d.dio, false)
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.clk, true)
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.dio, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) writeByte(data uint8) {
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
pinMode(d.dio, data&(1<<i) > 0) // send bits from LSB to MSB
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.clk, true)
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.clk, false)
|
||||||
|
delaytm()
|
||||||
|
}
|
||||||
|
pinMode(d.clk, false)
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.clk, true)
|
||||||
|
delaytm()
|
||||||
|
pinMode(d.clk, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) writeCmd() {
|
||||||
|
d.start()
|
||||||
|
d.writeByte(TM1637_CMD1)
|
||||||
|
d.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) writeDsp() {
|
||||||
|
d.start()
|
||||||
|
d.writeByte(TM1637_CMD3 | TM1637_DSP_ON | d.brightness)
|
||||||
|
d.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) writeData(segments []byte, position uint8) {
|
||||||
|
d.writeCmd()
|
||||||
|
d.start()
|
||||||
|
d.writeByte(TM1637_CMD2 | position)
|
||||||
|
for _, seg := range segments {
|
||||||
|
d.writeByte(seg)
|
||||||
|
}
|
||||||
|
d.stop()
|
||||||
|
d.writeDsp()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user