This commit is contained in:
Andrey Egorov 2024-08-20 15:14:10 +03:00
commit ae312a0457
6 changed files with 196 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
out/
go.sum
.git/
*.swp

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
export GOOS=linux
export GOARCH=arm
export GOARM=6
export CGO_ENABLED=0
build:
@go build -o out/out main.go

33
display/display.go Normal file
View File

@ -0,0 +1,33 @@
package display
import (
"fmt"
"image"
"io"
"log"
"golang.org/x/image/font"
)
type Display interface {
GetImg() *image.Gray
GetFont() font.Face
Clear() error
PutText(x, y int, text string) error
io.Closer
}
type DisplayModel int
const (
SSD1306 DisplayModel = iota
)
func New(logger *log.Logger, model DisplayModel) (Display, error) {
switch model {
case SSD1306:
return newSsd1306(logger)
}
return nil, fmt.Errorf("invalid display model")
}

112
display/ssd1336.go Normal file
View File

@ -0,0 +1,112 @@
package display
import (
"fmt"
"image"
"image/color"
"log"
"sync"
"golang.org/x/image/font"
"golang.org/x/image/font/inconsolata"
"golang.org/x/image/math/fixed"
"periph.io/x/conn/v3/i2c"
"periph.io/x/conn/v3/i2c/i2creg"
"periph.io/x/devices/v3/ssd1306"
"periph.io/x/host/v3"
)
type displaySsd1306 struct {
mutex sync.Mutex
logger *log.Logger
font font.Face
bus i2c.BusCloser
dev *ssd1306.Dev
img *image.Gray
}
func newSsd1306(logger *log.Logger) (Display, error) {
if _, err := host.Init(); err != nil {
return nil, fmt.Errorf("drivers init: %w(may be i2c is disabled)", err)
}
// Setup device
bus, err := i2creg.Open("")
if err != nil {
return nil, fmt.Errorf("open i2c bus: %w", err)
}
opts := ssd1306.Opts{
W: 128,
H: 32,
Rotated: false,
Sequential: true,
SwapTopBottom: false,
}
dev, err := ssd1306.NewI2C(bus, &opts)
if err != nil {
return nil, fmt.Errorf("create i2c: %w", err)
}
// Create image
img := image.NewGray(image.Rect(0, 0, dev.Bounds().Dx(), dev.Bounds().Dy()))
return &displaySsd1306{
logger: logger,
font: inconsolata.Regular8x16,
bus: bus,
dev: dev,
img: img,
}, nil
}
func (d *displaySsd1306) GetImg() *image.Gray {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.img
}
func (d *displaySsd1306) GetFont() font.Face {
return d.font
}
func (d *displaySsd1306) Clear() error {
d.mutex.Lock()
defer d.mutex.Unlock()
for i := range d.img.Pix {
d.img.Pix[i] = 0
}
return nil
}
func (d *displaySsd1306) PutText(x, y int, text string) error {
d.mutex.Lock()
defer d.mutex.Unlock()
// Create font drawer
col := color.Gray{255}
point := fixed.Point26_6{X: fixed.I(x), Y: fixed.I(y)}
drawer := &font.Drawer{
Dst: d.img,
Src: image.NewUniform(col),
Face: d.font,
Dot: point,
}
drawer.DrawString(text)
d.dev.Draw(d.img.Bounds(), d.img, image.Point{})
return nil
}
func (d *displaySsd1306) Close() error {
d.mutex.Lock()
defer d.mutex.Unlock()
if err := d.bus.Close(); err != nil {
d.logger.Println("Close i2c bus:", err.Error())
}
return nil
}

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module display-test
go 1.22.5
require (
golang.org/x/image v0.1.0
periph.io/x/conn/v3 v3.7.1
periph.io/x/devices/v3 v3.7.1
periph.io/x/host/v3 v3.8.2
)

30
main.go Normal file
View File

@ -0,0 +1,30 @@
package main
import (
"display-test/display"
"fmt"
"log"
)
func main() {
log.Println("CGSG forever!!!")
if err := mainE(); err != nil {
log.Println("MAIN finished with error:", err.Error())
}
log.Println("END")
}
func mainE() error {
d, err := display.New(log.New(log.Writer(), "display", log.LstdFlags), display.SSD1306)
if err != nil {
return fmt.Errorf("new display: %w", err)
}
defer d.Close()
for {
d.Clear()
d.PutText(0, d.GetFont().Metrics().Height.Ceil(), "Satelites: 0")
d.PutText(0, d.GetFont().Metrics().Height.Ceil()*2, "Coords: 0N 0E")
}
}