118 lines
2.7 KiB
Go
118 lines
2.7 KiB
Go
package firmata
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/hybridgroup/gobot"
|
|
"github.com/tarm/goserial"
|
|
"strconv"
|
|
)
|
|
|
|
type FirmataAdaptor struct {
|
|
gobot.Adaptor
|
|
Board *board
|
|
i2cAddress byte
|
|
connect func(*FirmataAdaptor)
|
|
}
|
|
|
|
func NewFirmataAdaptor(name, port string) *FirmataAdaptor {
|
|
return &FirmataAdaptor{
|
|
Adaptor: gobot.Adaptor{
|
|
Name: name,
|
|
Port: port,
|
|
},
|
|
connect: func(f *FirmataAdaptor) {
|
|
sp, err := serial.OpenPort(&serial.Config{Name: f.Port, Baud: 57600})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
f.Board = newBoard(sp)
|
|
},
|
|
}
|
|
}
|
|
|
|
func (f *FirmataAdaptor) Connect() bool {
|
|
f.connect(f)
|
|
f.Board.connect()
|
|
f.Connected = true
|
|
return true
|
|
}
|
|
|
|
func (f *FirmataAdaptor) Disconnect() bool {
|
|
err := f.Board.Serial.Close()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
return true
|
|
}
|
|
func (f *FirmataAdaptor) Finalize() bool { return f.Disconnect() }
|
|
|
|
func (f *FirmataAdaptor) InitServo() {}
|
|
func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) {
|
|
p, _ := strconv.Atoi(pin)
|
|
|
|
f.Board.setPinMode(byte(p), SERVO)
|
|
f.Board.analogWrite(byte(p), angle)
|
|
}
|
|
|
|
func (f *FirmataAdaptor) PwmWrite(pin string, level byte) {
|
|
p, _ := strconv.Atoi(pin)
|
|
|
|
f.Board.setPinMode(byte(p), PWM)
|
|
f.Board.analogWrite(byte(p), level)
|
|
}
|
|
|
|
func (f *FirmataAdaptor) DigitalWrite(pin string, level byte) {
|
|
p, _ := strconv.Atoi(pin)
|
|
|
|
f.Board.setPinMode(byte(p), OUTPUT)
|
|
f.Board.digitalWrite(byte(p), level)
|
|
}
|
|
|
|
func (f *FirmataAdaptor) DigitalRead(pin string) int {
|
|
p, _ := strconv.Atoi(pin)
|
|
f.Board.setPinMode(byte(p), INPUT)
|
|
f.Board.togglePinReporting(byte(p), HIGH, REPORT_DIGITAL)
|
|
events := f.Board.findEvents(fmt.Sprintf("digital_read_%v", pin))
|
|
if len(events) > 0 {
|
|
return int(events[len(events)-1].Data[0])
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// NOTE pins are numbered A0-A5, which translate to digital pins 14-19
|
|
func (f *FirmataAdaptor) AnalogRead(pin string) int {
|
|
p, _ := strconv.Atoi(pin)
|
|
p = f.digitalPin(p)
|
|
f.Board.setPinMode(byte(p), ANALOG)
|
|
f.Board.togglePinReporting(byte(p), HIGH, REPORT_ANALOG)
|
|
events := f.Board.findEvents(fmt.Sprintf("analog_read_%v", pin))
|
|
if len(events) > 0 {
|
|
event := events[len(events)-1]
|
|
return int(uint(event.Data[0])<<24 | uint(event.Data[1])<<16 | uint(event.Data[2])<<8 | uint(event.Data[3]))
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func (f *FirmataAdaptor) digitalPin(pin int) int {
|
|
return pin + 14
|
|
}
|
|
|
|
func (f *FirmataAdaptor) I2cStart(address byte) {
|
|
f.i2cAddress = address
|
|
f.Board.i2cConfig([]uint16{0})
|
|
}
|
|
|
|
func (f *FirmataAdaptor) I2cRead(size uint16) []uint16 {
|
|
f.Board.i2cReadRequest(f.i2cAddress, size)
|
|
|
|
events := f.Board.findEvents("i2c_reply")
|
|
if len(events) > 0 {
|
|
return events[len(events)-1].I2cReply["data"]
|
|
}
|
|
return make([]uint16, 0)
|
|
}
|
|
|
|
func (f *FirmataAdaptor) I2cWrite(data []uint16) {
|
|
f.Board.i2cWriteRequest(f.i2cAddress, data)
|
|
}
|