diff --git a/Makefile b/Makefile index fb2b301..e410049 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +SKETCH_PATH = $(shell pwd)/sketches/BLE_Scratch scratch-gui-version = v3.2.37 .PHONY: init @@ -35,3 +36,32 @@ fmt: fmt-check: npx prettier --check "scratch-arduino-extensions/**/*.{js,jsx,ts,tsx,json,css,scss,md}" find . -name '*.ino' -or -name '*.cpp' -or -name '*.h' | xargs clang-format -n -Werror + +.PHONY: compile-all +compile-all: compile-nano33ble compile-nanorp2040connect + +.PHONY: compile-nano33ble +compile-nano33ble: + arduino-cli compile -v -e --profile nano33ble ${SKETCH_PATH} + +.PHONY: compile-nanorp2040connect +compile-nanorp2040connect: + arduino-cli compile -v -e --profile nanorp2040connect ${SKETCH_PATH} + +.PHONY: upload-nano33ble +upload-nano33ble: + arduino-cli upload -v \ + -i "${SKETCH_PATH}/build/arduino.mbed_nano.nano33ble/BLE_Scratch.ino.bin" \ + -b arduino:mbed_nano:nano33ble \ + -p "$(shell arduino-cli board list | grep "arduino:mbed_nano:nano33ble" | awk '{print $$1}' | head -n 1)" + +.PHONY: upload-nanorp2040connect +upload-nanorp2040connect: + arduino-cli upload -v \ + -i "${SKETCH_PATH}/build/arduino.mbed_nano.nanorp2040connect/BLE_Scratch.ino.bin" \ + -b arduino:mbed_nano:nanorp2040connect \ + -p "$(shell arduino-cli board list | grep "arduino:mbed_nano:nanorp2040connect" | awk '{print $$1}' | head -n 1)" + +.PHONY: monitor +monitor: + sh -c "arduino-cli monitor -p "$(shell arduino-cli board list | grep -E "arduino:mbed_nano:nano33ble|arduino:mbed_nano:nanorp2040connect" | awk '{print $$1}' | head -n 1)"" diff --git a/scripts/compile.sh b/scripts/compile.sh deleted file mode 100755 index 0a21949..0000000 --- a/scripts/compile.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -xe - -base=$(dirname "$0") - -arduino-cli -v compile -b arduino:mbed_nano:nano33ble -e "$base/../sketches/BLE_Scratch/BLE_Scratch.ino" diff --git a/scripts/upload.sh b/scripts/upload.sh deleted file mode 100755 index 3e84c4a..0000000 --- a/scripts/upload.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -xe - -base=$(dirname "$0") -binary="$base/../sketches/BLE_Scratch/build/arduino.mbed_nano.nano33ble/BLE_Scratch.ino.bin.cfg.bin" - -port=$(arduino-cli board list | grep "arduino:mbed_nano:nano33ble" | awk '{print $1}' | head -n 1) - -arduino-cli upload -v \ - -i "$binary" \ - -b arduino:mbed_nano:nano33ble \ - -p "$port" diff --git a/sketches/BLE_Scratch/BLE_Scratch.ino b/sketches/BLE_Scratch/BLE_Scratch.ino index 3c62cd2..adb47c9 100644 --- a/sketches/BLE_Scratch/BLE_Scratch.ino +++ b/sketches/BLE_Scratch/BLE_Scratch.ino @@ -1,37 +1,49 @@ // BLE Scratch v3 / Connect BLE Sense boards to Scratch via Bluetooth // 2023.03.04 Added support for BLE Sense R2 and STOPSERVO command - -// Uncomment one of these defines to select which board you are using - -//#define ARDUINO_NANO_BLE_SENSE +// Select the variant of the NANO 33 BLE +#ifdef ARDUINO_ARDUINO_NANO33BLE //#define ARDUINO_NANO_BLE +//#define ARDUINO_NANO_BLE_SENSE #define ARDUINO_NANO_BLE_SENSE_R2 +#endif // when this is defined the board will print debug messages on serial -// #define DEBUG +#define DEBUG // when this is defined the board fail if a sensor fails to initialize -// #define SENSOR_CHECKS +#define SENSOR_CHECKS -#if defined(ARDUINO_NANO_BLE_SENSE) +#ifdef ARDUINO_NANO_BLE_SENSE #include #include #include #include #endif -#if defined(ARDUINO_NANO_BLE_SENSE_R2) +#ifdef ARDUINO_NANO_BLE_SENSE_R2 #include #include #include #include #endif -#if defined(ARDUINO_NANO_BLE) +#ifdef ARDUINO_NANO_BLE #include #endif +#ifdef ARDUINO_NANO_RP2040_CONNECT +#include +#include +const int lred = LEDR.get(); +const int lgreen = LEDG.get(); +const int lblue = LEDB.get(); +#else +const int lred = LEDR; +const int lgreen = LEDG; +const int lblue = LEDB; +#endif + #include #include #include @@ -43,7 +55,7 @@ const int VERSION = 0x00000000; const uint8_t HEADER[] = { 0x8a, 0x48, 0x92, 0xdf, 0xaa, 0x69, 0x5c, 0x41 }; const uint8_t MAGIC = 0x7F; -const uint32_t MEMORY_SIZE = 0x80000; // 512KB +const uint32_t MEMORY_SIZE = 0x500000; // 5MB // Config values String myname; @@ -64,23 +76,39 @@ BLECharacteristic pinRobotCharacteristic(BLE_SENSE_UUID("6003"), BLEWrite, 3 * s // delay beafore each sensor getter int delayTime = 10; -// Sensor data -int red = 0, green = 0, blue = 0, ambientLight = 0; -int proximity = 255; - -void printSerialMsg(const char *msg) { +void printMsg(const char *msg) { if (Serial) { Serial.println(msg); } } +template +void printValues(const char* name, T value) { + if (Serial) { + Serial.print(name); + Serial.print("="); + Serial.println(value); + } +} +template +void printValues(const char* name, T value, Args... args) { + if (Serial) { + Serial.print(name); + Serial.print("="); + Serial.print(value); + Serial.print(" "); + printValues(args...); + } +} + uint32_t get_config_bytes(uint8_t *buff, const uint32_t n) { auto search_in_mem = [](const uint32_t start, const uint32_t end, const uint8_t *buff, const int size) -> int32_t { if (start >= end || size <= 0) { return -1; } - for (int i = start; i <= end - size; i++) { + for (uint32_t i = start; i <= end - size; i++) { + // printValues("i", i); if (memcmp(reinterpret_cast(i), buff, size) == 0) { return i; } @@ -89,19 +117,19 @@ uint32_t get_config_bytes(uint8_t *buff, const uint32_t n) { return -1; }; - uint32_t addr = 0; + uint32_t addr = XIP_BASE; while (1) { - auto found = search_in_mem(addr, MEMORY_SIZE, HEADER, sizeof(HEADER)); + auto found = search_in_mem(addr, XIP_BASE + MEMORY_SIZE, HEADER, sizeof(HEADER)); if (found == -1) { - printSerialMsg("config header not found"); + printMsg("config header not found"); return 0; } - printSerialMsg("config header founded"); + printMsg("config header founded"); uint8_t magic = *reinterpret_cast(found + sizeof(HEADER)); if (magic == MAGIC) { - printSerialMsg("config magic number founded"); + printMsg("config magic number founded"); uint8_t size = *reinterpret_cast(found + sizeof(HEADER) + 1); memcpy(buff, reinterpret_cast(found + sizeof(HEADER) + 2), min(size, n)); @@ -121,41 +149,41 @@ bool init_sensors() { #if defined(ARDUINO_NANO_BLE_SENSE) if (!APDS.begin()) { - printSerialMsg("Failed to initialized APDS!"); + printMsg("Failed to initialized APDS!"); ok = false; } if (!HTS.begin()) { - printSerialMsg("Failed to initialized HTS!"); + printMsg("Failed to initialized HTS!"); ok = false; } if (!BARO.begin()) { - printSerialMsg("Failed to initialized BARO!"); + printMsg("Failed to initialized BARO!"); ok = false; } #endif #if defined(ARDUINO_NANO_BLE_SENSE_R2) if (!APDS.begin()) { - printSerialMsg("Failed to initialized APDS!"); + printMsg("Failed to initialized APDS!"); ok = false; } if (!HS300x.begin()) { - printSerialMsg("Failed to initialized HTS!"); + printMsg("Failed to initialized HTS!"); ok = false; } if (!BARO.begin()) { - printSerialMsg("Failed to initialized BARO!"); + printMsg("Failed to initialized BARO!"); ok = false; } #endif // All 3 variants have an IMU on it if (!IMU.begin()) { - printSerialMsg("Failed to initialized IMU!"); + printMsg("Failed to initialized IMU!"); ok = false; } @@ -164,44 +192,41 @@ bool init_sensors() { void setup() { Serial.begin(9600); + #ifdef DEBUG - while (!Serial) - ; - Serial.println("Started"); + while (!Serial); #endif + printMsg("Starting"); auto ok = init_sensors(); #ifdef SENSOR_CHECKS if (!ok) { - while (1) - ; + while (1); } #endif // get binary leading config and interpret as string uint8_t cfg[100]; auto n = get_config_bytes(cfg, 100); + // auto n = 0; if (n != 0) { MsgPack::Unpacker unpacker; unpacker.feed(cfg, n); unpacker.deserialize(myname, rservo, lservo); + printValues("myname", myname, "rservo", rservo, "lservo", lservo); } myra = Robot(rservo, lservo); if (!BLE.begin()) { - printSerialMsg("Failed to initialized BLE!"); + printMsg("Failed to initialized BLE!"); - while (1) - ; + while (1); } String address = BLE.address(); - if (Serial) { - Serial.print("address = "); - Serial.println(address); - } + printValues("address", address); address.toUpperCase(); String name("BLESense-"); @@ -213,11 +238,7 @@ void setup() { name += address[address.length() - 2]; name += address[address.length() - 1]; } - - if (Serial) { - Serial.print("name = "); - Serial.println(name); - } + printValues("name", name); BLE.setLocalName(name.c_str()); BLE.setDeviceName(name.c_str()); @@ -251,89 +272,85 @@ enum bleNotification notificationState = NOTIFY_FIRST_PART; void loop() { while (BLE.connected()) { if (sensorsData.subscribed()) { - switch (notificationState) { case NOTIFY_FIRST_PART: sendFirstPartData(); notificationState = NOTIFY_SECOND_PART; break; - case NOTIFY_SECOND_PART: sendSecondPartData(); notificationState = NOTIFY_FIRST_PART; break; - - default: - notificationState = NOTIFY_FIRST_PART; } } } } - - void sendFirstPartData() { - - + float temperature = 0, + pressure = 0, + humidity = 0, + magneticFieldX = 0, magneticFieldY = 0, magneticFieldZ = 0, + accelerationX = 0, accelerationY = 0, accelerationZ = 0, + gyroscopeX = 0, gyroscopeY = 0, gyroscopeZ = 0; + +/* + Temperature +*/ #if defined(ARDUINO_NANO_BLE_SENSE) - /* - BARO sensor - */ - float pressure = BARO.readPressure(); + temperature = HTS.readTemperature(); delay(delayTime); - - /* - HTS sensor - */ - float temperature = HTS.readTemperature(); +#elif defined(ARDUINO_NANO_BLE_SENSE_R2) + temperature = HS300x.readTemperature(); delay(delayTime); +#elif defined(ARDUINO_NANO_RP2040_CONNECT) + if (IMU.temperatureAvailable()) { + int t; + IMU.readTemperature(t); + temperature = (float)t; + } +#endif - float humidity = HTS.readHumidity(); +/* + Pressure +*/ +#if defined(ARDUINO_NANO_BLE_SENSE) + pressure = BARO.readPressure(); delay(delayTime); - #elif defined(ARDUINO_NANO_BLE_SENSE_R2) - /* - BARO sensor - */ - float pressure = BARO.readPressure(); + pressure = BARO.readPressure(); delay(delayTime); +#endif /* - HTS sensor + Humidity */ - float temperature = HS300x.readTemperature(); +#if defined(ARDUINO_NANO_BLE_SENSE) + humidity = HTS.readHumidity(); delay(delayTime); - - float humidity = HS300x.readHumidity(); +#elif defined(ARDUINO_NANO_BLE_SENSE_R2) + humidity = HS300x.readHumidity(); delay(delayTime); - -#else - float pressure = 0; - float temperature = 0; - float humidity = 0; #endif /* IMU sensor */ - float accelerationX = 0, accelerationY = 0, accelerationZ = 0; +#if defined(ARDUINO_NANO_BLE_SENSE) || defined(ARDUINO_NANO_BLE_SENSE_R2) || defined(ARDUINO_NANO_BLE) + if (IMU.magneticFieldAvailable()) { + IMU.readMagneticField(magneticFieldX, magneticFieldY, magneticFieldZ); + } +#endif + if (IMU.accelerationAvailable()) { IMU.readAcceleration(accelerationX, accelerationY, accelerationZ); } delay(delayTime); - - float gyroscopeX = 0, gyroscopeY = 0, gyroscopeZ = 0; if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(gyroscopeX, gyroscopeY, gyroscopeZ); } delay(delayTime); - float magneticFieldX = 0, magneticFieldY = 0, magneticFieldZ = 0; - if (IMU.magneticFieldAvailable()) { - IMU.readMagneticField(magneticFieldX, magneticFieldY, magneticFieldZ); - } - delay(delayTime); - float data[16] = { (float)notificationState, temperature, @@ -362,11 +379,15 @@ void sendFirstPartData() { } void sendSecondPartData() { - int gesture = -1; -#if defined(ARDUINO_NANO_BLE_SENSE) || defined(ARDUINO_NANO_BLE_SENSE_R2) + int gesture = -1, + red = 0, green = 0, blue = 0, + ambientLight = 0, + proximity = 255; + /* APDS sensor */ +#if defined(ARDUINO_NANO_BLE_SENSE) || defined(ARDUINO_NANO_BLE_SENSE_R2) // check if a color reading is available if (APDS.colorAvailable()) { // read the color @@ -380,19 +401,11 @@ void sendSecondPartData() { } delay(delayTime); - // check if a proximity reading is available if (APDS.gestureAvailable()) { gesture = APDS.readGesture(); } delay(delayTime); -#else - red = 0; - green = 0; - blue = 0; - ambientLight = 0; - proximity = 0; - gesture = 0; #endif @@ -408,6 +421,10 @@ void sendSecondPartData() { (float)proximity, +#if defined(ARDUINO_NANO_RP2040_CONNECT) + // TODO: implement analog read + 0, 0, 0, 0, 0, 0, 0, 0, +#else (float)analogRead(0), (float)analogRead(1), (float)analogRead(2), @@ -416,6 +433,7 @@ void sendSecondPartData() { (float)analogRead(5), (float)analogRead(6), (float)analogRead(7), +#endif 0 }; @@ -450,6 +468,8 @@ void onPinActionCharacteristicWrite(BLEDevice central, BLECharacteristic charact uint8_t pinNumber = pinActionCharacteristic[1]; uint8_t pinValue = pinActionCharacteristic[2]; + printValues("action", action, "pinNumber", pinNumber, "pinValue", pinValue); + uint8_t response[4] = { 0xFF, pinNumber, 0xFF, 0xFF }; uint16_t value; WrapServo *n, *nxt; @@ -562,9 +582,15 @@ void onRgbLedCharacteristicWrite(BLEDevice central, BLECharacteristic characteri byte g = rgbLedCharacteristic[1]; byte b = rgbLedCharacteristic[2]; - setLedPinValue(LEDR, r); - setLedPinValue(LEDG, g); - setLedPinValue(LEDB, b); + printValues("led_r", r, "led_g", g, "led_b", b); + +#ifdef ARDUINO_NANO_RP2040_CONNECT + // TODO: implement RGB LED control +#else + setLedPinValue(lred, r); + setLedPinValue(lgreen, g); + setLedPinValue(lblue, b); +#endif } void setLedPinValue(int pin, int value) { @@ -591,12 +617,8 @@ enum robotAction { void onRobotActionCharacteristicWrite(BLEDevice central, BLECharacteristic characteristic) { robotAction action = static_cast(pinRobotCharacteristic[0]); uint8_t arg1 = pinRobotCharacteristic[1]; - if (Serial) { - Serial.print("action="); - Serial.println(action); - Serial.print("arg1="); - Serial.println(arg1); - } + + printValues("robot_action", action, "arg1", arg1); switch (action) { case robotAction::MOVE_FORWARD_STEP: diff --git a/sketches/BLE_Scratch/sketch.yaml b/sketches/BLE_Scratch/sketch.yaml index d964311..e942b1c 100644 --- a/sketches/BLE_Scratch/sketch.yaml +++ b/sketches/BLE_Scratch/sketch.yaml @@ -14,3 +14,16 @@ profiles: - ArxTypeTraits (0.3.1) - ArxContainer (0.6.0) - Servo (1.2.1) + nanorp2040connect: + fqbn: arduino:mbed_nano:nanorp2040connect + platforms: + - platform: arduino:mbed_nano (4.1.3) + libraries: + - Arduino_LSM6DSOX (1.1.2) + - WiFiNINA (1.8.14) + - ArduinoBLE (1.3.6) + - MsgPack (0.4.2) + - DebugLog (0.8.3) + - ArxTypeTraits (0.3.1) + - ArxContainer (0.6.0) + - Servo (1.2.1) diff --git a/sketches/USB_Scratch_FW/USB_Scratch_FW.ino b/sketches/USB_Scratch_FW/USB_Scratch_FW.ino index 90de7ef..93416c5 100644 --- a/sketches/USB_Scratch_FW/USB_Scratch_FW.ino +++ b/sketches/USB_Scratch_FW/USB_Scratch_FW.ino @@ -36,33 +36,28 @@ int proximity = 255; */ void setup() { SerialUSB.begin(9600); - while (!SerialUSB) - ; + while (!SerialUSB); #ifdef BLE_SENSE if (!APDS.begin()) { sendError("Failled to initialized APDS!"); - while (1) - ; + while (1); } if (!HTS.begin()) { sendError("Failled to initialized HTS!"); - while (1) - ; + while (1); } if (!BARO.begin()) { sendError("Failled to initialized BARO!"); - while (1) - ; + while (1); } #endif if (!IMU.begin()) { sendError("Failled to initialized IMU!"); - while (1) - ; + while (1); } }