diff --git a/docs/tutorials/ble/advertising.mdx b/docs/tutorials/ble/advertising.mdx index 093814d6..51a216c9 100644 --- a/docs/tutorials/ble/advertising.mdx +++ b/docs/tutorials/ble/advertising.mdx @@ -6,12 +6,14 @@ A BLE device can advertise itself for other devices to see it. So in the base fo import ble main: - device := ble.Device.default + adapter := ble.Adapter + peripheral := adapter.peripheral - advertiser := device.advertise - advertiser.start + data := ble.AdvertisementData - advertiser.wait_for_done + peripheral.start_advertise data + sleep --ms=10000 + peripheral.stop_advertise ``` ## Name @@ -22,16 +24,15 @@ Sometimes it can be beneficial to advertise the name of the BLE device. That can import ble main: - device := ble.Device.default + adapter := ble.Adapter + peripheral := adapter.peripheral data := ble.AdvertisementData - --name="Toit device" - - advertiser := device.advertise - advertiser.set_data data - advertiser.start + --name="Toit device" - advertiser.wait_for_done + peripheral.start_advertise data + sleep --ms=10000 + peripheral.stop_advertise ``` The name is included in all advertisements, so power and bandwidth is saved by omitting it. @@ -43,19 +44,19 @@ To signal what services the device implements, service classes can be added to t ```toit import ble -BATTERY_SERVICE ::= ble.uuid 0x180F +BATTERY_SERVICE ::= ble.BleUuid "180F" main: - device := ble.Device.default + adapter := ble.Adapter + peripheral := adapter.peripheral data := ble.AdvertisementData - --service_classes=[BATTERY_SERVICE] + --name="Toit device" + --service_classes=[BATTERY_SERVICE] - advertiser := device.advertise - advertiser.set_data data - advertiser.start - - advertiser.wait_for_done + peripheral.start_advertise data + sleep --ms=10000 + peripheral.stop_advertise ``` @@ -70,22 +71,23 @@ The manufacturer data field is a custom payload that can be sent with an adverti For example, the manufacturer data field can be used to periodically broadcast a sensor value, e.g. the temperature or the GPS location, to make it available to all nearby devices. -In the following example, the values between 0 and 255 are broadcasted incrementally with a new value every 5 seconds. +In the following example, the manufacturer data is simply set to 'toit'. ```toit import ble -INTERVAL ::= Duration --s=1 +BATTERY_SERVICE ::= ble.BleUuid "180F" main: - device := ble.Device.default + adapter := ble.Adapter + peripheral := adapter.peripheral - advertiser := device.advertise - advertiser.start --interval=INTERVAL + data := ble.AdvertisementData + --name="Toit device" + --service_classes=[BATTERY_SERVICE] + --manufacturer_data=#[0xFF, 0xFF, 't', 'o', 'i', 't'] - 256.repeat: - data := ble.AdvertisementData - --manufacturer_data=#[0xFF, 0xFF, it] - advertiser.set_data data - sleep INTERVAL + peripheral.start_advertise data + sleep --ms=1000000 + peripheral.stop_advertise ``` diff --git a/docs/tutorials/ble/client.mdx b/docs/tutorials/ble/client.mdx index bc7a937f..a396e3f0 100644 --- a/docs/tutorials/ble/client.mdx +++ b/docs/tutorials/ble/client.mdx @@ -9,27 +9,31 @@ In order for a BLE device to establish a connection to a remote device, the devi ```toit import ble -import uuid -// Find the address with the service. -find_with_service device/ble.Device service/uuid.Uuid -> ble.Address: - device.scan: | remote_device/ble.RemoteDevice | - if remote_device.data.service_classes.contains service: - return remote_device.address +SCAN_DURATION ::= Duration --s=3 + +find_with_service central/ble.Central service/ble.BleUuid: + central.scan --duration=SCAN_DURATION: | device/ble.RemoteScannedDevice | + if device.data.service_classes.contains service: + return device.address throw "no device found" ``` -With the address available, the connection can be established. In the following example, we use the `find_with_service` function to find a remote device with a battery service and establish a connection to that device. +With the address available, the connection can be established. In the following example, we use the `find_with_service` function to find a remote device with an advertised battery service and establish a connection to that device. Note that the device might also support services that are not explicitly advertised. ```toit -import ble - -BATTERY_SERVICE ::= ble.uuid 0x180F +// The battery service is defined in the Bluetooth specification. +// Devices that implement the battery service should (but don't +// need to) advertise it. +// For custom services use a full 128-bit UUID. +BATTERY_SERVICE ::= ble.uuid "180F" main: - device := ble.Device.default - address := find_with_service device BATTERY_SERVICE - client := device.connect address + adapter := ble.Adapter + central := adapter.central + + address := find_with_service central BATTERY_SERVICE + remote_device := central.connect address ``` ## Reading service characteristics @@ -39,18 +43,34 @@ With the client in place, the battery service can be accessed. The battery servi ```toit import ble -BATTERY_SERVICE ::= ble.uuid 0x180F -BATTERY_LEVEL ::= ble.uuid 0x2A19 +BATTERY_SERVICE ::= ble.BleUuid "180F" +BATTERY_LEVEL ::= ble.BleUuid "2A19" + +SCAN_DURATION ::= Duration --s=3 + +find_with_service central/ble.Central service/ble.BleUuid: + central.scan --duration=SCAN_DURATION: | device/ble.RemoteScannedDevice | + if device.data.service_classes.contains service: + return device.address + throw "no device found" main: - device := ble.Device.default + adapter := ble.Adapter + central := adapter.central - address := find_with_service device BATTERY_SERVICE - client := device.connect address - service := client.read_service BATTERY_SERVICE - value := service.read_value BATTERY_LEVEL + address := find_with_service central BATTERY_SERVICE + remote_device := central.connect address + // Discover the battery service. + services := remote_device.discover_services [BATTERY_SERVICE] + battery_service/ble.RemoteService := services.first - // The battery level is a single-byte characteristic, between 0 and 100. + // Discover the battery level characteristic. + characteristics := battery_service.discover_characteristics [BATTERY_LEVEL] + battery_level_characteristic/ble.RemoteCharacteristic := characteristics.first + + // Read the battery level which is a value between 0 and 100. + value := battery_level_characteristic.read battery_level := value[0] - print "Battery level of $address: $battery_level" + + print "Battery level of $address: $battery_level%" ``` diff --git a/docs/tutorials/ble/scanning.mdx b/docs/tutorials/ble/scanning.mdx index 3cf14ea5..680bd2b7 100644 --- a/docs/tutorials/ble/scanning.mdx +++ b/docs/tutorials/ble/scanning.mdx @@ -1,15 +1,17 @@ # Scanning -To start scanning and for nearby BLE devices, simply call `scan` on the `ble.Device`. The provided block will be called for each scan result: +To start scanning for nearby BLE devices, simply call `scan` on the adapter's +central. The provided block will be called for each scan result: ```toit import ble main: - device := ble.Device.default + adapter := ble.Adapter + central := adapter.central - device.scan: | remote_device/ble.RemoteDevice | - print "Found $remote_device" + central.scan: | device/ble.RemoteScannedDevice | + print "Found $device" ``` Here the scan will run indefinitely. @@ -24,17 +26,18 @@ The following example shows how to scan for 3 seconds for the addresses of remot ```toit import ble -BATTERY_SERVICE ::= ble.uuid 0x180F +BATTERY_SERVICE ::= ble.BleUuid "180F" SCAN_DURATION ::= Duration --s=3 main: - device := ble.Device.default + adapter := ble.Adapter + central := adapter.central addresses := [] - device.scan --duration=SCAN_DURATION: | remote_device/ble.RemoteDevice | - if remote_device.data.service_classes.contains BATTERY_SERVICE: - addresses.add remote_device.address + central.scan --duration=SCAN_DURATION: | device/ble.RemoteScannedDevice | + if device.data.service_classes.contains BATTERY_SERVICE: + addresses.add device.address print addresses ```