From 44de8014c534d2bbd5283dcc4c70329f9477de15 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 28 Feb 2017 19:40:16 +0100 Subject: [PATCH 1/9] microbit: initial implementation for LEDs Signed-off-by: deadprogram --- examples/microbit_led.go | 33 ++++++ platforms/microbit/LICENSE | 13 +++ platforms/microbit/README.md | 42 ++++++++ platforms/microbit/doc.go | 7 ++ platforms/microbit/led_driver.go | 149 ++++++++++++++++++++++++++ platforms/microbit/led_driver_test.go | 23 ++++ 6 files changed, 267 insertions(+) create mode 100644 examples/microbit_led.go create mode 100644 platforms/microbit/LICENSE create mode 100644 platforms/microbit/README.md create mode 100644 platforms/microbit/doc.go create mode 100644 platforms/microbit/led_driver.go create mode 100644 platforms/microbit/led_driver_test.go diff --git a/examples/microbit_led.go b/examples/microbit_led.go new file mode 100644 index 00000000..c0085509 --- /dev/null +++ b/examples/microbit_led.go @@ -0,0 +1,33 @@ +package main + +import ( + "os" + "time" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + ubit := microbit.NewLEDDriver(bleAdaptor) + + work := func() { + ubit.Blank() + gobot.After(1*time.Second, func() { + ubit.WriteText("Hello") + }) + gobot.After(7*time.Second, func() { + ubit.Smile() + }) + } + + robot := gobot.NewRobot("blinkBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{ubit}, + work, + ) + + robot.Start() +} diff --git a/platforms/microbit/LICENSE b/platforms/microbit/LICENSE new file mode 100644 index 00000000..11e7f03c --- /dev/null +++ b/platforms/microbit/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2014-2017 The Hybrid Group + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/platforms/microbit/README.md b/platforms/microbit/README.md new file mode 100644 index 00000000..fb422b45 --- /dev/null +++ b/platforms/microbit/README.md @@ -0,0 +1,42 @@ +# Microbit + +The Microbit is a tiny computer with built-in Bluetooth LE aka Bluetooth 4.0. + +## How to Install +``` +go get -d -u gobot.io/x/gobot/... && go install gobot.io/x/gobot/platforms/microbit +``` + +## How to Use +```go +// code here... +``` + +## How to Connect + +The Microbit is a Bluetooth LE device. + +You need to know the BLE ID of the Microbit that you want to connect to. + +### OSX + +To run any of the Gobot BLE code you must use the `GODEBUG=cgocheck=0` flag in order to get around some of the issues in the CGo-based implementation. + +For example: + + GODEBUG=cgocheck=0 go run examples/microbit_blink.go "BBC micro:bit" + +OSX uses its own Bluetooth ID system which is different from the IDs used on Linux. The code calls thru the XPC interfaces provided by OSX, so as a result does not need to run under sudo. + +### Ubuntu + +On Linux the BLE code will need to run as a root user account. The easiest way to accomplish this is probably to use `go build` to build your program, and then to run the requesting executable using `sudo`. + +For example: + + go build examples/microbit_blink.go + sudo ./microbit_blink "BBC micro:bit" + +### Windows + +Hopefully coming soon... diff --git a/platforms/microbit/doc.go b/platforms/microbit/doc.go new file mode 100644 index 00000000..b06dd141 --- /dev/null +++ b/platforms/microbit/doc.go @@ -0,0 +1,7 @@ +/* +Package microbit contains the Gobot driver for the Microbit. + +For more information refer to the microbit README: +https://github.com/hybridgroup/gobot/blob/master/platforms/microbit/README.md +*/ +package microbit // import "gobot.io/x/gobot/platforms/microbit" diff --git a/platforms/microbit/led_driver.go b/platforms/microbit/led_driver.go new file mode 100644 index 00000000..bd014b64 --- /dev/null +++ b/platforms/microbit/led_driver.go @@ -0,0 +1,149 @@ +package microbit + +import ( + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" +) + +// LEDDriver is the Gobot interface to the Microbit LED +type LEDDriver struct { + name string + connection gobot.Connection + gobot.Eventer +} + +const ( + // BLE services + ledService = "e95dd91d251d470aa062fa1922dfa9a8" + + // BLE characteristics + ledMatrixStateCharacteristic = "e95d7b77251d470aa062fa1922dfa9a8" + ledTextCharacteristic = "e95d93ee251d470aa062fa1922dfa9a8" + ledScrollingDelayCharacteristic = "e95d0d2d251d470aa062fa1922dfa9a8" +) + +// NewLEDDriver creates a Microbit LEDDriver +func NewLEDDriver(a *ble.ClientAdaptor) *LEDDriver { + n := &LEDDriver{ + name: gobot.DefaultName("Microbit LED"), + connection: a, + Eventer: gobot.NewEventer(), + } + + return n +} + +// Connection returns the BLE connection +func (b *LEDDriver) Connection() gobot.Connection { return b.connection } + +// Name returns the Driver Name +func (b *LEDDriver) Name() string { return b.name } + +// SetName sets the Driver Name +func (b *LEDDriver) SetName(n string) { b.name = n } + +// adaptor returns BLE adaptor +func (b *LEDDriver) adaptor() *ble.ClientAdaptor { + return b.Connection().(*ble.ClientAdaptor) +} + +// Start tells driver to get ready to do work +func (b *LEDDriver) Start() (err error) { + return +} + +// Halt stops LED driver (void) +func (b *LEDDriver) Halt() (err error) { + return +} + +// ReadMatrix read the current LED matrix state +func (b *LEDDriver) ReadMatrix() (data []byte, err error) { + data, err = b.adaptor().ReadCharacteristic(ledMatrixStateCharacteristic) + return +} + +// WriteMatrix writes an array of 5 bytes to set the LED matrix +func (b *LEDDriver) WriteMatrix(data []byte) (err error) { + err = b.adaptor().WriteCharacteristic(ledMatrixStateCharacteristic, data) + return +} + +// WriteText writes a text message to the Microbit LED matrix +func (b *LEDDriver) WriteText(msg string) (err error) { + err = b.adaptor().WriteCharacteristic(ledTextCharacteristic, []byte(msg)) + return err +} + +func (b *LEDDriver) ReadScrollingDelay() (delay uint16, err error) { + return +} + +func (b *LEDDriver) WriteScrollingDelay(delay uint16) (err error) { + buf := []byte{byte(delay)} + err = b.adaptor().WriteCharacteristic(ledScrollingDelayCharacteristic, buf) + return +} + +// Blank clears the LEDs on the Microbit +func (b *LEDDriver) Blank() (err error) { + buf := []byte{0x00, 0x00, 0x00, 0x00, 0x00} + err = b.WriteMatrix(buf) + return +} + +// Solid turns on all of the Microbit LEDs +func (b *LEDDriver) Solid() (err error) { + buf := []byte{0x1F, 0x1F, 0x1F, 0x1F, 0x1F} + err = b.WriteMatrix(buf) + return +} + +// UpRightArrow displays an arrow pointing upwards and to the right on the Microbit LEDs +func (b *LEDDriver) UpRightArrow() (err error) { + buf := []byte{0x0F, 0x03, 0x05, 0x09, 0x10} + err = b.WriteMatrix(buf) + return +} + +// UpLeftArrow displays an arrow pointing upwards and to the left on the Microbit LEDs +func (b *LEDDriver) UpLeftArrow() (err error) { + buf := []byte{0x1E, 0x18, 0x14, 0x12, 0x01} + err = b.WriteMatrix(buf) + return +} + +// DownRightArrow displays an arrow pointing down and to the right on the Microbit LEDs +func (b *LEDDriver) DownRightArrow() (err error) { + buf := []byte{0x10, 0x09, 0x05, 0x03, 0x0F} + err = b.WriteMatrix(buf) + return +} + +// DownLeftArrow displays an arrow pointing down and to the left on the Microbit LEDs +func (b *LEDDriver) DownLeftArrow() (err error) { + buf := []byte{0x01, 0x12, 0x14, 0x18, 0x1E} + err = b.WriteMatrix(buf) + return +} + +// Dimond displays a dimond on the Microbit LEDs +func (b *LEDDriver) Dimond() (err error) { + buf := []byte{0x04, 0x0A, 0x11, 0x0A, 0x04} + err = b.WriteMatrix(buf) + return +} + +// Smile displays a smile on the Microbit LEDs +func (b *LEDDriver) Smile() (err error) { + buf := []byte{0x0A, 0x0A, 0x00, 0x11, 0x0E} + err = b.WriteMatrix(buf) + return +} + +// Wink displays a wink on the Microbit LEDs +func (b *LEDDriver) Wink() (err error) { + buf := []byte{0x08, 0x0B, 0x00, 0x11, 0x0E} + err = b.WriteMatrix(buf) + return +} diff --git a/platforms/microbit/led_driver_test.go b/platforms/microbit/led_driver_test.go new file mode 100644 index 00000000..46bb38bc --- /dev/null +++ b/platforms/microbit/led_driver_test.go @@ -0,0 +1,23 @@ +package microbit + +import ( + "strings" + "testing" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/gobottest" + + "gobot.io/x/gobot/platforms/ble" +) + +var _ gobot.Driver = (*LEDDriver)(nil) + +func initTestLEDDriver() *LEDDriver { + d := NewLEDDriver(ble.NewClientAdaptor("D7:99:5A:26:EC:38")) + return d +} + +func TestLEDDriver(t *testing.T) { + d := initTestLEDDriver() + gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit LED"), true) +} From 9634a9822cf6bf6b0bdba065c04c2831bf65afe2 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 28 Feb 2017 20:03:20 +0100 Subject: [PATCH 2/9] microbit: initial implementation for built-in buttons Signed-off-by: deadprogram --- examples/microbit_buttons.go | 33 ++++++++++ platforms/microbit/button_driver.go | 76 ++++++++++++++++++++++++ platforms/microbit/button_driver_test.go | 23 +++++++ platforms/microbit/led_driver.go | 2 +- 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 examples/microbit_buttons.go create mode 100644 platforms/microbit/button_driver.go create mode 100644 platforms/microbit/button_driver_test.go diff --git a/examples/microbit_buttons.go b/examples/microbit_buttons.go new file mode 100644 index 00000000..fc2d6d46 --- /dev/null +++ b/examples/microbit_buttons.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "os" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + ubit := microbit.NewButtonDriver(bleAdaptor) + + work := func() { + ubit.On(microbit.ButtonA, func(data interface{}) { + fmt.Println("button A") + }) + + ubit.On(microbit.ButtonB, func(data interface{}) { + fmt.Println("button B") + }) + } + + robot := gobot.NewRobot("buttonBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{ubit}, + work, + ) + + robot.Start() +} diff --git a/platforms/microbit/button_driver.go b/platforms/microbit/button_driver.go new file mode 100644 index 00000000..70936c15 --- /dev/null +++ b/platforms/microbit/button_driver.go @@ -0,0 +1,76 @@ +package microbit + +import ( + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" +) + +// ButtonDriver is the Gobot driver for the Microbit's built-in buttons +type ButtonDriver struct { + name string + connection gobot.Connection + gobot.Eventer +} + +const ( + // BLE services + buttonService = "e95d9882251d470aa062fa1922dfa9a8" + + // BLE characteristics + buttonACharacteristic = "e95dda90251d470aa062fa1922dfa9a8" + buttonBCharacteristic = "e95dda91251d470aa062fa1922dfa9a8" + + // ButtonA event + ButtonA = "buttonA" + + // ButtonB event + ButtonB = "buttonB" +) + +// NewButtonDriver creates a Microbit ButtonDriver +func NewButtonDriver(a *ble.ClientAdaptor) *ButtonDriver { + n := &ButtonDriver{ + name: gobot.DefaultName("Microbit Button"), + connection: a, + Eventer: gobot.NewEventer(), + } + + n.AddEvent(ButtonA) + n.AddEvent(ButtonB) + + return n +} + +// Connection returns the BLE connection +func (b *ButtonDriver) Connection() gobot.Connection { return b.connection } + +// Name returns the Driver Name +func (b *ButtonDriver) Name() string { return b.name } + +// SetName sets the Driver Name +func (b *ButtonDriver) SetName(n string) { b.name = n } + +// adaptor returns BLE adaptor +func (b *ButtonDriver) adaptor() *ble.ClientAdaptor { + return b.Connection().(*ble.ClientAdaptor) +} + +// Start tells driver to get ready to do work +func (b *ButtonDriver) Start() (err error) { + // subscribe to button A notifications + b.adaptor().Subscribe(buttonACharacteristic, func(data []byte, e error) { + b.Publish(b.Event(ButtonA), nil) + }) + + // subscribe to button B notifications + b.adaptor().Subscribe(buttonBCharacteristic, func(data []byte, e error) { + b.Publish(b.Event(ButtonB), nil) + }) + + return +} + +// Halt stops LED driver (void) +func (b *ButtonDriver) Halt() (err error) { + return +} diff --git a/platforms/microbit/button_driver_test.go b/platforms/microbit/button_driver_test.go new file mode 100644 index 00000000..77363b29 --- /dev/null +++ b/platforms/microbit/button_driver_test.go @@ -0,0 +1,23 @@ +package microbit + +import ( + "strings" + "testing" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/gobottest" + + "gobot.io/x/gobot/platforms/ble" +) + +var _ gobot.Driver = (*ButtonDriver)(nil) + +func initTestButtonDriver() *ButtonDriver { + d := NewButtonDriver(ble.NewClientAdaptor("D7:99:5A:26:EC:38")) + return d +} + +func TestButtonDriver(t *testing.T) { + d := initTestButtonDriver() + gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Button"), true) +} diff --git a/platforms/microbit/led_driver.go b/platforms/microbit/led_driver.go index bd014b64..f693a7a7 100644 --- a/platforms/microbit/led_driver.go +++ b/platforms/microbit/led_driver.go @@ -5,7 +5,7 @@ import ( "gobot.io/x/gobot/platforms/ble" ) -// LEDDriver is the Gobot interface to the Microbit LED +// LEDDriver is the Gobot driver for the Microbit's LED array type LEDDriver struct { name string connection gobot.Connection From ec9de10a105905cc8f722814b6c49699540bdd33 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 28 Feb 2017 20:19:09 +0100 Subject: [PATCH 3/9] microbit: improve button implementation, add integrated example Signed-off-by: deadprogram --- examples/microbit_buttons.go | 4 +-- examples/microbit_buttons_leds.go | 46 +++++++++++++++++++++++++++++ platforms/microbit/button_driver.go | 4 +-- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 examples/microbit_buttons_leds.go diff --git a/examples/microbit_buttons.go b/examples/microbit_buttons.go index fc2d6d46..53dc14c3 100644 --- a/examples/microbit_buttons.go +++ b/examples/microbit_buttons.go @@ -15,11 +15,11 @@ func main() { work := func() { ubit.On(microbit.ButtonA, func(data interface{}) { - fmt.Println("button A") + fmt.Println("button A", data) }) ubit.On(microbit.ButtonB, func(data interface{}) { - fmt.Println("button B") + fmt.Println("button B", data) }) } diff --git a/examples/microbit_buttons_leds.go b/examples/microbit_buttons_leds.go new file mode 100644 index 00000000..7e8e45a2 --- /dev/null +++ b/examples/microbit_buttons_leds.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + "os" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + buttons := microbit.NewButtonDriver(bleAdaptor) + leds := microbit.NewLEDDriver(bleAdaptor) + + work := func() { + buttons.On(microbit.ButtonA, func(data interface{}) { + fmt.Println("a", data) + if data.([]byte)[0] == 1 { + leds.UpLeftArrow() + return + } + + leds.Blank() + }) + + buttons.On(microbit.ButtonB, func(data interface{}) { + fmt.Println("b", data) + if data.([]byte)[0] == 1 { + leds.UpRightArrow() + return + } + + leds.Blank() + }) + } + + robot := gobot.NewRobot("buttonBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{buttons, leds}, + work, + ) + + robot.Start() +} diff --git a/platforms/microbit/button_driver.go b/platforms/microbit/button_driver.go index 70936c15..14871388 100644 --- a/platforms/microbit/button_driver.go +++ b/platforms/microbit/button_driver.go @@ -59,12 +59,12 @@ func (b *ButtonDriver) adaptor() *ble.ClientAdaptor { func (b *ButtonDriver) Start() (err error) { // subscribe to button A notifications b.adaptor().Subscribe(buttonACharacteristic, func(data []byte, e error) { - b.Publish(b.Event(ButtonA), nil) + b.Publish(b.Event(ButtonA), data) }) // subscribe to button B notifications b.adaptor().Subscribe(buttonBCharacteristic, func(data []byte, e error) { - b.Publish(b.Event(ButtonB), nil) + b.Publish(b.Event(ButtonB), data) }) return From 3fdf0639e17a79099e114433229235fba92a6073 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Wed, 1 Mar 2017 01:23:50 +0100 Subject: [PATCH 4/9] microbit: add accelerometer implementation Signed-off-by: deadprogram --- examples/microbit_accelerometer.go | 29 ++++++ examples/microbit_buttons_leds.go | 3 - platforms/microbit/accelerometer_driver.go | 92 +++++++++++++++++++ .../microbit/accelerometer_driver_test.go | 23 +++++ 4 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 examples/microbit_accelerometer.go create mode 100644 platforms/microbit/accelerometer_driver.go create mode 100644 platforms/microbit/accelerometer_driver_test.go diff --git a/examples/microbit_accelerometer.go b/examples/microbit_accelerometer.go new file mode 100644 index 00000000..4da0611b --- /dev/null +++ b/examples/microbit_accelerometer.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "os" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + ubit := microbit.NewAccelerometerDriver(bleAdaptor) + + work := func() { + ubit.On(microbit.Accelerometer, func(data interface{}) { + fmt.Println("Accelerometer", data) + }) + } + + robot := gobot.NewRobot("buttonBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{ubit}, + work, + ) + + robot.Start() +} diff --git a/examples/microbit_buttons_leds.go b/examples/microbit_buttons_leds.go index 7e8e45a2..d65bfccf 100644 --- a/examples/microbit_buttons_leds.go +++ b/examples/microbit_buttons_leds.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "os" "gobot.io/x/gobot" @@ -16,7 +15,6 @@ func main() { work := func() { buttons.On(microbit.ButtonA, func(data interface{}) { - fmt.Println("a", data) if data.([]byte)[0] == 1 { leds.UpLeftArrow() return @@ -26,7 +24,6 @@ func main() { }) buttons.On(microbit.ButtonB, func(data interface{}) { - fmt.Println("b", data) if data.([]byte)[0] == 1 { leds.UpRightArrow() return diff --git a/platforms/microbit/accelerometer_driver.go b/platforms/microbit/accelerometer_driver.go new file mode 100644 index 00000000..e39cc7e5 --- /dev/null +++ b/platforms/microbit/accelerometer_driver.go @@ -0,0 +1,92 @@ +package microbit + +import ( + "bytes" + "encoding/binary" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" +) + +// AccelerometerDriver is the Gobot driver for the Microbit's built-in accelerometer +type AccelerometerDriver struct { + name string + connection gobot.Connection + gobot.Eventer +} + +type RawAccelerometerData struct { + X int16 + Y int16 + Z int16 +} + +type AccelerometerData struct { + X float32 + Y float32 + Z float32 +} + +const ( + // BLE services + accelerometerService = "e95d0753251d470aa062fa1922dfa9a8" + + // BLE characteristics + accelerometerCharacteristic = "e95dca4b251d470aa062fa1922dfa9a8" + + // Accelerometer event + Accelerometer = "accelerometer" +) + +// NewAccelerometerDriver creates a Microbit AccelerometerDriver +func NewAccelerometerDriver(a *ble.ClientAdaptor) *AccelerometerDriver { + n := &AccelerometerDriver{ + name: gobot.DefaultName("Microbit Accelerometer"), + connection: a, + Eventer: gobot.NewEventer(), + } + + n.AddEvent(Accelerometer) + + return n +} + +// Connection returns the BLE connection +func (b *AccelerometerDriver) Connection() gobot.Connection { return b.connection } + +// Name returns the Driver Name +func (b *AccelerometerDriver) Name() string { return b.name } + +// SetName sets the Driver Name +func (b *AccelerometerDriver) SetName(n string) { b.name = n } + +// adaptor returns BLE adaptor +func (b *AccelerometerDriver) adaptor() *ble.ClientAdaptor { + return b.Connection().(*ble.ClientAdaptor) +} + +// Start tells driver to get ready to do work +func (b *AccelerometerDriver) Start() (err error) { + // subscribe to button A notifications + b.adaptor().Subscribe(accelerometerCharacteristic, func(data []byte, e error) { + a := &RawAccelerometerData{X: 0, Y: 0, Z: 0} + + buf := bytes.NewBuffer(data) + binary.Read(buf, binary.LittleEndian, &a.X) + binary.Read(buf, binary.LittleEndian, &a.Y) + binary.Read(buf, binary.LittleEndian, &a.Z) + + result := &AccelerometerData{X: float32(a.X) / 1000.0, + Y: float32(a.Y) / 1000.0, + Z: float32(a.Z) / 1000.0} + + b.Publish(b.Event(Accelerometer), result) + }) + + return +} + +// Halt stops LED driver (void) +func (b *AccelerometerDriver) Halt() (err error) { + return +} diff --git a/platforms/microbit/accelerometer_driver_test.go b/platforms/microbit/accelerometer_driver_test.go new file mode 100644 index 00000000..159d231d --- /dev/null +++ b/platforms/microbit/accelerometer_driver_test.go @@ -0,0 +1,23 @@ +package microbit + +import ( + "strings" + "testing" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/gobottest" + + "gobot.io/x/gobot/platforms/ble" +) + +var _ gobot.Driver = (*AccelerometerDriver)(nil) + +func initTestAccelerometerDriver() *AccelerometerDriver { + d := NewAccelerometerDriver(ble.NewClientAdaptor("D7:99:5A:26:EC:38")) + return d +} + +func TestAccelerometerDriver(t *testing.T) { + d := initTestAccelerometerDriver() + gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Accelerometer"), true) +} From b538f4db80c6f6c08319ad790f210171bbeb109e Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 10 Mar 2017 12:37:32 +0100 Subject: [PATCH 5/9] microbit: update docs Signed-off-by: deadprogram --- platforms/microbit/README.md | 45 ++++++++++++++++++++++++++++++++++-- platforms/microbit/doc.go | 2 +- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/platforms/microbit/README.md b/platforms/microbit/README.md index fb422b45..3203a19a 100644 --- a/platforms/microbit/README.md +++ b/platforms/microbit/README.md @@ -1,6 +1,6 @@ # Microbit -The Microbit is a tiny computer with built-in Bluetooth LE aka Bluetooth 4.0. +The [Microbit](http://microbit.org/) is a tiny computer with built-in Bluetooth LE aka Bluetooth 4.0. ## How to Install ``` @@ -8,8 +8,49 @@ go get -d -u gobot.io/x/gobot/... && go install gobot.io/x/gobot/platforms/micro ``` ## How to Use + +The Gobot platform for the Microbit includes several different drivers, each one corresponding to a different capability: + +- AccelerometerDriver +- ButtonDriver +- LEDDriver + +The following example uses the LEDDriver: + ```go -// code here... +package main + +import ( + "os" + "time" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + ubit := microbit.NewLEDDriver(bleAdaptor) + + work := func() { + ubit.Blank() + gobot.After(1*time.Second, func() { + ubit.WriteText("Hello") + }) + gobot.After(7*time.Second, func() { + ubit.Smile() + }) + } + + robot := gobot.NewRobot("blinkBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{ubit}, + work, + ) + + robot.Start() +} ``` ## How to Connect diff --git a/platforms/microbit/doc.go b/platforms/microbit/doc.go index b06dd141..471bb7ed 100644 --- a/platforms/microbit/doc.go +++ b/platforms/microbit/doc.go @@ -1,5 +1,5 @@ /* -Package microbit contains the Gobot driver for the Microbit. +Package microbit contains the Gobot drivers for the Microbit. For more information refer to the microbit README: https://github.com/hybridgroup/gobot/blob/master/platforms/microbit/README.md From 88a260a221e509de459278aab342a9abbf26746f Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 18 Mar 2017 17:09:43 +0100 Subject: [PATCH 6/9] microbit: add magnetometer driver Signed-off-by: deadprogram --- examples/microbit_magnetometer.go | 29 ++++++ platforms/microbit/README.md | 6 ++ platforms/microbit/accelerometer_driver.go | 5 +- platforms/microbit/magnetometer_driver.go | 93 +++++++++++++++++++ .../microbit/magnetometer_driver_test.go | 23 +++++ 5 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 examples/microbit_magnetometer.go create mode 100644 platforms/microbit/magnetometer_driver.go create mode 100644 platforms/microbit/magnetometer_driver_test.go diff --git a/examples/microbit_magnetometer.go b/examples/microbit_magnetometer.go new file mode 100644 index 00000000..21f7e758 --- /dev/null +++ b/examples/microbit_magnetometer.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "os" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + ubit := microbit.NewMagnetometerDriver(bleAdaptor) + + work := func() { + ubit.On(microbit.Magnetometer, func(data interface{}) { + fmt.Println("Magnetometer", data) + }) + } + + robot := gobot.NewRobot("magnetoBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{ubit}, + work, + ) + + robot.Start() +} diff --git a/platforms/microbit/README.md b/platforms/microbit/README.md index 3203a19a..ef1b71d7 100644 --- a/platforms/microbit/README.md +++ b/platforms/microbit/README.md @@ -7,6 +7,12 @@ The [Microbit](http://microbit.org/) is a tiny computer with built-in Bluetooth go get -d -u gobot.io/x/gobot/... && go install gobot.io/x/gobot/platforms/microbit ``` +You must install the Microbit firmware from [@sandeepmistry] located at [https://github.com/sandeepmistry/node-bbc-microbit](https://github.com/sandeepmistry/node-bbc-microbit) to use the Microbit with Gobot. This firmware is based on the micro:bit template, but with a few changes. + +You can either use the [Gort](https://gort.io) command line tool's `gort microbit` commands, or follow the firmware installation instructions at [https://github.com/sandeepmistry/node-bbc-microbit#flashing-microbit-firmware](https://github.com/sandeepmistry/node-bbc-microbit#flashing-microbit-firmware). + +The source code for the firmware is located at [https://github.com/sandeepmistry/node-bbc-microbit/files/546610/node-bbc-microbit_zip_nrf51_microbit.zip](https://github.com/sandeepmistry/node-bbc-microbit/files/546610/node-bbc-microbit_zip_nrf51_microbit.zip) however you do not need this source code to install the firmware using the installation instructions. + ## How to Use The Gobot platform for the Microbit includes several different drivers, each one corresponding to a different capability: diff --git a/platforms/microbit/accelerometer_driver.go b/platforms/microbit/accelerometer_driver.go index e39cc7e5..c30b8004 100644 --- a/platforms/microbit/accelerometer_driver.go +++ b/platforms/microbit/accelerometer_driver.go @@ -67,7 +67,7 @@ func (b *AccelerometerDriver) adaptor() *ble.ClientAdaptor { // Start tells driver to get ready to do work func (b *AccelerometerDriver) Start() (err error) { - // subscribe to button A notifications + // subscribe to accelerometer notifications b.adaptor().Subscribe(accelerometerCharacteristic, func(data []byte, e error) { a := &RawAccelerometerData{X: 0, Y: 0, Z: 0} @@ -76,7 +76,8 @@ func (b *AccelerometerDriver) Start() (err error) { binary.Read(buf, binary.LittleEndian, &a.Y) binary.Read(buf, binary.LittleEndian, &a.Z) - result := &AccelerometerData{X: float32(a.X) / 1000.0, + result := &AccelerometerData{ + X: float32(a.X) / 1000.0, Y: float32(a.Y) / 1000.0, Z: float32(a.Z) / 1000.0} diff --git a/platforms/microbit/magnetometer_driver.go b/platforms/microbit/magnetometer_driver.go new file mode 100644 index 00000000..af79ba60 --- /dev/null +++ b/platforms/microbit/magnetometer_driver.go @@ -0,0 +1,93 @@ +package microbit + +import ( + "bytes" + "encoding/binary" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" +) + +// MagnetometerDriver is the Gobot driver for the Microbit's built-in magnetometer +type MagnetometerDriver struct { + name string + connection gobot.Connection + gobot.Eventer +} + +type RawMagnetometerData struct { + X int16 + Y int16 + Z int16 +} + +type MagnetometerData struct { + X float32 + Y float32 + Z float32 +} + +const ( + // BLE services + magnetometerService = "e95df2d8251d470aa062fa1922dfa9a8" + + // BLE characteristics + magnetometerCharacteristic = "e95dfb11251d470aa062fa1922dfa9a8" + + // Magnetometer event + Magnetometer = "magnetometer" +) + +// NewMagnetometerDriver creates a Microbit MagnetometerDriver +func NewMagnetometerDriver(a *ble.ClientAdaptor) *MagnetometerDriver { + n := &MagnetometerDriver{ + name: gobot.DefaultName("Microbit Magnetometer"), + connection: a, + Eventer: gobot.NewEventer(), + } + + n.AddEvent(Magnetometer) + + return n +} + +// Connection returns the BLE connection +func (b *MagnetometerDriver) Connection() gobot.Connection { return b.connection } + +// Name returns the Driver Name +func (b *MagnetometerDriver) Name() string { return b.name } + +// SetName sets the Driver Name +func (b *MagnetometerDriver) SetName(n string) { b.name = n } + +// adaptor returns BLE adaptor +func (b *MagnetometerDriver) adaptor() *ble.ClientAdaptor { + return b.Connection().(*ble.ClientAdaptor) +} + +// Start tells driver to get ready to do work +func (b *MagnetometerDriver) Start() (err error) { + // subscribe to magnetometer notifications + b.adaptor().Subscribe(magnetometerCharacteristic, func(data []byte, e error) { + a := &RawMagnetometerData{X: 0, Y: 0, Z: 0} + + buf := bytes.NewBuffer(data) + binary.Read(buf, binary.LittleEndian, &a.X) + binary.Read(buf, binary.LittleEndian, &a.Y) + binary.Read(buf, binary.LittleEndian, &a.Z) + + result := &MagnetometerData{ + X: float32(a.X) / 1000.0, + Y: float32(a.Y) / 1000.0, + Z: float32(a.Z) / 1000.0} + + b.Publish(b.Event(Magnetometer), result) + }) + + return +} + +// Halt stops LED driver (void) +func (b *MagnetometerDriver) Halt() (err error) { + return +} diff --git a/platforms/microbit/magnetometer_driver_test.go b/platforms/microbit/magnetometer_driver_test.go new file mode 100644 index 00000000..20700f97 --- /dev/null +++ b/platforms/microbit/magnetometer_driver_test.go @@ -0,0 +1,23 @@ +package microbit + +import ( + "strings" + "testing" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/gobottest" + + "gobot.io/x/gobot/platforms/ble" +) + +var _ gobot.Driver = (*MagnetometerDriver)(nil) + +func initTestMagnetometerDriver() *MagnetometerDriver { + d := NewMagnetometerDriver(ble.NewClientAdaptor("D7:99:5A:26:EC:38")) + return d +} + +func TestMagnetometerDriver(t *testing.T) { + d := initTestMagnetometerDriver() + gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Magnetometer"), true) +} From 132080f63ac95dfdca10699cfa05c1cb05ae3fb7 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 18 Mar 2017 17:22:17 +0100 Subject: [PATCH 7/9] microbit: add temperature driver Signed-off-by: deadprogram --- examples/microbit_temperature.go | 29 ++++++++ platforms/microbit/temperature_driver.go | 73 +++++++++++++++++++ platforms/microbit/temperature_driver_test.go | 23 ++++++ 3 files changed, 125 insertions(+) create mode 100644 examples/microbit_temperature.go create mode 100644 platforms/microbit/temperature_driver.go create mode 100644 platforms/microbit/temperature_driver_test.go diff --git a/examples/microbit_temperature.go b/examples/microbit_temperature.go new file mode 100644 index 00000000..a481b266 --- /dev/null +++ b/examples/microbit_temperature.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "os" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" + "gobot.io/x/gobot/platforms/microbit" +) + +func main() { + bleAdaptor := ble.NewClientAdaptor(os.Args[1]) + ubit := microbit.NewTemperatureDriver(bleAdaptor) + + work := func() { + ubit.On(microbit.Temperature, func(data interface{}) { + fmt.Println("Temperature", data) + }) + } + + robot := gobot.NewRobot("thermoBot", + []gobot.Connection{bleAdaptor}, + []gobot.Device{ubit}, + work, + ) + + robot.Start() +} diff --git a/platforms/microbit/temperature_driver.go b/platforms/microbit/temperature_driver.go new file mode 100644 index 00000000..0592d448 --- /dev/null +++ b/platforms/microbit/temperature_driver.go @@ -0,0 +1,73 @@ +package microbit + +import ( + "bytes" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/ble" +) + +// TemperatureDriver is the Gobot driver for the Microbit's built-in thermometer +type TemperatureDriver struct { + name string + connection gobot.Connection + gobot.Eventer +} + +const ( + // BLE services + temperatureService = "e95d6100251d470aa062fa1922dfa9a8" + + // BLE characteristics + temperatureCharacteristic = "e95d9250251d470aa062fa1922dfa9a8" + + // Temperature event + Temperature = "temperature" +) + +// NewTemperatureDriver creates a Microbit TemperatureDriver +func NewTemperatureDriver(a *ble.ClientAdaptor) *TemperatureDriver { + n := &TemperatureDriver{ + name: gobot.DefaultName("Microbit Temperature"), + connection: a, + Eventer: gobot.NewEventer(), + } + + n.AddEvent(Temperature) + + return n +} + +// Connection returns the BLE connection +func (b *TemperatureDriver) Connection() gobot.Connection { return b.connection } + +// Name returns the Driver Name +func (b *TemperatureDriver) Name() string { return b.name } + +// SetName sets the Driver Name +func (b *TemperatureDriver) SetName(n string) { b.name = n } + +// adaptor returns BLE adaptor +func (b *TemperatureDriver) adaptor() *ble.ClientAdaptor { + return b.Connection().(*ble.ClientAdaptor) +} + +// Start tells driver to get ready to do work +func (b *TemperatureDriver) Start() (err error) { + // subscribe to temperature notifications + b.adaptor().Subscribe(temperatureCharacteristic, func(data []byte, e error) { + var l int8 + buf := bytes.NewBuffer(data) + val, _ := buf.ReadByte() + l = int8(val) + + b.Publish(b.Event(Temperature), l) + }) + + return +} + +// Halt stops Temperature driver (void) +func (b *TemperatureDriver) Halt() (err error) { + return +} diff --git a/platforms/microbit/temperature_driver_test.go b/platforms/microbit/temperature_driver_test.go new file mode 100644 index 00000000..5604a1ae --- /dev/null +++ b/platforms/microbit/temperature_driver_test.go @@ -0,0 +1,23 @@ +package microbit + +import ( + "strings" + "testing" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/gobottest" + + "gobot.io/x/gobot/platforms/ble" +) + +var _ gobot.Driver = (*TemperatureDriver)(nil) + +func initTestTemperatureDriver() *TemperatureDriver { + d := NewTemperatureDriver(ble.NewClientAdaptor("D7:99:5A:26:EC:38")) + return d +} + +func TestTemperatureDriver(t *testing.T) { + d := initTestTemperatureDriver() + gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Temperature"), true) +} From 5f82e8eb439b0698737a791feaedca4296a33854 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 18 Mar 2017 17:23:38 +0100 Subject: [PATCH 8/9] microbit: add supported driver to README Signed-off-by: deadprogram --- platforms/microbit/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platforms/microbit/README.md b/platforms/microbit/README.md index ef1b71d7..2163299c 100644 --- a/platforms/microbit/README.md +++ b/platforms/microbit/README.md @@ -20,6 +20,8 @@ The Gobot platform for the Microbit includes several different drivers, each one - AccelerometerDriver - ButtonDriver - LEDDriver +- MagnetometerDriver +- TemperatureDriver The following example uses the LEDDriver: From a6f9ba8c283e9a15165b3449cffe5471d59ae8d1 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 18 Mar 2017 17:25:17 +0100 Subject: [PATCH 9/9] microbit: add microbit platform to main README Signed-off-by: deadprogram --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 44bef575..7ee21ddb 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,7 @@ Gobot has a extensible system for connecting to hardware devices. The following - [Leap Motion](https://www.leapmotion.com/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/leapmotion) - [MavLink](http://qgroundcontrol.org/mavlink/start) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/mavlink) - [MegaPi](http://www.makeblock.com/megapi) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/megapi) +- [Microbit](http://microbit.org/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/microbit) - [MQTT](http://mqtt.org/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/mqtt) - [NATS](http://nats.io/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/nats) - [Neurosky](http://neurosky.com/products-markets/eeg-biosensors/hardware/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/neurosky)