Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Max7219 LED Driver #79

Merged
merged 4 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions max7219/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Max7219 7-Segment/Matrix LED Driver

## Introduction

The Maxim 7219 LED driver is an SPI chip that simplifies driving 7-Segment LED
displays. It's also commonly used to create 8x8 LED matrixes. The datasheet
is available at:

https://www.analog.com/media/en/technical-documentation/data-sheets/MAX7219-MAX7221.pdf

You can find 8 digit, 7-segment LED boards on Ebay for $1-2. You can find
inexpensive matrixes in various sizes from 1 - 8 segments as well.

For matrixes, the driver provides a basic CP437 font that can be used to
display characters on 8x8 matrixes. If desired, you can supply your own glyph
set, or special characters for your specific application.

## Driver Functions

This driver provides simplified handling for using either 7-segment numeric
displays, or 8x8 matrixes.

It provides methods for scrolling data across either one or multiple displays.
For example, you can pass an IP address of "10.100.10.11" to the scroll function
and it will automatically scroll the display a desired number of times. The
scroll feature also works with matrixes, and scrolls characters one LED column
at a time for a smooth, even display.

## Notes About Daisy-Chaining

The Max7219 is specifically designed to handle larger displays by daisy chaining
units together. Say you want to write to digit 8 on the 3rd unit chained
together. You would make one SPI write. The first write would be the register
number (8), and the data value. Next, you would write a NOOP. The first record
would then be shifted to the second device. Finally, you write another NOOP. The
first record is shifted from the second device to the 3rd device, the first NOOP is
shifted to the second device. When the ChipSelect line goes low, each unit applies
the last data it received.
76 changes: 76 additions & 0 deletions max7219/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2024 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

package max7219_test

import (
"fmt"
"log"
"time"

"periph.io/x/conn/v3/spi/spireg"
"periph.io/x/devices/v3/max7219"
"periph.io/x/host/v3"
)

// basic test program. To do a numeric display, set matrix to false and
// matrixUnits to 1.
func Example() {
// basic test program. To do a numeric display, set matrix to false and
// matrixUnits to 1.
matrix := false
matrixUnits := 1
if _, err := host.Init(); err != nil {
log.Fatal(err)
}

s, err := spireg.Open("")
if err != nil {
log.Fatal(err)
}
defer s.Close()

dev, err := max7219.NewSPI(s, matrixUnits, 8)
if err != nil {
log.Fatal(err)
}

_ = dev.TestDisplay(true)
time.Sleep(time.Second * 1)
_ = dev.TestDisplay(false)

_ = dev.SetIntensity(1)
_ = dev.Clear()

if matrix {
dev.SetGlyphs(max7219.CP437Glyphs, true)
dev.SetDecode(max7219.DecodeNone)
dev.ScrollChars([]byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1, 100*time.Millisecond)
} else {
dev.SetDecode(max7219.DecodeB)
}
for i := -128; i < 128; i++ {
dev.WriteInt(i)
time.Sleep(100 * time.Millisecond)
}
var tData []byte
// Continuously display a clock
for {
t := time.Now()
if matrix {
// Assumes a 4 unit matrix
tData = []byte(fmt.Sprintf("%2d%02d", t.Hour(), t.Minute()))
} else {
// 8 digit 7-segment LED display
tData = []byte(t.Format(time.TimeOnly))
tData[2] = max7219.ClearDigit
tData[5] = max7219.ClearDigit
}
_ = dev.Write(tData)
// Try to get the iteration exactly on time. FWIW, on a Pi Zero this loop
// executes in ~ 2-3ms.
dNext := time.Duration(1000-(t.UnixMilli()%1000)) * time.Millisecond
time.Sleep(dNext)
}
}
Loading