This commit is contained in:
Thomas Vogl 2022-12-30 18:42:48 +01:00
parent 5b25457224
commit 005b167f5e
6 changed files with 155 additions and 42 deletions

2
go.mod
View File

@ -5,12 +5,12 @@ go 1.17
require ( require (
github.com/eclipse/paho.mqtt.golang v1.3.5 github.com/eclipse/paho.mqtt.golang v1.3.5
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/stianeikeland/go-rpio v4.2.0+incompatible
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
) )
require ( require (
github.com/gorilla/websocket v1.4.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect
github.com/stianeikeland/go-rpio v4.2.0+incompatible // indirect
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect
) )

View File

@ -0,0 +1,30 @@
//go:build !arm && !arm64
package PinControlService
type PinEmu struct {
}
func (*PinEmu) Toggle() {}
func (*PinEmu) High() {}
func (*PinEmu) Low() {}
func (*PinEmu) Input() {}
func (*PinEmu) Output() {}
func (*PinEmu) Detect(Edge) {}
func (*PinEmu) PullUp() {}
func (*PinEmu) PullDown() {}
func (*PinEmu) PullOff() {}
func (*PinEmu) Read() State { return LowState }
func (*PinEmu) EdgeDetected() bool { return false }
type HardwarePin struct {
Pin PinEmu
}
func NewHardwarePin(n int) HardwarePinInterface {
return &PinEmu{}
}
func HardwarePinOpen() error {
return nil
}

View File

@ -0,0 +1,39 @@
package PinControlService
type Mode uint8
type State uint8
type Pull uint8
type Edge uint8
type HardwarePinInterface interface {
Toggle()
High()
Low()
Input()
Output()
Detect(Edge)
PullUp()
PullDown()
PullOff()
Read() State
EdgeDetected() bool
}
const (
ModeInput Mode = iota
ModeOutput
ModeClock
ModePwm
)
const (
LowState State = iota
HighState
)
const (
NoEdge Edge = iota
RiseEdge
FallEdge
AnyEdge = RiseEdge | FallEdge
)

View File

@ -0,0 +1,55 @@
//go:build (arm || arm64) && linux
package PinControlService
import "github.com/stianeikeland/go-rpio"
type PinRpi struct {
pin rpio.Pin
}
func (p *PinRpi) Toggle() {
p.pin.Toggle()
}
func (p *PinRpi) High() {
p.pin.High()
}
func (p *PinRpi) Low() {
p.pin.Low()
}
func (p *PinRpi) Input() {
p.pin.Input()
}
func (p *PinRpi) Output() {
p.pin.Output()
}
func (p *PinRpi) Detect(e Edge) {
p.pin.Detect(rpio.Edge(e))
}
func (p *PinRpi) PullUp() {
p.pin.PullUp()
}
func (p *PinRpi) PullDown() {
p.pin.PullDown()
}
func (p *PinRpi) PullOff() {
p.pin.PullOff()
}
func (p *PinRpi) Read() State {
return State(p.pin.Read())
}
func (p *PinRpi) EdgeDetected() bool {
return p.pin.EdgeDetected()
}
func NewHardwarePin(n int) HardwarePinInterface {
return &PinRpi{
pin: rpio.Pin(n),
}
}
func HardwarePinOpen() error {
return rpio.Open()
}

View File

@ -3,7 +3,6 @@ package PinControlService
import ( import (
"errors" "errors"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/stianeikeland/go-rpio"
) )
type Pin struct { type Pin struct {
@ -12,10 +11,9 @@ type Pin struct {
Direction PinDirection Direction PinDirection
PullConfig PinPull PullConfig PinPull
InitialState PinCommand InitialState PinCommand
PinHandle rpio.Pin PinHandle HardwarePinInterface
SendPollingEvents bool SendPollingEvents bool
SendChangeEvents bool SendChangeEvents bool
} }
func NewPin(config PinConfig) Pin { func NewPin(config PinConfig) Pin {
@ -24,7 +22,7 @@ func NewPin(config PinConfig) Pin {
PullConfig: config.PullConfig, PullConfig: config.PullConfig,
Name: config.Name, Name: config.Name,
Id: config.PinNumber, Id: config.PinNumber,
PinHandle: rpio.Pin(config.PinNumber), PinHandle: NewHardwarePin(config.PinNumber),
} }
if config.SendPollingEvents != nil { if config.SendPollingEvents != nil {
@ -49,14 +47,14 @@ func NewPin(config PinConfig) Pin {
} }
func (p *Pin) State() PinState { func (p *Pin) State() PinState {
if state := p.PinHandle.Read(); state == rpio.High { if state := p.PinHandle.Read(); State(state) == HighState {
return StateOn return StateOn
} else { } else {
return StateOff return StateOff
} }
} }
func (p *Pin) Command(cmd PinCommand) error{ func (p *Pin) Command(cmd PinCommand) error {
log.Debugf("try to send command %s for pin %s (pin no: %d)", cmd, p.Name, p.Id) log.Debugf("try to send command %s for pin %s (pin no: %d)", cmd, p.Name, p.Id)
if p.Direction != Output { if p.Direction != Output {
return errors.New("pin is not an output") return errors.New("pin is not an output")
@ -83,7 +81,7 @@ func (p *Pin) Configure() {
_ = p.Command(p.InitialState) _ = p.Command(p.InitialState)
} }
p.PinHandle.Detect(rpio.AnyEdge) p.PinHandle.Detect(AnyEdge)
if p.PullConfig == PullUp { if p.PullConfig == PullUp {
p.PinHandle.PullUp() p.PinHandle.PullUp()
@ -98,4 +96,3 @@ func (p *Pin) Configure() {
func (p *Pin) Changed() bool { func (p *Pin) Changed() bool {
return p.PinHandle.EdgeDetected() return p.PinHandle.EdgeDetected()
} }

View File

@ -3,32 +3,25 @@ package PinControlService
import ( import (
"errors" "errors"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/stianeikeland/go-rpio"
"time" "time"
) )
type PinControlService struct { type PinControlService struct {
Pins map[string]Pin Pins map[string]Pin
timer* time.Ticker timer *time.Ticker
exit chan bool exit chan bool
OnChangeCallback PinCallback OnChangeCallback PinCallback
OnCycleCallback PinCallback OnCycleCallback PinCallback
} }
func (p *PinControlService) AddPin(
func (p*PinControlService) AddPin(
config PinConfig) { config PinConfig) {
pin := NewPin(config) pin := NewPin(config)
p.Pins[pin.Name] = pin p.Pins[pin.Name] = pin
} }
func (p*PinControlService) Command(pinName string, command PinCommand) error { func (p *PinControlService) Command(pinName string, command PinCommand) error {
if pin, found := p.Pins[pinName]; found == false { if pin, found := p.Pins[pinName]; found == false {
return errors.New("pin not configured") return errors.New("pin not configured")
} else { } else {
@ -36,25 +29,25 @@ func (p*PinControlService) Command(pinName string, command PinCommand) error {
} }
} }
func (p*PinControlService) Start() { func (p *PinControlService) Start() {
if err := rpio.Open(); err != nil { if err := HardwarePinOpen(); err != nil {
log.Fatal(err) log.Fatal(err)
panic(err) panic(err)
} }
for _,v := range p.Pins { for _, v := range p.Pins {
v.Configure() v.Configure()
} }
go p._task() go p._task()
} }
func (p*PinControlService) Stop() { func (p *PinControlService) Stop() {
p.exit <- true p.exit <- true
} }
func (p*PinControlService) _task() { func (p *PinControlService) _task() {
for { for {
select { select {
case <- p.timer.C: case <-p.timer.C:
for pinName, pin := range p.Pins { for pinName, pin := range p.Pins {
log.Debug("timer event") log.Debug("timer event")
if pin.Changed() { if pin.Changed() {
@ -69,7 +62,7 @@ func (p*PinControlService) _task() {
p.OnCycleCallback(pinName, pin.State()) p.OnCycleCallback(pinName, pin.State())
} }
} }
case <- p.exit: case <-p.exit:
log.Debug("stop timer") log.Debug("stop timer")
p.timer.Stop() p.timer.Stop()
return return
@ -79,11 +72,10 @@ func (p*PinControlService) _task() {
} }
func NewPinControl(config *PinControlConfig) (*PinControlService, error) { func NewPinControl(config *PinControlConfig) (*PinControlService, error) {
p := PinControlService{ p := PinControlService{
Pins: make(map[string]Pin), Pins: make(map[string]Pin),
exit: make(chan bool,1), exit: make(chan bool, 1),
timer: time.NewTicker(time.Duration(config.PollingTimeMs) * time.Millisecond)} timer: time.NewTicker(time.Duration(config.PollingTimeMs) * time.Millisecond)}
for _, pinConfig := range config.GpioPins { for _, pinConfig := range config.GpioPins {