prototooth/examples/ledcolor/main.go
Ayke van Laethem c034fbca54
all: change NewAdvertisement to DefaultAdvertisement
Instead of attempting to allocate multiple advertisement instances, only
use one by default. If needed, a NewAdvertisement method could be added
in the future for devices that actually do support multiple
advertisements at a time.

The motivation for this change is fix an inconsistency with the nrf51
(which already had the behavior of DefaultAdvertisement) and the
discovery that nrf52 devices also don't seem to support more than one
advertisement instance, even though their API does allow for multiple
instances. But the primary motivation is that for consistency with
hosted systems, it would be best if the nrf port would automatically
re-enable advertisement when a connection is lost (or made).

While BlueZ does support more than one instance, it is implemented by
simply iterating through the active advertisement instances so could
also be implemented by doing that manually. I haven't checked the
behavior of Windows and MacOS - but as always, the API is not yet stable
and can be changed if needed.
2020-06-01 18:09:44 +02:00

87 lines
2.3 KiB
Go

package main
import (
"machine"
"time"
"github.com/tinygo-org/bluetooth"
)
var adapter = bluetooth.DefaultAdapter
// TODO: use atomics to access this value.
var ledColor = [3]byte{0xff, 0x00, 0x00} // start out with red
var leds = [3]machine.Pin{machine.LED_RED, machine.LED_GREEN, machine.LED_BLUE}
var hasColorChange = true
var (
serviceUUID = [16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}
charUUID = [16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}
)
func main() {
println("starting")
adapter.SetEventHandler(handleBluetoothEvents)
must("enable BLE stack", adapter.Enable())
adv := adapter.DefaultAdvertisement()
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "LED colors",
Interval: bluetooth.NewAdvertisementInterval(100),
}))
must("start adv", adv.Start())
var ledColorCharacteristic bluetooth.Characteristic
must("add service", adapter.AddService(&bluetooth.Service{
UUID: bluetooth.NewUUID(serviceUUID),
Characteristics: []bluetooth.CharacteristicConfig{
{
Handle: &ledColorCharacteristic,
UUID: bluetooth.NewUUID(charUUID),
Value: ledColor[:],
Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission,
WriteEvent: func(client bluetooth.Connection, offset int, value []byte) {
if offset != 0 || len(value) != 3 {
return
}
ledColor[0] = value[0]
ledColor[1] = value[1]
ledColor[2] = value[2]
hasColorChange = true
},
},
},
}))
for _, led := range leds {
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
}
for {
for !hasColorChange {
time.Sleep(10 * time.Millisecond)
}
hasColorChange = false
for i, led := range leds {
led.Set(ledColor[i] == 0)
}
}
}
func must(action string, err error) {
if err != nil {
panic("failed to " + action + ": " + err.Error())
}
}
// handleBluetoothEvents prints BLE events as they happen.
func handleBluetoothEvents(evt bluetooth.Event) {
switch evt := evt.(type) {
case *bluetooth.ConnectEvent:
println("evt: connected", evt.Connection)
case *bluetooth.DisconnectEvent:
println("evt: disconnected", evt.Connection)
default:
println("evt: unknown")
}
}