Adding godocs to firmata package

This commit is contained in:
Javier Cervantes 2014-10-17 12:42:07 -05:00
parent bf7bc97c3a
commit 58c15eb116
4 changed files with 100 additions and 6 deletions

47
platforms/firmata/doc.go Normal file
View File

@ -0,0 +1,47 @@
/*
This package provides the adaptor for microcontrollers such as Arduino that support the [Firmata](http://firmata.org/wiki/Main_Page) protocol
Installing:
go get github.com/hybridgroup/gobot && go install github.com/hybridgroup/gobot/platforms/firmata
## Example
package main
import (
"time"
"github.com/hybridgroup/gobot"
"github.com/hybridgroup/gobot/platforms/firmata"
"github.com/hybridgroup/gobot/platforms/gpio"
)
func main() {
gbot := gobot.NewGobot()
firmataAdaptor := firmata.NewFirmataAdaptor("arduino", "/dev/ttyACM0")
led := gpio.NewLedDriver(firmataAdaptor, "led", "13")
work := func() {
gobot.Every(1*time.Second, func() {
led.Toggle()
})
}
robot := gobot.NewRobot("bot",
[]gobot.Connection{firmataAdaptor},
[]gobot.Device{led},
work,
)
gbot.AddRobot(robot)
gbot.Start()
}
For further information refer to firmata readme:
https://github.com/hybridgroup/gobot/blob/master/platforms/firmata/README.md
*/
package firmata

View File

@ -69,6 +69,10 @@ type pin struct {
analogChannel byte
}
// newBoard creates a new board connected in specified serial port.
// Adds following events: "firmware_query", "capability_query",
// "analog_mapping_query", "report_version", "i2c_reply",
// "string_data", "firmware_query"
func newBoard(sp io.ReadWriteCloser) *board {
board := &board{
majorVersion: 0,
@ -88,7 +92,6 @@ func newBoard(sp io.ReadWriteCloser) *board {
"analog_mapping_query",
"report_version",
"i2c_reply",
"analog_mapping_query",
"string_data",
"firmware_query",
} {
@ -98,6 +101,8 @@ func newBoard(sp io.ReadWriteCloser) *board {
return board
}
// connect starts connection to board.
// Queries report version until connected
func (b *board) connect() {
if b.connected == false {
b.reset()
@ -114,6 +119,8 @@ func (b *board) connect() {
}
}
// initBoard initializes board by listening for "firware_query", "capability_query"
// and "analog_mapping_query" events
func (b *board) initBoard() {
gobot.Once(b.events["firmware_query"], func(data interface{}) {
b.queryCapabilities()
@ -130,19 +137,23 @@ func (b *board) initBoard() {
})
}
// readAndProcess reads from serial port and parses data.
func (b *board) readAndProcess() {
b.process(b.read())
}
// reset writes system reset bytes.
func (b *board) reset() {
b.write([]byte{systemReset})
}
// setPinMode writes pin mode bytes for specified pin.
func (b *board) setPinMode(pin byte, mode byte) {
b.pins[pin].mode = mode
b.write([]byte{pinMode, pin, mode})
}
// digitalWrite is used to send a digital value to a specified pin.
func (b *board) digitalWrite(pin byte, value byte) {
port := byte(math.Floor(float64(pin) / 8))
portValue := byte(0)
@ -157,48 +168,54 @@ func (b *board) digitalWrite(pin byte, value byte) {
b.write([]byte{digitalMessage | port, portValue & 0x7F, (portValue >> 7) & 0x7F})
}
// analogWrite writes value to specified pin
func (b *board) analogWrite(pin byte, value byte) {
b.pins[pin].value = int(value)
b.write([]byte{analogMessage | pin, value & 0x7F, (value >> 7) & 0x7F})
}
// version returns board version following MAYOR.minor convention.
func (b *board) version() string {
return fmt.Sprintf("%v.%v", b.majorVersion, b.minorVersion)
}
func (b *board) reportVersion() {
b.write([]byte{reportVersion})
}
// queryFirmware writes bytes to query firmware from board.
func (b *board) queryFirmware() {
b.write([]byte{startSysex, firmwareQuery, endSysex})
}
// queryPinState writes bytes to retrieve pin state
func (b *board) queryPinState(pin byte) {
b.write([]byte{startSysex, pinStateQuery, pin, endSysex})
}
// queryReportVersion sends query for report version
func (b *board) queryReportVersion() {
b.write([]byte{reportVersion})
}
// queryCapabilities is used to retrieve board capabilities.
func (b *board) queryCapabilities() {
b.write([]byte{startSysex, capabilityQuery, endSysex})
}
// queryAnalogMapping returns analog mapping for board.
func (b *board) queryAnalogMapping() {
b.write([]byte{startSysex, analogMappingQuery, endSysex})
}
// togglePinReporting is used to change pin reporting mode.
func (b *board) togglePinReporting(pin byte, state byte, mode byte) {
b.write([]byte{mode | pin, state})
}
// i2cReadRequest reads from slaveAddress.
func (b *board) i2cReadRequest(slaveAddress byte, numBytes uint) {
b.write([]byte{startSysex, i2CRequest, slaveAddress, (i2CModeRead << 3),
byte(numBytes & 0x7F), byte(((numBytes >> 7) & 0x7F)), endSysex})
}
// i2cWriteRequest writes to slaveAddress.
func (b *board) i2cWriteRequest(slaveAddress byte, data []byte) {
ret := []byte{startSysex, i2CRequest, slaveAddress, (i2CModeWrite << 3)}
for _, val := range data {
@ -209,6 +226,7 @@ func (b *board) i2cWriteRequest(slaveAddress byte, data []byte) {
b.write(ret)
}
// i2xConfig returns i2c configuration.
func (b *board) i2cConfig(data []byte) {
ret := []byte{startSysex, i2CConfig}
for _, val := range data {
@ -219,16 +237,24 @@ func (b *board) i2cConfig(data []byte) {
b.write(ret)
}
// write is used to send commands to serial port
func (b *board) write(commands []byte) {
b.serial.Write(commands[:])
}
// read returns buffer reading from serial port (1024 bytes)
func (b *board) read() []byte {
buf := make([]byte, 1024)
b.serial.Read(buf)
return buf
}
// process uses incoming data and executes actions depending on what is received.
// The following messages are processed: reportVersion, AnalogMessageRangeStart,
// digitalMessageRangeStart.
// And the following responses: capability, analog mapping, pin state,
// i2c, firmwareQuery, string data.
// If neither of those messages is received, then data is treated as "bad_byte"
func (b *board) process(data []byte) {
buf := bytes.NewBuffer(data)
for {

View File

@ -16,6 +16,8 @@ type FirmataAdaptor struct {
connect func(*FirmataAdaptor)
}
// NewFirmataAdaptor returns a new firmata adaptor with specified name
// Generates a connect function that opens serial communication in specified port
func NewFirmataAdaptor(name, port string) *FirmataAdaptor {
return &FirmataAdaptor{
Adaptor: *gobot.NewAdaptor(
@ -33,6 +35,7 @@ func NewFirmataAdaptor(name, port string) *FirmataAdaptor {
}
}
// Connect returns true if connection to board is succesfull
func (f *FirmataAdaptor) Connect() bool {
f.connect(f)
f.board.connect()
@ -40,6 +43,8 @@ func (f *FirmataAdaptor) Connect() bool {
return true
}
// close finishes connection to serial port
// Prints error message on error
func (f *FirmataAdaptor) Disconnect() bool {
err := f.board.serial.Close()
if err != nil {
@ -47,9 +52,14 @@ func (f *FirmataAdaptor) Disconnect() bool {
}
return true
}
// Finalize disconnects firmata adaptor
func (f *FirmataAdaptor) Finalize() bool { return f.Disconnect() }
// InitServo (not yet implemented)
func (f *FirmataAdaptor) InitServo() {}
// ServoWrite sets angle form 0 to 360 to specified servo pin
func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) {
p, _ := strconv.Atoi(pin)
@ -57,6 +67,7 @@ func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) {
f.board.analogWrite(byte(p), angle)
}
// PwmWrite writes analog value to specified pin
func (f *FirmataAdaptor) PwmWrite(pin string, level byte) {
p, _ := strconv.Atoi(pin)
@ -64,6 +75,7 @@ func (f *FirmataAdaptor) PwmWrite(pin string, level byte) {
f.board.analogWrite(byte(p), level)
}
// DigitalWrite writes digital values to specified pin
func (f *FirmataAdaptor) DigitalWrite(pin string, level byte) {
p, _ := strconv.Atoi(pin)
@ -71,6 +83,8 @@ func (f *FirmataAdaptor) DigitalWrite(pin string, level byte) {
f.board.digitalWrite(byte(p), level)
}
// DigitalRead retrieves digital value from specified pin
// Returns -1 if response from board is timed out
func (f *FirmataAdaptor) DigitalRead(pin string) int {
ret := make(chan int)
@ -91,6 +105,7 @@ func (f *FirmataAdaptor) DigitalRead(pin string) int {
return -1
}
// AnalogRead retrieves value from analog pin.
// NOTE pins are numbered A0-A5, which translate to digital pins 14-19
func (f *FirmataAdaptor) AnalogRead(pin string) int {
ret := make(chan int)
@ -114,19 +129,24 @@ func (f *FirmataAdaptor) AnalogRead(pin string) int {
return -1
}
// AnalogWrite writes value to ananlog pin
func (f *FirmataAdaptor) AnalogWrite(pin string, level byte) {
f.PwmWrite(pin, level)
}
// digitalPin converts pin number to digital mapping
func (f *FirmataAdaptor) digitalPin(pin int) int {
return pin + 14
}
// I2cStart initializes board with i2c configuration
func (f *FirmataAdaptor) I2cStart(address byte) {
f.i2cAddress = address
f.board.i2cConfig([]byte{0})
}
// I2cRead reads from I2c specified size
// Returns empty byte array if response is timed out
func (f *FirmataAdaptor) I2cRead(size uint) []byte {
ret := make(chan []byte)
f.board.i2cReadRequest(f.i2cAddress, size)
@ -145,6 +165,7 @@ func (f *FirmataAdaptor) I2cRead(size uint) []byte {
return []byte{}
}
// I2cWrite retrieves i2c data
func (f *FirmataAdaptor) I2cWrite(data []byte) {
f.board.i2cWriteRequest(f.i2cAddress, data)
}

View File

@ -31,7 +31,7 @@ func initTestFirmata() *board {
func TestReportVersion(t *testing.T) {
b := initTestFirmata()
//test if functions executes
b.reportVersion()
b.queryReportVersion()
}
func TestQueryFirmware(t *testing.T) {