Initial.
This commit is contained in:
commit
ae312a0457
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
out/
|
||||||
|
go.sum
|
||||||
|
.git/
|
||||||
|
*.swp
|
7
Makefile
Normal file
7
Makefile
Normal 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
33
display/display.go
Normal 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
112
display/ssd1336.go
Normal 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
10
go.mod
Normal 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
30
main.go
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user