1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-05-11 19:29:20 +08:00

WIP firmata refactor

This commit is contained in:
Adrian Zankich 2014-07-13 13:54:41 -07:00
parent 167aa1091b
commit d8be3d11d2
2 changed files with 211 additions and 224 deletions

View File

@ -6,142 +6,130 @@ import (
"io" "io"
"math" "math"
"time" "time"
"github.com/hybridgroup/gobot"
) )
const ( const (
Open byte = 1 open byte = 1
Close byte = 0 close byte = 0
Input byte = 0x00 input byte = 0x00
Output byte = 0x01 output byte = 0x01
Analog byte = 0x02 analog byte = 0x02
PWM byte = 0x03 pwm byte = 0x03
Servo byte = 0x04 servo byte = 0x04
Low byte = 0 low byte = 0
High byte = 1 high byte = 1
ReportVersion byte = 0xF9 reportVersion byte = 0xF9
SystemReset byte = 0xFF systemReset byte = 0xFF
DigitalMessage byte = 0x90 digitalMessage byte = 0x90
DigitalMessageRangeStart byte = 0x90 digitalMessageRangeStart byte = 0x90
DigitalMessageRangeEnd byte = 0x9F digitalMessageRangeEnd byte = 0x9F
AnalogMessage byte = 0xE0 analogMessage byte = 0xE0
AnalogMessageRangeStart byte = 0xE0 analogMessageRangeStart byte = 0xE0
AnalogMessageRangeEnd byte = 0xEF analogMessageRangeEnd byte = 0xEF
ReportAnalog byte = 0xC0 reportAnalog byte = 0xC0
ReportDigital byte = 0xD0 reportDigital byte = 0xD0
PinMode byte = 0xF4 pinMode byte = 0xF4
StartSysex byte = 0xF0 startSysex byte = 0xF0
EndSysex byte = 0xF7 endSysex byte = 0xF7
CapabilityQuery byte = 0x6B capabilityQuery byte = 0x6B
CapabilityResponse byte = 0x6C capabilityResponse byte = 0x6C
PinStateQuery byte = 0x6D pinStateQuery byte = 0x6D
PinStateResponse byte = 0x6E pinStateResponse byte = 0x6E
AnalogMappingQuery byte = 0x69 analogMappingQuery byte = 0x69
AnalogMappingResponse byte = 0x6A analogMappingResponse byte = 0x6A
StringData byte = 0x71 stringData byte = 0x71
I2CRequest byte = 0x76 i2CRequest byte = 0x76
I2CReply byte = 0x77 i2CReply byte = 0x77
I2CConfig byte = 0x78 i2CConfig byte = 0x78
FirmwareQuery byte = 0x79 firmwareQuery byte = 0x79
I2CModeWrite byte = 0x00 i2CModeWrite byte = 0x00
I2CModeRead byte = 0x01 i2CModeRead byte = 0x01
I2CmodeContinuousRead byte = 0x02 i2CmodeContinuousRead byte = 0x02
I2CModeStopReading byte = 0x03 i2CModeStopReading byte = 0x03
) )
type board struct { type board struct {
Serial io.ReadWriteCloser serial io.ReadWriteCloser
Pins []pin pins []pin
AnalogPins []byte analogPins []byte
FirmwareName string firmwareName string
MajorVersion byte majorVersion byte
MinorVersion byte minorVersion byte
Events []event connected bool
Connected bool events map[string]*gobot.Event
} }
type pin struct { type pin struct {
SupportedModes []byte supportedModes []byte
Mode byte mode byte
Value int value int
AnalogChannel byte analogChannel byte
}
type event struct {
Name string
Data []byte
I2cReply map[string][]byte
} }
func newBoard(sp io.ReadWriteCloser) *board { func newBoard(sp io.ReadWriteCloser) *board {
board := new(board) board := &board{
board.MajorVersion = 0 majorVersion: 0,
board.MinorVersion = 0 minorVersion: 0,
board.Serial = sp serial: sp,
board.FirmwareName = "" firmwareName: "",
board.Pins = []pin{} pins: []pin{},
board.AnalogPins = []byte{} analogPins: []byte{},
board.Connected = false connected: false,
board.Events = []event{} events: make(map[string]*gobot.Event),
}
for _, s := range []string{
"firmware_query",
"capability_query",
"analog_mapping_query",
"report_version",
"i2c_reply",
"analog_mapping_query",
"string_data",
"firmware_query",
} {
board.events[s] = gobot.NewEvent()
}
return board return board
} }
func (b *board) connect() { func (b *board) connect() {
if b.Connected == false { if b.connected == false {
b.initBoard() b.initBoard()
b.Connected = true
go func() { for {
for { b.queryReportVersion()
b.queryReportVersion() <-time.After(1 * time.Second)
time.Sleep(50 * time.Millisecond) b.readAndProcess()
b.readAndProcess() if b.connected == true {
break
} }
}() }
} }
} }
func (b *board) initBoard() { func (b *board) initBoard() {
for { gobot.On(b.events["firmware_query"], func(data interface{}) {
b.queryFirmware() b.events["firmware_query"] = gobot.NewEvent()
time.Sleep(50 * time.Millisecond)
b.readAndProcess()
if len(b.findEvents("firmware_query")) > 0 {
break
}
}
for {
b.queryCapabilities() b.queryCapabilities()
time.Sleep(50 * time.Millisecond) })
b.readAndProcess()
if len(b.findEvents("capability_query")) > 0 {
break
}
}
for {
b.queryAnalogMapping()
time.Sleep(50 * time.Millisecond)
b.readAndProcess()
if len(b.findEvents("analog_mapping_query")) > 0 {
break
}
}
b.togglePinReporting(0, High, ReportDigital)
time.Sleep(50 * time.Millisecond)
b.togglePinReporting(1, High, ReportDigital)
time.Sleep(50 * time.Millisecond)
}
func (b *board) findEvents(name string) []event { gobot.On(b.events["capability_query"], func(data interface{}) {
ret := []event{} b.events["capability_query"] = gobot.NewEvent()
for key, val := range b.Events { b.queryAnalogMapping()
if val.Name == name { })
ret = append(ret, val)
if len(b.Events) > key+1 { gobot.On(b.events["analog_mapping_query"], func(data interface{}) {
b.Events = append(b.Events[:key], b.Events[key+1:]...) b.events["analog_mapping_query"] = gobot.NewEvent()
} b.togglePinReporting(0, high, reportDigital)
} <-time.After(50 * time.Millisecond)
} b.togglePinReporting(1, high, reportDigital)
return ret <-time.After(50 * time.Millisecond)
b.connected = true
})
} }
func (b *board) readAndProcess() { func (b *board) readAndProcess() {
@ -149,59 +137,59 @@ func (b *board) readAndProcess() {
} }
func (b *board) reset() { func (b *board) reset() {
b.write([]byte{SystemReset}) b.write([]byte{systemReset})
} }
func (b *board) setPinMode(pin byte, mode byte) { func (b *board) setPinMode(pin byte, mode byte) {
b.Pins[pin].Mode = mode b.pins[pin].mode = mode
b.write([]byte{PinMode, pin, mode}) b.write([]byte{pinMode, pin, mode})
} }
func (b *board) digitalWrite(pin byte, value byte) { func (b *board) digitalWrite(pin byte, value byte) {
port := byte(math.Floor(float64(pin) / 8)) port := byte(math.Floor(float64(pin) / 8))
portValue := byte(0) portValue := byte(0)
b.Pins[pin].Value = int(value) b.pins[pin].value = int(value)
for i := byte(0); i < 8; i++ { for i := byte(0); i < 8; i++ {
if b.Pins[8*port+i].Value != 0 { if b.pins[8*port+i].value != 0 {
portValue = portValue | (1 << i) portValue = portValue | (1 << i)
} }
} }
b.write([]byte{DigitalMessage | port, portValue & 0x7F, (portValue >> 7) & 0x7F}) b.write([]byte{digitalMessage | port, portValue & 0x7F, (portValue >> 7) & 0x7F})
} }
func (b *board) analogWrite(pin byte, value byte) { func (b *board) analogWrite(pin byte, value byte) {
b.Pins[pin].Value = int(value) b.pins[pin].value = int(value)
b.write([]byte{AnalogMessage | pin, value & 0x7F, (value >> 7) & 0x7F}) b.write([]byte{analogMessage | pin, value & 0x7F, (value >> 7) & 0x7F})
} }
func (b *board) version() string { func (b *board) version() string {
return fmt.Sprintf("%v.%v", b.MajorVersion, b.MinorVersion) return fmt.Sprintf("%v.%v", b.majorVersion, b.minorVersion)
} }
func (b *board) reportVersion() { func (b *board) reportVersion() {
b.write([]byte{ReportVersion}) b.write([]byte{reportVersion})
} }
func (b *board) queryFirmware() { func (b *board) queryFirmware() {
b.write([]byte{StartSysex, FirmwareQuery, EndSysex}) b.write([]byte{startSysex, firmwareQuery, endSysex})
} }
func (b *board) queryPinState(pin byte) { func (b *board) queryPinState(pin byte) {
b.write([]byte{StartSysex, PinStateQuery, pin, EndSysex}) b.write([]byte{startSysex, pinStateQuery, pin, endSysex})
} }
func (b *board) queryReportVersion() { func (b *board) queryReportVersion() {
b.write([]byte{ReportVersion}) b.write([]byte{reportVersion})
} }
func (b *board) queryCapabilities() { func (b *board) queryCapabilities() {
b.write([]byte{StartSysex, CapabilityQuery, EndSysex}) b.write([]byte{startSysex, capabilityQuery, endSysex})
} }
func (b *board) queryAnalogMapping() { func (b *board) queryAnalogMapping() {
b.write([]byte{StartSysex, AnalogMappingQuery, EndSysex}) b.write([]byte{startSysex, analogMappingQuery, endSysex})
} }
func (b *board) togglePinReporting(pin byte, state byte, mode byte) { func (b *board) togglePinReporting(pin byte, state byte, mode byte) {
@ -209,37 +197,37 @@ func (b *board) togglePinReporting(pin byte, state byte, mode byte) {
} }
func (b *board) i2cReadRequest(slaveAddress byte, numBytes uint) { func (b *board) i2cReadRequest(slaveAddress byte, numBytes uint) {
b.write([]byte{StartSysex, I2CRequest, slaveAddress, (I2CModeRead << 3), b.write([]byte{startSysex, i2CRequest, slaveAddress, (i2CModeRead << 3),
byte(numBytes & 0x7F), byte(((numBytes >> 7) & 0x7F)), EndSysex}) byte(numBytes & 0x7F), byte(((numBytes >> 7) & 0x7F)), endSysex})
} }
func (b *board) i2cWriteRequest(slaveAddress byte, data []byte) { func (b *board) i2cWriteRequest(slaveAddress byte, data []byte) {
ret := []byte{StartSysex, I2CRequest, slaveAddress, (I2CModeWrite << 3)} ret := []byte{startSysex, i2CRequest, slaveAddress, (i2CModeWrite << 3)}
for _, val := range data { for _, val := range data {
ret = append(ret, byte(val&0x7F)) ret = append(ret, byte(val&0x7F))
ret = append(ret, byte((val>>7)&0x7F)) ret = append(ret, byte((val>>7)&0x7F))
} }
ret = append(ret, EndSysex) ret = append(ret, endSysex)
b.write(ret) b.write(ret)
} }
func (b *board) i2cConfig(data []byte) { func (b *board) i2cConfig(data []byte) {
ret := []byte{StartSysex, I2CConfig} ret := []byte{startSysex, i2CConfig}
for _, val := range data { for _, val := range data {
ret = append(ret, byte(val&0xFF)) ret = append(ret, byte(val&0xFF))
ret = append(ret, byte((val>>8)&0xFF)) ret = append(ret, byte((val>>8)&0xFF))
} }
ret = append(ret, EndSysex) ret = append(ret, endSysex)
b.write(ret) b.write(ret)
} }
func (b *board) write(commands []byte) { func (b *board) write(commands []byte) {
b.Serial.Write(commands[:]) b.serial.Write(commands[:])
} }
func (b *board) read() []byte { func (b *board) read() []byte {
buf := make([]byte, 1024) buf := make([]byte, 1024)
b.Serial.Read(buf) b.serial.Read(buf)
return buf return buf
} }
@ -251,27 +239,27 @@ func (b *board) process(data []byte) {
break break
} }
switch { switch {
case ReportVersion == messageType: case reportVersion == messageType:
b.MajorVersion, _ = buf.ReadByte() b.majorVersion, _ = buf.ReadByte()
b.MinorVersion, _ = buf.ReadByte() b.minorVersion, _ = buf.ReadByte()
b.Events = append(b.Events, event{Name: "report_version"}) gobot.Publish(b.events["report_version"], b.version())
case AnalogMessageRangeStart <= messageType && AnalogMessageRangeEnd >= messageType: case analogMessageRangeStart <= messageType && analogMessageRangeEnd >= messageType:
leastSignificantByte, _ := buf.ReadByte() leastSignificantByte, _ := buf.ReadByte()
mostSignificantByte, _ := buf.ReadByte() mostSignificantByte, _ := buf.ReadByte()
value := uint(leastSignificantByte) | uint(mostSignificantByte)<<7 value := uint(leastSignificantByte) | uint(mostSignificantByte)<<7
pin := (messageType & 0x0F) pin := (messageType & 0x0F)
b.Pins[b.AnalogPins[pin]].Value = int(value) b.pins[b.analogPins[pin]].value = int(value)
b.Events = append(b.Events, gobot.Publish(b.events[fmt.Sprintf("analog_read_%v", pin)],
event{Name: fmt.Sprintf("analog_read_%v", pin), []byte{
Data: []byte{ byte(value >> 24),
byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value & 0xff), byte(value >> 16),
}, byte(value >> 8),
byte(value & 0xff),
}, },
) )
case digitalMessageRangeStart <= messageType && digitalMessageRangeEnd >= messageType:
case DigitalMessageRangeStart <= messageType && DigitalMessageRangeEnd >= messageType:
port := messageType & 0x0F port := messageType & 0x0F
firstBitmask, _ := buf.ReadByte() firstBitmask, _ := buf.ReadByte()
secondBitmask, _ := buf.ReadByte() secondBitmask, _ := buf.ReadByte()
@ -279,18 +267,14 @@ func (b *board) process(data []byte) {
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
pinNumber := (8*byte(port) + byte(i)) pinNumber := (8*byte(port) + byte(i))
pin := b.Pins[pinNumber] pin := b.pins[pinNumber]
if byte(pin.Mode) == Input { if byte(pin.mode) == input {
pin.Value = int((portValue >> (byte(i) & 0x07)) & 0x01) pin.value = int((portValue >> (byte(i) & 0x07)) & 0x01)
b.Events = append(b.Events, gobot.Publish(fmt.Sprintf("digital_read_%v", pinNumber),
event{Name: fmt.Sprintf("digital_read_%v", pinNumber), []byte{byte(pin.value & 0xff)})
Data: []byte{byte(pin.Value & 0xff)},
},
)
} }
} }
case startSysex == messageType:
case StartSysex == messageType:
currentBuffer := []byte{messageType} currentBuffer := []byte{messageType}
for { for {
b, err := buf.ReadByte() b, err := buf.ReadByte()
@ -298,25 +282,26 @@ func (b *board) process(data []byte) {
break break
} }
currentBuffer = append(currentBuffer, b) currentBuffer = append(currentBuffer, b)
if currentBuffer[len(currentBuffer)-1] == EndSysex { if currentBuffer[len(currentBuffer)-1] == endSysex {
break break
} }
} }
command := currentBuffer[1] command := currentBuffer[1]
switch command { switch command {
case CapabilityResponse: case capabilityResponse:
supportedModes := 0 supportedModes := 0
n := 0 n := 0
for _, val := range currentBuffer[2:(len(currentBuffer) - 5)] { for _, val := range currentBuffer[2:(len(currentBuffer) - 5)] {
if val == 127 { if val == 127 {
modes := []byte{} modes := []byte{}
for _, mode := range []byte{Input, Output, Analog, PWM, Servo} { for _, mode := range []byte{input, output, analog, pwm, servo} {
if (supportedModes & (1 << mode)) != 0 { if (supportedModes & (1 << mode)) != 0 {
modes = append(modes, mode) modes = append(modes, mode)
} }
} }
b.Pins = append(b.Pins, pin{modes, Output, 0, 0}) b.pins = append(b.pins, pin{modes, output, 0, 0})
b.Events[fmt.Sprintf("digital_read_%v", len(b.pins)-1)] = gobot.NewEvent()
supportedModes = 0 supportedModes = 0
n = 0 n = 0
continue continue
@ -327,42 +312,38 @@ func (b *board) process(data []byte) {
} }
n ^= 1 n ^= 1
} }
b.Events = append(b.Events, event{Name: "capability_query"}) gobot.Publish(b.events["capability_query"], nil)
case analogMappingResponse:
case AnalogMappingResponse:
pinIndex := byte(0) pinIndex := byte(0)
for _, val := range currentBuffer[2 : len(b.Pins)-1] { for _, val := range currentBuffer[2 : len(b.pins)-1] {
b.Pins[pinIndex].AnalogChannel = val b.pins[pinIndex].analogChannel = val
if val != 127 { if val != 127 {
b.AnalogPins = append(b.AnalogPins, pinIndex) b.analogPins = append(b.analogPins, pinIndex)
} }
b.events[fmt.Sprintf("analog_read_%v", pinIndex)] = gobot.NewEvent()
pinIndex++ pinIndex++
} }
b.Events = append(b.Events, event{Name: "analog_mapping_query"}) gobot.Publish(b.events["analog_mapping_query"], nil)
case pinStateResponse:
case PinStateResponse: pin := b.pins[currentBuffer[2]]
pin := b.Pins[currentBuffer[2]] pin.mode = currentBuffer[3]
pin.Mode = currentBuffer[3] pin.value = int(currentBuffer[4])
pin.Value = int(currentBuffer[4])
if len(currentBuffer) > 6 { if len(currentBuffer) > 6 {
pin.Value = int(uint(pin.Value) | uint(currentBuffer[5])<<7) pin.value = int(uint(pin.value) | uint(currentBuffer[5])<<7)
} }
if len(currentBuffer) > 7 { if len(currentBuffer) > 7 {
pin.Value = int(uint(pin.Value) | uint(currentBuffer[6])<<14) pin.value = int(uint(pin.value) | uint(currentBuffer[6])<<14)
} }
b.Events = append(b.Events, gobot.Publish(b.events[fmt.Sprintf("pin_%v_state", currentBuffer[2])],
event{Name: fmt.Sprintf("pin_%v_state", currentBuffer[2]), []byte{byte(pin.value & 0xff)},
Data: []byte{byte(pin.Value & 0xff)},
},
) )
case I2CReply: case i2CReply:
i2cReply := map[string][]byte{ i2cReply := map[string][]byte{
"slave_address": []byte{byte(currentBuffer[2]) | byte(currentBuffer[3])<<7}, "slave_address": []byte{byte(currentBuffer[2]) | byte(currentBuffer[3])<<7},
"register": []byte{byte(currentBuffer[4]) | byte(currentBuffer[5])<<7}, "register": []byte{byte(currentBuffer[4]) | byte(currentBuffer[5])<<7},
@ -379,21 +360,20 @@ func (b *board) process(data []byte) {
byte(currentBuffer[i])|byte(currentBuffer[i+1])<<7, byte(currentBuffer[i])|byte(currentBuffer[i+1])<<7,
) )
} }
b.Events = append(b.Events, event{Name: "i2c_reply", I2cReply: i2cReply}) gobo.Publish(b.events["i2c_reply"], i2cReply)
case firmwareQuery:
case FirmwareQuery:
name := []byte{} name := []byte{}
for _, val := range currentBuffer[4:(len(currentBuffer) - 1)] { for _, val := range currentBuffer[4:(len(currentBuffer) - 1)] {
if val != 0 { if val != 0 {
name = append(name, val) name = append(name, val)
} }
} }
b.FirmwareName = string(name[:]) b.firmwareName = string(name[:])
b.Events = append(b.Events, event{Name: "firmware_query"}) gobot.Publish(b.events["firmware_query"], b.firmwareName)
case StringData: case stringData:
str := currentBuffer[2 : len(currentBuffer)-1] str := currentBuffer[2 : len(currentBuffer)-1]
fmt.Println(string(str[:len(str)])) fmt.Println(string(str[:len(str)]))
b.Events = append(b.Events, event{Name: "string_data", Data: str}) gobot.Publish(b.events["string_data"], str)
default: default:
fmt.Println("bad byte", fmt.Sprintf("0x%x", command)) fmt.Println("bad byte", fmt.Sprintf("0x%x", command))
} }

View File

@ -10,7 +10,7 @@ import (
type FirmataAdaptor struct { type FirmataAdaptor struct {
gobot.Adaptor gobot.Adaptor
Board *board board *board
i2cAddress byte i2cAddress byte
connect func(*FirmataAdaptor) connect func(*FirmataAdaptor)
} }
@ -27,20 +27,20 @@ func NewFirmataAdaptor(name, port string) *FirmataAdaptor {
if err != nil { if err != nil {
panic(err) panic(err)
} }
f.Board = newBoard(sp) f.board = newBoard(sp)
}, },
} }
} }
func (f *FirmataAdaptor) Connect() bool { func (f *FirmataAdaptor) Connect() bool {
f.connect(f) f.connect(f)
f.Board.connect() f.board.connect()
f.SetConnected(true) f.SetConnected(true)
return true return true
} }
func (f *FirmataAdaptor) Disconnect() bool { func (f *FirmataAdaptor) Disconnect() bool {
err := f.Board.Serial.Close() err := f.board.serial.Close()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
@ -52,50 +52,54 @@ func (f *FirmataAdaptor) InitServo() {}
func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) { func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) {
p, _ := strconv.Atoi(pin) p, _ := strconv.Atoi(pin)
f.Board.setPinMode(byte(p), Servo) f.board.setPinMode(byte(p), servo)
f.Board.analogWrite(byte(p), angle) f.board.analogWrite(byte(p), angle)
} }
func (f *FirmataAdaptor) PwmWrite(pin string, level byte) { func (f *FirmataAdaptor) PwmWrite(pin string, level byte) {
p, _ := strconv.Atoi(pin) p, _ := strconv.Atoi(pin)
f.Board.setPinMode(byte(p), PWM) f.board.setPinMode(byte(p), pwm)
f.Board.analogWrite(byte(p), level) f.board.analogWrite(byte(p), level)
} }
func (f *FirmataAdaptor) DigitalWrite(pin string, level byte) { func (f *FirmataAdaptor) DigitalWrite(pin string, level byte) {
p, _ := strconv.Atoi(pin) p, _ := strconv.Atoi(pin)
f.Board.setPinMode(byte(p), Output) f.board.setPinMode(byte(p), output)
f.Board.digitalWrite(byte(p), level) f.board.digitalWrite(byte(p), level)
} }
func (f *FirmataAdaptor) DigitalRead(pin string) int { func (f *FirmataAdaptor) DigitalRead(pin string) int {
ret := make(chan int)
p, _ := strconv.Atoi(pin) p, _ := strconv.Atoi(pin)
f.Board.setPinMode(byte(p), Input) f.board.setPinMode(byte(p), input)
f.Board.togglePinReporting(byte(p), High, ReportDigital) f.board.togglePinReporting(byte(p), high, reportDigital)
events := f.Board.findEvents(fmt.Sprintf("digital_read_%v", pin)) f.board.readAndProcess()
if len(events) > 0 {
return int(events[len(events)-1].Data[0]) gobot.On(f.board.events[fmt.Sprintf("digital_read_%v", pin)], func(data interface{}) {
} ret <- int(data.([]byte)[0])
return -1 })
return <-ret
} }
// NOTE pins are numbered A0-A5, which translate to digital pins 14-19 // NOTE pins are numbered A0-A5, which translate to digital pins 14-19
func (f *FirmataAdaptor) AnalogRead(pin string) int { func (f *FirmataAdaptor) AnalogRead(pin string) int {
ret := make(chan int)
p, _ := strconv.Atoi(pin) p, _ := strconv.Atoi(pin)
p = f.digitalPin(p) p = f.digitalPin(p)
f.Board.setPinMode(byte(p), Analog) f.board.setPinMode(byte(p), analog)
f.Board.togglePinReporting(byte(p), High, ReportAnalog) f.board.togglePinReporting(byte(p), high, reportAnalog)
events := f.Board.findEvents(fmt.Sprintf("analog_read_%v", pin)) f.board.readAndProcess()
if len(events) > 0 {
event := events[len(events)-1] gobot.On(f.board.events[fmt.Sprintf("analog_read_%v", pin)], func(data interface{}) {
return int(uint(event.Data[0])<<24 | b := data.([]byte)
uint(event.Data[1])<<16 | ret <- int(uint(b[0])<<24 | uint(b[1])<<16 | uint(b[2])<<8 | uint(b[3]))
uint(event.Data[2])<<8 | })
uint(event.Data[3]))
} return <-ret
return -1
} }
func (f *FirmataAdaptor) AnalogWrite(pin string, level byte) { func (f *FirmataAdaptor) AnalogWrite(pin string, level byte) {
@ -108,19 +112,22 @@ func (f *FirmataAdaptor) digitalPin(pin int) int {
func (f *FirmataAdaptor) I2cStart(address byte) { func (f *FirmataAdaptor) I2cStart(address byte) {
f.i2cAddress = address f.i2cAddress = address
f.Board.i2cConfig([]byte{0}) f.board.i2cConfig([]byte{0})
} }
func (f *FirmataAdaptor) I2cRead(size uint) []byte { func (f *FirmataAdaptor) I2cRead(size uint) []byte {
f.Board.i2cReadRequest(f.i2cAddress, size) ret := make(chan []byte)
f.board.i2cReadRequest(f.i2cAddress, size)
events := f.Board.findEvents("i2c_reply") f.board.readAndProcess()
if len(events) > 0 {
return events[len(events)-1].I2cReply["data"] gobot.On(f.board.events["i2c_reply"], func(data interface{}) {
} ret <- data.(i2CReply)["data"]
return make([]byte, 0) })
return <-ret
} }
func (f *FirmataAdaptor) I2cWrite(data []byte) { func (f *FirmataAdaptor) I2cWrite(data []byte) {
f.Board.i2cWriteRequest(f.i2cAddress, data) f.board.i2cWriteRequest(f.i2cAddress, data)
} }