From 7819bb95d6a0dcc839812ae66e6ce34eede3abe7 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 29 Nov 2014 11:02:10 -0800 Subject: [PATCH 1/4] Refactor gpio driver interfaces --- platforms/gpio/analog_sensor_driver.go | 21 +++++------ platforms/gpio/button_driver.go | 28 +++++--------- platforms/gpio/button_driver_test.go | 6 --- platforms/gpio/direct_pin_driver.go | 47 ++++++++++++++---------- platforms/gpio/direct_pin_driver_test.go | 5 --- platforms/gpio/gpio.go | 47 ++++++++++++++++++++++++ platforms/gpio/led_driver.go | 19 +++++----- platforms/gpio/makey_button_driver.go | 28 +++++--------- platforms/gpio/motor_driver.go | 31 ++++++++-------- platforms/gpio/servo_driver.go | 18 +++------ platforms/gpio/servo_driver_test.go | 5 --- platforms/gpio/test_helper.go | 2 - platforms/gpio/utils.go | 33 ----------------- 13 files changed, 132 insertions(+), 158 deletions(-) create mode 100644 platforms/gpio/gpio.go delete mode 100644 platforms/gpio/utils.go diff --git a/platforms/gpio/analog_sensor_driver.go b/platforms/gpio/analog_sensor_driver.go index 4e39c4edc..39637a1a0 100644 --- a/platforms/gpio/analog_sensor_driver.go +++ b/platforms/gpio/analog_sensor_driver.go @@ -13,7 +13,7 @@ type AnalogSensorDriver struct { name string pin string interval time.Duration - connection gobot.Connection + connection AnalogReader gobot.Eventer gobot.Commander } @@ -25,7 +25,7 @@ type AnalogSensorDriver struct { func NewAnalogSensorDriver(a AnalogReader, name string, pin string, v ...time.Duration) *AnalogSensorDriver { d := &AnalogSensorDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, pin: pin, Eventer: gobot.NewEventer(), Commander: gobot.NewCommander(), @@ -36,8 +36,9 @@ func NewAnalogSensorDriver(a AnalogReader, name string, pin string, v ...time.Du d.interval = v[0] } - d.AddEvent("data") - d.AddEvent("error") + d.AddEvent(Data) + d.AddEvent(Error) + d.AddCommand("Read", func(params map[string]interface{}) interface{} { val, err := d.Read() return map[string]interface{}{"val": val, "err": err} @@ -46,10 +47,6 @@ func NewAnalogSensorDriver(a AnalogReader, name string, pin string, v ...time.Du return d } -func (a *AnalogSensorDriver) conn() AnalogReader { - return a.Connection().(AnalogReader) -} - // Starts the AnalogSensorDriver and reads the Analog Sensor at the given Driver.Interval(). // Returns true on successful start of the driver. // Emits the Events: @@ -60,10 +57,10 @@ func (a *AnalogSensorDriver) Start() (errs []error) { for { newValue, err := a.Read() if err != nil { - gobot.Publish(a.Event("error"), err) + gobot.Publish(a.Event(Error), err) } else if newValue != value && newValue != -1 { value = newValue - gobot.Publish(a.Event("data"), value) + gobot.Publish(a.Event(Data), value) } <-time.After(a.interval) } @@ -75,9 +72,9 @@ func (a *AnalogSensorDriver) Start() (errs []error) { func (a *AnalogSensorDriver) Halt() (errs []error) { return } func (a *AnalogSensorDriver) Name() string { return a.name } func (a *AnalogSensorDriver) Pin() string { return a.pin } -func (a *AnalogSensorDriver) Connection() gobot.Connection { return a.connection } +func (a *AnalogSensorDriver) Connection() gobot.Connection { return a.connection.(gobot.Connection) } // Read returns the current reading from the Analog Sensor func (a *AnalogSensorDriver) Read() (val int, err error) { - return a.conn().AnalogRead(a.Pin()) + return a.connection.AnalogRead(a.Pin()) } diff --git a/platforms/gpio/button_driver.go b/platforms/gpio/button_driver.go index 791c9c7fb..0a817427f 100644 --- a/platforms/gpio/button_driver.go +++ b/platforms/gpio/button_driver.go @@ -14,7 +14,7 @@ type ButtonDriver struct { pin string name string interval time.Duration - connection gobot.Connection + connection DigitalReader gobot.Eventer } @@ -22,7 +22,7 @@ type ButtonDriver struct { func NewButtonDriver(a DigitalReader, name string, pin string, v ...time.Duration) *ButtonDriver { b := &ButtonDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, pin: pin, Active: false, Eventer: gobot.NewEventer(), @@ -33,17 +33,13 @@ func NewButtonDriver(a DigitalReader, name string, pin string, v ...time.Duratio b.interval = v[0] } - b.AddEvent("push") - b.AddEvent("release") - b.AddEvent("error") + b.AddEvent(Push) + b.AddEvent(Release) + b.AddEvent(Error) return b } -func (b *ButtonDriver) adaptor() DigitalReader { - return b.Connection().(DigitalReader) -} - // Starts the ButtonDriver and reads the state of the button at the given Driver.Interval(). // Returns true on successful start of the driver. // @@ -55,9 +51,9 @@ func (b *ButtonDriver) Start() (errs []error) { state := 0 go func() { for { - newValue, err := b.readState() + newValue, err := b.connection.DigitalRead(b.Pin()) if err != nil { - gobot.Publish(b.Event("error"), err) + gobot.Publish(b.Event(Error), err) } else if newValue != state && newValue != -1 { state = newValue b.update(newValue) @@ -73,18 +69,14 @@ func (b *ButtonDriver) Halt() (errs []error) { return } func (b *ButtonDriver) Name() string { return b.name } func (b *ButtonDriver) Pin() string { return b.pin } -func (b *ButtonDriver) Connection() gobot.Connection { return b.connection } - -func (b *ButtonDriver) readState() (val int, err error) { - return b.adaptor().DigitalRead(b.Pin()) -} +func (b *ButtonDriver) Connection() gobot.Connection { return b.connection.(gobot.Connection) } func (b *ButtonDriver) update(newValue int) { if newValue == 1 { b.Active = true - gobot.Publish(b.Event("push"), newValue) + gobot.Publish(b.Event(Push), newValue) } else { b.Active = false - gobot.Publish(b.Event("release"), newValue) + gobot.Publish(b.Event(Release), newValue) } } diff --git a/platforms/gpio/button_driver_test.go b/platforms/gpio/button_driver_test.go index 02b5a31db..ca7cf1d4f 100644 --- a/platforms/gpio/button_driver_test.go +++ b/platforms/gpio/button_driver_test.go @@ -20,12 +20,6 @@ func TestButtonDriverHalt(t *testing.T) { gobot.Assert(t, len(d.Halt()), 0) } -func TestButtonDriverReadState(t *testing.T) { - d := initTestButtonDriver() - val, _ := d.readState() - gobot.Assert(t, val, 1) -} - func TestButtonDriverActive(t *testing.T) { d := initTestButtonDriver() d.update(1) diff --git a/platforms/gpio/direct_pin_driver.go b/platforms/gpio/direct_pin_driver.go index 1a0fa7238..230e4f83b 100644 --- a/platforms/gpio/direct_pin_driver.go +++ b/platforms/gpio/direct_pin_driver.go @@ -25,10 +25,10 @@ type DirectPinDriver struct { // "AnalogWrite" - See DirectPinDriver.AnalogWrite // "PwmWrite" - See DirectPinDriver.PwmWrite // "ServoWrite" - See DirectPinDriver.ServoWrite -func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver { +func NewDirectPinDriver(a gobot.Connection, name string, pin string) *DirectPinDriver { d := &DirectPinDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, pin: pin, Commander: gobot.NewCommander(), } @@ -45,10 +45,6 @@ func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver { val, err := d.AnalogRead() return map[string]interface{}{"val": val, "err": err} }) - d.AddCommand("AnalogWrite", func(params map[string]interface{}) interface{} { - level, _ := strconv.Atoi(params["level"].(string)) - return d.AnalogWrite(byte(level)) - }) d.AddCommand("PwmWrite", func(params map[string]interface{}) interface{} { level, _ := strconv.Atoi(params["level"].(string)) return d.PwmWrite(byte(level)) @@ -61,10 +57,6 @@ func NewDirectPinDriver(a DirectPin, name string, pin string) *DirectPinDriver { return d } -func (d *DirectPinDriver) adaptor() DirectPin { - return d.Connection().(DirectPin) -} - func (d *DirectPinDriver) Name() string { return d.name } func (d *DirectPinDriver) Pin() string { return d.pin } func (d *DirectPinDriver) Connection() gobot.Connection { return d.connection } @@ -77,30 +69,45 @@ func (d *DirectPinDriver) Halt() (errs []error) { return } // DigitalRead returns the current digital state of the pin func (d *DirectPinDriver) DigitalRead() (val int, err error) { - return d.adaptor().DigitalRead(d.Pin()) + if reader, ok := d.Connection().(DigitalReader); ok { + return reader.DigitalRead(d.Pin()) + } + err = ErrDigitalReadUnsupported + return } // DigitalWrite writes to the pin func (d *DirectPinDriver) DigitalWrite(level byte) (err error) { - return d.adaptor().DigitalWrite(d.Pin(), level) + if writer, ok := d.Connection().(DigitalWriter); ok { + return writer.DigitalWrite(d.Pin(), level) + } + err = ErrDigitalWriteUnsupported + return } // AnalogRead reads the current analog reading of the pin func (d *DirectPinDriver) AnalogRead() (val int, err error) { - return d.adaptor().AnalogRead(d.Pin()) -} - -// AnalogWrite writes to the pin -func (d *DirectPinDriver) AnalogWrite(level byte) (err error) { - return d.adaptor().AnalogWrite(d.Pin(), level) + if reader, ok := d.Connection().(AnalogReader); ok { + return reader.AnalogRead(d.Pin()) + } + err = ErrAnalogReadUnsupported + return } // PwmWrite writes to the pin func (d *DirectPinDriver) PwmWrite(level byte) (err error) { - return d.adaptor().PwmWrite(d.Pin(), level) + if writer, ok := d.Connection().(PwmWriter); ok { + return writer.PwmWrite(d.Pin(), level) + } + err = ErrPwmWriteUnsupported + return } // ServoWrite writes to the pin func (d *DirectPinDriver) ServoWrite(level byte) (err error) { - return d.adaptor().ServoWrite(d.Pin(), level) + if writer, ok := d.Connection().(ServoWriter); ok { + return writer.ServoWrite(d.Pin(), level) + } + err = ErrServoWriteUnsupported + return } diff --git a/platforms/gpio/direct_pin_driver_test.go b/platforms/gpio/direct_pin_driver_test.go index 328f770a2..871143791 100644 --- a/platforms/gpio/direct_pin_driver_test.go +++ b/platforms/gpio/direct_pin_driver_test.go @@ -37,11 +37,6 @@ func TestDirectPinDriverAnalogRead(t *testing.T) { gobot.Assert(t, val, 99) } -func TestDirectPinDriverAnalogWrite(t *testing.T) { - d := initTestDirectPinDriver() - d.AnalogWrite(100) -} - func TestDirectPinDriverPwmWrite(t *testing.T) { d := initTestDirectPinDriver() d.PwmWrite(100) diff --git a/platforms/gpio/gpio.go b/platforms/gpio/gpio.go new file mode 100644 index 000000000..a0b417a73 --- /dev/null +++ b/platforms/gpio/gpio.go @@ -0,0 +1,47 @@ +package gpio + +import ( + "errors" + + "github.com/hybridgroup/gobot" +) + +var ( + ErrServoWriteUnsupported = errors.New("ServoWrite is not supported by this platform") + ErrPwmWriteUnsupported = errors.New("PwmWrite is not supported by this platform") + ErrAnalogReadUnsupported = errors.New("AnalogRead is not supported by this platform") + ErrDigitalWriteUnsupported = errors.New("DigitalWrite is not supported by this platform") + ErrDigitalReadUnsupported = errors.New("DigitalRead is not supported by this platform") +) + +const ( + Release = "release" + Push = "push" + Error = "error" + Data = "data" +) + +type PwmWriter interface { + gobot.Adaptor + PwmWrite(string, byte) (err error) +} + +type ServoWriter interface { + gobot.Adaptor + ServoWrite(string, byte) (err error) +} + +type AnalogReader interface { + gobot.Adaptor + AnalogRead(string) (val int, err error) +} + +type DigitalWriter interface { + gobot.Adaptor + DigitalWrite(string, byte) (err error) +} + +type DigitalReader interface { + gobot.Adaptor + DigitalRead(string) (val int, err error) +} diff --git a/platforms/gpio/led_driver.go b/platforms/gpio/led_driver.go index 5d902a67a..3d6b9077e 100644 --- a/platforms/gpio/led_driver.go +++ b/platforms/gpio/led_driver.go @@ -8,7 +8,7 @@ var _ gobot.Driver = (*LedDriver)(nil) type LedDriver struct { pin string name string - connection gobot.Connection + connection DigitalWriter high bool gobot.Commander } @@ -20,11 +20,11 @@ type LedDriver struct { // "Toggle" - See LedDriver.Toggle // "On" - See LedDriver.On // "Off" - See LedDriver.Off -func NewLedDriver(a PwmDigitalWriter, name string, pin string) *LedDriver { +func NewLedDriver(a DigitalWriter, name string, pin string) *LedDriver { l := &LedDriver{ name: name, pin: pin, - connection: a.(gobot.Connection), + connection: a, high: false, Commander: gobot.NewCommander(), } @@ -49,10 +49,6 @@ func NewLedDriver(a PwmDigitalWriter, name string, pin string) *LedDriver { return l } -func (l *LedDriver) adaptor() PwmDigitalWriter { - return l.Connection().(PwmDigitalWriter) -} - // Start starts the LedDriver. Returns true on successful start of the driver func (l *LedDriver) Start() (errs []error) { return } @@ -61,7 +57,7 @@ func (l *LedDriver) Halt() (errs []error) { return } func (l *LedDriver) Name() string { return l.name } func (l *LedDriver) Pin() string { return l.pin } -func (l *LedDriver) Connection() gobot.Connection { return l.connection } +func (l *LedDriver) Connection() gobot.Connection { return l.connection.(gobot.Connection) } // State return true if the led is On and false if the led is Off func (l *LedDriver) State() bool { @@ -100,9 +96,12 @@ func (l *LedDriver) Toggle() (err error) { // Brightness sets the led to the specified level of brightness func (l *LedDriver) Brightness(level byte) (err error) { - return l.adaptor().PwmWrite(l.Pin(), level) + if writer, ok := l.connection.(PwmWriter); ok { + return writer.PwmWrite(l.Pin(), level) + } + return ErrPwmWriteUnsupported } func (l *LedDriver) changeState(level byte) (err error) { - return l.adaptor().DigitalWrite(l.Pin(), level) + return l.connection.DigitalWrite(l.Pin(), level) } diff --git a/platforms/gpio/makey_button_driver.go b/platforms/gpio/makey_button_driver.go index d5caaeb8d..ac4eab7cb 100644 --- a/platforms/gpio/makey_button_driver.go +++ b/platforms/gpio/makey_button_driver.go @@ -12,7 +12,7 @@ var _ gobot.Driver = (*MakeyButtonDriver)(nil) type MakeyButtonDriver struct { name string pin string - connection gobot.Connection + connection DigitalReader Active bool data []int interval time.Duration @@ -23,7 +23,7 @@ type MakeyButtonDriver struct { func NewMakeyButtonDriver(a DigitalReader, name string, pin string, v ...time.Duration) *MakeyButtonDriver { m := &MakeyButtonDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, pin: pin, Active: false, Eventer: gobot.NewEventer(), @@ -34,20 +34,16 @@ func NewMakeyButtonDriver(a DigitalReader, name string, pin string, v ...time.Du m.interval = v[0] } - m.AddEvent("error") - m.AddEvent("push") - m.AddEvent("release") + m.AddEvent(Error) + m.AddEvent(Push) + m.AddEvent(Release) return m } func (b *MakeyButtonDriver) Name() string { return b.name } func (b *MakeyButtonDriver) Pin() string { return b.pin } -func (b *MakeyButtonDriver) Connection() gobot.Connection { return b.connection } - -func (b *MakeyButtonDriver) adaptor() DigitalReader { - return b.Connection().(DigitalReader) -} +func (b *MakeyButtonDriver) Connection() gobot.Connection { return b.connection.(gobot.Connection) } // Starts the MakeyButtonDriver and reads the state of the button at the given Driver.Interval(). // Returns true on successful start of the driver. @@ -59,17 +55,17 @@ func (m *MakeyButtonDriver) Start() (errs []error) { state := 0 go func() { for { - newValue, err := m.readState() + newValue, err := m.connection.DigitalRead(m.Pin()) if err != nil { - gobot.Publish(m.Event("error"), err) + gobot.Publish(m.Event(Error), err) } else if newValue != state && newValue != -1 { state = newValue if newValue == 0 { m.Active = true - gobot.Publish(m.Event("push"), newValue) + gobot.Publish(m.Event(Push), newValue) } else { m.Active = false - gobot.Publish(m.Event("release"), newValue) + gobot.Publish(m.Event(Release), newValue) } } } @@ -80,7 +76,3 @@ func (m *MakeyButtonDriver) Start() (errs []error) { // Halt returns true on a successful halt of the driver func (m *MakeyButtonDriver) Halt() (errs []error) { return } - -func (m *MakeyButtonDriver) readState() (val int, err error) { - return m.adaptor().DigitalRead(m.Pin()) -} diff --git a/platforms/gpio/motor_driver.go b/platforms/gpio/motor_driver.go index 3cd11a057..9773a6a9a 100644 --- a/platforms/gpio/motor_driver.go +++ b/platforms/gpio/motor_driver.go @@ -9,7 +9,7 @@ var _ gobot.Driver = (*MotorDriver)(nil) // Represents a Motor type MotorDriver struct { name string - connection gobot.Connection + connection DigitalWriter SpeedPin string SwitchPin string DirectionPin string @@ -21,11 +21,11 @@ type MotorDriver struct { CurrentDirection string } -// NewMotorDriver return a new MotorDriver given a PwmDigitalWriter, name and pin -func NewMotorDriver(a PwmDigitalWriter, name string) *MotorDriver { +// NewMotorDriver return a new MotorDriver given a DigitalWriter, name and pin +func NewMotorDriver(a DigitalWriter, name string) *MotorDriver { return &MotorDriver{ name: name, - connection: a.(gobot.Adaptor), + connection: a, CurrentState: 0, CurrentSpeed: 0, CurrentMode: "digital", @@ -34,11 +34,7 @@ func NewMotorDriver(a PwmDigitalWriter, name string) *MotorDriver { } func (m *MotorDriver) Name() string { return m.name } -func (m *MotorDriver) Connection() gobot.Connection { return m.connection } - -func (m *MotorDriver) adaptor() PwmDigitalWriter { - return m.Connection().(PwmDigitalWriter) -} +func (m *MotorDriver) Connection() gobot.Connection { return m.connection.(gobot.Connection) } // Start starts the MotorDriver. Returns true on successful start of the driver func (m *MotorDriver) Start() (errs []error) { return } @@ -104,9 +100,12 @@ func (m *MotorDriver) Toggle() (err error) { // Speed sets the speed of the motor func (m *MotorDriver) Speed(value byte) (err error) { - m.CurrentMode = "analog" - m.CurrentSpeed = value - return m.adaptor().PwmWrite(m.SpeedPin, value) + if writer, ok := m.connection.(PwmWriter); ok { + m.CurrentMode = "analog" + m.CurrentSpeed = value + return writer.PwmWrite(m.SpeedPin, value) + } + return ErrPwmWriteUnsupported } // Forward sets the forward pin to the specified speed @@ -145,7 +144,7 @@ func (m *MotorDriver) Direction(direction string) (err error) { } else { level = 0 } - err = m.adaptor().DigitalWrite(m.DirectionPin, level) + err = m.connection.DigitalWrite(m.DirectionPin, level) } else { var forwardLevel, backwardLevel byte switch direction { @@ -159,11 +158,11 @@ func (m *MotorDriver) Direction(direction string) (err error) { forwardLevel = 0 backwardLevel = 0 } - err = m.adaptor().DigitalWrite(m.ForwardPin, forwardLevel) + err = m.connection.DigitalWrite(m.ForwardPin, forwardLevel) if err != nil { return } - err = m.adaptor().DigitalWrite(m.BackwardPin, backwardLevel) + err = m.connection.DigitalWrite(m.BackwardPin, backwardLevel) if err != nil { return } @@ -201,7 +200,7 @@ func (m *MotorDriver) changeState(state byte) (err error) { err = m.Direction("none") } } else { - err = m.adaptor().DigitalWrite(m.SpeedPin, state) + err = m.connection.DigitalWrite(m.SpeedPin, state) } return diff --git a/platforms/gpio/servo_driver.go b/platforms/gpio/servo_driver.go index 2d0383ad6..c7d2bbcb0 100644 --- a/platforms/gpio/servo_driver.go +++ b/platforms/gpio/servo_driver.go @@ -12,7 +12,7 @@ var _ gobot.Driver = (*ServoDriver)(nil) type ServoDriver struct { name string pin string - connection gobot.Connection + connection ServoWriter gobot.Commander CurrentAngle byte } @@ -24,10 +24,10 @@ type ServoDriver struct { // "Min" - See ServoDriver.Min // "Center" - See ServoDriver.Center // "Max" - See ServoDriver.Max -func NewServoDriver(a Servo, name string, pin string) *ServoDriver { +func NewServoDriver(a ServoWriter, name string, pin string) *ServoDriver { s := &ServoDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, pin: pin, Commander: gobot.NewCommander(), CurrentAngle: 0, @@ -53,10 +53,7 @@ func NewServoDriver(a Servo, name string, pin string) *ServoDriver { func (s *ServoDriver) Name() string { return s.name } func (s *ServoDriver) Pin() string { return s.pin } -func (s *ServoDriver) Connection() gobot.Connection { return s.connection } -func (s *ServoDriver) adaptor() Servo { - return s.Connection().(Servo) -} +func (s *ServoDriver) Connection() gobot.Connection { return s.connection.(gobot.Connection) } // Start starts the ServoDriver. Returns true on successful start of the driver. func (s *ServoDriver) Start() (errs []error) { return } @@ -64,18 +61,13 @@ func (s *ServoDriver) Start() (errs []error) { return } // Halt halts the ServoDriver. Returns true on successful halt of the driver. func (s *ServoDriver) Halt() (errs []error) { return } -// InitServo initializes the ServoDriver on platforms which require an explicit initialization. -func (s *ServoDriver) InitServo() (err error) { - return s.adaptor().InitServo() -} - // Move sets the servo to the specified angle func (s *ServoDriver) Move(angle uint8) (err error) { if !(angle >= 0 && angle <= 180) { return errors.New("Servo angle must be an integer between 0-180") } s.CurrentAngle = angle - return s.adaptor().ServoWrite(s.Pin(), s.angleToSpan(angle)) + return s.connection.ServoWrite(s.Pin(), s.angleToSpan(angle)) } // Min sets the servo to it's minimum position diff --git a/platforms/gpio/servo_driver_test.go b/platforms/gpio/servo_driver_test.go index a888fcacf..0525e781b 100644 --- a/platforms/gpio/servo_driver_test.go +++ b/platforms/gpio/servo_driver_test.go @@ -43,8 +43,3 @@ func TestServoDriverCenter(t *testing.T) { d.Center() gobot.Assert(t, d.CurrentAngle, uint8(90)) } - -func TestServoDriverInitServo(t *testing.T) { - d := initTestServoDriver() - d.InitServo() -} diff --git a/platforms/gpio/test_helper.go b/platforms/gpio/test_helper.go index f75587270..4a1c4501e 100644 --- a/platforms/gpio/test_helper.go +++ b/platforms/gpio/test_helper.go @@ -5,11 +5,9 @@ type gpioTestAdaptor struct { port string } -func (t *gpioTestAdaptor) AnalogWrite(string, byte) (err error) { return nil } func (t *gpioTestAdaptor) DigitalWrite(string, byte) (err error) { return nil } func (t *gpioTestAdaptor) ServoWrite(string, byte) (err error) { return nil } func (t *gpioTestAdaptor) PwmWrite(string, byte) (err error) { return nil } -func (t *gpioTestAdaptor) InitServo() (err error) { return nil } func (t *gpioTestAdaptor) AnalogRead(string) (val int, err error) { return 99, nil } diff --git a/platforms/gpio/utils.go b/platforms/gpio/utils.go deleted file mode 100644 index 3b7e014ea..000000000 --- a/platforms/gpio/utils.go +++ /dev/null @@ -1,33 +0,0 @@ -package gpio - -type PwmDigitalWriter interface { - DigitalWriter - Pwm -} -type DirectPin interface { - DigitalWriter - DigitalReader - Pwm - Servo - AnalogWriter - AnalogReader -} -type Pwm interface { - PwmWrite(string, byte) (err error) -} -type Servo interface { - InitServo() (err error) - ServoWrite(string, byte) (err error) -} -type AnalogWriter interface { - AnalogWrite(string, byte) (err error) -} -type AnalogReader interface { - AnalogRead(string) (val int, err error) -} -type DigitalWriter interface { - DigitalWrite(string, byte) (err error) -} -type DigitalReader interface { - DigitalRead(string) (val int, err error) -} From 89f3f53e0924a9e06b2af327d911a3918c835ded Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 29 Nov 2014 11:51:16 -0800 Subject: [PATCH 2/4] Update platforms for new gpio interfaces --- platforms/beaglebone/beaglebone_adaptor.go | 17 +++++++-------- .../beaglebone/beaglebone_adaptor_test.go | 15 ------------- platforms/digispark/digispark_adaptor.go | 16 +++++--------- platforms/digispark/digispark_adaptor_test.go | 2 -- platforms/firmata/firmata_adaptor.go | 18 +++++++--------- platforms/firmata/firmata_adaptor_test.go | 10 +-------- platforms/intel-iot/edison/edison_adaptor.go | 21 ++++++------------- .../intel-iot/edison/edison_adaptor_test.go | 7 ------- platforms/raspi/raspi_adaptor.go | 9 ++++---- platforms/spark/spark_core_adaptor.go | 6 ++++++ 10 files changed, 36 insertions(+), 85 deletions(-) diff --git a/platforms/beaglebone/beaglebone_adaptor.go b/platforms/beaglebone/beaglebone_adaptor.go index 41cf96822..bf7218312 100644 --- a/platforms/beaglebone/beaglebone_adaptor.go +++ b/platforms/beaglebone/beaglebone_adaptor.go @@ -11,11 +11,18 @@ import ( "strings" "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot/platforms/gpio" "github.com/hybridgroup/gobot/sysfs" ) var _ gobot.Adaptor = (*BeagleboneAdaptor)(nil) +var _ gpio.DigitalReader = (*BeagleboneAdaptor)(nil) +var _ gpio.DigitalWriter = (*BeagleboneAdaptor)(nil) +var _ gpio.AnalogReader = (*BeagleboneAdaptor)(nil) +var _ gpio.PwmWriter = (*BeagleboneAdaptor)(nil) +var _ gpio.ServoWriter = (*BeagleboneAdaptor)(nil) + var slots = "/sys/devices/bone_capemgr.*" var ocp = "/sys/devices/ocp.*" var usrLed = "/sys/devices/ocp.3/gpio-leds.8/leds/beaglebone:green:" @@ -190,11 +197,6 @@ func (b *BeagleboneAdaptor) PwmWrite(pin string, val byte) (err error) { return b.pwmWrite(pin, val) } -// InitServo starts servo (not yet implemented) -func (b *BeagleboneAdaptor) InitServo() (err error) { - return errors.New("InitServo is not yet implemented") -} - // ServoWrite writes scaled value to servo in specified pin func (b *BeagleboneAdaptor) ServoWrite(pin string, val byte) (err error) { i, err := b.pwmPin(pin) @@ -257,11 +259,6 @@ func (b *BeagleboneAdaptor) AnalogRead(pin string) (val int, err error) { return } -// AnalogWrite writes an analog value to specified pin -func (b *BeagleboneAdaptor) AnalogWrite(pin string, val byte) (err error) { - return b.pwmWrite(pin, val) -} - // I2cStart starts a i2c device in specified address func (b *BeagleboneAdaptor) I2cStart(address byte) (err error) { b.i2cDevice, err = sysfs.NewI2cDevice("/dev/i2c-1", address) diff --git a/platforms/beaglebone/beaglebone_adaptor_test.go b/platforms/beaglebone/beaglebone_adaptor_test.go index a310a0729..fe6f92609 100644 --- a/platforms/beaglebone/beaglebone_adaptor_test.go +++ b/platforms/beaglebone/beaglebone_adaptor_test.go @@ -60,18 +60,6 @@ func TestBeagleboneAdaptor(t *testing.T) { "156862", ) - a.AnalogWrite("P9_14", 175) - gobot.Assert( - t, - fs.Files["/sys/devices/ocp.3/pwm_test_P9_14.5/period"].Contents, - "500000", - ) - gobot.Assert( - t, - fs.Files["/sys/devices/ocp.3/pwm_test_P9_14.5/duty"].Contents, - "156862", - ) - a.ServoWrite("P9_14", 100) gobot.Assert( t, @@ -117,7 +105,4 @@ func TestBeagleboneAdaptor(t *testing.T) { gobot.Assert(t, data, []byte{0x00, 0x01}) gobot.Assert(t, len(a.Finalize()), 0) - - gobot.Assert(t, a.InitServo(), errors.New("InitServo is not yet implemented")) - } diff --git a/platforms/digispark/digispark_adaptor.go b/platforms/digispark/digispark_adaptor.go index bb75cb1b8..0db3b8e44 100644 --- a/platforms/digispark/digispark_adaptor.go +++ b/platforms/digispark/digispark_adaptor.go @@ -6,10 +6,15 @@ import ( "strconv" "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot/platforms/gpio" ) var _ gobot.Adaptor = (*DigisparkAdaptor)(nil) +var _ gpio.DigitalWriter = (*DigisparkAdaptor)(nil) +var _ gpio.PwmWriter = (*DigisparkAdaptor)(nil) +var _ gpio.ServoWriter = (*DigisparkAdaptor)(nil) + type DigisparkAdaptor struct { name string littleWire lw @@ -61,12 +66,6 @@ func (d *DigisparkAdaptor) DigitalWrite(pin string, level byte) (err error) { return } -// DigitalRead (not yet implemented) -func (d *DigisparkAdaptor) DigitalRead(pin string) (val int, err error) { - err = errors.New("DigitalRead is not yet implemented") - return -} - // PwmWrite updates pwm pin with sent value func (d *DigisparkAdaptor) PwmWrite(pin string, value byte) (err error) { if d.pwm == false { @@ -84,11 +83,6 @@ func (d *DigisparkAdaptor) PwmWrite(pin string, value byte) (err error) { return } -// InitServo (not yet implemented) -func (d *DigisparkAdaptor) InitServo() (err error) { - return errors.New("InitServo is not yet implemented") -} - // ServoWrite updates servo location with specified angle func (d *DigisparkAdaptor) ServoWrite(pin string, angle uint8) (err error) { if d.servo == false { diff --git a/platforms/digispark/digispark_adaptor_test.go b/platforms/digispark/digispark_adaptor_test.go index 420d88018..873d8e0b5 100644 --- a/platforms/digispark/digispark_adaptor_test.go +++ b/platforms/digispark/digispark_adaptor_test.go @@ -66,8 +66,6 @@ func TestDigisparkAdaptorFinalize(t *testing.T) { func TestDigisparkAdaptorIO(t *testing.T) { a := initTestDigisparkAdaptor() - a.InitServo() - a.DigitalRead("1") a.DigitalWrite("0", uint8(1)) gobot.Assert(t, a.littleWire.(*mock).pin, uint8(0)) gobot.Assert(t, a.littleWire.(*mock).state, uint8(1)) diff --git a/platforms/firmata/firmata_adaptor.go b/platforms/firmata/firmata_adaptor.go index 8ba707141..92d32b4db 100644 --- a/platforms/firmata/firmata_adaptor.go +++ b/platforms/firmata/firmata_adaptor.go @@ -1,18 +1,24 @@ package firmata import ( - "errors" "fmt" "io" "strconv" "time" "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot/platforms/gpio" "github.com/tarm/goserial" ) var _ gobot.Adaptor = (*FirmataAdaptor)(nil) +var _ gpio.DigitalReader = (*FirmataAdaptor)(nil) +var _ gpio.DigitalWriter = (*FirmataAdaptor)(nil) +var _ gpio.AnalogReader = (*FirmataAdaptor)(nil) +var _ gpio.PwmWriter = (*FirmataAdaptor)(nil) +var _ gpio.ServoWriter = (*FirmataAdaptor)(nil) + type FirmataAdaptor struct { name string port string @@ -88,11 +94,6 @@ func (f *FirmataAdaptor) Finalize() (errs []error) { func (f *FirmataAdaptor) Port() string { return f.port } func (f *FirmataAdaptor) Name() string { return f.name } -// InitServo (not yet implemented) -func (f *FirmataAdaptor) InitServo() (err error) { - return errors.New("InitServo is not yet implemented") -} - // ServoWrite sets angle form 0 to 360 to specified servo pin func (f *FirmataAdaptor) ServoWrite(pin string, angle byte) (err error) { p, err := strconv.Atoi(pin) @@ -205,11 +206,6 @@ func (f *FirmataAdaptor) AnalogRead(pin string) (val int, err error) { return -1, nil } -// AnalogWrite writes value to ananlog pin -func (f *FirmataAdaptor) AnalogWrite(pin string, level byte) (err error) { - return f.PwmWrite(pin, level) -} - // digitalPin converts pin number to digital mapping func (f *FirmataAdaptor) digitalPin(pin int) int { return pin + 14 diff --git a/platforms/firmata/firmata_adaptor_test.go b/platforms/firmata/firmata_adaptor_test.go index cf1088f3c..ad65d575d 100644 --- a/platforms/firmata/firmata_adaptor_test.go +++ b/platforms/firmata/firmata_adaptor_test.go @@ -48,11 +48,6 @@ func TestFirmataAdaptorConnect(t *testing.T) { gobot.Assert(t, a.connect(a), nil) } -func TestFirmataAdaptorInitServo(t *testing.T) { - a := initTestFirmataAdaptor() - a.InitServo() -} - func TestFirmataAdaptorServoWrite(t *testing.T) { a := initTestFirmataAdaptor() a.ServoWrite("1", 50) @@ -106,10 +101,7 @@ func TestFirmataAdaptorAnalogRead(t *testing.T) { val, _ = a.AnalogRead(pinNumber) gobot.Assert(t, val, 133) } -func TestFirmataAdaptorAnalogWrite(t *testing.T) { - a := initTestFirmataAdaptor() - a.AnalogWrite("1", 50) -} + func TestFirmataAdaptorI2cStart(t *testing.T) { a := initTestFirmataAdaptor() a.I2cStart(0x00) diff --git a/platforms/intel-iot/edison/edison_adaptor.go b/platforms/intel-iot/edison/edison_adaptor.go index 84fcc69b0..e282de987 100644 --- a/platforms/intel-iot/edison/edison_adaptor.go +++ b/platforms/intel-iot/edison/edison_adaptor.go @@ -7,11 +7,17 @@ import ( "strconv" "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot/platforms/gpio" "github.com/hybridgroup/gobot/sysfs" ) var _ gobot.Adaptor = (*EdisonAdaptor)(nil) +var _ gpio.DigitalReader = (*EdisonAdaptor)(nil) +var _ gpio.DigitalWriter = (*EdisonAdaptor)(nil) +var _ gpio.AnalogReader = (*EdisonAdaptor)(nil) +var _ gpio.PwmWriter = (*EdisonAdaptor)(nil) + func writeFile(path string, data []byte) (i int, err error) { file, err := sysfs.OpenFile(path, os.O_WRONLY, 0644) defer file.Close() @@ -422,21 +428,6 @@ func (e *EdisonAdaptor) PwmWrite(pin string, val byte) (err error) { return errors.New("Not a PWM pin") } -// AnalogWrite Not Implemented -func (e *EdisonAdaptor) AnalogWrite(string, byte) (err error) { - return errors.New("AnalogWrite is not yet implemented") -} - -// InitServo Not Implemented -func (e *EdisonAdaptor) InitServo() (err error) { - return errors.New("InitServo is not yet implemented") -} - -// ServoWrite Not Implemented -func (e *EdisonAdaptor) ServoWrite(string, byte) (err error) { - return errors.New("ServoWrite is not yet implemented") -} - // AnalogRead returns value from analog reading of specified pin func (e *EdisonAdaptor) AnalogRead(pin string) (val int, err error) { buf, err := readFile( diff --git a/platforms/intel-iot/edison/edison_adaptor_test.go b/platforms/intel-iot/edison/edison_adaptor_test.go index 4915864c0..d87c4b802 100644 --- a/platforms/intel-iot/edison/edison_adaptor_test.go +++ b/platforms/intel-iot/edison/edison_adaptor_test.go @@ -139,10 +139,3 @@ func TestEdisonAdaptorAnalog(t *testing.T) { i, _ := a.AnalogRead("0") gobot.Assert(t, i, 1000) } - -func TestEdisonAdaptorNotImplemented(t *testing.T) { - a, _ := initTestEdisonAdaptor() - gobot.Assert(t, a.AnalogWrite("", 100), errors.New("AnalogWrite is not yet implemented")) - gobot.Assert(t, a.InitServo(), errors.New("InitServo is not yet implemented")) - gobot.Assert(t, a.ServoWrite("", 100), errors.New("ServoWrite is not yet implemented")) -} diff --git a/platforms/raspi/raspi_adaptor.go b/platforms/raspi/raspi_adaptor.go index a3e923472..50ae86370 100644 --- a/platforms/raspi/raspi_adaptor.go +++ b/platforms/raspi/raspi_adaptor.go @@ -10,11 +10,15 @@ import ( "strings" "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot/platforms/gpio" "github.com/hybridgroup/gobot/sysfs" ) var _ gobot.Adaptor = (*RaspiAdaptor)(nil) +var _ gpio.DigitalReader = (*RaspiAdaptor)(nil) +var _ gpio.DigitalWriter = (*RaspiAdaptor)(nil) + var boardRevision = func() (string, string) { cat, _ := exec.Command("cat", "/proc/cpuinfo").Output() grep := exec.Command("grep", "Revision") @@ -221,11 +225,6 @@ func (r *RaspiAdaptor) DigitalWrite(pin string, val byte) (err error) { return sysfsPin.Write(int(val)) } -// PwmWrite Not Implemented -func (r *RaspiAdaptor) PwmWrite(pin string, val byte) (err error) { - return errors.New("PwmWrite is not yet implemented.") -} - // I2cStart starts a i2c device in specified address func (r *RaspiAdaptor) I2cStart(address byte) (err error) { r.i2cDevice, err = sysfs.NewI2cDevice(r.i2cLocation, address) diff --git a/platforms/spark/spark_core_adaptor.go b/platforms/spark/spark_core_adaptor.go index 95fbeaf44..0511e38ab 100644 --- a/platforms/spark/spark_core_adaptor.go +++ b/platforms/spark/spark_core_adaptor.go @@ -9,10 +9,16 @@ import ( "net/url" "github.com/hybridgroup/gobot" + "github.com/hybridgroup/gobot/platforms/gpio" ) var _ gobot.Adaptor = (*SparkCoreAdaptor)(nil) +var _ gpio.DigitalReader = (*SparkCoreAdaptor)(nil) +var _ gpio.DigitalWriter = (*SparkCoreAdaptor)(nil) +var _ gpio.AnalogReader = (*SparkCoreAdaptor)(nil) +var _ gpio.PwmWriter = (*SparkCoreAdaptor)(nil) + type SparkCoreAdaptor struct { name string DeviceID string From 69a93ad088ec834c25c8c3975fbf982315918fb5 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 29 Nov 2014 12:10:23 -0800 Subject: [PATCH 3/4] Refactor i2c driver interfaces --- platforms/i2c/blinkm_driver.go | 31 +++++++++---------- platforms/i2c/blinkm_driver_test.go | 9 ------ platforms/i2c/hmc6352_driver.go | 29 ++++++------------ platforms/i2c/hmc6352_driver_test.go | 9 ------ platforms/i2c/i2c.go | 21 ++++++++++++- platforms/i2c/mpl115a2_driver.go | 33 +++++++++----------- platforms/i2c/mpl115a2_driver_test.go | 9 ------ platforms/i2c/mpu6050_driver.go | 33 +++++++++----------- platforms/i2c/mpu6050_driver_test.go | 9 ------ platforms/i2c/wiichuck_driver.go | 44 ++++++++++++--------------- platforms/i2c/wiichuck_driver_test.go | 22 +++++--------- 11 files changed, 98 insertions(+), 151 deletions(-) diff --git a/platforms/i2c/blinkm_driver.go b/platforms/i2c/blinkm_driver.go index f5e30f026..9b8dc6a8c 100644 --- a/platforms/i2c/blinkm_driver.go +++ b/platforms/i2c/blinkm_driver.go @@ -10,7 +10,7 @@ var _ gobot.Driver = (*BlinkMDriver)(nil) type BlinkMDriver struct { name string - connection gobot.Connection + connection I2c gobot.Commander } @@ -21,10 +21,10 @@ type BlinkMDriver struct { // Fade - fades the RGB color // FirmwareVersion - returns the version of the current Frimware // Color - returns the color of the LED. -func NewBlinkMDriver(a I2cInterface, name string) *BlinkMDriver { +func NewBlinkMDriver(a I2c, name string) *BlinkMDriver { b := &BlinkMDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, Commander: gobot.NewCommander(), } @@ -52,19 +52,16 @@ func NewBlinkMDriver(a I2cInterface, name string) *BlinkMDriver { return b } func (b *BlinkMDriver) Name() string { return b.name } -func (b *BlinkMDriver) Connection() gobot.Connection { return b.connection } +func (b *BlinkMDriver) Connection() gobot.Connection { return b.connection.(gobot.Connection) } // adaptor returns I2C adaptor -func (b *BlinkMDriver) adaptor() I2cInterface { - return b.Connection().(I2cInterface) -} // Start writes start bytes func (b *BlinkMDriver) Start() (errs []error) { - if err := b.adaptor().I2cStart(0x09); err != nil { + if err := b.connection.I2cStart(0x09); err != nil { return []error{err} } - if err := b.adaptor().I2cWrite([]byte("o")); err != nil { + if err := b.connection.I2cWrite([]byte("o")); err != nil { return []error{err} } return @@ -75,28 +72,28 @@ func (b *BlinkMDriver) Halt() (errs []error) { return } // Rgb sets color using r,g,b params func (b *BlinkMDriver) Rgb(red byte, green byte, blue byte) (err error) { - if err = b.adaptor().I2cWrite([]byte("n")); err != nil { + if err = b.connection.I2cWrite([]byte("n")); err != nil { return } - err = b.adaptor().I2cWrite([]byte{red, green, blue}) + err = b.connection.I2cWrite([]byte{red, green, blue}) return } // Fade removes color using r,g,b params func (b *BlinkMDriver) Fade(red byte, green byte, blue byte) (err error) { - if err = b.adaptor().I2cWrite([]byte("c")); err != nil { + if err = b.connection.I2cWrite([]byte("c")); err != nil { return } - err = b.adaptor().I2cWrite([]byte{red, green, blue}) + err = b.connection.I2cWrite([]byte{red, green, blue}) return } // FirmwareVersion returns version with MAYOR.minor format func (b *BlinkMDriver) FirmwareVersion() (version string, err error) { - if err = b.adaptor().I2cWrite([]byte("Z")); err != nil { + if err = b.connection.I2cWrite([]byte("Z")); err != nil { return } - data, err := b.adaptor().I2cRead(2) + data, err := b.connection.I2cRead(2) if len(data) != 2 || err != nil { return } @@ -105,10 +102,10 @@ func (b *BlinkMDriver) FirmwareVersion() (version string, err error) { // Color returns an array with current rgb color func (b *BlinkMDriver) Color() (color []byte, err error) { - if err = b.adaptor().I2cWrite([]byte("g")); err != nil { + if err = b.connection.I2cWrite([]byte("g")); err != nil { return } - data, err := b.adaptor().I2cRead(3) + data, err := b.connection.I2cRead(3) if len(data) != 3 || err != nil { return []byte{}, err } diff --git a/platforms/i2c/blinkm_driver_test.go b/platforms/i2c/blinkm_driver_test.go index d586cc843..c182f38c5 100644 --- a/platforms/i2c/blinkm_driver_test.go +++ b/platforms/i2c/blinkm_driver_test.go @@ -19,15 +19,6 @@ func initTestBlinkDriverWithStubbedAdaptor() (*BlinkMDriver, *i2cTestAdaptor) { // --------- TESTS -func TestBlinkMDriver(t *testing.T) { - // Does it implement gobot.DriverInterface? - var _ gobot.Driver = (*BlinkMDriver)(nil) - - // Does its adaptor implements the I2cInterface? - driver := initTestBlinkMDriver() - var _ I2cInterface = driver.adaptor() -} - func TestNewBlinkMDriver(t *testing.T) { // Does it return a pointer to an instance of BlinkMDriver? var bm interface{} = NewBlinkMDriver(newI2cTestAdaptor("adaptor"), "bot") diff --git a/platforms/i2c/hmc6352_driver.go b/platforms/i2c/hmc6352_driver.go index feaef44f5..bf0234716 100644 --- a/platforms/i2c/hmc6352_driver.go +++ b/platforms/i2c/hmc6352_driver.go @@ -1,40 +1,31 @@ package i2c -import ( - "errors" - - "github.com/hybridgroup/gobot" -) +import "github.com/hybridgroup/gobot" var _ gobot.Driver = (*HMC6352Driver)(nil) type HMC6352Driver struct { name string - connection gobot.Connection + connection I2c } // NewHMC6352Driver creates a new driver with specified name and i2c interface -func NewHMC6352Driver(a I2cInterface, name string) *HMC6352Driver { +func NewHMC6352Driver(a I2c, name string) *HMC6352Driver { return &HMC6352Driver{ name: name, - connection: a.(gobot.Connection), + connection: a, } } func (h *HMC6352Driver) Name() string { return h.name } -func (h *HMC6352Driver) Connection() gobot.Connection { return h.connection } - -// adaptor returns HMC6352 adaptor -func (h *HMC6352Driver) adaptor() I2cInterface { - return h.Connection().(I2cInterface) -} +func (h *HMC6352Driver) Connection() gobot.Connection { return h.connection.(gobot.Connection) } // Start initialized the hmc6352 func (h *HMC6352Driver) Start() (errs []error) { - if err := h.adaptor().I2cStart(0x21); err != nil { + if err := h.connection.I2cStart(0x21); err != nil { return []error{err} } - if err := h.adaptor().I2cWrite([]byte("A")); err != nil { + if err := h.connection.I2cWrite([]byte("A")); err != nil { return []error{err} } return @@ -45,10 +36,10 @@ func (h *HMC6352Driver) Halt() (errs []error) { return } // Heading returns the current heading func (h *HMC6352Driver) Heading() (heading uint16, err error) { - if err = h.adaptor().I2cWrite([]byte("A")); err != nil { + if err = h.connection.I2cWrite([]byte("A")); err != nil { return } - ret, err := h.adaptor().I2cRead(2) + ret, err := h.connection.I2cRead(2) if err != nil { return } @@ -56,7 +47,7 @@ func (h *HMC6352Driver) Heading() (heading uint16, err error) { heading = (uint16(ret[1]) + uint16(ret[0])*256) / 10 return } else { - err = errors.New("Not enough bytes read") + err = ErrNotEnoughBytes } return } diff --git a/platforms/i2c/hmc6352_driver_test.go b/platforms/i2c/hmc6352_driver_test.go index 024e51466..fc054d192 100644 --- a/platforms/i2c/hmc6352_driver_test.go +++ b/platforms/i2c/hmc6352_driver_test.go @@ -20,15 +20,6 @@ func initTestHMC6352DriverWithStubbedAdaptor() (*HMC6352Driver, *i2cTestAdaptor) // --------- TESTS -func TestHMC6352Driver(t *testing.T) { - // Does it implement gobot.DriverInterface? - var _ gobot.Driver = (*HMC6352Driver)(nil) - - // Does its adaptor implements the I2cInterface? - driver := initTestHMC6352Driver() - var _ I2cInterface = driver.adaptor() -} - func TestNewHMC6352Driver(t *testing.T) { // Does it return a pointer to an instance of HMC6352Driver? var bm interface{} = NewHMC6352Driver(newI2cTestAdaptor("adaptor"), "bot") diff --git a/platforms/i2c/i2c.go b/platforms/i2c/i2c.go index 622ea2f70..5f5bb35c4 100644 --- a/platforms/i2c/i2c.go +++ b/platforms/i2c/i2c.go @@ -1,6 +1,25 @@ package i2c -type I2cInterface interface { +import ( + "errors" + + "github.com/hybridgroup/gobot" +) + +var ( + ErrEncryptedBytes = errors.New("Encrypted bytes") + ErrNotEnoughBytes = errors.New("Not enough bytes read") +) + +const ( + Error = "error" + Joystick = "joystick" + C = "c" + Z = "z" +) + +type I2c interface { + gobot.Adaptor I2cStart(address byte) (err error) I2cRead(len uint) (data []byte, err error) I2cWrite(buf []byte) (err error) diff --git a/platforms/i2c/mpl115a2_driver.go b/platforms/i2c/mpl115a2_driver.go index cd9095f05..87993aaff 100644 --- a/platforms/i2c/mpl115a2_driver.go +++ b/platforms/i2c/mpl115a2_driver.go @@ -26,7 +26,7 @@ const MPL115A2_REGISTER_STARTCONVERSION = 0x12 type MPL115A2Driver struct { name string - connection gobot.Connection + connection I2c interval time.Duration gobot.Eventer A0 float32 @@ -38,10 +38,10 @@ type MPL115A2Driver struct { } // NewMPL115A2Driver creates a new driver with specified name and i2c interface -func NewMPL115A2Driver(a I2cInterface, name string, v ...time.Duration) *MPL115A2Driver { +func NewMPL115A2Driver(a I2c, name string, v ...time.Duration) *MPL115A2Driver { m := &MPL115A2Driver{ name: name, - connection: a.(gobot.Connection), + connection: a, Eventer: gobot.NewEventer(), interval: 10 * time.Millisecond, } @@ -49,17 +49,12 @@ func NewMPL115A2Driver(a I2cInterface, name string, v ...time.Duration) *MPL115A if len(v) > 0 { m.interval = v[0] } - m.AddEvent("error") + m.AddEvent(Error) return m } func (h *MPL115A2Driver) Name() string { return h.name } -func (h *MPL115A2Driver) Connection() gobot.Connection { return h.connection } - -// adaptor returns MPL115A2 adaptor -func (h *MPL115A2Driver) adaptor() I2cInterface { - return h.Connection().(I2cInterface) -} +func (h *MPL115A2Driver) Connection() gobot.Connection { return h.connection.(gobot.Connection) } // Start writes initialization bytes and reads from adaptor // using specified interval to accelerometer andtemperature data @@ -73,20 +68,20 @@ func (h *MPL115A2Driver) Start() (errs []error) { } gobot.Every(h.interval, func() { - if err := h.adaptor().I2cWrite([]byte{MPL115A2_REGISTER_STARTCONVERSION, 0}); err != nil { - gobot.Publish(h.Event("error"), err) + if err := h.connection.I2cWrite([]byte{MPL115A2_REGISTER_STARTCONVERSION, 0}); err != nil { + gobot.Publish(h.Event(Error), err) return } <-time.After(5 * time.Millisecond) - if err := h.adaptor().I2cWrite([]byte{MPL115A2_REGISTER_PRESSURE_MSB}); err != nil { - gobot.Publish(h.Event("error"), err) + if err := h.connection.I2cWrite([]byte{MPL115A2_REGISTER_PRESSURE_MSB}); err != nil { + gobot.Publish(h.Event(Error), err) return } - ret, err := h.adaptor().I2cRead(4) + ret, err := h.connection.I2cRead(4) if err != nil { - gobot.Publish(h.Event("error"), err) + gobot.Publish(h.Event(Error), err) return } if len(ret) == 4 { @@ -114,13 +109,13 @@ func (h *MPL115A2Driver) initialization() (err error) { var coB2 int16 var coC12 int16 - if err = h.adaptor().I2cStart(0x60); err != nil { + if err = h.connection.I2cStart(0x60); err != nil { return } - if err = h.adaptor().I2cWrite([]byte{MPL115A2_REGISTER_A0_COEFF_MSB}); err != nil { + if err = h.connection.I2cWrite([]byte{MPL115A2_REGISTER_A0_COEFF_MSB}); err != nil { return } - ret, err := h.adaptor().I2cRead(8) + ret, err := h.connection.I2cRead(8) if err != nil { return } diff --git a/platforms/i2c/mpl115a2_driver_test.go b/platforms/i2c/mpl115a2_driver_test.go index dc271c5f3..5da3f097f 100644 --- a/platforms/i2c/mpl115a2_driver_test.go +++ b/platforms/i2c/mpl115a2_driver_test.go @@ -19,15 +19,6 @@ func initTestMPL115A2DriverWithStubbedAdaptor() (*MPL115A2Driver, *i2cTestAdapto // --------- TESTS -func TestMPL115A2DriverDriver(t *testing.T) { - // Does it implement gobot.DriverInterface? - var _ gobot.Driver = (*MPL115A2Driver)(nil) - - // Does its adaptor implements the I2cInterface? - driver := initTestMPL115A2Driver() - var _ I2cInterface = driver.adaptor() -} - func TestNewMPL115A2Driver(t *testing.T) { // Does it return a pointer to an instance of MPL115A2Driver? var mpl interface{} = NewMPL115A2Driver(newI2cTestAdaptor("adaptor"), "bot") diff --git a/platforms/i2c/mpu6050_driver.go b/platforms/i2c/mpu6050_driver.go index 0e0d89c29..0c66a6724 100644 --- a/platforms/i2c/mpu6050_driver.go +++ b/platforms/i2c/mpu6050_driver.go @@ -33,7 +33,7 @@ type ThreeDData struct { type MPU6050Driver struct { name string - connection gobot.Connection + connection I2c interval time.Duration Accelerometer ThreeDData Gyroscope ThreeDData @@ -42,10 +42,10 @@ type MPU6050Driver struct { } // NewMPU6050Driver creates a new driver with specified name and i2c interface -func NewMPU6050Driver(a I2cInterface, name string, v ...time.Duration) *MPU6050Driver { +func NewMPU6050Driver(a I2c, name string, v ...time.Duration) *MPU6050Driver { m := &MPU6050Driver{ name: name, - connection: a.(gobot.Connection), + connection: a, interval: 10 * time.Millisecond, Eventer: gobot.NewEventer(), } @@ -54,17 +54,12 @@ func NewMPU6050Driver(a I2cInterface, name string, v ...time.Duration) *MPU6050D m.interval = v[0] } - m.AddEvent("error") + m.AddEvent(Error) return m } func (h *MPU6050Driver) Name() string { return h.name } -func (h *MPU6050Driver) Connection() gobot.Connection { return h.connection } - -// adaptor returns MPU6050 adaptor -func (h *MPU6050Driver) adaptor() I2cInterface { - return h.Connection().(I2cInterface) -} +func (h *MPU6050Driver) Connection() gobot.Connection { return h.connection.(gobot.Connection) } // Start writes initialization bytes and reads from adaptor // using specified interval to accelerometer andtemperature data @@ -74,14 +69,14 @@ func (h *MPU6050Driver) Start() (errs []error) { } gobot.Every(h.interval, func() { - if err := h.adaptor().I2cWrite([]byte{MPU6050_RA_ACCEL_XOUT_H}); err != nil { - gobot.Publish(h.Event("error"), err) + if err := h.connection.I2cWrite([]byte{MPU6050_RA_ACCEL_XOUT_H}); err != nil { + gobot.Publish(h.Event(Error), err) return } - ret, err := h.adaptor().I2cRead(14) + ret, err := h.connection.I2cRead(14) if err != nil { - gobot.Publish(h.Event("error"), err) + gobot.Publish(h.Event(Error), err) return } buf := bytes.NewBuffer(ret) @@ -96,12 +91,12 @@ func (h *MPU6050Driver) Start() (errs []error) { func (h *MPU6050Driver) Halt() (errs []error) { return } func (h *MPU6050Driver) initialize() (err error) { - if err = h.adaptor().I2cStart(0x68); err != nil { + if err = h.connection.I2cStart(0x68); err != nil { return } // setClockSource - if err = h.adaptor().I2cWrite([]byte{MPU6050_RA_PWR_MGMT_1, + if err = h.connection.I2cWrite([]byte{MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, MPU6050_CLOCK_PLL_XGYRO}); err != nil { @@ -109,7 +104,7 @@ func (h *MPU6050Driver) initialize() (err error) { } // setFullScaleGyroRange - if err = h.adaptor().I2cWrite([]byte{MPU6050_GYRO_FS_250, + if err = h.connection.I2cWrite([]byte{MPU6050_GYRO_FS_250, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_LENGTH, MPU6050_GCONFIG_FS_SEL_BIT}); err != nil { @@ -117,7 +112,7 @@ func (h *MPU6050Driver) initialize() (err error) { } // setFullScaleAccelRange - if err = h.adaptor().I2cWrite([]byte{MPU6050_RA_ACCEL_CONFIG, + if err = h.connection.I2cWrite([]byte{MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, MPU6050_ACCEL_FS_2}); err != nil { @@ -125,7 +120,7 @@ func (h *MPU6050Driver) initialize() (err error) { } // setSleepEnabled - if err = h.adaptor().I2cWrite([]byte{MPU6050_RA_PWR_MGMT_1, + if err = h.connection.I2cWrite([]byte{MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, 0}); err != nil { return diff --git a/platforms/i2c/mpu6050_driver_test.go b/platforms/i2c/mpu6050_driver_test.go index 071ff4ac8..2a572fd4f 100644 --- a/platforms/i2c/mpu6050_driver_test.go +++ b/platforms/i2c/mpu6050_driver_test.go @@ -19,15 +19,6 @@ func initTestMPU6050DriverWithStubbedAdaptor() (*MPU6050Driver, *i2cTestAdaptor) // --------- TESTS -func TestMPU6050Driver(t *testing.T) { - // Does it implement gobot.DriverInterface? - var _ gobot.Driver = (*MPU6050Driver)(nil) - - // Does its adaptor implements the I2cInterface? - driver := initTestMPU6050Driver() - var _ I2cInterface = driver.adaptor() -} - func TestNewMPU6050Driver(t *testing.T) { // Does it return a pointer to an instance of MPU6050Driver? var bm interface{} = NewMPU6050Driver(newI2cTestAdaptor("adaptor"), "bot") diff --git a/platforms/i2c/wiichuck_driver.go b/platforms/i2c/wiichuck_driver.go index 9c92dbf79..d97459153 100644 --- a/platforms/i2c/wiichuck_driver.go +++ b/platforms/i2c/wiichuck_driver.go @@ -1,7 +1,6 @@ package i2c import ( - "errors" "time" "github.com/hybridgroup/gobot" @@ -11,7 +10,7 @@ var _ gobot.Driver = (*WiichuckDriver)(nil) type WiichuckDriver struct { name string - connection gobot.Connection + connection I2c interval time.Duration gobot.Eventer joystick map[string]float64 @@ -24,10 +23,10 @@ type WiichuckDriver struct { // "z"- Get's triggered every interval amount of time if the z button is pressed // "c" - Get's triggered every interval amount of time if the c button is pressed // "joystick" - Get's triggered every "interval" amount of time if a joystick event occured, you can access values x, y -func NewWiichuckDriver(a I2cInterface, name string, v ...time.Duration) *WiichuckDriver { +func NewWiichuckDriver(a I2c, name string, v ...time.Duration) *WiichuckDriver { w := &WiichuckDriver{ name: name, - connection: a.(gobot.Connection), + connection: a, interval: 10 * time.Millisecond, Eventer: gobot.NewEventer(), joystick: map[string]float64{ @@ -46,42 +45,37 @@ func NewWiichuckDriver(a I2cInterface, name string, v ...time.Duration) *Wiichuc w.interval = v[0] } - w.AddEvent("z") - w.AddEvent("c") - w.AddEvent("joystick") + w.AddEvent(Z) + w.AddEvent(C) + w.AddEvent(Joystick) return w } func (w *WiichuckDriver) Name() string { return w.name } -func (w *WiichuckDriver) Connection() gobot.Connection { return w.connection } - -// adaptor returns i2c interface adaptor -func (w *WiichuckDriver) adaptor() I2cInterface { - return w.Connection().(I2cInterface) -} +func (w *WiichuckDriver) Connection() gobot.Connection { return w.connection.(gobot.Connection) } // Start initilizes i2c and reads from adaptor // using specified interval to update with new value func (w *WiichuckDriver) Start() (errs []error) { - if err := w.adaptor().I2cStart(0x52); err != nil { + if err := w.connection.I2cStart(0x52); err != nil { return []error{err} } gobot.Every(w.interval, func() { - if err := w.adaptor().I2cWrite([]byte{0x40, 0x00}); err != nil { - gobot.Publish(w.Event("error"), err) + if err := w.connection.I2cWrite([]byte{0x40, 0x00}); err != nil { + gobot.Publish(w.Event(Error), err) return } - if err := w.adaptor().I2cWrite([]byte{0x00}); err != nil { - gobot.Publish(w.Event("error"), err) + if err := w.connection.I2cWrite([]byte{0x00}); err != nil { + gobot.Publish(w.Event(Error), err) return } - newValue, err := w.adaptor().I2cRead(6) + newValue, err := w.connection.I2cRead(6) if err != nil { - gobot.Publish(w.Event("error"), err) + gobot.Publish(w.Event(Error), err) return } if len(newValue) == 6 { if err = w.update(newValue); err != nil { - gobot.Publish(w.Event("error"), err) + gobot.Publish(w.Event(Error), err) return } } @@ -96,7 +90,7 @@ func (w *WiichuckDriver) Halt() (errs []error) { return } // If value is encrypted, warning message is printed func (w *WiichuckDriver) update(value []byte) (err error) { if w.isEncrypted(value) { - return errors.New("Encrypted bytes from wii device!") + return ErrEncryptedBytes } else { w.parse(value) w.adjustOrigins() @@ -140,16 +134,16 @@ func (w *WiichuckDriver) adjustOrigins() { // updateButtons publishes "c" and "x" events if present in data func (w *WiichuckDriver) updateButtons() { if w.data["c"] == 0 { - gobot.Publish(w.Event("c"), true) + gobot.Publish(w.Event(C), true) } if w.data["z"] == 0 { - gobot.Publish(w.Event("z"), true) + gobot.Publish(w.Event(Z), true) } } // updateJoystick publishes event with current x and y values for joystick func (w *WiichuckDriver) updateJoystick() { - gobot.Publish(w.Event("joystick"), map[string]float64{ + gobot.Publish(w.Event(Joystick), map[string]float64{ "x": w.calculateJoystickValue(w.data["sx"], w.joystick["sx_origin"]), "y": w.calculateJoystickValue(w.data["sy"], w.joystick["sy_origin"]), }) diff --git a/platforms/i2c/wiichuck_driver_test.go b/platforms/i2c/wiichuck_driver_test.go index f1044e808..504af6bdf 100644 --- a/platforms/i2c/wiichuck_driver_test.go +++ b/platforms/i2c/wiichuck_driver_test.go @@ -19,14 +19,6 @@ func initTestWiichuckDriverWithStubbedAdaptor() (*WiichuckDriver, *i2cTestAdapto } // --------- TESTS -func TestWiichuckDriver(t *testing.T) { - // Does it implement gobot.DriverInterface? - var _ gobot.Driver = (*WiichuckDriver)(nil) - - // Does its adaptor implements the I2cInterface? - driver := initTestWiichuckDriver() - var _ I2cInterface = driver.adaptor() -} func TestNewWiichuckDriver(t *testing.T) { // Does it return a pointer to an instance of WiichuckDriver? @@ -94,7 +86,7 @@ func TestWiichuckDriverUpdate(t *testing.T) { // - This should be done by WiichuckDriver.updateButtons chann := make(chan bool) - gobot.On(wii.Event("c"), func(data interface{}) { + gobot.On(wii.Event(C), func(data interface{}) { gobot.Assert(t, data, true) chann <- true }) @@ -103,7 +95,7 @@ func TestWiichuckDriverUpdate(t *testing.T) { chann = make(chan bool) wii.update(decryptedValue) - gobot.On(wii.Event("z"), func(data interface{}) { + gobot.On(wii.Event(Z), func(data interface{}) { gobot.Assert(t, data, true) chann <- true }) @@ -118,7 +110,7 @@ func TestWiichuckDriverUpdate(t *testing.T) { "y": float64(0), } - gobot.On(wii.Event("joystick"), func(data interface{}) { + gobot.On(wii.Event(Joystick), func(data interface{}) { gobot.Assert(t, data, expectedData) chann <- true }) @@ -250,7 +242,7 @@ func TestWiichuckDriverUpdateButtons(t *testing.T) { wii.updateButtons() - gobot.On(wii.Event("c"), func(data interface{}) { + gobot.On(wii.Event(C), func(data interface{}) { gobot.Assert(t, true, data) chann <- true }) @@ -264,7 +256,7 @@ func TestWiichuckDriverUpdateButtons(t *testing.T) { wii.updateButtons() - gobot.On(wii.Event("z"), func(data interface{}) { + gobot.On(wii.Event(Z), func(data interface{}) { gobot.Assert(t, true, data) chann <- true }) @@ -288,7 +280,7 @@ func TestWiichuckDriverUpdateJoystick(t *testing.T) { "y": float64(50), } - gobot.On(wii.Event("joystick"), func(data interface{}) { + gobot.On(wii.Event(Joystick), func(data interface{}) { gobot.Assert(t, data, expectedData) chann <- true }) @@ -310,7 +302,7 @@ func TestWiichuckDriverUpdateJoystick(t *testing.T) { "y": float64(7), } - gobot.On(wii.Event("joystick"), func(data interface{}) { + gobot.On(wii.Event(Joystick), func(data interface{}) { gobot.Assert(t, data, expectedData) chann <- true }) From 560ebaf3e0bce2c916127c78869e53ab55e6ff02 Mon Sep 17 00:00:00 2001 From: Adrian Zankich Date: Sat, 29 Nov 2014 12:14:36 -0800 Subject: [PATCH 4/4] Enforce I2c interface --- platforms/beaglebone/beaglebone_adaptor.go | 3 +++ platforms/firmata/firmata_adaptor.go | 3 +++ platforms/intel-iot/edison/edison_adaptor.go | 3 +++ platforms/raspi/raspi_adaptor.go | 3 +++ 4 files changed, 12 insertions(+) diff --git a/platforms/beaglebone/beaglebone_adaptor.go b/platforms/beaglebone/beaglebone_adaptor.go index bf7218312..d8a0da118 100644 --- a/platforms/beaglebone/beaglebone_adaptor.go +++ b/platforms/beaglebone/beaglebone_adaptor.go @@ -12,6 +12,7 @@ import ( "github.com/hybridgroup/gobot" "github.com/hybridgroup/gobot/platforms/gpio" + "github.com/hybridgroup/gobot/platforms/i2c" "github.com/hybridgroup/gobot/sysfs" ) @@ -23,6 +24,8 @@ var _ gpio.AnalogReader = (*BeagleboneAdaptor)(nil) var _ gpio.PwmWriter = (*BeagleboneAdaptor)(nil) var _ gpio.ServoWriter = (*BeagleboneAdaptor)(nil) +var _ i2c.I2c = (*BeagleboneAdaptor)(nil) + var slots = "/sys/devices/bone_capemgr.*" var ocp = "/sys/devices/ocp.*" var usrLed = "/sys/devices/ocp.3/gpio-leds.8/leds/beaglebone:green:" diff --git a/platforms/firmata/firmata_adaptor.go b/platforms/firmata/firmata_adaptor.go index 92d32b4db..3522058df 100644 --- a/platforms/firmata/firmata_adaptor.go +++ b/platforms/firmata/firmata_adaptor.go @@ -8,6 +8,7 @@ import ( "github.com/hybridgroup/gobot" "github.com/hybridgroup/gobot/platforms/gpio" + "github.com/hybridgroup/gobot/platforms/i2c" "github.com/tarm/goserial" ) @@ -19,6 +20,8 @@ var _ gpio.AnalogReader = (*FirmataAdaptor)(nil) var _ gpio.PwmWriter = (*FirmataAdaptor)(nil) var _ gpio.ServoWriter = (*FirmataAdaptor)(nil) +var _ i2c.I2c = (*FirmataAdaptor)(nil) + type FirmataAdaptor struct { name string port string diff --git a/platforms/intel-iot/edison/edison_adaptor.go b/platforms/intel-iot/edison/edison_adaptor.go index e282de987..fec275ed7 100644 --- a/platforms/intel-iot/edison/edison_adaptor.go +++ b/platforms/intel-iot/edison/edison_adaptor.go @@ -8,6 +8,7 @@ import ( "github.com/hybridgroup/gobot" "github.com/hybridgroup/gobot/platforms/gpio" + "github.com/hybridgroup/gobot/platforms/i2c" "github.com/hybridgroup/gobot/sysfs" ) @@ -18,6 +19,8 @@ var _ gpio.DigitalWriter = (*EdisonAdaptor)(nil) var _ gpio.AnalogReader = (*EdisonAdaptor)(nil) var _ gpio.PwmWriter = (*EdisonAdaptor)(nil) +var _ i2c.I2c = (*EdisonAdaptor)(nil) + func writeFile(path string, data []byte) (i int, err error) { file, err := sysfs.OpenFile(path, os.O_WRONLY, 0644) defer file.Close() diff --git a/platforms/raspi/raspi_adaptor.go b/platforms/raspi/raspi_adaptor.go index 50ae86370..30100d1d5 100644 --- a/platforms/raspi/raspi_adaptor.go +++ b/platforms/raspi/raspi_adaptor.go @@ -11,6 +11,7 @@ import ( "github.com/hybridgroup/gobot" "github.com/hybridgroup/gobot/platforms/gpio" + "github.com/hybridgroup/gobot/platforms/i2c" "github.com/hybridgroup/gobot/sysfs" ) @@ -19,6 +20,8 @@ var _ gobot.Adaptor = (*RaspiAdaptor)(nil) var _ gpio.DigitalReader = (*RaspiAdaptor)(nil) var _ gpio.DigitalWriter = (*RaspiAdaptor)(nil) +var _ i2c.I2c = (*RaspiAdaptor)(nil) + var boardRevision = func() (string, string) { cat, _ := exec.Command("cat", "/proc/cpuinfo").Output() grep := exec.Command("grep", "Revision")