2014-04-27 19:56:18 -07:00
|
|
|
package firmata
|
2014-04-26 03:11:51 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2014-07-10 13:42:18 -07:00
|
|
|
"strconv"
|
|
|
|
|
2014-04-26 03:11:51 -07:00
|
|
|
"github.com/hybridgroup/gobot"
|
|
|
|
"github.com/tarm/goserial"
|
|
|
|
)
|
|
|
|
|
|
|
|
type FirmataAdaptor struct {
|
|
|
|
gobot.Adaptor
|
2014-07-13 13:54:41 -07:00
|
|
|
board *board
|
2014-04-26 03:11:51 -07:00
|
|
|
i2cAddress byte
|
2014-04-27 19:56:18 -07:00
|
|
|
connect func(*FirmataAdaptor)
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-04-30 08:10:44 -07:00
|
|
|
func NewFirmataAdaptor(name, port string) *FirmataAdaptor {
|
2014-04-27 19:56:18 -07:00
|
|
|
return &FirmataAdaptor{
|
2014-06-23 20:33:59 -07:00
|
|
|
Adaptor: *gobot.NewAdaptor(
|
|
|
|
name,
|
|
|
|
"FirmataAdaptor",
|
2014-07-03 19:52:31 -07:00
|
|
|
port,
|
2014-06-23 20:33:59 -07:00
|
|
|
),
|
2014-04-27 19:56:18 -07:00
|
|
|
connect: func(f *FirmataAdaptor) {
|
2014-07-03 19:52:31 -07:00
|
|
|
sp, err := serial.OpenPort(&serial.Config{Name: f.Port(), Baud: 57600})
|
2014-04-27 19:56:18 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board = newBoard(sp)
|
2014-04-27 19:56:18 -07:00
|
|
|
},
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) Connect() bool {
|
|
|
|
f.connect(f)
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.connect()
|
2014-07-03 19:52:31 -07:00
|
|
|
f.SetConnected(true)
|
2014-04-26 03:11:51 -07:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) Disconnect() bool {
|
2014-07-13 13:54:41 -07:00
|
|
|
err := f.board.serial.Close()
|
2014-04-26 03:11:51 -07:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) Finalize() bool { return f.Disconnect() }
|
2014-04-26 03:11:51 -07:00
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) InitServo() {}
|
|
|
|
func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) {
|
2014-04-26 03:11:51 -07:00
|
|
|
p, _ := strconv.Atoi(pin)
|
|
|
|
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.setPinMode(byte(p), servo)
|
|
|
|
f.board.analogWrite(byte(p), angle)
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) PwmWrite(pin string, level byte) {
|
2014-04-26 03:11:51 -07:00
|
|
|
p, _ := strconv.Atoi(pin)
|
|
|
|
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.setPinMode(byte(p), pwm)
|
|
|
|
f.board.analogWrite(byte(p), level)
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) DigitalWrite(pin string, level byte) {
|
2014-04-26 03:11:51 -07:00
|
|
|
p, _ := strconv.Atoi(pin)
|
|
|
|
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.setPinMode(byte(p), output)
|
|
|
|
f.board.digitalWrite(byte(p), level)
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) DigitalRead(pin string) int {
|
2014-07-13 13:54:41 -07:00
|
|
|
ret := make(chan int)
|
2014-04-26 03:11:51 -07:00
|
|
|
p, _ := strconv.Atoi(pin)
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.setPinMode(byte(p), input)
|
|
|
|
f.board.togglePinReporting(byte(p), high, reportDigital)
|
|
|
|
f.board.readAndProcess()
|
|
|
|
|
|
|
|
gobot.On(f.board.events[fmt.Sprintf("digital_read_%v", pin)], func(data interface{}) {
|
|
|
|
ret <- int(data.([]byte)[0])
|
|
|
|
})
|
|
|
|
|
|
|
|
return <-ret
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE pins are numbered A0-A5, which translate to digital pins 14-19
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) AnalogRead(pin string) int {
|
2014-07-13 13:54:41 -07:00
|
|
|
ret := make(chan int)
|
|
|
|
|
2014-04-26 03:11:51 -07:00
|
|
|
p, _ := strconv.Atoi(pin)
|
2014-04-27 19:56:18 -07:00
|
|
|
p = f.digitalPin(p)
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.setPinMode(byte(p), analog)
|
|
|
|
f.board.togglePinReporting(byte(p), high, reportAnalog)
|
|
|
|
f.board.readAndProcess()
|
|
|
|
|
|
|
|
gobot.On(f.board.events[fmt.Sprintf("analog_read_%v", pin)], func(data interface{}) {
|
|
|
|
b := data.([]byte)
|
|
|
|
ret <- int(uint(b[0])<<24 | uint(b[1])<<16 | uint(b[2])<<8 | uint(b[3]))
|
|
|
|
})
|
|
|
|
|
|
|
|
return <-ret
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-06-09 14:28:48 -07:00
|
|
|
func (f *FirmataAdaptor) AnalogWrite(pin string, level byte) {
|
|
|
|
f.PwmWrite(pin, level)
|
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) digitalPin(pin int) int {
|
2014-04-26 03:11:51 -07:00
|
|
|
return pin + 14
|
|
|
|
}
|
|
|
|
|
2014-04-27 19:56:18 -07:00
|
|
|
func (f *FirmataAdaptor) I2cStart(address byte) {
|
|
|
|
f.i2cAddress = address
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.i2cConfig([]byte{0})
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-06-06 18:58:04 -07:00
|
|
|
func (f *FirmataAdaptor) I2cRead(size uint) []byte {
|
2014-07-13 13:54:41 -07:00
|
|
|
ret := make(chan []byte)
|
|
|
|
f.board.i2cReadRequest(f.i2cAddress, size)
|
2014-04-26 03:11:51 -07:00
|
|
|
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.readAndProcess()
|
|
|
|
|
|
|
|
gobot.On(f.board.events["i2c_reply"], func(data interface{}) {
|
|
|
|
ret <- data.(i2CReply)["data"]
|
|
|
|
})
|
|
|
|
|
|
|
|
return <-ret
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|
|
|
|
|
2014-06-06 18:58:04 -07:00
|
|
|
func (f *FirmataAdaptor) I2cWrite(data []byte) {
|
2014-07-13 13:54:41 -07:00
|
|
|
f.board.i2cWriteRequest(f.i2cAddress, data)
|
2014-04-26 03:11:51 -07:00
|
|
|
}
|