├── screen-mobile.png ├── sequence.puml ├── README.md ├── index.html └── sequence-nano33ble.svg /screen-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patterns/web-bluetooth/main/screen-mobile.png -------------------------------------------------------------------------------- /sequence.puml: -------------------------------------------------------------------------------- 1 | @startuml Nano33BLE 2 | hide footbox 3 | skinparam Shadowing false 4 | 5 | participant "User" as UU #CornflowerBlue 6 | participant "Central(Web)" as WW #ADD1B2 7 | box "Nano" 8 | participant "alarmService" as SV #white 9 | participant "alarmCharacteristic" as CH #white 10 | participant "Arduino" as FS << (A,#FFB700) Sys >> order 2 11 | participant "Bluetooth" as BLE << (B,#FFB700) I/O >> order 3 12 | end box 13 | 14 | SV -/ SV :suuid 15 | activate SV #white 16 | CH -/ CH :cuuid,BLERead|BLENotify 17 | activate CH #white 18 | 19 | group setup 20 | autonumber 21 | FS -> BLE :begin() 22 | FS -> BLE :setAdvertisedService(alarmService) 23 | SV -> CH :addCharacteristic(alarmCharacteristic) 24 | FS -> BLE :addService(alarmService) 25 | FS -> CH :writeValue(3) 26 | FS -> BLE :advertise() 27 | autonumber stop 28 | end alt 29 | 30 | loop 31 | FS -\ BLE :central() 32 | BLE --/ FS :BLEDevice 33 | break central absent 34 | FS -/ FS :delay 1 sec 35 | note right 36 | When a central device connection 37 | is not active, we exit the loop after 1000ms. 38 | end note 39 | end break 40 | 41 | UU -> WW :click 42 | WW -// WW :bluetooth.requestDevice() 43 | WW -\\ FS :gatt.connect() 44 | FS --// WW :server 45 | 46 | alt central connected 47 | WW -\\ FS :getPrimaryService(suuid) 48 | FS --// WW :alarmService 49 | WW -\\ SV :getCharacteristic(cuuid) 50 | SV --// WW :alarmCharacteristic 51 | WW -\\ CH :startNotifications() 52 | note left 53 | When the central device sends 54 | the notify request, the Nano 55 | takes 14*2 seconds to establish 56 | the subscription (so any alarms 57 | during this period will not be 58 | published to central.) 59 | end note 60 | FS -/ FS :delay 2 sec 61 | note right 62 | When a central device connection 63 | is active, we start inference after 2000ms. 64 | end note 65 | FS -/ FS :microphone_inference_record 66 | FS -/ FS :run_classifier 67 | FS -\ CH :value() 68 | CH --/ FS :byte[] 69 | alt 70 | else "score crosses threshold" 71 | FS -> CH :writeCharacteristic(1) 72 | CH ->> SV :event 73 | SV ->> BLE :event 74 | BLE ->> WW :event 75 | WW -> UU :display alarm 76 | else "score within threshold" 77 | 78 | FS -> CH :writeCharacteristic(0) 79 | 80 | end alt 81 | end alt 82 | 83 | end loop 84 | 85 | @enduml 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Bluetooth 2 | 3 | ### What is this? 4 | This is a demo of the BLE Notify support on the Nano 33 BLE. 5 | The Nano is the peripheral with the alarm service and alarm characteristic. 6 | Then when you navigate to this static HTML page on your mobile device's Chrome browser, it acts as the Android central role. Waiting for notifications from the Nano. 7 | 8 | ![mobile page](screen-mobile.png) 9 | 10 | ### Quickstart 11 | 0. You need an Edge Impulse project (or [use ours](https://studio.edgeimpulse.com/public/699161/live)) 12 | 1. From Edge Impulse: Deployment, choose the Arduino library for the build target. 13 | 2. Add the resulting (.zip) file as a library in the Arduino workspace: 14 | ```bash 15 | arduino-cli lib install --zip-path ~/path/to/download/ei-.zip 16 | ``` 17 | 3. Find the sketch (.ino) in the library path: 18 | ```bash 19 | ls ~/Arduino/Libraries//examples/nano_ble33_sense/nano_ble33_sense_microphone 20 | ``` 21 | 4. Make your changes for BLE (or [use ours](https://github.com/patterns/certification/blob/28fe69ef87690d60916bce50de26ca7d3f8f3eb2/ace/eep564/proj/nano_ble33_sense_microphone.ino)) 22 | 5. Include the ArduinoBLE library: 23 | ```bash 24 | arduino-cli lib install ArduinoBLE 25 | ``` 26 | 6. Flash the sketch to the Nano: 27 | ```bash 28 | cd ~/Arduino/libraries//examples/nano_ble33_sense && \ 29 | arduino-cli compile --fqbn arduino:mbed_nano:nano33ble nano_ble33_sense_microphone 30 | cd ~/Arduino/libraries//examples/nano_ble33_sense && \ 31 | arduino-cli upload -p /dev/ttyACM0 --fqbn arduino:mbed_nano:nano33ble nano_ble33_sense_microphone 32 | ``` 33 | 7. Start the serial comm to monitor the inference scores: 34 | ```bash 35 | arduino-cli monitor -p /dev/ttyACM0 --fqbn arduino:mbed_nano:nano33ble 36 | ``` 37 | 8. From your mobile device (supports Bluetooth), navigate to this page; it's just static HTML so you can run a local file server (or [use gh-pages](https://patterns.github.io/web-bluetooth/)) 38 | 39 | 40 | ### Configuration 41 | - In our sketch, we define a `THRESHOLD_ALARM` value of 0.6 for alarm scores to meet in order to publish an event. You may want to adjust this for your noise scenarios. 42 | - As the comment suggested, we disable the `EIDSP_QUANTIZE_FILTERBANK` macro to save 10K of memory. 43 | - Also in the comments, we created the `boards.local.txt` to pass the build flag. We had the mbed core used in EI flash_linux.sh steps (other homework), as well as mbed_nano core (for Arduino sketches). So we made two copies of the `boards.local.txt`: 44 | ```bash 45 | cat boards.local.txt 46 | nano33ble.build.extra_flags= -DEI_CLASSIFIER_ALLOCATION_STATIC 47 | cp boards.local.txt ~/.arduino15/packages/arduino/hardware/mbed/3.3.0/ 48 | cp boards.local.txt ~/.arduino15/packages/arduino/hardware/mbed_nano/4.2.4/ 49 | ``` 50 | 51 | ### Caveats 52 | - Inside the Arduino library (.zip), there are two microphone examples. The `_continuous` version does not work with the BLE modified sketch. So double-check which one you are using, if you encounter errors about adjusting the "slices" per window. 53 | - When using the scanner in the nRF Connect app from Nordic Semiconductor, you may not see the Nano peripheral unless you know the MAC address. There must be API calls in the ArduinoBLE library to specify the name to advertise. I didn't understand this at first, and didn't know the MAC address so thought the Nano was not showing in the scan results. 54 | - The notify subscription takes 14 * 2 seconds to initialize (so alarms in that period will not be received by central). 55 | 56 | ### Diagram 57 | ![BLENotify detail](sequence-nano33ble.svg) 58 | 59 | ### Credits 60 | Bluetooth Notifications demo 61 | by [Google](https://github.com/project-idx/templates/tree/main/gemini) 62 | 63 | Nano Bluetooth tutorial 64 | by [Arduino](https://docs.arduino.cc/tutorials/nano-33-ble-sense/ble-device-to-device/) 65 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | EEP564 - Nano BLE 5 | 6 | 129 | 130 | 131 |
132 |
133 |
134 | 135 |
136 |
137 | 138 |
139 |
140 |
141 |
142 | 143 |
144 | 145 |
146 |
147 |
148 | 149 |
150 | 151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |

EEP564 - Nano BLE

159 |
Demo of Nano as peripheral connected to Web Bluetooth in central role.
160 |
161 |
162 |
163 |
164 | 165 |
166 | 167 | 168 | 169 | 173 | -------------------------------------------------------------------------------- /sequence-nano33ble.svg: -------------------------------------------------------------------------------- 1 | NanoalarmServicealarmCharacteristicUserCentral(Web)alarmServicealarmCharacteristicA << Sys >>B << I/O >>UserCentral(Web)alarmServicealarmCharacteristic«Sys»Arduino«I/O»BluetoothalarmServicealarmCharacteristicsuuidcuuid,BLERead|BLENotifysetup1begin()2setAdvertisedService(alarmService)3addCharacteristic(alarmCharacteristic)4addService(alarmService)5writeValue(3)6advertise()loopcentral()BLEDevicebreak[central absent]delay 1 secWhen a central device connectionis not active, we exit the loop after 1000ms.clickbluetooth.requestDevice()gatt.connect()serveralt[central connected]getPrimaryService(suuid)alarmServicegetCharacteristic(cuuid)alarmCharacteristicstartNotifications()When the central device sendsthe notify request, the Nanotakes 14*2 seconds to establishthe subscription (so any alarmsduring this period will not bepublished to central.)delay 2 secWhen a central device connectionis active, we start inference after 2000ms.microphone_inference_recordrun_classifiervalue()byte[]alt["score crosses threshold"]writeCharacteristic(1)eventeventeventdisplay alarm["score within threshold"]writeCharacteristic(0) --------------------------------------------------------------------------------