From 10f51fbc1bae848dd7d36e021e6e6a71b5d53f59 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 3 Jun 2021 19:58:50 +0700 Subject: [PATCH 01/24] Bluefruit.setName() from example to use default board name from USB_PRODUCT --- .../examples/DualRoles/dual_bleuart/dual_bleuart.ino | 1 - .../Peripheral/StandardFirmataBLE/StandardFirmataBLE.ino | 1 - .../Peripheral/adv_AdafruitColor/adv_AdafruitColor.ino | 4 ++-- .../examples/Peripheral/adv_advanced/adv_advanced.ino | 1 - .../Bluefruit52Lib/examples/Peripheral/beacon/beacon.ino | 1 - .../Bluefruit52Lib/examples/Peripheral/blemidi/blemidi.ino | 1 - .../Bluefruit52Lib/examples/Peripheral/bleuart/bleuart.ino | 1 - .../examples/Peripheral/bleuart_multi/bleuart_multi.ino | 2 +- .../examples/Peripheral/blinky_ota/blinky_ota.ino | 1 - .../Peripheral/bluefruit_playground/bluefruit_playground.ino | 1 - .../examples/Peripheral/controller/controller.ino | 1 - .../examples/Peripheral/custom_hrm/custom_hrm.ino | 4 ---- .../examples/Peripheral/custom_htm/custom_htm.ino | 1 - .../examples/Peripheral/eddystone_url/eddystone_url.ino | 1 - .../Peripheral/hid_camerashutter/hid_camerashutter.ino | 1 - .../examples/Peripheral/hid_keyboard/hid_keyboard.ino | 1 - .../examples/Peripheral/hid_keyscan/hid_keyscan.ino | 1 - .../examples/Peripheral/hid_mouse/hid_mouse.ino | 1 - .../Peripheral/image_eink_transfer/image_eink_transfer.ino | 2 +- .../examples/Peripheral/image_transfer/image_transfer.ino | 2 +- .../examples/Peripheral/neomatrix/neomatrix.ino | 2 +- .../Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino | 2 +- .../examples/Peripheral/pairing_pin/pairing_pin.ino | 1 - .../examples/Peripheral/rssi_callback/rssi_callback.ino | 1 - .../examples/Peripheral/rssi_poll/rssi_poll.ino | 1 - .../examples/Peripheral/throughput/throughput.ino | 1 - .../Projects/homekit/homekit_lightbulb/homekit_lightbulb.ino | 1 - .../rssi_proximity_central/rssi_proximity_central.ino | 3 --- .../rssi_proximity_peripheral/rssi_proximity_peripheral.ino | 1 - 29 files changed, 7 insertions(+), 35 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/DualRoles/dual_bleuart/dual_bleuart.ino b/libraries/Bluefruit52Lib/examples/DualRoles/dual_bleuart/dual_bleuart.ino index ae11c7e78..e0e1b5538 100644 --- a/libraries/Bluefruit52Lib/examples/DualRoles/dual_bleuart/dual_bleuart.ino +++ b/libraries/Bluefruit52Lib/examples/DualRoles/dual_bleuart/dual_bleuart.ino @@ -42,7 +42,6 @@ void setup() // SRAM usage required by SoftDevice will increase with number of connections Bluefruit.begin(1, 1); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52 duo"); // Callbacks for Peripheral Bluefruit.Periph.setConnectCallback(prph_connect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/StandardFirmataBLE/StandardFirmataBLE.ino b/libraries/Bluefruit52Lib/examples/Peripheral/StandardFirmataBLE/StandardFirmataBLE.ino index 4fcccf7fc..4232732db 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/StandardFirmataBLE/StandardFirmataBLE.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/StandardFirmataBLE/StandardFirmataBLE.ino @@ -790,7 +790,6 @@ void setup() Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); Bluefruit.begin(); - Bluefruit.setName("Bluefruit52"); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values // try to go as fast as possible, could be rejected by some central, increase it if needed diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/adv_AdafruitColor/adv_AdafruitColor.ino b/libraries/Bluefruit52Lib/examples/Peripheral/adv_AdafruitColor/adv_AdafruitColor.ino index 7eb6104e8..2f775bdd1 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/adv_AdafruitColor/adv_AdafruitColor.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/adv_AdafruitColor/adv_AdafruitColor.ino @@ -40,8 +40,8 @@ char nibble_to_hex(uint8_t nibble) { // convert a 4-bit nibble to a hexadecimal void setup() { - Serial.begin(115200); - while ( !Serial ) delay(10); // for nrf52840 with native usb +// Serial.begin(115200); +// while ( !Serial ) delay(10); Serial.println("Bluefruit52 Color Advertising Example"); Serial.println("----------------------------------------\n"); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/adv_advanced/adv_advanced.ino b/libraries/Bluefruit52Lib/examples/Peripheral/adv_advanced/adv_advanced.ino index a6a6917ef..c165c693c 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/adv_advanced/adv_advanced.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/adv_advanced/adv_advanced.ino @@ -36,7 +36,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Set up and start advertising startAdv(); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/beacon/beacon.ino b/libraries/Bluefruit52Lib/examples/Peripheral/beacon/beacon.ino index 60f010821..01444b0db 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/beacon/beacon.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/beacon/beacon.ino @@ -48,7 +48,6 @@ void setup() // off Blue LED for lowest power consumption Bluefruit.autoConnLed(false); Bluefruit.setTxPower(0); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Manufacturer ID is required for Manufacturer Specific Data beacon.setManufacturer(MANUFACTURER_ID); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/blemidi/blemidi.ino b/libraries/Bluefruit52Lib/examples/Peripheral/blemidi/blemidi.ino index d455b8c45..45048a7cd 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/blemidi/blemidi.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/blemidi/blemidi.ino @@ -50,7 +50,6 @@ void setup() Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); Bluefruit.begin(); - Bluefruit.setName("Bluefruit52 MIDI"); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values // Setup the on board blue LED to be enabled on CONNECT diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/bleuart/bleuart.ino b/libraries/Bluefruit52Lib/examples/Peripheral/bleuart/bleuart.ino index dc0bfb52f..48e9b8a02 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/bleuart/bleuart.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/bleuart/bleuart.ino @@ -45,7 +45,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); //Bluefruit.setName(getMcuUniqueID()); // useful testing with multiple central connections Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/bleuart_multi/bleuart_multi.ino b/libraries/Bluefruit52Lib/examples/Peripheral/bleuart_multi/bleuart_multi.ino index a870ef480..43caaa743 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/bleuart_multi/bleuart_multi.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/bleuart_multi/bleuart_multi.ino @@ -37,7 +37,7 @@ void setup() // Initialize Bluefruit with max concurrent connections as Peripheral = 2, Central = 0 Bluefruit.begin(MAX_PRPH_CONNECTION, 0); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); + Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/blinky_ota/blinky_ota.ino b/libraries/Bluefruit52Lib/examples/Peripheral/blinky_ota/blinky_ota.ino index fce828f3f..c9ee0f6c3 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/blinky_ota/blinky_ota.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/blinky_ota/blinky_ota.ino @@ -27,7 +27,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // To be consistent OTA DFU should be added first if it exists bledfu.begin(); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/bluefruit_playground/bluefruit_playground.ino b/libraries/Bluefruit52Lib/examples/Peripheral/bluefruit_playground/bluefruit_playground.ino index a771b9ee9..f07eb8053 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/bluefruit_playground/bluefruit_playground.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/bluefruit_playground/bluefruit_playground.ino @@ -331,7 +331,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(8); // Check bluefruit.h for supported values Bluefruit.setName(DEVICE_NAME); - //Bluefruit.setName(getMcuUniqueID()); // useful testing with multiple central connections Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/controller/controller.ino b/libraries/Bluefruit52Lib/examples/Peripheral/controller/controller.ino index 9835428ec..045cd5374 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/controller/controller.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/controller/controller.ino @@ -38,7 +38,6 @@ void setup(void) Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // To be consistent OTA DFU should be added first if it exists bledfu.begin(); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/custom_hrm/custom_hrm.ino b/libraries/Bluefruit52Lib/examples/Peripheral/custom_hrm/custom_hrm.ino index 7b5a6132c..793731491 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/custom_hrm/custom_hrm.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/custom_hrm/custom_hrm.ino @@ -39,10 +39,6 @@ void setup() Serial.println("Initialise the Bluefruit nRF52 module"); Bluefruit.begin(); - // Set the advertised device name (keep it short!) - Serial.println("Setting Device Name to 'Feather52 HRM'"); - Bluefruit.setName("Bluefruit52 HRM"); - // Set the connect/disconnect callback handlers Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino b/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino index 5d4717ce1..249342a72 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino @@ -42,7 +42,6 @@ void setup() // Initialise the Bluefruit module Serial.println("Initialise the Bluefruit nRF52 module"); Bluefruit.begin(); - Bluefruit.setName("Bluefruit52"); // Set the connect/disconnect callback handlers Bluefruit.Periph.setConnectCallback(connect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/eddystone_url/eddystone_url.ino b/libraries/Bluefruit52Lib/examples/Peripheral/eddystone_url/eddystone_url.ino index e54b3fcf9..79a030975 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/eddystone_url/eddystone_url.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/eddystone_url/eddystone_url.ino @@ -28,7 +28,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Setup the advertising packet startAdv(); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/hid_camerashutter/hid_camerashutter.ino b/libraries/Bluefruit52Lib/examples/Peripheral/hid_camerashutter/hid_camerashutter.ino index da03966d2..4bece77c7 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/hid_camerashutter/hid_camerashutter.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/hid_camerashutter/hid_camerashutter.ino @@ -49,7 +49,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Configure and start DIS (Device Information Service) bledis.setManufacturer("Adafruit Industries"); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyboard/hid_keyboard.ino b/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyboard/hid_keyboard.ino index 3412cfba8..54697f9a3 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyboard/hid_keyboard.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyboard/hid_keyboard.ino @@ -36,7 +36,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Configure and Start Device Information Service bledis.setManufacturer("Adafruit Industries"); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyscan/hid_keyscan.ino b/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyscan/hid_keyscan.ino index 63cdf30a4..ad96e1320 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyscan/hid_keyscan.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyscan/hid_keyscan.ino @@ -54,7 +54,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Configure and Start Device Information Service bledis.setManufacturer("Adafruit Industries"); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/hid_mouse/hid_mouse.ino b/libraries/Bluefruit52Lib/examples/Peripheral/hid_mouse/hid_mouse.ino index 113f8fcb8..5fcc513d4 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/hid_mouse/hid_mouse.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/hid_mouse/hid_mouse.ino @@ -38,7 +38,6 @@ void setup() // HID Device can have a min connection interval of 9*1.25 = 11.25 ms Bluefruit.Periph.setConnInterval(9, 16); // min = 9*1.25=11.25 ms, max = 16*1.25=20ms Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Configure and Start Device Information Service bledis.setManufacturer("Adafruit Industries"); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/image_eink_transfer/image_eink_transfer.ino b/libraries/Bluefruit52Lib/examples/Peripheral/image_eink_transfer/image_eink_transfer.ino index ce96be204..5f4f208e9 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/image_eink_transfer/image_eink_transfer.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/image_eink_transfer/image_eink_transfer.ino @@ -85,7 +85,7 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); + Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/image_transfer/image_transfer.ino b/libraries/Bluefruit52Lib/examples/Peripheral/image_transfer/image_transfer.ino index 6b06ca019..7daeb8157 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/image_transfer/image_transfer.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/image_transfer/image_transfer.ino @@ -152,7 +152,7 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); + Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/neomatrix/neomatrix.ino b/libraries/Bluefruit52Lib/examples/Peripheral/neomatrix/neomatrix.ino index 125a9356a..46c5777c8 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/neomatrix/neomatrix.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/neomatrix/neomatrix.ino @@ -87,7 +87,7 @@ void setup() // Init Bluefruit Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); + Bluefruit.Periph.setConnectCallback(connect_callback); // Configure and Start Device Information Service diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino b/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino index cbca694e7..cf5438def 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino @@ -72,7 +72,7 @@ void setup() // Init Bluefruit Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); + Bluefruit.Periph.setConnectCallback(connect_callback); // To be consistent OTA DFU should be added first if it exists diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/pairing_pin/pairing_pin.ino b/libraries/Bluefruit52Lib/examples/Peripheral/pairing_pin/pairing_pin.ino index 19a714bf1..24e034ecb 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/pairing_pin/pairing_pin.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/pairing_pin/pairing_pin.ino @@ -48,7 +48,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); Serial.println("Setting pairing PIN to: " PAIRING_PIN); Bluefruit.Security.setPIN(PAIRING_PIN); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/rssi_callback/rssi_callback.ino b/libraries/Bluefruit52Lib/examples/Peripheral/rssi_callback/rssi_callback.ino index 1791d1ebc..3b15948c5 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/rssi_callback/rssi_callback.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/rssi_callback/rssi_callback.ino @@ -35,7 +35,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/rssi_poll/rssi_poll.ino b/libraries/Bluefruit52Lib/examples/Peripheral/rssi_poll/rssi_poll.ino index 22f767a7e..6206a79ce 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/rssi_poll/rssi_poll.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/rssi_poll/rssi_poll.ino @@ -35,7 +35,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/throughput/throughput.ino b/libraries/Bluefruit52Lib/examples/Peripheral/throughput/throughput.ino index a5597a315..80b1fe110 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/throughput/throughput.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/throughput/throughput.ino @@ -60,7 +60,6 @@ void setup(void) Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); Bluefruit.Periph.setConnectCallback(connect_callback); Bluefruit.Periph.setDisconnectCallback(disconnect_callback); Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms diff --git a/libraries/Bluefruit52Lib/examples/Projects/homekit/homekit_lightbulb/homekit_lightbulb.ino b/libraries/Bluefruit52Lib/examples/Projects/homekit/homekit_lightbulb/homekit_lightbulb.ino index 27ab1f064..36f3d5a12 100644 --- a/libraries/Bluefruit52Lib/examples/Projects/homekit/homekit_lightbulb/homekit_lightbulb.ino +++ b/libraries/Bluefruit52Lib/examples/Projects/homekit/homekit_lightbulb/homekit_lightbulb.ino @@ -121,7 +121,6 @@ void setup() Bluefruit.begin(); Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); //InternalFS.remove(CRYPTO_KEYFILE); //File file(CRYPTO_KEYFILE, FILE_O_WRITE, InternalFS); diff --git a/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_central/rssi_proximity_central.ino b/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_central/rssi_proximity_central.ino index e34da7664..4f43e89bb 100644 --- a/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_central/rssi_proximity_central.ino +++ b/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_central/rssi_proximity_central.ino @@ -186,9 +186,6 @@ void setup() Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - /* Set the device name */ - Bluefruit.setName("Bluefruit52"); - /* Set the LED interval for blinky pattern on BLUE LED */ Bluefruit.setConnLedInterval(250); diff --git a/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_peripheral/rssi_proximity_peripheral.ino b/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_peripheral/rssi_proximity_peripheral.ino index 56e5e97de..7e3f42bb4 100644 --- a/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_peripheral/rssi_proximity_peripheral.ino +++ b/libraries/Bluefruit52Lib/examples/Projects/rssi_proximity/rssi_proximity_peripheral/rssi_proximity_peripheral.ino @@ -75,7 +75,6 @@ void setup() } Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); // Set up and start advertising startAdv(); From cf004e0a1d0684be4811de5e06febb81971213a0 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Jun 2021 00:17:15 +0700 Subject: [PATCH 02/24] update cmsis from 5.4.0 to 5.7.0, enable dsp libmath add initial (wip) tf4micro-motion-kit sketch --- .../tf4micro-motion-kit/data_provider.cpp | 160 +++++ .../tf4micro-motion-kit/data_provider.h | 29 + .../tf4micro-motion-kit/model_tester.cpp | 271 ++++++++ .../tf4micro-motion-kit/model_tester.h | 43 ++ .../tf4micro-motion-kit.ino | 591 ++++++++++++++++++ platform.txt | 6 +- 6 files changed, 1097 insertions(+), 3 deletions(-) create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.h create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.h create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp new file mode 100644 index 000000000..f7f1bb950 --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp @@ -0,0 +1,160 @@ +/* Copyright 2021 Google LLC + +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 + + https://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. +==============================================================================*/ + +/* + * Namespaced methods for providing IMU data + * @author Rikard Lindstrom +*/ +#include "data_provider.h" +#include // change to Arduino_LSM6DS3.h for Nano 33 IoT or Uno WiFi Rev 2 + +namespace data_provider +{ +#define DATA_PROVIDER_CALIBRATION_THRESHOLD 10.0 +#define DATA_PROVIDER_CALIBRATION_STEPS 40 + + /************************************************************************ + * Calibration vars + ************************************************************************/ + + float lastMagneticFieldReading[3] = {0.0, 0.0, 0.0}; + float calibratedMagneticFieldHeading[3] = {0.0, 0.0, 0.0}; + int calibrationStep = 0; + bool calibrating = false; + + /************************************************************************ + * "Public" functions + ************************************************************************/ + + // Calibrate the magnetometer + void calibrate() + { + calibrating = true; + calibrationStep = 0; + } + + bool dataAvailable() + { + // Skip magnetometer since it's running a lot slower and always wanted + return IMU.accelerationAvailable() && IMU.gyroscopeAvailable(); + } + + bool setup() + { + + if (!IMU.begin()) + { + Serial.println("Failed to initialized IMU!"); + return false; + } + + // Experimental, enabling this will capture all readings + // from the IMU sensors and should be more accurate. However, + // it slows down the main loop by a lot when enabled. + + // IMU.setContinuousMode(); + + Serial.println("IMU sample rates: "); + Serial.print("Accelerometer sample rate = "); + Serial.println(IMU.accelerationSampleRate()); + Serial.print("Gyroscope sample rate = "); + Serial.println(IMU.gyroscopeSampleRate()); + Serial.print("Magnetometer sample rate = "); + Serial.println(IMU.magneticFieldSampleRate()); + + return true; + } + + void update(float *buffer, bool useMagnetometer) + { + + if (!dataAvailable()) + { + return; + } + + float ax, ay, az, gx, gy, gz; + + // read the acceleration and gyroscope data + IMU.readAcceleration(ax, ay, az); + IMU.readGyroscope(gx, gy, gz); + + // Accelorameter has a range of -4 – 4 + buffer[0] = ax / 4.0; + buffer[1] = ay / 4.0; + buffer[2] = az / 4.0; + + // Gyroscope has a range of -2000 – 2000 + buffer[3] = gx / 2000.0; + buffer[4] = gy / 2000.0; + buffer[5] = gz / 2000.0; + + if (useMagnetometer || calibrating) + { + float mx, my, mz; + + // The Magnetometer sample rate is only 20hz, so we'll use previous values + // if no new ones are available + if (IMU.magneticFieldAvailable()) + { + IMU.readMagneticField(mx, my, mz); + lastMagneticFieldReading[0] = mx; + lastMagneticFieldReading[1] = my; + lastMagneticFieldReading[2] = mz; + + if (calibrating) + { + // Running avarage + calibratedMagneticFieldHeading[0] += mx; + calibratedMagneticFieldHeading[1] += my; + calibratedMagneticFieldHeading[2] += mz; + calibratedMagneticFieldHeading[0] /= 2.0; + calibratedMagneticFieldHeading[1] /= 2.0; + calibratedMagneticFieldHeading[2] /= 2.0; + calibrationStep++; + if (calibrationStep > DATA_PROVIDER_CALIBRATION_STEPS && + abs(calibratedMagneticFieldHeading[0] - mx) < DATA_PROVIDER_CALIBRATION_THRESHOLD && + abs(calibratedMagneticFieldHeading[1] - my) < DATA_PROVIDER_CALIBRATION_THRESHOLD && + abs(calibratedMagneticFieldHeading[2] - mz) < DATA_PROVIDER_CALIBRATION_THRESHOLD) + { + calibrating = false; + data_provider_calibrationComplete(); + return; + } + } + } + else + { + mx = lastMagneticFieldReading[0]; + my = lastMagneticFieldReading[1]; + mz = lastMagneticFieldReading[2]; + } + + if (calibrating) + { + return; + } + + mx -= calibratedMagneticFieldHeading[0]; + my -= calibratedMagneticFieldHeading[1]; + mz -= calibratedMagneticFieldHeading[2]; + + // Raw magnetometer data + buffer[6] = mx / 50.0; + buffer[7] = my / 50.0; + buffer[8] = mz / 50.0; + } + } +} diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.h b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.h new file mode 100644 index 000000000..9903ace10 --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.h @@ -0,0 +1,29 @@ +/* Copyright 2021 Google LLC + +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 + + https://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. +==============================================================================*/ + +#ifndef DATA_PROVIDER_CPP +#define DATA_PROVIDER_CPP + +// Forward declare the function that will be called when data has been delivered to us. +void data_provider_calibrationComplete(); + +namespace data_provider { + bool setup(); + void update(float* buffer, bool useMagnetometer); + void calibrate(); + bool dataAvailable(); +} + +#endif diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp new file mode 100644 index 000000000..b07f0eee7 --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp @@ -0,0 +1,271 @@ +/* Copyright 2021 Google LLC + +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 + + https://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. +==============================================================================*/ + +/* + * Namespaced methods for loading a TF model and running inference + * @author Rikard Lindstrom +*/ +#include "model_tester.h" +#include +//#include + +namespace model_tester +{ + +/************************************************************************ +* Capture settings variables +************************************************************************/ + + int numSamples = 10; + int samplesRead = numSamples; + float accelerationThreshold = 0.167; + int captureDelay = 125; + unsigned char numClasses = 3; + bool disableMagnetometer = false; + + float maxVelocity = 0.; + int lastCaptureTimestamp = 0; + +/************************************************************************ +* Model loading / inference variables +************************************************************************/ + + bool isModelLoaded = false; + uint8_t interpreterBuffer[sizeof(tflite::MicroInterpreter)]; + + constexpr int tensorArenaSize = 8 * 1024; + byte tensorArena[tensorArenaSize]; + + // global variables used for TensorFlow Lite (Micro) + tflite::MicroErrorReporter tflErrorReporter; + + // pull in all the TFLM ops, you can remove this line and + // only pull in the TFLM ops you need, if would like to reduce + // the compiled size of the sketch. + tflite::AllOpsResolver tflOpsResolver; + + const tflite::Model *tflModel = nullptr; + tflite::MicroInterpreter *tflInterpreter = nullptr; + TfLiteTensor *tflInputTensor = nullptr; + TfLiteTensor *tflOutputTensor = nullptr; + + +/************************************************************************ +* Setters +************************************************************************/ + + void setCaptureDelay(int val){ + captureDelay = val; + } + + void setNumSamples(int val){ + numSamples = val; + samplesRead = val; + } + + void setThreshold(float val){ + accelerationThreshold = val; + } + + void setNumClasses(unsigned char val){ + numClasses = val; + } + + void setDisableMagnetometer(bool val){ + disableMagnetometer = val; + } + +/************************************************************************ +* Model loading +************************************************************************/ + + void loadModel(unsigned char model[]) + { + + // get the TFL representation of the model byte array + tflModel = tflite::GetModel(model); + if (tflModel->version() != TFLITE_SCHEMA_VERSION) + { + Serial.println("Model schema mismatch!"); + while (1) + ; + } + + // Create an interpreter to run the model + tflInterpreter = new (interpreterBuffer) tflite::MicroInterpreter(tflModel, tflOpsResolver, tensorArena, tensorArenaSize, &tflErrorReporter); + + // Allocate memory for the model's input and output tensors + tflInterpreter->AllocateTensors(); + + // Get pointers for the model's input and output tensors + tflInputTensor = tflInterpreter->input(0); + tflOutputTensor = tflInterpreter->output(0); + + isModelLoaded = true; + } + +/************************************************************************ +* Life cycle +************************************************************************/ + + // #define DEBUG - uncomment to log out each capture as CSV + + void update(float buffer[]) + { + + + int now = millis(); + + if (samplesRead == numSamples) + { + + // Honor captureDelay setting + if(now - lastCaptureTimestamp < captureDelay){ + return; + } + + const float aSum = (fabs(buffer[0]) + fabs(buffer[1]) + fabs(buffer[2]) + fabs(buffer[3]) + fabs(buffer[4]) + fabs(buffer[5])) / 6.0; + + // check if it's above the threshold + if (aSum >= accelerationThreshold) + { + #ifdef DEBUG + Serial.println("Capture started:"); + Serial.println("ax,ay,az,gx,gy,gz,mx,my,mz"); + #endif + + // reset the sample read count + samplesRead = 0; + maxVelocity = 0.; + } + } + + if (samplesRead < numSamples) + { + const int dataLen = disableMagnetometer ? 6 : 9; + + #ifdef DEBUG + for(int j = 0; j < dataLen; j++){ + Serial.print(buffer[j], 16); + if(j < dataLen - 1){ + Serial.print(","); + } + } + Serial.println(); + #endif + + const float velocity = (fabs(buffer[0]) + fabs(buffer[1]) + fabs(buffer[2])) / 3.0; + maxVelocity = max(maxVelocity, velocity); + + tflInputTensor->data.f[samplesRead * dataLen + 0] = buffer[0]; + tflInputTensor->data.f[samplesRead * dataLen + 1] = buffer[1]; + tflInputTensor->data.f[samplesRead * dataLen + 2] = buffer[2]; + tflInputTensor->data.f[samplesRead * dataLen + 3] = buffer[3]; + tflInputTensor->data.f[samplesRead * dataLen + 4] = buffer[4]; + tflInputTensor->data.f[samplesRead * dataLen + 5] = buffer[5]; + if(!disableMagnetometer){ + tflInputTensor->data.f[samplesRead * dataLen + 6] = buffer[6]; + tflInputTensor->data.f[samplesRead * dataLen + 7] = buffer[7]; + tflInputTensor->data.f[samplesRead * dataLen + 8] = buffer[8]; + } + + samplesRead++; + + if (samplesRead == numSamples) + { + // Run inferencing + TfLiteStatus invokeStatus = tflInterpreter->Invoke(); + if (invokeStatus != kTfLiteOk) + { + Serial.println("Invoke failed!"); + while (1) + ; + return; + } + #ifdef DEBUG + Serial.println(); + Serial.println("-----------------------------------------"); + #endif + + // Loop through the output tensor values from the model + unsigned char maxIndex = 0; + float maxValue = 0; + for (int i = 0; i < numClasses; i++) + { + float _value = tflOutputTensor->data.f[i]; + Serial.print("class: "); + Serial.println(i); + Serial.print(" score: "); + Serial.println(_value, 6); + + if (_value > maxValue) + { + maxValue = _value; + maxIndex = i; + } + } + + // callback + unsigned char velocity = (unsigned char )(((maxVelocity - accelerationThreshold) / (1.0 - accelerationThreshold)) * 255.999); + unsigned char score = (unsigned char)(maxValue * 255.999); + + model_tester_onInference(maxIndex, score, velocity); + + Serial.print("Winner: "); + Serial.print(maxIndex); + + // timestamp to follow the capture delay setting + lastCaptureTimestamp = now; + } + } + } + + void runTest(float *data, int len){ + const int numTests = len / numSamples; + const int dataLen = disableMagnetometer ? 6 : 9; + samplesRead = numSamples; + const int tmpCaptureDelay = captureDelay; + captureDelay = 0; + for(int i = 0; i < len; i+= dataLen){ + if(disableMagnetometer){ + float buffer[] = { + data[i + 0], + data[i + 1], + data[i + 2], + data[i + 3], + data[i + 4], + data[i + 5] + }; + update(buffer); + } else { + float buffer[] = { + data[i + 0], + data[i + 1], + data[i + 2], + data[i + 3], + data[i + 4], + data[i + 5], + data[i + 6], + data[i + 7], + data[i + 8] + }; + + //update(buffer); + } + } + + captureDelay = tmpCaptureDelay; + } +} diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.h b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.h new file mode 100644 index 000000000..50056b079 --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.h @@ -0,0 +1,43 @@ +/* Copyright 2021 Google LLC + +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 + + https://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. +==============================================================================*/ + +#ifndef MODEL_TESTER_CPP +#define MODEL_TESTER_CPP + +#include +#include +#include +#include +#include +#include + +// Forward declare the function that will be called when data has been delivered to us. +void model_tester_onInference(unsigned char classIndex, unsigned char score, unsigned char velocity); + +namespace model_tester { + void loadModel(unsigned char model[]); + void update(float buffer[]); + extern bool isModelLoaded; + + // Setters + void setCaptureDelay(int val); + void setNumSamples(int val); + void setThreshold(float val); + void setNumClasses(unsigned char val); + void setDisableMagnetometer(bool val); + void runTest(float *testData, int len); +} + +#endif diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino new file mode 100644 index 000000000..686c6c1a2 --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -0,0 +1,591 @@ +/* Copyright 2021 Google LLC + +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 + + https://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. +==============================================================================*/ + +/* +* @author Rikard Lindstrom +*/ + +#define VERSION 5 +#define FLOAT_BYTE_SIZE 4 + +//#include + +#include +#include +#include + +//#include "ble_file_transfer.h" +#include "model_tester.h" +#include "data_provider.h" + +/************************************************************************ +* State +************************************************************************/ + +enum State +{ + IDLE_DISCONNECTED, // Arduino was just turned on + IDLE_CONNECTED, // BLE was connected + FILE_TRANSFER, // File transfer mode + INFERENCE, // Inference is happening and published + IMU_DATA_PROVIDER, // Send IMU data over BLE for IMU Trainer + ERROR_STATE, // Something went wrong, + CALIBRATION, // Calibrate Magnetometer position + INFERENCE_AND_DATA_PROVIDER // both inference and IMU Data +}; + +State currentState = IDLE_DISCONNECTED; +State prevState = IDLE_DISCONNECTED; + +enum FileTransferType +{ + MODEL_FILE, + TEST_FILE +}; + +FileTransferType fileTransferType = MODEL_FILE; + +/************************************************************************ +* Globals / General +************************************************************************/ +bool useMagnetometer = false; // Can be toggled with BLE (disableMagnetometerRx) + +Adafruit_NeoPixel neopixels = Adafruit_NeoPixel(NEOPIXEL_NUM, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800); + +/************************************************************************ +* BLE Characteristic / Service UUIDs +************************************************************************/ + +#define LOCAL_NAME "TF4Micro - Motion Kit" + +#define UUID_GEN(val) ("81c30e5c-" val "-4f7d-a886-de3e90749161") + +//BLEService service (UUID_GEN("0000")); +// +//BLECharacteristic dataProviderTxChar (UUID_GEN("1001"), BLERead | BLENotify, 9 * FLOAT_BYTE_SIZE); +//BLECharacteristic dataProviderLabelsTxChar (UUID_GEN("1002"), BLERead, 128); +//BLEUnsignedCharCharacteristic versionTxChar (UUID_GEN("1003"), BLERead); +//BLECharacteristic inferenceTxChar (UUID_GEN("1004"), BLERead | BLENotify, 3); +// +//BLEUnsignedCharCharacteristic numClassesRxChar (UUID_GEN("2001"), BLEWrite); +//BLEIntCharacteristic numSamplesRxChar (UUID_GEN("2002"), BLEWrite); +//BLEIntCharacteristic captureDelayRxChar (UUID_GEN("2003"), BLEWrite); +//BLEFloatCharacteristic thresholdRxChar (UUID_GEN("2004"), BLEWrite); +//BLEBoolCharacteristic disableMagnetometerRx (UUID_GEN("2005"), BLEWrite); +// +//BLEUnsignedCharCharacteristic stateRxChar (UUID_GEN("3001"), BLEWrite); +//BLEUnsignedCharCharacteristic stateTxChar (UUID_GEN("3002"), BLERead | BLENotify); +//BLEUnsignedCharCharacteristic fileTransferTypeRxChar (UUID_GEN("3003"), BLEWrite); +//BLEBoolCharacteristic hasModelTxChar (UUID_GEN("3004"), BLERead | BLENotify); +// +//// Meta is for future-proofing, we can use it to store and read any 64 bytes +//BLECharacteristic metaRxChar (UUID_GEN("4001"), BLEWrite, 64); +//BLECharacteristic metaTxChar (UUID_GEN("4002"), BLERead, 64); + +/************************************************************************ +* Model file transfer +************************************************************************/ + +uint8_t *newModelFileData = nullptr; +int newModelFileLength = 0; + +/************************************************************************ +* LED / State status functions +************************************************************************/ + +void rgbLedOff() +{ +// digitalWrite(LEDR, HIGH); +// digitalWrite(LEDG, HIGH); +// digitalWrite(LEDB, HIGH); +} + +void rgbLedYellow() +{ +// digitalWrite(LEDR, LOW); +// digitalWrite(LEDG, LOW); +// digitalWrite(LEDB, HIGH); +} + +void rgbLedRed() +{ +// digitalWrite(LEDR, LOW); +// digitalWrite(LEDG, HIGH); +// digitalWrite(LEDB, HIGH); +} + +void rgbLedGreen() +{ +// digitalWrite(LEDR, HIGH); +// digitalWrite(LEDG, LOW); +// digitalWrite(LEDB, HIGH); +} + +void rgbLedBlue() +{ +// digitalWrite(LEDR, HIGH); +// digitalWrite(LEDG, HIGH); +// digitalWrite(LEDB, LOW); +} + +void showErrorLed() +{ + // blink red + millis() % 1000 > 500 ? rgbLedOff() : rgbLedRed(); +} + +void updateLed() +{ + switch (currentState) + { + + case FILE_TRANSFER: +#if 0 + if (ble_file_transfer::isTransfering()) +#else + if (0) +#endif + { + // Rapid blink while transfering is in progress + millis() % 100 > 50 ? rgbLedOff() : rgbLedYellow(); + } + else + { + rgbLedYellow(); + } + break; + + case INFERENCE: + rgbLedGreen(); + break; + + case IMU_DATA_PROVIDER: + rgbLedBlue(); + break; + + case INFERENCE_AND_DATA_PROVIDER: + millis() % 800 > 400 ? rgbLedBlue() : rgbLedGreen(); + break; + + case ERROR_STATE: + showErrorLed(); + break; + + case CALIBRATION: + millis() % 100 > 50 ? rgbLedOff() : rgbLedGreen(); + break; + + case IDLE_DISCONNECTED: + case IDLE_CONNECTED: + default: +#if 0 + if (BLE.connected()) +#else + if (1) +#endif + { + rgbLedBlue(); + } + else + { + // Blink yellow at a .5 second interval + const int now = millis(); + if (now % 1000 > 800) + { + rgbLedOff(); + } + else + { + int blinkStep = floor(now % 3000); + switch (blinkStep) + { + case 0: + rgbLedRed(); + break; + case 1000: + rgbLedGreen(); + break; + case 2000: + rgbLedBlue(); + break; + } + } + } + break; + } +} + +void setState(State state) +{ + if (state != prevState && state != currentState) + { + prevState = currentState; + } + currentState = state; +#if 0 + stateTxChar.writeValue((unsigned char)state); +#endif + switch (currentState) + { + case IDLE_DISCONNECTED: + Serial.println("state is now IDLE_DISCONNECTED"); + break; + case IDLE_CONNECTED: + Serial.println("state is now IDLE_CONNECTED"); + break; + case FILE_TRANSFER: + Serial.println("state is now FILE_TRANSFER"); + break; + case IMU_DATA_PROVIDER: + Serial.println("state is now IMU_DATA_PROVIDER"); + break; + case ERROR_STATE: + Serial.println("state is now ERROR_STATE"); + break; + case CALIBRATION: + data_provider::calibrate(); + Serial.println("state is now CALIBRATION"); + break; + case INFERENCE_AND_DATA_PROVIDER: + Serial.println("state is now INFERENCE_AND_DATA_PROVIDER"); + break; + default: + Serial.println("Error: Unknown state"); + } +} + +/************************************************************************ +* BLE Event handlers +************************************************************************/ + +#if 0 +void handleNumSamplesRxWritten(BLEDevice central, BLECharacteristic characteristic) +{ + model_tester::setNumSamples(numSamplesRxChar.value()); + Serial.print("Received numSamples: "); + Serial.println(numSamplesRxChar.value()); +} + +void handleThresholdRxWritten(BLEDevice central, BLECharacteristic characteristic) +{ + model_tester::setThreshold(thresholdRxChar.value()); + Serial.print("Received threshold: "); + Serial.println(thresholdRxChar.value(), 4); +} + +void handleCaptureDelayRxWritten(BLEDevice central, BLECharacteristic characteristic) +{ + model_tester::setCaptureDelay(captureDelayRxChar.value()); + Serial.print("Received delay: "); + Serial.println(captureDelayRxChar.value()); +} + +void handleNumClassesRxWritten(BLEDevice central, BLECharacteristic characteristic) +{ + model_tester::setNumClasses(numClassesRxChar.value()); + Serial.print("Received numClasses: "); + Serial.println(numClassesRxChar.value()); +} + +void handleDisableMagnetometerRxWritten(BLEDevice central, BLECharacteristic characteristic) +{ + bool val = disableMagnetometerRx.value(); + model_tester::setDisableMagnetometer(val); + + useMagnetometer = !val; + + Serial.print("Received disableMagnetometer: "); + Serial.println(disableMagnetometerRx.value()); +} + +void handleStateWritten(BLEDevice central, BLECharacteristic characteristic) +{ + setState((State)stateRxChar.value()); + Serial.print("Received state: "); + Serial.println(stateRxChar.value()); +} + +void handleMetaWritten(BLEDevice central, BLECharacteristic characteristic) +{ + // Meta is just a 64 byte storage for anything, just publish it + byte values[64]; + metaRxChar.readValue(values, 64); + metaTxChar.writeValue(values, 64); +} + +void handleFileTransferTypeWritten(BLEDevice central, BLECharacteristic characteristic) +{ + fileTransferType = (FileTransferType)fileTransferTypeRxChar.value(); + Serial.print("Received fileTransferType: "); + Serial.println(fileTransferType); +} +#endif + +/************************************************************************ +* Callbacks +************************************************************************/ + +// called on inference (gesture detected) +void model_tester_onInference(unsigned char classIndex, unsigned char score, unsigned char velocity) +{ + const byte buffer[]{classIndex, score, velocity}; +#if 0 + inferenceTxChar.setValue(buffer, 3); +#endif + Serial.print("Inference - class: "); + Serial.print(classIndex); + Serial.print(" score: "); + Serial.println(score); +} + +// called when calibration completes +void data_provider_calibrationComplete(){ + setState(prevState); +} + +// called on file transfer complete +void onBLEFileReceived(uint8_t *file_data, int file_length) +{ + switch (fileTransferType) + { + case MODEL_FILE: + // Queue up the model swap + newModelFileData = file_data; + newModelFileLength = file_length; + break; + case TEST_FILE: + { + int floatLength = file_length / 4; + float buffer[floatLength]; + for (int i = 0; i < file_length; i += 4) + { + union u_tag + { + byte b[4]; + float fval; + } u; + + u.b[0] = file_data[i + 0]; + u.b[1] = file_data[i + 1]; + u.b[2] = file_data[i + 2]; + u.b[3] = file_data[i + 3]; + + buffer[i / 4] = u.fval; + } + // set state to inference so we can capture result + setState(INFERENCE); + model_tester::runTest(buffer, floatLength); + } + break; + default: + Serial.println("Error: unkown file type"); + setState(ERROR_STATE); + while (0) updateLed(); + } +} + +/************************************************************************ +* Main / Lifecycle +************************************************************************/ + +void setup() +{ + + Serial.begin(9600); + const int startTime = millis(); + + // Give serial port 2 second to connect. + while (!Serial && millis() - startTime < 2000) + yield(); + + // Prepare LED pins. + pinMode(LED_BUILTIN, OUTPUT); + neopixels.begin(); + + // Start IMU / Data provider. + if (!data_provider::setup()) + { + Serial.println("Failed to initialize IMU!"); + while (1) showErrorLed(); + } +#if 0 + service.addCharacteristic(versionTxChar); + service.addCharacteristic(dataProviderTxChar); + service.addCharacteristic(dataProviderLabelsTxChar); + service.addCharacteristic(inferenceTxChar); + + service.addCharacteristic(numClassesRxChar); + service.addCharacteristic(numSamplesRxChar); + service.addCharacteristic(captureDelayRxChar); + service.addCharacteristic(thresholdRxChar); + service.addCharacteristic(disableMagnetometerRx); + + service.addCharacteristic(stateRxChar); + service.addCharacteristic(stateTxChar); + service.addCharacteristic(fileTransferTypeRxChar); + service.addCharacteristic(hasModelTxChar); + + service.addCharacteristic(metaRxChar); + service.addCharacteristic(metaTxChar); + + // Event driven reads. + numClassesRxChar.setEventHandler(BLEWritten, handleNumClassesRxWritten); + numSamplesRxChar.setEventHandler(BLEWritten, handleNumSamplesRxWritten); + thresholdRxChar.setEventHandler(BLEWritten, handleThresholdRxWritten); + captureDelayRxChar.setEventHandler(BLEWritten, handleCaptureDelayRxWritten); + stateRxChar.setEventHandler(BLEWritten, handleStateWritten); + fileTransferTypeRxChar.setEventHandler(BLEWritten, handleFileTransferTypeWritten); + metaRxChar.setEventHandler(BLEWritten, handleMetaWritten); + disableMagnetometerRx.setEventHandler(BLEWritten, handleDisableMagnetometerRxWritten); + + // Start the core BLE engine. + if (!BLE.begin()) + { + Serial.println("Failed to initialized BLE!"); + setState(ERROR_STATE); + while (1) showErrorLed(); + } +#endif + +#if 0 + String address = BLE.address(); + + // Output BLE settings over Serial. + Serial.print("address = "); + Serial.println(address); + + address.toUpperCase(); + + static String deviceName = LOCAL_NAME; + deviceName += " - "; + deviceName += address[address.length() - 5]; + deviceName += address[address.length() - 4]; + deviceName += address[address.length() - 2]; + deviceName += address[address.length() - 1]; + + Serial.print("deviceName = "); + Serial.println(deviceName); + + Serial.print("localName = "); + Serial.println(deviceName); + + // Set up properties for the whole service. + BLE.setLocalName(deviceName.c_str()); + BLE.setDeviceName(deviceName.c_str()); + BLE.setAdvertisedService(service); + + ble_file_transfer::setupBLEFileTransfer(service); + + // Print out full UUID and MAC address. + Serial.println("Peripheral advertising info: "); + Serial.print("Name: "); + Serial.println(LOCAL_NAME); + Serial.print("MAC: "); + Serial.println(BLE.address()); + Serial.print("Service UUID: "); + Serial.println(service.uuid()); + + // Start up the service itself. + BLE.addService(service); + BLE.advertise(); + + Serial.println("Bluetooth device active, waiting for connections..."); + + // Broadcast sketch version + versionTxChar.writeValue(VERSION); + + // Used for Tiny Motion Trainer to label / filter values + dataProviderLabelsTxChar.writeValue("acc.x, acc.y, acc.z, gyro.x, gyro.y, gyro.z, mag.x, mag.y, max.zl"); +#endif +} + +inline void updateIMU() +{ + const char bufferSize = useMagnetometer ? 9 : 6; + float buffer[bufferSize]; + while(data_provider::dataAvailable()){ + + // Collect the IMU data + data_provider::update(buffer, useMagnetometer); + + if(currentState == INFERENCE || currentState == INFERENCE_AND_DATA_PROVIDER){ + // if we have a model, do inference + if(model_tester::isModelLoaded){ + model_tester::update(buffer); + } + } +#if 0 + if(currentState == IMU_DATA_PROVIDER || currentState == INFERENCE_AND_DATA_PROVIDER){ + // provide data to IMU trainer + dataProviderTxChar.writeValue(buffer, bufferSize * FLOAT_BYTE_SIZE); + } +#endif + } +} + +inline void updateFileTransfer() +{ +#if 0 + // Update file transfer state + ble_file_transfer::updateBLEFileTransfer(); + + // Check if we should load a new model + if (newModelFileData != nullptr) + { + Serial.println("reloading model"); + model_tester::loadModel(newModelFileData); + Serial.println("done reloading model"); + newModelFileData = nullptr; + + hasModelTxChar.writeValue(true); + + // We have a new model, always enter INFERENCE mode + setState(INFERENCE); + } +#endif +} + +void loop() +{ +#if 0 + // Make sure we're connected and not busy file-transfering + if (BLE.connected()) + { + switch (currentState) + { + case FILE_TRANSFER: + updateFileTransfer(); + break; + + case CALIBRATION: + case IMU_DATA_PROVIDER: + case INFERENCE_AND_DATA_PROVIDER: + case INFERENCE: + if(!ble_file_transfer::isTransfering()){ + updateIMU(); + } + break; + + default: + break; + } + } else if(currentState != IDLE_DISCONNECTED){ + setState(IDLE_DISCONNECTED); + } +#endif + + // Update led based on state + updateLed(); +} diff --git a/platform.txt b/platform.txt index 76e750322..2087a3b5b 100644 --- a/platform.txt +++ b/platform.txt @@ -71,10 +71,10 @@ compiler.libraries.ldflags= compiler.elf2bin.extra_flags= compiler.elf2hex.extra_flags= -compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/DSP/Include/" +compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.7.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.7.0.path}/CMSIS/DSP/Include/" # TODO enable linking with libmath later on -compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" -larm_cortexM4lf_math +compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.7.0.path}/CMSIS/DSP/Lib/GCC/" -larm_cortexM4lf_math # common compiler for nrf rtos.path={build.core.path}/freertos @@ -100,7 +100,7 @@ recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU= recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-L{build.core.path}/linker" "-T{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group -lm "{build.path}/{archive_file}" {compiler.libraries.ldflags} -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-L{build.core.path}/linker" "-T{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.ldflags} {compiler.arm.cmsis.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group -lm "{build.path}/{archive_file}" {compiler.libraries.ldflags} -Wl,--end-group ## Create output (bin file) #recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2bin.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" From c5727eef8cf15a2b32720bbc0122551ff80c5b60 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Jun 2021 20:08:30 +0700 Subject: [PATCH 03/24] implement BLEUuid from string style like ArduinoBLE --- libraries/Bluefruit52Lib/src/BLEUuid.cpp | 168 +++++++++++++++++++---- libraries/Bluefruit52Lib/src/BLEUuid.h | 14 +- 2 files changed, 150 insertions(+), 32 deletions(-) diff --git a/libraries/Bluefruit52Lib/src/BLEUuid.cpp b/libraries/Bluefruit52Lib/src/BLEUuid.cpp index 882184b3b..a80229be6 100644 --- a/libraries/Bluefruit52Lib/src/BLEUuid.cpp +++ b/libraries/Bluefruit52Lib/src/BLEUuid.cpp @@ -48,20 +48,145 @@ const uint8_t UUID128_CHR_ADAFRUIT_VERSION[16] = 0xA8, 0x42, 0x32, 0xC3, 0x02, 0x00, 0xAF, 0xAD }; +//--------------------------------------------------------------------+ +// Constructor +//--------------------------------------------------------------------+ + +BLEUuid::BLEUuid(void) +{ + _uuid.type = BLE_UUID_TYPE_UNKNOWN; + _uuid.uuid = 0; + + _uuid128 = NULL; + _str = NULL; +} + +BLEUuid::BLEUuid(uint16_t uuid16) +{ + set(uuid16); +} + +BLEUuid::BLEUuid(const char *str) +{ + set(str); +} + +BLEUuid::BLEUuid(uint8_t const uuid128[16]) +{ + set(uuid128); +} + +BLEUuid::BLEUuid(ble_uuid_t uuid) +{ + _uuid = uuid; + + _uuid128 = NULL; + _str = NULL; +} + +BLEUuid::~BLEUuid() +{ + if (_str && _uuid128) + { + // don't even free _uuid128, it could be pointer copyied to other + // check again if it is a major memory leak + } +} + +// Get size of uuid in bit length. return 16, 32 or 128 +size_t BLEUuid::size (void) const +{ + // uuid 16 + if (_uuid.type == BLE_UUID_TYPE_BLE ) return 16; + if (_uuid128 != NULL || _str != NULL || _uuid.type >= BLE_UUID_TYPE_VENDOR_BEGIN) return 128; + + // unknown + return 0; +} + +uint8_t* parse_str2uuid128(const char* str) +{ + uint8_t* u128 = (uint8_t*) rtos_malloc(16); + uint8_t len = 0; + + // str is input as big endian + for(int i = strlen(str)-1; i >= 0 && len < 16; i -= 2 ) + { + if (str[i] == '-' ) + { + // skip dash + i++; + }else + { + char temp[3] = { 0 }; + temp[0] = str[i-1]; + temp[1] = str[i]; + + u128[len++] = (uint8_t) strtoul(temp, NULL, 16); + } + } + + return u128; +} + +bool BLEUuid::begin(void) +{ + // Add base uuid and decode to get uuid16 + // This should cover the already added base uuid128 previously + if (_uuid.type == BLE_UUID_TYPE_UNKNOWN) + { + // allocate uuid128 and parse str (str for uuid16 already parsed at this point) + if (_str) + { + _uuid128 = parse_str2uuid128(_str); + } + + if (_uuid128 != NULL ) + { + (void) sd_ble_uuid_vs_add( (ble_uuid128_t const*) _uuid128, &_uuid.type ); + VERIFY_STATUS( sd_ble_uuid_decode(16, _uuid128, &_uuid), false ); + } + } + + return true; +} + +//--------------------------------------------------------------------+ +// Set & Get +//--------------------------------------------------------------------+ void BLEUuid::set(uint16_t uuid16) { _uuid.type = BLE_UUID_TYPE_BLE; _uuid.uuid = uuid16; _uuid128 = NULL; + _str = NULL; } void BLEUuid::set(uint8_t const uuid128[16]) { + _uuid128 = uuid128; + _uuid.type = BLE_UUID_TYPE_UNKNOWN; _uuid.uuid = 0; + _str = NULL; +} - _uuid128 = uuid128; +void BLEUuid::set(const char* str) +{ + // Check if str is uuid16 + if (strlen(str) == 4) + { + uint16_t uuid16 = strtoul(str, NULL, 16); + set(uuid16); + }else + { + _str = str; + + _uuid.type = BLE_UUID_TYPE_UNKNOWN; + _uuid.uuid = 0; + _uuid128 = NULL; + } } bool BLEUuid::get(uint16_t* uuid16 ) const @@ -88,33 +213,9 @@ bool BLEUuid::get(uint8_t uuid128[16]) return true; } -/** - * Get size of uuid in BIT - * @return 16, 32 or 128 - */ -size_t BLEUuid::size (void) const -{ - // uuid 16 - if (_uuid.type == BLE_UUID_TYPE_BLE ) return 16; - if (_uuid128 != NULL || _uuid.type >= BLE_UUID_TYPE_VENDOR_BEGIN) return 128; - - // unknown - return 0; -} - -bool BLEUuid::begin(void) -{ - /* Add base uuid and decode to get uuid16 - * This should cover the already added base uuid128 previously - */ - if (_uuid.type == BLE_UUID_TYPE_UNKNOWN && _uuid128 != NULL ) - { - (void) sd_ble_uuid_vs_add( (ble_uuid128_t const*) _uuid128, &_uuid.type ); - VERIFY_STATUS( sd_ble_uuid_decode(16, _uuid128, &_uuid), false ); - } - - return true; -} +//--------------------------------------------------------------------+ +// Comparison +//--------------------------------------------------------------------+ bool BLEUuid::operator== (const BLEUuid& uuid) const { @@ -136,6 +237,10 @@ bool BLEUuid::operator!= (const ble_uuid_t uuid) const return !(*this == uuid); } +//--------------------------------------------------------------------+ +// Copy operator +//--------------------------------------------------------------------+ + // Overload copy operator to allow initialization from other type BLEUuid& BLEUuid::operator=(const uint16_t uuid) { @@ -149,6 +254,13 @@ BLEUuid& BLEUuid::operator=(uint8_t const uuid128[16]) return *this; } +BLEUuid& BLEUuid::operator=(const char* str) +{ + set(str); + return *this; +} + + BLEUuid& BLEUuid::operator=(ble_uuid_t uuid) { _uuid = uuid; diff --git a/libraries/Bluefruit52Lib/src/BLEUuid.h b/libraries/Bluefruit52Lib/src/BLEUuid.h index 1193cdadf..287b8456b 100644 --- a/libraries/Bluefruit52Lib/src/BLEUuid.h +++ b/libraries/Bluefruit52Lib/src/BLEUuid.h @@ -43,15 +43,20 @@ class BLEUuid public: ble_uuid_t _uuid; uint8_t const* _uuid128; + const char* _str; // Constructors - BLEUuid(void ) { _uuid.type = BLE_UUID_TYPE_UNKNOWN; _uuid.uuid = 0; _uuid128 = NULL; } - BLEUuid(uint16_t uuid16 ) { set(uuid16 ); } - BLEUuid(uint8_t const uuid128[16] ) { set(uuid128); } - BLEUuid(ble_uuid_t uuid ) { _uuid = uuid; _uuid128 = NULL; } + BLEUuid(void ); + BLEUuid(uint16_t uuid16 ); + BLEUuid(uint8_t const uuid128[16] ); + BLEUuid(const char* str ); + BLEUuid(ble_uuid_t uuid ); + + virtual ~BLEUuid(); void set(uint16_t uuid16); void set(uint8_t const uuid128[16]); + void set(const char* str); bool get(uint16_t* uuid16) const; bool get(uint8_t uuid128[16]); @@ -70,6 +75,7 @@ class BLEUuid BLEUuid& operator=(const uint16_t uuid); BLEUuid& operator=(uint8_t const uuid128[16]); BLEUuid& operator=(ble_uuid_t uuid); + BLEUuid& operator=(const char* str); }; //--------------------------------------------------------------------+ From 10ad828bae3fe75138df120e3fd41feba9f9cf8c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Jun 2021 20:53:20 +0700 Subject: [PATCH 04/24] advertise ok, have issue with IMU begin --- .../tf4micro-motion-kit.ino | 67 +++++++++++++------ platform.txt | 2 +- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 686c6c1a2..603a172b8 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -72,8 +72,8 @@ Adafruit_NeoPixel neopixels = Adafruit_NeoPixel(NEOPIXEL_NUM, PIN_NEOPIXEL, NEO_ #define UUID_GEN(val) ("81c30e5c-" val "-4f7d-a886-de3e90749161") -//BLEService service (UUID_GEN("0000")); -// +BLEService service (UUID_GEN("0000")); + //BLECharacteristic dataProviderTxChar (UUID_GEN("1001"), BLERead | BLENotify, 9 * FLOAT_BYTE_SIZE); //BLECharacteristic dataProviderLabelsTxChar (UUID_GEN("1002"), BLERead, 128); //BLEUnsignedCharCharacteristic versionTxChar (UUID_GEN("1003"), BLERead); @@ -107,9 +107,8 @@ int newModelFileLength = 0; void rgbLedOff() { -// digitalWrite(LEDR, HIGH); -// digitalWrite(LEDG, HIGH); -// digitalWrite(LEDB, HIGH); + neopixels.setPixelColor(0, 0, 0, 0); + neopixels.show(); } void rgbLedYellow() @@ -117,33 +116,33 @@ void rgbLedYellow() // digitalWrite(LEDR, LOW); // digitalWrite(LEDG, LOW); // digitalWrite(LEDB, HIGH); + neopixels.setPixelColor(0, 0xff, 0xff, 0); + neopixels.show(); } void rgbLedRed() { -// digitalWrite(LEDR, LOW); -// digitalWrite(LEDG, HIGH); -// digitalWrite(LEDB, HIGH); + neopixels.setPixelColor(0, 0xff, 0, 0); + neopixels.show(); } void rgbLedGreen() { -// digitalWrite(LEDR, HIGH); -// digitalWrite(LEDG, LOW); -// digitalWrite(LEDB, HIGH); + neopixels.setPixelColor(0, 0, 0xff, 0); + neopixels.show(); } void rgbLedBlue() { -// digitalWrite(LEDR, HIGH); -// digitalWrite(LEDG, HIGH); -// digitalWrite(LEDB, LOW); + neopixels.setPixelColor(0, 0, 0, 0xff); + neopixels.show(); } void showErrorLed() { // blink red millis() % 1000 > 500 ? rgbLedOff() : rgbLedRed(); + delay(500); } void updateLed() @@ -410,16 +409,27 @@ void setup() while (!Serial && millis() - startTime < 2000) yield(); + Serial.println("Bluefruit52 Example"); + Serial.println("-------------------\n"); + // Prepare LED pins. pinMode(LED_BUILTIN, OUTPUT); neopixels.begin(); // Start IMU / Data provider. - if (!data_provider::setup()) - { - Serial.println("Failed to initialize IMU!"); - while (1) showErrorLed(); - } +// if (!data_provider::setup()) +// { +// Serial.println("Failed to initialize IMU!"); +// while (1) showErrorLed(); +// } + + Bluefruit.autoConnLed(true); + Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); + Bluefruit.begin(); + Bluefruit.setTxPower(4); + + service.begin(); + #if 0 service.addCharacteristic(versionTxChar); service.addCharacteristic(dataProviderTxChar); @@ -480,12 +490,29 @@ void setup() Serial.print("localName = "); Serial.println(deviceName); - // Set up properties for the whole service. BLE.setLocalName(deviceName.c_str()); BLE.setDeviceName(deviceName.c_str()); BLE.setAdvertisedService(service); +#endif + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + + // Include bleuart 128-bit uuid + Bluefruit.Advertising.addService(service); + + // Secondary Scan Response packet (optional) + // Since there is no room for 'Name' in Advertising packet + Bluefruit.ScanResponse.addName(); + + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds + +#if 0 ble_file_transfer::setupBLEFileTransfer(service); // Print out full UUID and MAC address. diff --git a/platform.txt b/platform.txt index 2087a3b5b..50eab070a 100644 --- a/platform.txt +++ b/platform.txt @@ -100,7 +100,7 @@ recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU= recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-L{build.core.path}/linker" "-T{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.ldflags} {compiler.arm.cmsis.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group -lm "{build.path}/{archive_file}" {compiler.libraries.ldflags} -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-L{build.core.path}/linker" "-T{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group {compiler.arm.cmsis.ldflags} -lm "{build.path}/{archive_file}" {compiler.libraries.ldflags} -Wl,--end-group ## Create output (bin file) #recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2bin.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" From a58a9c9e9ae5403e53e788641c1ba82ee39a5dcd Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Jun 2021 22:51:00 +0700 Subject: [PATCH 05/24] IMU init Ok with LSM6DSOX --- .../tf4micro-motion-kit/tf4micro-motion-kit.ino | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 603a172b8..620c2beb0 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -113,9 +113,6 @@ void rgbLedOff() void rgbLedYellow() { -// digitalWrite(LEDR, LOW); -// digitalWrite(LEDG, LOW); -// digitalWrite(LEDB, HIGH); neopixels.setPixelColor(0, 0xff, 0xff, 0); neopixels.show(); } @@ -417,11 +414,11 @@ void setup() neopixels.begin(); // Start IMU / Data provider. -// if (!data_provider::setup()) -// { -// Serial.println("Failed to initialize IMU!"); -// while (1) showErrorLed(); -// } + if (!data_provider::setup()) + { + Serial.println("Failed to initialize IMU!"); + while (1) showErrorLed(); + } Bluefruit.autoConnLed(true); Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); From e732631e5c4a1409c596c93499c59dcc0d09701d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Jun 2021 23:41:57 +0700 Subject: [PATCH 06/24] add BLECharacteristic constructor with properties also add properties as BLERead/Write etc.. to make it easier to migrate from arduino ble --- libraries/Bluefruit52Lib/src/BLECharacteristic.cpp | 7 +++++++ libraries/Bluefruit52Lib/src/BLECharacteristic.h | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp b/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp index 46dc152f0..39f688f47 100644 --- a/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp +++ b/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp @@ -83,6 +83,13 @@ BLECharacteristic::BLECharacteristic(BLEUuid bleuuid) _init(); } +BLECharacteristic::BLECharacteristic(BLEUuid bleuuid, uint8_t properties) + : uuid(bleuuid) +{ + _init(); + setProperties(properties); +} + void BLECharacteristic::setUuid(BLEUuid bleuuid) { uuid = bleuuid; diff --git a/libraries/Bluefruit52Lib/src/BLECharacteristic.h b/libraries/Bluefruit52Lib/src/BLECharacteristic.h index b0decf524..168131a17 100644 --- a/libraries/Bluefruit52Lib/src/BLECharacteristic.h +++ b/libraries/Bluefruit52Lib/src/BLECharacteristic.h @@ -53,6 +53,17 @@ enum CharsProperties CHR_PROPS_INDICATE = bit(5) }; +// same as CharsProperties, but make it easier to migrate from ArduinoBLE +enum BLECharsProperties +{ + BLEBroadcast = 0x01, + BLERead = 0x02, + BLEWriteWithoutResponse = 0x04, + BLEWrite = 0x08, + BLENotify = 0x10, + BLEIndicate = 0x20 +}; + class BLECharacteristic { public: @@ -67,6 +78,7 @@ class BLECharacteristic // Constructors BLECharacteristic(void); BLECharacteristic(BLEUuid bleuuid); + BLECharacteristic(BLEUuid bleuuid, uint8_t properties); // Destructor virtual ~BLECharacteristic(); From 3995b428a1b76e14ffc4ecf9194d9ccec79b27ce Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 11:31:25 +0700 Subject: [PATCH 07/24] add BLECharacteristic constructor with max_len and fixed len --- .../Bluefruit52Lib/src/BLECharacteristic.cpp | 24 +++++++++++++++---- .../Bluefruit52Lib/src/BLECharacteristic.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp b/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp index 39f688f47..f728d8b0e 100644 --- a/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp +++ b/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp @@ -90,6 +90,20 @@ BLECharacteristic::BLECharacteristic(BLEUuid bleuuid, uint8_t properties) setProperties(properties); } +BLECharacteristic::BLECharacteristic(BLEUuid bleuuid, uint8_t properties, int max_len, bool fixed_len) + : uuid(bleuuid) +{ + _init(); + setProperties(properties); + if (fixed_len) + { + setFixedLen(max_len); + }else + { + setMaxLen(max_len); + } +} + void BLECharacteristic::setUuid(BLEUuid bleuuid) { uuid = bleuuid; @@ -135,11 +149,6 @@ uint16_t BLECharacteristic::getMaxLen(void) return _max_len; } -bool BLECharacteristic::isFixedLen(void) -{ - return _attr_meta.vlen == 0; -} - void BLECharacteristic::setFixedLen(uint16_t fixed_len) { if ( fixed_len ) @@ -152,6 +161,11 @@ void BLECharacteristic::setFixedLen(uint16_t fixed_len) } } +bool BLECharacteristic::isFixedLen(void) +{ + return _attr_meta.vlen == 0; +} + // Use application buffer instead of SD stack buffer void BLECharacteristic::setBuffer(void* buf, uint16_t bufsize) { diff --git a/libraries/Bluefruit52Lib/src/BLECharacteristic.h b/libraries/Bluefruit52Lib/src/BLECharacteristic.h index 168131a17..8ae795ff6 100644 --- a/libraries/Bluefruit52Lib/src/BLECharacteristic.h +++ b/libraries/Bluefruit52Lib/src/BLECharacteristic.h @@ -79,6 +79,7 @@ class BLECharacteristic BLECharacteristic(void); BLECharacteristic(BLEUuid bleuuid); BLECharacteristic(BLEUuid bleuuid, uint8_t properties); + BLECharacteristic(BLEUuid bleuuid, uint8_t properties, int max_len, bool fixed_len = false); // Destructor virtual ~BLECharacteristic(); From 97fad974007aac0754a84375f71119b54279297f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 12:00:47 +0700 Subject: [PATCH 08/24] bump nRFCrypto, log clean up --- cores/nRF5/common_func.h | 6 +++--- libraries/Adafruit_nRFCrypto | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cores/nRF5/common_func.h b/cores/nRF5/common_func.h index ed5ac272d..127b00d19 100644 --- a/cores/nRF5/common_func.h +++ b/cores/nRF5/common_func.h @@ -184,7 +184,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place #define PRINT_HEX(x) \ do {\ PRINTF("%s: %d: " #x " = 0x", __PRETTY_FUNCTION__, __LINE__);\ - char fmt[] = "%00X\n";\ + char fmt[] = "%00X\r\n";\ fmt[2] += 2*sizeof(x); /* Hex with correct size */\ PRINTF(fmt, (x) );\ }while(0) @@ -197,14 +197,14 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place if (i%16 == 0) PRINTF("\n"); \ PRINTF("%02x ", p8[i]); \ }\ - PRINTF("\n");\ + PRINTF("\r\n");\ }while(0) #define ADALOG(tag, ...) \ do { \ if ( tag ) PRINTF("[%-6s] ", tag);\ PRINTF(__VA_ARGS__);\ - PRINTF("\n");\ + PRINTF("\r\n");\ }while(0) #define ADALOG_BUFFER(_tag, _buf, _n) \ diff --git a/libraries/Adafruit_nRFCrypto b/libraries/Adafruit_nRFCrypto index 3686f2413..7444c2e94 160000 --- a/libraries/Adafruit_nRFCrypto +++ b/libraries/Adafruit_nRFCrypto @@ -1 +1 @@ -Subproject commit 3686f2413672ec72e8f8a163d6c69fe7faa0b743 +Subproject commit 7444c2e9472b8731cbcb76be5216df04680c5529 From b28bba797c129e81b1707bbd12d0391b3f51f8fa Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 12:10:40 +0700 Subject: [PATCH 09/24] mimic version, data provider, data provider label --- .../tf4micro-motion-kit.ino | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 620c2beb0..977586c58 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -74,9 +74,9 @@ Adafruit_NeoPixel neopixels = Adafruit_NeoPixel(NEOPIXEL_NUM, PIN_NEOPIXEL, NEO_ BLEService service (UUID_GEN("0000")); -//BLECharacteristic dataProviderTxChar (UUID_GEN("1001"), BLERead | BLENotify, 9 * FLOAT_BYTE_SIZE); -//BLECharacteristic dataProviderLabelsTxChar (UUID_GEN("1002"), BLERead, 128); -//BLEUnsignedCharCharacteristic versionTxChar (UUID_GEN("1003"), BLERead); +BLECharacteristic dataProviderTxChar (UUID_GEN("1001"), BLERead | BLENotify, 9 * FLOAT_BYTE_SIZE); +BLECharacteristic dataProviderLabelsTxChar (UUID_GEN("1002"), BLERead, 128); +BLECharacteristic versionTxChar (UUID_GEN("1003"), BLERead, 1, true); //BLECharacteristic inferenceTxChar (UUID_GEN("1004"), BLERead | BLENotify, 3); // //BLEUnsignedCharCharacteristic numClassesRxChar (UUID_GEN("2001"), BLEWrite); @@ -427,10 +427,11 @@ void setup() service.begin(); + versionTxChar.begin(); + dataProviderTxChar.begin(); + dataProviderLabelsTxChar.begin(); + #if 0 - service.addCharacteristic(versionTxChar); - service.addCharacteristic(dataProviderTxChar); - service.addCharacteristic(dataProviderLabelsTxChar); service.addCharacteristic(inferenceTxChar); service.addCharacteristic(numClassesRxChar); @@ -526,13 +527,13 @@ void setup() BLE.advertise(); Serial.println("Bluetooth device active, waiting for connections..."); +#endif // Broadcast sketch version - versionTxChar.writeValue(VERSION); + versionTxChar.write8(VERSION); // Used for Tiny Motion Trainer to label / filter values - dataProviderLabelsTxChar.writeValue("acc.x, acc.y, acc.z, gyro.x, gyro.y, gyro.z, mag.x, mag.y, max.zl"); -#endif + dataProviderLabelsTxChar.write("acc.x, acc.y, acc.z, gyro.x, gyro.y, gyro.z, mag.x, mag.y, max.zl"); } inline void updateIMU() From e29a324d79b542d27653bb578869e9d0a4eab442 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 16:14:04 +0700 Subject: [PATCH 10/24] add most of the ble char --- cores/nRF5/utility/debug.cpp | 24 +++--- cores/nRF5/verify.h | 2 +- .../tf4micro-motion-kit.ino | 74 +++++++++---------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/cores/nRF5/utility/debug.cpp b/cores/nRF5/utility/debug.cpp index 33118c30c..cf2aef352 100644 --- a/cores/nRF5/utility/debug.cpp +++ b/cores/nRF5/utility/debug.cpp @@ -107,14 +107,14 @@ static void printMemRegion(const char* name, uint32_t top, uint32_t bottom, uint sprintf(buffer, "%lu", top-bottom); } - PRINTF("| %-5s| 0x%04X - 0x%04X | %-19s |\n", name, (uint16_t) bottom, (uint16_t) (top-1), buffer); + PRINTF("| %-5s| 0x%04X - 0x%04X | %-19s |\r\n", name, (uint16_t) bottom, (uint16_t) (top-1), buffer); } void dbgMemInfo(void) { - PRINTF(" ______________________________________________\n"); - PRINTF("| Name | Addr 0x2000xxxx | Usage |\n"); - PRINTF("| ---------------------------------------------|\n"); + PRINTF(" ______________________________________________\r\n"); + PRINTF("| Name | Addr 0x2000xxxx | Usage |\r\n"); + PRINTF("| ---------------------------------------------|\r\n"); // Pritn SRAM used for Stack executed by Softdevice and ISR printMemRegion("Stack", ((uint32_t) __StackTop), ((uint32_t) __StackLimit), dbgStackUsed() ); @@ -128,7 +128,7 @@ void dbgMemInfo(void) // Print SRAM Used by SoftDevice printMemRegion("SD", (uint32_t) __data_start__, 0x20000000, 0); - PRINTF("|______________________________________________|\n"); + PRINTF("|______________________________________________|\r\n"); PRINTF("\n"); // Print Task list @@ -137,8 +137,8 @@ void dbgMemInfo(void) vTaskList(buf); - PRINTF("Task State Prio StackLeft Num\n"); - PRINTF("-----------------------------------\n"); + PRINTF("Task State Prio StackLeft Num\r\n"); + PRINTF("-----------------------------------\r\n"); PRINTF(buf); PRINTF("\n"); rtos_free(buf); @@ -146,11 +146,11 @@ void dbgMemInfo(void) void dbgPrintVersion(void) { - PRINTF("\n"); - PRINTF("BSP Library : " ARDUINO_BSP_VERSION "\n"); - PRINTF("Bootloader : %s\n", getBootloaderVersion()); - PRINTF("Serial No : %s\n", getMcuUniqueID()); - PRINTF("\n"); + PRINTF("\r\n"); + PRINTF("BSP Library : " ARDUINO_BSP_VERSION "\r\n"); + PRINTF("Bootloader : %s\r\n", getBootloaderVersion()); + PRINTF("Serial No : %s\r\n", getMcuUniqueID()); + PRINTF("\r\n"); } /******************************************************************************/ diff --git a/cores/nRF5/verify.h b/cores/nRF5/verify.h index b4d028a81..cc0886e36 100644 --- a/cores/nRF5/verify.h +++ b/cores/nRF5/verify.h @@ -67,7 +67,7 @@ extern "C" { PRINTF("0x%lX (%ld)", _status, _status); } - PRINTF("\n"); + PRINTF("\r\n"); } #else #define VERIFY_MESS(_status, _funcstr) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 977586c58..28cb8c3d5 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -72,27 +72,27 @@ Adafruit_NeoPixel neopixels = Adafruit_NeoPixel(NEOPIXEL_NUM, PIN_NEOPIXEL, NEO_ #define UUID_GEN(val) ("81c30e5c-" val "-4f7d-a886-de3e90749161") -BLEService service (UUID_GEN("0000")); - -BLECharacteristic dataProviderTxChar (UUID_GEN("1001"), BLERead | BLENotify, 9 * FLOAT_BYTE_SIZE); -BLECharacteristic dataProviderLabelsTxChar (UUID_GEN("1002"), BLERead, 128); -BLECharacteristic versionTxChar (UUID_GEN("1003"), BLERead, 1, true); -//BLECharacteristic inferenceTxChar (UUID_GEN("1004"), BLERead | BLENotify, 3); -// -//BLEUnsignedCharCharacteristic numClassesRxChar (UUID_GEN("2001"), BLEWrite); -//BLEIntCharacteristic numSamplesRxChar (UUID_GEN("2002"), BLEWrite); -//BLEIntCharacteristic captureDelayRxChar (UUID_GEN("2003"), BLEWrite); -//BLEFloatCharacteristic thresholdRxChar (UUID_GEN("2004"), BLEWrite); -//BLEBoolCharacteristic disableMagnetometerRx (UUID_GEN("2005"), BLEWrite); -// -//BLEUnsignedCharCharacteristic stateRxChar (UUID_GEN("3001"), BLEWrite); -//BLEUnsignedCharCharacteristic stateTxChar (UUID_GEN("3002"), BLERead | BLENotify); -//BLEUnsignedCharCharacteristic fileTransferTypeRxChar (UUID_GEN("3003"), BLEWrite); -//BLEBoolCharacteristic hasModelTxChar (UUID_GEN("3004"), BLERead | BLENotify); -// -//// Meta is for future-proofing, we can use it to store and read any 64 bytes -//BLECharacteristic metaRxChar (UUID_GEN("4001"), BLEWrite, 64); -//BLECharacteristic metaTxChar (UUID_GEN("4002"), BLERead, 64); +BLEService service (UUID_GEN("0000")); + +BLECharacteristic dataProviderTxChar (UUID_GEN("1001") , BLERead | BLENotify , 9 * FLOAT_BYTE_SIZE); +BLECharacteristic dataProviderLabelsTxChar (UUID_GEN("1002") , BLERead , 128); +BLECharacteristic versionTxChar (UUID_GEN("1003") , BLERead , 1 , true); +BLECharacteristic inferenceTxChar (UUID_GEN("1004") , BLERead | BLENotify , 3 , true); + +BLECharacteristic numClassesRxChar (UUID_GEN("2001") , BLEWrite , 1 , true); +BLECharacteristic numSamplesRxChar (UUID_GEN("2002") , BLEWrite , 4 , true); +BLECharacteristic captureDelayRxChar (UUID_GEN("2003") , BLEWrite , 4 , true); +BLECharacteristic thresholdRxChar (UUID_GEN("2004") , BLEWrite , 4 , true); +BLECharacteristic disableMagnetometerRx (UUID_GEN("2005") , BLEWrite , 1 , true); + +BLECharacteristic stateRxChar (UUID_GEN("3001") , BLEWrite , 1 , true); +BLECharacteristic stateTxChar (UUID_GEN("3002") , BLERead | BLENotify , 1 , true); +BLECharacteristic fileTransferTypeRxChar (UUID_GEN("3003") , BLEWrite , 1 , true); +BLECharacteristic hasModelTxChar (UUID_GEN("3004") , BLERead | BLENotify , 1 , true); + +// Meta is for future-proofing, we can use it to store and read any 64 bytes +BLECharacteristic metaRxChar (UUID_GEN("4001") , BLEWrite , 64); +BLECharacteristic metaTxChar (UUID_GEN("4002") , BLERead , 64); /************************************************************************ * Model file transfer @@ -421,6 +421,7 @@ void setup() } Bluefruit.autoConnLed(true); + Bluefruit.configUuid128Count(20); Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); Bluefruit.begin(); Bluefruit.setTxPower(4); @@ -430,24 +431,23 @@ void setup() versionTxChar.begin(); dataProviderTxChar.begin(); dataProviderLabelsTxChar.begin(); - -#if 0 - service.addCharacteristic(inferenceTxChar); - - service.addCharacteristic(numClassesRxChar); - service.addCharacteristic(numSamplesRxChar); - service.addCharacteristic(captureDelayRxChar); - service.addCharacteristic(thresholdRxChar); - service.addCharacteristic(disableMagnetometerRx); - - service.addCharacteristic(stateRxChar); - service.addCharacteristic(stateTxChar); - service.addCharacteristic(fileTransferTypeRxChar); - service.addCharacteristic(hasModelTxChar); + inferenceTxChar.begin(); + + numClassesRxChar.begin(); + numSamplesRxChar.begin(); + captureDelayRxChar.begin(); + thresholdRxChar.begin(); + disableMagnetometerRx.begin(); + + stateRxChar.begin(); + stateTxChar.begin(); + fileTransferTypeRxChar.begin(); + hasModelTxChar.begin(); - service.addCharacteristic(metaRxChar); - service.addCharacteristic(metaTxChar); + metaRxChar.begin(); + metaTxChar.begin(); +#if 0 // Event driven reads. numClassesRxChar.setEventHandler(BLEWritten, handleNumClassesRxWritten); numSamplesRxChar.setEventHandler(BLEWritten, handleNumSamplesRxWritten); From a4679bd8a30eb31e6af58d1509e15d8ccc5fc647 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 16:41:57 +0700 Subject: [PATCH 11/24] add Char readFloat() and writeFloat() --- .../Bluefruit52Lib/src/BLECharacteristic.cpp | 11 +++++++++++ libraries/Bluefruit52Lib/src/BLECharacteristic.h | 16 +++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp b/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp index f728d8b0e..f344ef8bf 100644 --- a/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp +++ b/libraries/Bluefruit52Lib/src/BLECharacteristic.cpp @@ -609,6 +609,11 @@ uint16_t BLECharacteristic::write32(int num) return write32( (uint32_t) num ); } +uint16_t BLECharacteristic::writeFloat(float num) +{ + return write( (uint8_t*) &num, sizeof(num) ); +} + /*------------------------------------------------------------------*/ /* READ *------------------------------------------------------------------*/ @@ -652,6 +657,12 @@ uint32_t BLECharacteristic::read32(void) return read(&num, sizeof(num)) ? num : 0; } +float BLECharacteristic::readFloat(void) +{ + float num; + return read(&num, sizeof(num)) ? num : 0; +} + uint16_t BLECharacteristic::getCccd(uint16_t conn_hdl) { VERIFY( Bluefruit.connected(conn_hdl) && (_handles.cccd_handle != BLE_GATT_HANDLE_INVALID), 0 ); diff --git a/libraries/Bluefruit52Lib/src/BLECharacteristic.h b/libraries/Bluefruit52Lib/src/BLECharacteristic.h index 8ae795ff6..64b9d66e3 100644 --- a/libraries/Bluefruit52Lib/src/BLECharacteristic.h +++ b/libraries/Bluefruit52Lib/src/BLECharacteristic.h @@ -121,17 +121,19 @@ class BLECharacteristic uint16_t write (const void* data, uint16_t len); uint16_t write (const char* str); - uint16_t write8 (uint8_t num); - uint16_t write16 (uint16_t num); - uint16_t write32 (uint32_t num); - uint16_t write32 (int num); + uint16_t write8 (uint8_t num); + uint16_t write16 (uint16_t num); + uint16_t write32 (uint32_t num); + uint16_t write32 (int num); + uint16_t writeFloat (float num); /*------------- Read -------------*/ uint16_t read (void* buffer, uint16_t bufsize, uint16_t offset = 0); - uint8_t read8 (void); - uint16_t read16(void); - uint32_t read32(void); + uint8_t read8 (void); + uint16_t read16 (void); + uint32_t read32 (void); + float readFloat (void); uint16_t getCccd(uint16_t conn_hdl); From 68b04d4d9825a9e6725c6370d44ef1f07e0cd7c6 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 16:52:51 +0700 Subject: [PATCH 12/24] convert all write callback --- .../tf4micro-motion-kit.ino | 88 +++++++++++-------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 28cb8c3d5..26a4615d8 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -266,68 +266,86 @@ void setState(State state) * BLE Event handlers ************************************************************************/ -#if 0 -void handleNumSamplesRxWritten(BLEDevice central, BLECharacteristic characteristic) +void handleNumSamplesRxWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - model_tester::setNumSamples(numSamplesRxChar.value()); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + const int value = (int) numSamplesRxChar.read32(); + model_tester::setNumSamples(value); Serial.print("Received numSamples: "); - Serial.println(numSamplesRxChar.value()); + Serial.println(value); } -void handleThresholdRxWritten(BLEDevice central, BLECharacteristic characteristic) +void handleThresholdRxWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - model_tester::setThreshold(thresholdRxChar.value()); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + const float value = thresholdRxChar.readFloat(); + model_tester::setThreshold(value); Serial.print("Received threshold: "); - Serial.println(thresholdRxChar.value(), 4); + Serial.println(value, 4); } -void handleCaptureDelayRxWritten(BLEDevice central, BLECharacteristic characteristic) +void handleCaptureDelayRxWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - model_tester::setCaptureDelay(captureDelayRxChar.value()); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + const int value = captureDelayRxChar.read32(); + model_tester::setCaptureDelay(value); Serial.print("Received delay: "); - Serial.println(captureDelayRxChar.value()); + Serial.println(value); } -void handleNumClassesRxWritten(BLEDevice central, BLECharacteristic characteristic) +void handleNumClassesRxWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - model_tester::setNumClasses(numClassesRxChar.value()); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + const unsigned char value = (unsigned char) numClassesRxChar.read8(); + model_tester::setNumClasses(value); Serial.print("Received numClasses: "); - Serial.println(numClassesRxChar.value()); + Serial.println(value); } -void handleDisableMagnetometerRxWritten(BLEDevice central, BLECharacteristic characteristic) +void handleDisableMagnetometerRxWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - bool val = disableMagnetometerRx.value(); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + const bool val = (bool) disableMagnetometerRx.read8(); model_tester::setDisableMagnetometer(val); useMagnetometer = !val; Serial.print("Received disableMagnetometer: "); - Serial.println(disableMagnetometerRx.value()); + Serial.println(val); } -void handleStateWritten(BLEDevice central, BLECharacteristic characteristic) +void handleStateWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - setState((State)stateRxChar.value()); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + const uint8_t value = stateRxChar.read8(); + + setState((State) value); Serial.print("Received state: "); - Serial.println(stateRxChar.value()); + Serial.println(value); } -void handleMetaWritten(BLEDevice central, BLECharacteristic characteristic) +void handleMetaWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { + (void) conn_hdl; (void) chr; (void) data; (void) len; + // Meta is just a 64 byte storage for anything, just publish it - byte values[64]; - metaRxChar.readValue(values, 64); - metaTxChar.writeValue(values, 64); + metaTxChar.write(data, len); } -void handleFileTransferTypeWritten(BLEDevice central, BLECharacteristic characteristic) +void handleFileTransferTypeWritten(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { - fileTransferType = (FileTransferType)fileTransferTypeRxChar.value(); + (void) conn_hdl; (void) chr; (void) data; (void) len; + + fileTransferType = (FileTransferType) fileTransferTypeRxChar.read8(); Serial.print("Received fileTransferType: "); Serial.println(fileTransferType); } -#endif /************************************************************************ * Callbacks @@ -447,17 +465,17 @@ void setup() metaRxChar.begin(); metaTxChar.begin(); -#if 0 // Event driven reads. - numClassesRxChar.setEventHandler(BLEWritten, handleNumClassesRxWritten); - numSamplesRxChar.setEventHandler(BLEWritten, handleNumSamplesRxWritten); - thresholdRxChar.setEventHandler(BLEWritten, handleThresholdRxWritten); - captureDelayRxChar.setEventHandler(BLEWritten, handleCaptureDelayRxWritten); - stateRxChar.setEventHandler(BLEWritten, handleStateWritten); - fileTransferTypeRxChar.setEventHandler(BLEWritten, handleFileTransferTypeWritten); - metaRxChar.setEventHandler(BLEWritten, handleMetaWritten); - disableMagnetometerRx.setEventHandler(BLEWritten, handleDisableMagnetometerRxWritten); + numClassesRxChar.setWriteCallback(handleNumClassesRxWritten); + numSamplesRxChar.setWriteCallback(handleNumSamplesRxWritten); + thresholdRxChar.setWriteCallback(handleThresholdRxWritten); + captureDelayRxChar.setWriteCallback(handleCaptureDelayRxWritten); + stateRxChar.setWriteCallback(handleStateWritten); + fileTransferTypeRxChar.setWriteCallback(handleFileTransferTypeWritten); + metaRxChar.setWriteCallback(handleMetaWritten); + disableMagnetometerRx.setWriteCallback(handleDisableMagnetometerRxWritten); +#if 0 // Start the core BLE engine. if (!BLE.begin()) { From bbef3eb81b14bd6e532663b28811576e98dd88bd Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 19:20:28 +0700 Subject: [PATCH 13/24] got adv device name --- .../tf4micro-motion-kit.ino | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 26a4615d8..e2c60a00c 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -475,18 +475,13 @@ void setup() metaRxChar.setWriteCallback(handleMetaWritten); disableMagnetometerRx.setWriteCallback(handleDisableMagnetometerRxWritten); -#if 0 - // Start the core BLE engine. - if (!BLE.begin()) - { - Serial.println("Failed to initialized BLE!"); - setState(ERROR_STATE); - while (1) showErrorLed(); - } -#endif -#if 0 - String address = BLE.address(); + uint8_t mac[6]; + char mac_str[20]; + Bluefruit.getAddr(mac); + sprintf(mac_str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); + + String address(mac_str); // Output BLE settings over Serial. Serial.print("address = "); @@ -506,17 +501,13 @@ void setup() Serial.print("localName = "); Serial.println(deviceName); + // Set up properties for the whole service. - BLE.setLocalName(deviceName.c_str()); - BLE.setDeviceName(deviceName.c_str()); - BLE.setAdvertisedService(service); -#endif + Bluefruit.setName(deviceName.c_str()); // Advertising packet Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); Bluefruit.Advertising.addTxPower(); - - // Include bleuart 128-bit uuid Bluefruit.Advertising.addService(service); // Secondary Scan Response packet (optional) From f152527719cc974128914f3e941604757e5c47bd Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 22:07:45 +0700 Subject: [PATCH 14/24] port ble file transfer --- .../tf4micro-motion-kit/ble_file_transfer.cpp | 331 ++++++++++++++++++ .../tf4micro-motion-kit/ble_file_transfer.h | 31 ++ 2 files changed, 362 insertions(+) create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.h diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp new file mode 100644 index 000000000..ac5d14a1c --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp @@ -0,0 +1,331 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. +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. +==============================================================================*/ + +/* + * Original here: https://github.com/petewarden/ble_file_transfer + * Modified from original: + * - added name to namespace + * - moved to separate file with a header file + * - moved BLEService outside of namespace + */ + +#include "ble_file_transfer.h" + +// This is part of a simple demonstration of how to transfer small (tens of +// kilobytes) files over BLE onto an Arduino Nano BLE Sense board. Most of this +// sketch is internal implementation details of the protocol, but if you just +// want to use it you can look at the bottom of this file. +// The API is that you call setupBLEFileTransfer() in your setup() function to +// open up communication with any clients that want to send you files, and then +// onBLEFileReceived() is called when a file has been downloaded. + + +// Comment this macro back in to log received data to the serial UART. +//#define ENABLE_LOGGING + +namespace ble_file_transfer { + +// Controls how large a file the board can receive. We double-buffer the files +// as they come in, so you'll need twice this amount of RAM. The default is set +// to 50KB. +constexpr int32_t file_maximum_byte_count = (50 * 1024); + +// Macro based on a master UUID that can be modified for each characteristic. +#define FILE_TRANSFER_UUID(val) ("bf88b656-" val "-4a61-86e0-769c741026c0") + +// How big each transfer block can be. In theory this could be up to 512 bytes, but +// in practice I've found that going over 128 affects reliability of the connection. +constexpr int32_t file_block_byte_count = 128; + +// Where each data block is written to during the transfer. +BLECharacteristic file_block_characteristic(FILE_TRANSFER_UUID("3000"), BLEWrite, file_block_byte_count); + +// Write the expected total length of the file in bytes to this characteristic +// before sending the command to transfer a file. +BLECharacteristic file_length_characteristic(FILE_TRANSFER_UUID("3001"), BLERead | BLEWrite, sizeof(uint32_t)); + +// Read-only attribute that defines how large a file the sketch can handle. +BLECharacteristic file_maximum_length_characteristic(FILE_TRANSFER_UUID("3002"), BLERead, sizeof(uint32_t)); + +// Write the checksum that you expect for the file here before you trigger the transfer. +BLECharacteristic file_checksum_characteristic(FILE_TRANSFER_UUID("3003"), BLERead | BLEWrite, sizeof(uint32_t)); + +// Writing a command of 1 starts a file transfer (the length and checksum characteristics should already have been set). +// A command of 2 tries to cancel any pending file transfers. All other commands are undefined. +BLECharacteristic command_characteristic(FILE_TRANSFER_UUID("3004"), BLEWrite, sizeof(uint32_t)); + +// A status set to 0 means a file transfer succeeded, 1 means there was an error, and 2 means a file transfer is +// in progress. +BLECharacteristic transfer_status_characteristic(FILE_TRANSFER_UUID("3005"), BLERead | BLENotify, sizeof(uint32_t)); + +// Informative text describing the most recent error, for user interface purposes. +constexpr int32_t error_message_byte_count = 128; +BLECharacteristic error_message_characteristic(FILE_TRANSFER_UUID("3006"), BLERead | BLENotify, error_message_byte_count); + +// Internal globals used for transferring the file. +uint8_t file_buffers[2][file_maximum_byte_count]; +int finished_file_buffer_index = -1; +uint8_t* finished_file_buffer = nullptr; +int32_t finished_file_buffer_byte_count = 0; + +uint8_t* in_progress_file_buffer = nullptr; +int32_t in_progress_bytes_received = 0; +int32_t in_progress_bytes_expected = 0; +uint32_t in_progress_checksum = 0; + +void notifyError(const String& error_message) { + Serial.println(error_message); + constexpr int32_t error_status_code = 1; + transfer_status_characteristic.notify32((int) error_status_code); + + const char* error_message_bytes = error_message.c_str(); + uint8_t error_message_buffer[error_message_byte_count]; + bool at_string_end = false; + for (int i = 0; i < error_message_byte_count; ++i) { + const bool at_last_byte = (i == (error_message_byte_count - 1)); + if (!at_string_end && !at_last_byte) { + const char current_char = error_message_bytes[i]; + if (current_char == 0) { + at_string_end = true; + } else { + error_message_buffer[i] = current_char; + } + } + + if (at_string_end || at_last_byte) { + error_message_buffer[i] = 0; + } + } + error_message_characteristic.notify(error_message_buffer, error_message_byte_count); +} + +void notifySuccess() { + constexpr int32_t success_status_code = 0; + transfer_status_characteristic.notify32( (int) success_status_code); +} + +void notifyInProgress() { + constexpr int32_t in_progress_status_code = 2; + transfer_status_characteristic.notify32( (int) in_progress_status_code); +} + +// See http://home.thep.lu.se/~bjorn/crc/ for more information on simple CRC32 calculations. +uint32_t crc32_for_byte(uint32_t r) { + for (int j = 0; j < 8; ++j) { + r = (r & 1? 0: (uint32_t)0xedb88320L) ^ r >> 1; + } + return r ^ (uint32_t)0xff000000L; +} + +uint32_t crc32(const uint8_t* data, size_t data_length) { + constexpr int table_size = 256; + static uint32_t table[table_size]; + static bool is_table_initialized = false; + if (!is_table_initialized) { + for(size_t i = 0; i < table_size; ++i) { + table[i] = crc32_for_byte(i); + } + is_table_initialized = true; + } + uint32_t crc = 0; + for (size_t i = 0; i < data_length; ++i) { + const uint8_t crc_low_byte = static_cast(crc); + const uint8_t data_byte = data[i]; + const uint8_t table_index = crc_low_byte ^ data_byte; + crc = table[table_index] ^ (crc >> 8); + } + return crc; +} + +// This is a small test function for the CRC32 implementation, not normally called but left in +// for debugging purposes. We know the expected CRC32 of [97, 98, 99, 100, 101] is 2240272485, +// or 0x8587d865, so if anything else is output we know there's an error in the implementation. +void testCrc32() { + constexpr int test_array_length = 5; + const uint8_t test_array[test_array_length] = {97, 98, 99, 100, 101}; + const uint32_t test_array_crc32 = crc32(test_array, test_array_length); + Serial.println(String("CRC32 for [97, 98, 99, 100, 101] is 0x") + String(test_array_crc32, 16) + + String(" (") + String(test_array_crc32) + String(")")); +} + +void onFileTransferComplete() { + uint32_t computed_checksum = crc32(in_progress_file_buffer, in_progress_bytes_expected);; + if (in_progress_checksum != computed_checksum) { + notifyError(String("File transfer failed: Expected checksum 0x") + String(in_progress_checksum, 16) + + String(" but received 0x") + String(computed_checksum, 16)); + in_progress_file_buffer = nullptr; + return; + } + + if (finished_file_buffer_index == 0) { + finished_file_buffer_index = 1; + } else { + finished_file_buffer_index = 0; + } + finished_file_buffer = &file_buffers[finished_file_buffer_index][0];; + finished_file_buffer_byte_count = in_progress_bytes_expected; + + in_progress_file_buffer = nullptr; + in_progress_bytes_received = 0; + in_progress_bytes_expected = 0; + + notifySuccess(); + + onBLEFileReceived(finished_file_buffer, finished_file_buffer_byte_count); +} + +void onFileBlockWritten(uint16_t conn_hdl, BLECharacteristic* characteristic, uint8_t* data, uint16_t len) { + if (in_progress_file_buffer == nullptr) { + notifyError("File block sent while no valid command is active"); + return; + } + + const int32_t file_block_length = len; + if (file_block_length > file_block_byte_count) { + notifyError(String("Too many bytes in block: Expected ") + String(file_block_byte_count) + + String(" but received ") + String(file_block_length)); + in_progress_file_buffer = nullptr; + return; + } + + const int32_t bytes_received_after_block = in_progress_bytes_received + file_block_length; + if ((bytes_received_after_block > in_progress_bytes_expected) || + (bytes_received_after_block > file_maximum_byte_count)) { + notifyError(String("Too many bytes: Expected ") + String(in_progress_bytes_expected) + + String(" but received ") + String(bytes_received_after_block)); + in_progress_file_buffer = nullptr; + return; + } + + uint8_t* file_block_buffer = in_progress_file_buffer + in_progress_bytes_received; + memcpy(file_block_buffer, data, file_block_length); + +// Enable this macro to show the data in the serial log. +#ifdef ENABLE_LOGGING + Serial.print("Data received: length = "); + Serial.println(file_block_length); + + char string_buffer[file_block_byte_count + 1]; + for (int i = 0; i < file_block_byte_count; ++i) { + unsigned char value = file_block_buffer[i]; + if (i < file_block_length) { + string_buffer[i] = value; + } else { + string_buffer[i] = 0; + } + } + string_buffer[file_block_byte_count] = 0; + Serial.println(String(string_buffer)); +#endif // ENABLE_LOGGING + + if (bytes_received_after_block == in_progress_bytes_expected) { + onFileTransferComplete(); + } else { + in_progress_bytes_received = bytes_received_after_block; + } +} + +void startFileTransfer() { + if (in_progress_file_buffer != nullptr) { + notifyError("File transfer command received while previous transfer is still in progress"); + return; + } + + int32_t file_length_value = (int32_t) file_length_characteristic.read32(); + if (file_length_value > file_maximum_byte_count) { + notifyError( + String("File too large: Maximum is ") + String(file_maximum_byte_count) + + String(" bytes but request is ") + String(file_length_value) + String(" bytes")); + return; + } + + in_progress_checksum = file_checksum_characteristic.read32(); + + int in_progress_file_buffer_index; + if (finished_file_buffer_index == 0) { + in_progress_file_buffer_index = 1; + } else { + in_progress_file_buffer_index = 0; + } + + in_progress_file_buffer = &file_buffers[in_progress_file_buffer_index][0]; + in_progress_bytes_received = 0; + in_progress_bytes_expected = file_length_value; + + notifyInProgress(); +} + +void cancelFileTransfer() { + if (in_progress_file_buffer != nullptr) { + notifyError("File transfer cancelled"); + in_progress_file_buffer = nullptr; + } +} + +void onCommandWritten(uint16_t conn_hdl, BLECharacteristic* characteristic, uint8_t* data, uint16_t len) { + int32_t command_value = (int32_t) characteristic->read32(); + + if ((command_value != 1) && (command_value != 2)) { + notifyError(String("Bad command value: Expected 1 or 2 but received ") + String(command_value)); + return; + } + + if (command_value == 1) { + startFileTransfer(); + } else if (command_value == 2) { + cancelFileTransfer(); + } + +} + +// Starts the BLE handling you need to support the file transfer. +void setupBLEFileTransfer(BLEService service) { + + + // Add in the characteristics we'll be making available. + file_block_characteristic.setWriteCallback(onFileBlockWritten); + file_block_characteristic.begin(); + + file_length_characteristic.begin(); + + file_maximum_length_characteristic.write32((int) file_maximum_byte_count); + file_maximum_length_characteristic.begin(); + + file_checksum_characteristic.begin(); + + command_characteristic.setWriteCallback(onCommandWritten); + command_characteristic.begin(); + + transfer_status_characteristic.begin(); + error_message_characteristic.begin(); + + Serial.println("BLE setup and advertising"); +} + + +// Called in your loop function to handle BLE housekeeping. +void updateBLEFileTransfer() { +// BLEDevice central = BLE.central(); +// static bool was_connected_last = false; +// if (central && !was_connected_last) { +// Serial.print("Connected to central: "); +// Serial.println(central.address()); +// } +// was_connected_last = central; +} + + +bool isTransfering(){ + return in_progress_file_buffer != nullptr; +} + +} // namespace diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.h b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.h new file mode 100644 index 000000000..447009c61 --- /dev/null +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.h @@ -0,0 +1,31 @@ +/* Copyright 2021 Google LLC + +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 + + https://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. +==============================================================================*/ + +#ifndef BLE_FILE_TRANSFER_CPP +#define BLE_FILE_TRANSFER_CPP + +//#include +#include + +// Forward declare the function that will be called when data has been delivered to us. +void onBLEFileReceived(uint8_t* file_data, int file_length); + +namespace ble_file_transfer{ + void updateBLEFileTransfer(); + bool isTransfering(); + void setupBLEFileTransfer(BLEService service); +} + +#endif // BLE_FILE_TRANSFER_CPP From 1ce065ef00a060942d67699313cf8c3673520b04 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 22:58:33 +0700 Subject: [PATCH 15/24] add BLEUuid toString() --- libraries/Bluefruit52Lib/src/BLEUuid.cpp | 19 +++++++++++++++++++ libraries/Bluefruit52Lib/src/BLEUuid.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/libraries/Bluefruit52Lib/src/BLEUuid.cpp b/libraries/Bluefruit52Lib/src/BLEUuid.cpp index a80229be6..667a79be7 100644 --- a/libraries/Bluefruit52Lib/src/BLEUuid.cpp +++ b/libraries/Bluefruit52Lib/src/BLEUuid.cpp @@ -151,6 +151,25 @@ bool BLEUuid::begin(void) return true; } +String BLEUuid::toString(void) const +{ + if (_str) return _str; + + char result[38]; + if (this->size() == 16) + { + sprintf(result, "%02X:%02X", _uuid.uuid); + }else + { + // uuid is little endian + sprintf(result, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + _uuid128[15], _uuid128[14], _uuid128[13], _uuid128[12], _uuid128[11], _uuid128[10], _uuid128[ 9], _uuid128[ 8], + _uuid128[ 7], _uuid128[ 6], _uuid128[ 5], _uuid128[ 4], _uuid128[ 3], _uuid128[ 2], _uuid128[ 1], _uuid128[ 0]); + } + + return result; +} + //--------------------------------------------------------------------+ // Set & Get //--------------------------------------------------------------------+ diff --git a/libraries/Bluefruit52Lib/src/BLEUuid.h b/libraries/Bluefruit52Lib/src/BLEUuid.h index 287b8456b..e29b95241 100644 --- a/libraries/Bluefruit52Lib/src/BLEUuid.h +++ b/libraries/Bluefruit52Lib/src/BLEUuid.h @@ -66,6 +66,8 @@ class BLEUuid // Add UUID128 if needed, in case of UUID16, no actions is required bool begin(void); + String toString(void) const; + bool operator==(const BLEUuid& uuid) const; bool operator!=(const BLEUuid& uuid) const; bool operator==(const ble_uuid_t uuid) const; From 1661be0a1dc94bac5354a6d25d5dcf681d22c31e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 23:05:46 +0700 Subject: [PATCH 16/24] able to add ble file transfer chars --- .../tf4micro-motion-kit/ble_file_transfer.cpp | 2 +- .../tf4micro-motion-kit.ino | 25 ++++++------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp index ac5d14a1c..1185fbbbf 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/ble_file_transfer.cpp @@ -297,8 +297,8 @@ void setupBLEFileTransfer(BLEService service) { file_length_characteristic.begin(); - file_maximum_length_characteristic.write32((int) file_maximum_byte_count); file_maximum_length_characteristic.begin(); + file_maximum_length_characteristic.write32((int) file_maximum_byte_count); file_checksum_characteristic.begin(); diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index e2c60a00c..c12a69f52 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -15,18 +15,17 @@ limitations under the License. /* * @author Rikard Lindstrom +* */ #define VERSION 5 #define FLOAT_BYTE_SIZE 4 -//#include - #include #include #include -//#include "ble_file_transfer.h" +#include "ble_file_transfer.h" #include "model_tester.h" #include "data_provider.h" @@ -186,11 +185,7 @@ void updateLed() case IDLE_DISCONNECTED: case IDLE_CONNECTED: default: -#if 0 - if (BLE.connected()) -#else - if (1) -#endif + if (Bluefruit.connected()) { rgbLedBlue(); } @@ -439,7 +434,7 @@ void setup() } Bluefruit.autoConnLed(true); - Bluefruit.configUuid128Count(20); + Bluefruit.configUuid128Count(25); Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); Bluefruit.begin(); Bluefruit.setTxPower(4); @@ -479,7 +474,7 @@ void setup() uint8_t mac[6]; char mac_str[20]; Bluefruit.getAddr(mac); - sprintf(mac_str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); String address(mac_str); @@ -519,7 +514,6 @@ void setup() Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds -#if 0 ble_file_transfer::setupBLEFileTransfer(service); // Print out full UUID and MAC address. @@ -527,16 +521,11 @@ void setup() Serial.print("Name: "); Serial.println(LOCAL_NAME); Serial.print("MAC: "); - Serial.println(BLE.address()); + Serial.println(mac_str); Serial.print("Service UUID: "); - Serial.println(service.uuid()); - - // Start up the service itself. - BLE.addService(service); - BLE.advertise(); + Serial.println(service.uuid.toString()); Serial.println("Bluetooth device active, waiting for connections..."); -#endif // Broadcast sketch version versionTxChar.write8(VERSION); From 1f83e4c623e67240142fb67da122b0217247a234 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 23:13:27 +0700 Subject: [PATCH 17/24] port the whole tf4 sketch --- .../tf4micro-motion-kit.ino | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index c12a69f52..7b3ce8cb9 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -15,9 +15,10 @@ limitations under the License. /* * @author Rikard Lindstrom -* */ +// Ported to Adafruit_nRF52_Arduino core by hathach for Adafruit + #define VERSION 5 #define FLOAT_BYTE_SIZE 4 @@ -147,11 +148,7 @@ void updateLed() { case FILE_TRANSFER: -#if 0 if (ble_file_transfer::isTransfering()) -#else - if (0) -#endif { // Rapid blink while transfering is in progress millis() % 100 > 50 ? rgbLedOff() : rgbLedYellow(); @@ -225,9 +222,7 @@ void setState(State state) prevState = currentState; } currentState = state; -#if 0 - stateTxChar.writeValue((unsigned char)state); -#endif + stateTxChar.notify8((unsigned char)state); switch (currentState) { case IDLE_DISCONNECTED: @@ -350,9 +345,7 @@ void handleFileTransferTypeWritten(uint16_t conn_hdl, BLECharacteristic* chr, ui void model_tester_onInference(unsigned char classIndex, unsigned char score, unsigned char velocity) { const byte buffer[]{classIndex, score, velocity}; -#if 0 - inferenceTxChar.setValue(buffer, 3); -#endif + inferenceTxChar.notify(buffer, 3); Serial.print("Inference - class: "); Serial.print(classIndex); Serial.print(" score: "); @@ -549,18 +542,17 @@ inline void updateIMU() model_tester::update(buffer); } } -#if 0 + if(currentState == IMU_DATA_PROVIDER || currentState == INFERENCE_AND_DATA_PROVIDER){ // provide data to IMU trainer - dataProviderTxChar.writeValue(buffer, bufferSize * FLOAT_BYTE_SIZE); + dataProviderTxChar.notify(buffer, bufferSize * FLOAT_BYTE_SIZE); } -#endif + } } inline void updateFileTransfer() { -#if 0 // Update file transfer state ble_file_transfer::updateBLEFileTransfer(); @@ -572,19 +564,17 @@ inline void updateFileTransfer() Serial.println("done reloading model"); newModelFileData = nullptr; - hasModelTxChar.writeValue(true); + hasModelTxChar.notify8(true); // We have a new model, always enter INFERENCE mode setState(INFERENCE); } -#endif } void loop() { -#if 0 // Make sure we're connected and not busy file-transfering - if (BLE.connected()) + if (Bluefruit.connected()) { switch (currentState) { @@ -607,7 +597,6 @@ void loop() } else if(currentState != IDLE_DISCONNECTED){ setState(IDLE_DISCONNECTED); } -#endif // Update led based on state updateLed(); From ec4713fd95f98122fc80a87c3ddf23fab4800c91 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Jun 2021 23:23:28 +0700 Subject: [PATCH 18/24] temporarily comment out mag field in data provider --- .../Peripheral/tf4micro-motion-kit/data_provider.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp index f7f1bb950..87bb5de0b 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp @@ -18,7 +18,10 @@ limitations under the License. * @author Rikard Lindstrom */ #include "data_provider.h" -#include // change to Arduino_LSM6DS3.h for Nano 33 IoT or Uno WiFi Rev 2 +//#include // change to Arduino_LSM6DS3.h for Nano 33 IoT or Uno WiFi Rev 2 +//#include + +#include namespace data_provider { @@ -71,9 +74,10 @@ namespace data_provider Serial.println(IMU.accelerationSampleRate()); Serial.print("Gyroscope sample rate = "); Serial.println(IMU.gyroscopeSampleRate()); +#if 0 Serial.print("Magnetometer sample rate = "); Serial.println(IMU.magneticFieldSampleRate()); - +#endif return true; } @@ -101,6 +105,7 @@ namespace data_provider buffer[4] = gy / 2000.0; buffer[5] = gz / 2000.0; +#if 0 if (useMagnetometer || calibrating) { float mx, my, mz; @@ -156,5 +161,6 @@ namespace data_provider buffer[7] = my / 50.0; buffer[8] = mz / 50.0; } +#endif } } From 74b64da4238ae9822cc2429983c7fd7e4fe52407 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Jun 2021 00:14:43 +0700 Subject: [PATCH 19/24] complete motion trainer with magnetic sensor --- .../.cluenrf52840.test.only | 0 .../.feather52840sense.test.only | 0 .../tf4micro-motion-kit/data_provider.cpp | 29 ++++++++++++------- .../tf4micro-motion-kit.ino | 6 ++-- 4 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/.cluenrf52840.test.only create mode 100644 libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/.feather52840sense.test.only diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/.cluenrf52840.test.only b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/.cluenrf52840.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/.feather52840sense.test.only b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/.feather52840sense.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp index 87bb5de0b..5a79573df 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp @@ -18,10 +18,21 @@ limitations under the License. * @author Rikard Lindstrom */ #include "data_provider.h" + +#if defined(ARDUINO_NRF52840_CLUE) || defined(ARDUINO_NRF52840_FEATHER_SENSE) + +#include +#include + +Adafruit_LSM6DS33 IMU; // Gyro and Accel +Adafruit_LIS3MDL IMUMag; // Magnetometer + +#else + +#error "Sensor driver library for your is not included" //#include // change to Arduino_LSM6DS3.h for Nano 33 IoT or Uno WiFi Rev 2 -//#include -#include +#endif namespace data_provider { @@ -57,7 +68,7 @@ namespace data_provider bool setup() { - if (!IMU.begin()) + if ( !(IMU.begin_I2C() && IMUMag.begin_I2C()) ) { Serial.println("Failed to initialized IMU!"); return false; @@ -74,10 +85,10 @@ namespace data_provider Serial.println(IMU.accelerationSampleRate()); Serial.print("Gyroscope sample rate = "); Serial.println(IMU.gyroscopeSampleRate()); -#if 0 + Serial.print("Magnetometer sample rate = "); - Serial.println(IMU.magneticFieldSampleRate()); -#endif + Serial.println(IMUMag.magneticFieldSampleRate()); + return true; } @@ -105,16 +116,15 @@ namespace data_provider buffer[4] = gy / 2000.0; buffer[5] = gz / 2000.0; -#if 0 if (useMagnetometer || calibrating) { float mx, my, mz; // The Magnetometer sample rate is only 20hz, so we'll use previous values // if no new ones are available - if (IMU.magneticFieldAvailable()) + if (IMUMag.magneticFieldAvailable()) { - IMU.readMagneticField(mx, my, mz); + IMUMag.readMagneticField(mx, my, mz); lastMagneticFieldReading[0] = mx; lastMagneticFieldReading[1] = my; lastMagneticFieldReading[2] = mz; @@ -161,6 +171,5 @@ namespace data_provider buffer[7] = my / 50.0; buffer[8] = mz / 50.0; } -#endif } } diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 7b3ce8cb9..36b05eeb7 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -139,7 +139,7 @@ void showErrorLed() { // blink red millis() % 1000 > 500 ? rgbLedOff() : rgbLedRed(); - delay(500); + yield(); } void updateLed() @@ -412,12 +412,10 @@ void setup() while (!Serial && millis() - startTime < 2000) yield(); - Serial.println("Bluefruit52 Example"); - Serial.println("-------------------\n"); - // Prepare LED pins. pinMode(LED_BUILTIN, OUTPUT); neopixels.begin(); + neopixels.setBrightness(0x20); // Start IMU / Data provider. if (!data_provider::setup()) From 76579e48fc5ed07ede1bde7378ee07e2339c1ccf Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Jun 2021 00:14:52 +0700 Subject: [PATCH 20/24] fix warning --- libraries/Bluefruit52Lib/src/BLEUuid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Bluefruit52Lib/src/BLEUuid.cpp b/libraries/Bluefruit52Lib/src/BLEUuid.cpp index 667a79be7..9480d9a21 100644 --- a/libraries/Bluefruit52Lib/src/BLEUuid.cpp +++ b/libraries/Bluefruit52Lib/src/BLEUuid.cpp @@ -158,7 +158,7 @@ String BLEUuid::toString(void) const char result[38]; if (this->size() == 16) { - sprintf(result, "%02X:%02X", _uuid.uuid); + sprintf(result, "%02X%02X", highByte(_uuid.uuid), lowByte(_uuid.uuid)); }else { // uuid is little endian From b5820b0ae4bb1a72418dc605f5fdb16205e92f99 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Jun 2021 00:20:16 +0700 Subject: [PATCH 21/24] add example doc --- .../tf4micro-motion-kit/tf4micro-motion-kit.ino | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 36b05eeb7..55ddaf52b 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -17,7 +17,15 @@ limitations under the License. * @author Rikard Lindstrom */ -// Ported to Adafruit_nRF52_Arduino core by hathach for Adafruit +// Ported to Adafruit_nRF52_Arduino core by hathach for Adafruit from +// https://github.com/googlecreativelab/tiny-motion-trainer +// +// Boards equipped with IMU sensor such as Clue and Feather nRF52840 Sense are supported +// out of the box. If you use other board, or sensor please edit the 'data_provider.cpp' file +// to include driver libraries for yours. + +// For how to run this example check out following +// https://experiments.withgoogle.com/tiny-motion-trainer #define VERSION 5 #define FLOAT_BYTE_SIZE 4 From 0e1357d8af91cf58c4f8510e48e2914862f058f2 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 14 Jun 2021 15:11:29 +0700 Subject: [PATCH 22/24] normalize sensor orientation for feather sense and clue --- .../tf4micro-motion-kit/data_provider.cpp | 41 +++++++++++++++++-- .../tf4micro-motion-kit.ino | 3 +- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp index 5a79573df..70a432e97 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/data_provider.cpp @@ -21,16 +21,43 @@ limitations under the License. #if defined(ARDUINO_NRF52840_CLUE) || defined(ARDUINO_NRF52840_FEATHER_SENSE) -#include #include +#include Adafruit_LSM6DS33 IMU; // Gyro and Accel Adafruit_LIS3MDL IMUMag; // Magnetometer -#else +#if defined ARDUINO_NRF52840_FEATHER_SENSE + // normalize sensor orientation to match Arduino nano + void normalize_orientation(float& x, float& y, float& z) + { + (void) x; + (void) z; + + y = -y; + } + +#elif defined ARDUINO_NRF52840_CLUE + // normalize sensor orientation to match Arduino nano + void normalize_orientation(float& x, float& y, float& z) + { + float temp = x; + + x = -y; + y = temp; // x + z = -z; + } +#endif + +#else // For custom boards, please include your own sensor #error "Sensor driver library for your is not included" -//#include // change to Arduino_LSM6DS3.h for Nano 33 IoT or Uno WiFi Rev 2 + +// normalize sensor orientation to match Arduino nano +void normalize_orientation(float& x, float& y, float& z) +{ + (void) x; (void) y; (void) z; +} #endif @@ -106,6 +133,10 @@ namespace data_provider IMU.readAcceleration(ax, ay, az); IMU.readGyroscope(gx, gy, gz); + // normalize sensor orientation to match Arduino nano + normalize_orientation(ax, ay, az); + normalize_orientation(gx, gy, gz); + // Accelorameter has a range of -4 – 4 buffer[0] = ax / 4.0; buffer[1] = ay / 4.0; @@ -125,6 +156,10 @@ namespace data_provider if (IMUMag.magneticFieldAvailable()) { IMUMag.readMagneticField(mx, my, mz); + + // normalize sensor orientation to match Arduino nano + normalize_orientation(mx, my, mz); + lastMagneticFieldReading[0] = mx; lastMagneticFieldReading[1] = my; lastMagneticFieldReading[2] = mz; diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index 55ddaf52b..b18cac673 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -25,7 +25,8 @@ limitations under the License. // to include driver libraries for yours. // For how to run this example check out following -// https://experiments.withgoogle.com/tiny-motion-trainer +// - https://github.com/googlecreativelab/tf4micro-motion-kit +// - https://experiments.withgoogle.com/collection/tfliteformicrocontrollers #define VERSION 5 #define FLOAT_BYTE_SIZE 4 From 5a98e4b7677adfad90217c34408869ab6c03ec5d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 14 Jun 2021 22:35:55 +0700 Subject: [PATCH 23/24] add local display for CLUE for AirSnare and FingerUserInterface --- .../tf4micro-motion-kit/model_tester.cpp | 4 +- .../tf4micro-motion-kit.ino | 107 ++++++++++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp index b07f0eee7..9b6517921 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/model_tester.cpp @@ -100,7 +100,7 @@ namespace model_tester { Serial.println("Model schema mismatch!"); while (1) - ; + delay(1); } // Create an interpreter to run the model @@ -191,7 +191,7 @@ namespace model_tester { Serial.println("Invoke failed!"); while (1) - ; + delay(1); return; } #ifdef DEBUG diff --git a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino index b18cac673..13b6f8b33 100644 --- a/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino +++ b/libraries/Bluefruit52Lib/examples/Peripheral/tf4micro-motion-kit/tf4micro-motion-kit.ino @@ -110,6 +110,96 @@ BLECharacteristic metaTxChar (UUID_GEN("4002") , BLERead uint8_t *newModelFileData = nullptr; int newModelFileLength = 0; +/************************************************************************ +* Labels for local display +************************************************************************/ + +// Currently there is no set Labels, this used actual data matched with 2 examples +// "Air Snare" and "Finger User Interface" to display TFT locally + +// from ARCADA color +#define COLOR_BLACK 0x0000 ///< 0, 0, 0 +#define COLOR_BLUE 0x001F ///< 0, 0, 255 +#define COLOR_GREEN 0x07E0 ///< 0, 255, 0 +#define COLOR_CYAN 0x07FF ///< 0, 255, 255 +#define COLOR_RED 0xF800 ///< 255, 0, 0 +#define COLOR_MAGENTA 0xF81F ///< 255, 0, 255 +#define COLOR_YELLOW 0xFFE0 ///< 255, 255, 0 +#define COLOR_WHITE 0xFFFF ///< 255, 255, 255 +#define COLOR_ORANGE 0xFD20 ///< 255, 165, 0 +#define COLOR_PINK 0xFC18 ///< 255, 130, 198 + +const char* labelAirSnare[] = { + "Side", "Down", "Up" +}; + +const char* labelFingerUserInterface[] = { + "Left", "Right", "Poke", "Twirl", "Pluck" +}; + +const char** modelLabel = NULL; + +// detect model label +const char** detectModelLabel(int file_length) { + uint8_t const numClasses = numClassesRxChar.read8(); + + if ( (numClasses == 3) && ( (file_length / 1000) == 17 ) ) { + return labelAirSnare; + } + + if ( (numClasses == 5) && ( (file_length / 1000) == 35 ) ) { + return labelFingerUserInterface; + } + + return NULL; +} + +uint16_t const color_pallete[] = { + COLOR_BLUE, + COLOR_GREEN, // Green + COLOR_YELLOW, // Yellow + COLOR_CYAN, // Cyan + COLOR_PINK, // Pink + COLOR_MAGENTA, // MAGENTA + COLOR_ORANGE, // Orange + COLOR_RED, // Red +}; + +#if defined(ARDUINO_NRF52840_CLUE) + +// use arcada for display +#include + +Adafruit_Arcada arcada; + +void displayInit(void) { + arcada.displayBegin(); + arcada.setBacklight(255); + + Adafruit_SPITFT* tft = arcada.display; + + tft->fillScreen(COLOR_BLACK); + tft->setRotation(3); +} + +void displayText(const char* text, uint8_t size, uint16_t color) { + Adafruit_SPITFT* tft = arcada.display; + + tft->fillScreen(COLOR_BLACK); + tft->setTextColor(color); + tft->setTextSize(size); + tft->setCursor(60, 100); + tft->print(text); +} + +#else + +// stub for no-tft board +void displayText(const char* text, uint8_t size, uint16_t color) { (void) text; (void) size; (void) color; } +void displayInit(void) { } + +#endif + /************************************************************************ * LED / State status functions ************************************************************************/ @@ -242,6 +332,11 @@ void setState(State state) break; case FILE_TRANSFER: Serial.println("state is now FILE_TRANSFER"); + displayText("Dwnloading", 3, COLOR_ORANGE); + break; + case INFERENCE: + Serial.println("state is now INFERENCE"); + displayText("Ready", 3, COLOR_GREEN); break; case IMU_DATA_PROVIDER: Serial.println("state is now IMU_DATA_PROVIDER"); @@ -359,6 +454,11 @@ void model_tester_onInference(unsigned char classIndex, unsigned char score, uns Serial.print(classIndex); Serial.print(" score: "); Serial.println(score); + + if ( modelLabel ) { + // display label on TFT use index as color id + displayText(modelLabel[classIndex], 5, color_pallete[classIndex]); + } } // called when calibration completes @@ -369,6 +469,12 @@ void data_provider_calibrationComplete(){ // called on file transfer complete void onBLEFileReceived(uint8_t *file_data, int file_length) { + Serial.print("file length "); + Serial.println(file_length); + + // detect label of model for local display + modelLabel = detectModelLabel(file_length); + switch (fileTransferType) { case MODEL_FILE: @@ -425,6 +531,7 @@ void setup() pinMode(LED_BUILTIN, OUTPUT); neopixels.begin(); neopixels.setBrightness(0x20); + displayInit(); // Start IMU / Data provider. if (!data_provider::setup()) From 556f36de1781a02f3ca38eb29b79b0165990978d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 21 Jun 2021 23:16:08 +0700 Subject: [PATCH 24/24] clean up --- platform.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform.txt b/platform.txt index 50eab070a..9096ab179 100644 --- a/platform.txt +++ b/platform.txt @@ -72,8 +72,6 @@ compiler.elf2bin.extra_flags= compiler.elf2hex.extra_flags= compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.7.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.7.0.path}/CMSIS/DSP/Include/" - -# TODO enable linking with libmath later on compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.7.0.path}/CMSIS/DSP/Lib/GCC/" -larm_cortexM4lf_math # common compiler for nrf