diff --git a/Readme.md b/Readme.md index 79bd508..69e5dd3 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,9 @@ -# Microchip_RN487x +# RN487x Arduino library for using the Microchip RN487x BLE module. +Updated to work with chipKIT boards. + ## Usage Quick example: @@ -10,21 +12,23 @@ Quick example: #include "RN487x_BLE.h" #define bleSerial Serial1 +#define BT_RESET 7 +#define BLUETOOTH_WAKE 12 void setup() { - rn487xBle.hwInit() ; - bleSerial.begin(rn487xBle.getDefaultBaudRate()) ; - rn487xBle.initBleStream(&bleSerial) ; - if (rn487xBle.swInit()) - { - rn487xBle.enterCommandMode() ; - rn487xBle.stopAdvertising() ; - rn487xBle.setAdvPower(3) ; - rn487xBle.setSerializedName("Microchip") ; - rn487xBle.clearAllServices() ; - rn487xBle.reboot() ; - } + rn487xBle.hwInit(BT_RESET, BLUETOOTH_WAKE); + bleSerial.begin(rn487xBle.getDefaultBaudRate()); + rn487xBle.initBleStream(&bleSerial); + if (rn487xBle.swInit()) + { + rn487xBle.enterCommandMode(); + rn487xBle.stopAdvertising(); + rn487xBle.setAdvPower(3); + rn487xBle.setSerializedName("Microchip"); + rn487xBle.clearAllServices(); + rn487xBle.reboot(); + } } void loop() @@ -41,6 +45,17 @@ void loop() v1.0.0 Initial Release +v1.1.0 Release +* enterCommandMode() now properly handles situation where module has prompt turned on or off +* Library now keeps track of if it is in command mode or not +* Added function setOperationMode() +* Added startCustomAdvertising() function +* Added support for PIC32 (chipKIT) +* Moved reset and wake pin definitions into hwInit() so that different boards can be supported without editing library + +v1.2.0 Release +* Examples updated to work properly with chipKIT boards (like Fubarino Mini and RGB Station) + ## License (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this diff --git a/examples/BLE_Peripheral/BLE_Peripheral.ino b/examples/BLE_Peripheral/BLE_Peripheral.ino deleted file mode 100644 index 874fb08..0000000 --- a/examples/BLE_Peripheral/BLE_Peripheral.ino +++ /dev/null @@ -1,296 +0,0 @@ -// BLE_Peripheral.ino -// Author: M16946 -// Date: 2017/01/13 - -/* - (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this - software and any derivatives exclusively with Microchip products. - - THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION - WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. - - IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, - INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND - WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS - BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE - FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN - ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, - THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. - - MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE - TERMS. -*/ - -#include -#include -#include - -#define debugSerial SerialUSB - -#if defined(ARDUINO_SODAQ_EXPLORER) -#define bleSerial Serial1 -#elif defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA) -#define bleSerial Serial -#endif - -#define SERIAL_TIMEOUT 10000 - -#define ADC_AREF 3.3f -#define BATVOLT_R1 4.7f -#define BATVOLT_R2 10.0f - -// Temperature offset for Sodaq One -#define TEMP_OFFSET 20 - -Sodaq_LIS3DE accelerometer; - -const char* myDeviceName = "My SODAQ BOARD" ; // Custom Device name -const char* myPrivateServiceUUID = "AD11CF40063F11E5BE3E0002A5D5C51B" ; // Custom private service UUID -const char* temperatureCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C501" ; // custom characteristic GATT -const uint8_t temperatureCharacteristicLen = 2 ; // data length (in bytes) -const uint16_t temperatureHandle = 0x72 ; -char temperaturePayload[temperatureCharacteristicLen*2] ; -float temperature_s ; -uint8_t newTempValue_u8 = 0 ; -uint8_t prevTempValue_u8 = 0 ; -const char* ledCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C503" ; // custom characteristic GATT -const uint8_t ledCharacteristicLen = 6 ; -uint16_t ledHandle = 0x75 ; -const char* ledPayload ; - -void initLed() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(LED_BUILTIN, OUTPUT) ; - #endif - pinMode(LED_RED, OUTPUT) ; - pinMode(LED_GREEN, OUTPUT) ; - pinMode(LED_BLUE, OUTPUT) ; - pinMode(BUTTON, INPUT_PULLUP) ; -} - -void turnBlueLedOn() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, HIGH) ; - #endif -} - -void turnBlueLedOff() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, LOW) ; - #endif -} - -#define COMMON_ANODE // LED driving -void setRgbColor(uint8_t red, uint8_t green, uint8_t blue) -{ -#ifdef COMMON_ANODE - red = 255 - red ; - green = 255 - green ; - blue = 255 - blue ; -#endif - - analogWrite(LED_RED, red) ; - analogWrite(LED_GREEN, green) ; - analogWrite(LED_BLUE, blue) ; -} - -/** - * Init Temperature for ExpLoRer - */ -void initTemperature() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(TEMP_SENSOR, INPUT) ; - //Set ADC resolution to 12 bits - analogReadResolution(12) ; - #endif -} - -/** - * Read ExpLoRer temperature sensor - */ -float getTemperature() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - float mVolts = (float)analogRead(TEMP_SENSOR) * 3300.0 / 1023.0 ; - #else - float mVolts = (float)getBoardTemperature() * 100 + 500; - #endif - float temp = (mVolts - 500.0) / 100.0 ; - return temp ; -} - -/** - * Initializes the accelerometer or puts it in power-down mode - * for the purpose of reading its temperature delta. -*/ -void setAccelerometerTempSensorActive(bool on) -{ - if (on) { - accelerometer.enable(false, Sodaq_LIS3DE::NormalLowPower100Hz, Sodaq_LIS3DE::XYZ, Sodaq_LIS3DE::Scale2g, true); - delay(300); // should be enough for initilization and 2 measurement periods - } - else { - accelerometer.disable(); - } -} - -/** - * Returns the board temperature. - * SDOAQ One -*/ -float getBoardTemperature() -{ - setAccelerometerTempSensorActive(true); - - float temp = TEMP_OFFSET + accelerometer.getTemperatureDelta(); - - setAccelerometerTempSensorActive(false); - - return temp; -} - -void setup() -{ - while ((!debugSerial) && (millis() < SERIAL_TIMEOUT)) ; - - debugSerial.begin(115200) ; - Wire.begin(); - - initLed() ; - - initTemperature() ; - - // Set the optional debug stream - rn487xBle.setDiag(debugSerial) ; - // Initialize the BLE hardware - rn487xBle.hwInit() ; - // Open the communication pipe with the BLE module - bleSerial.begin(rn487xBle.getDefaultBaudRate()) ; - // Assign the BLE serial port to the BLE library - rn487xBle.initBleStream(&bleSerial) ; - // Finalize the init. process - if (rn487xBle.swInit()) - { - setRgbColor(0, 255, 0) ; - debugSerial.println("Init. procedure done!") ; - } - else - { - setRgbColor(255, 0, 0) ; - debugSerial.println("Init. procedure failed!") ; - while(1) ; - } - - // Fist, enter into command mode - rn487xBle.enterCommandMode() ; - // Stop advertising before starting the demo - rn487xBle.stopAdvertising() ; - // Set the advertising output power (range: min = 5, max = 0) - rn487xBle.setAdvPower(3) ; - // Set the serialized device name - rn487xBle.setSerializedName(myDeviceName) ; - rn487xBle.clearAllServices() ; - rn487xBle.reboot() ; - rn487xBle.enterCommandMode() ; - // Set a private service ... - rn487xBle.setServiceUUID(myPrivateServiceUUID) ; - // which contains ... - // ...a temperature characteristic; readable and can perform notification, 2-octets size - rn487xBle.setCharactUUID(temperatureCharacteristicUUID, READ_PROPERTY | NOTIFY_PROPERTY, temperatureCharacteristicLen) ; - // ...an LED characteristic; properties: writable - rn487xBle.setCharactUUID(ledCharacteristicUUID, WRITE_PROPERTY, ledCharacteristicLen) ; - // take into account the settings by issuing a reboot - rn487xBle.reboot() ; - rn487xBle.enterCommandMode() ; - // Clear adv. packet - rn487xBle.clearImmediateAdvertising() ; - // Start adv. - rn487xBle.startImmediateAdvertising(AD_TYPE_MANUFACTURE_SPECIFIC_DATA, "CD00FE14AD11CF40063F11E5BE3E0002A5D5C51B") ; - - debugSerial.println("Starter Kit as a Peripheral with private service") ; - debugSerial.println("================================================") ; - debugSerial.print("Private service: ") ; debugSerial.println(myPrivateServiceUUID) ; - debugSerial.print("Private characteristic used for the Temperature: ") ; debugSerial.println(temperatureCharacteristicUUID) ; - debugSerial.print("Private characteristic used for the LED: ") ; debugSerial.println(ledCharacteristicUUID) ; - debugSerial.println("You can now establish a connection from the Microchip SmartDiscovery App") ; - debugSerial.print("with the starter kit: ") ; debugSerial.println(rn487xBle.getDeviceName()) ; - -} - -void loop() -{ - // Check the connection status - if (rn487xBle.getConnectionStatus()) - { - // Connected to a peer - debugSerial.print("Connected to a peer central ") ; - debugSerial.println(rn487xBle.getLastResponse()) ; - - // Temperature - prevTempValue_u8 = newTempValue_u8 ; - temperature_s = getTemperature() ; - newTempValue_u8 = (int)temperature_s ; - // Update the local characteristic only if value has changed - if (newTempValue_u8 != prevTempValue_u8) - { - uint8_t data = newTempValue_u8 ; - temperaturePayload[3] = '0' + (data % 10) ; // LSB - data /= 10 ; - temperaturePayload[2] = '0' + (data % 10) ; - data /= 10 ; - temperaturePayload[1] = '0' + (data % 10) ; - if (temperature_s > 0) temperaturePayload[0] = '0' ; // MSB = 0, positive temp. - else temperaturePayload[0] = '8' ; // MSB = 1, negative temp. - - if (rn487xBle.writeLocalCharacteristic(temperatureHandle, temperaturePayload)) - { - debugSerial.print("Temperature characteristic has been updated with the value = ") ; debugSerial.println(newTempValue_u8) ; - } - } - - // LED - if (rn487xBle.readLocalCharacteristic(ledHandle)) - { - // Read the local characteristic written by the client: smartphone/tablet - // The payload must follow the 6-bit RGB coded format: - // [0] Red MSB - // [1] Red LSB - // [2] Green MSB - // [3] Green LSB - // [4] Blue MSB - // [5] Blue LSB - // Each color can be coded from range 0x00 to 0xFF - ledPayload = rn487xBle.getLastResponse() ; - if (ledPayload != NULL) - { - if (ledPayload[0] != 'N') // != "N/A" response - { - debugSerial.println(ledPayload) ; - if (strlen(ledPayload) == ledCharacteristicLen) - { - // Filter only the 6-digit len - // Convert ASCII to integer values - uint8_t r = (ledPayload[0] - '0') * 10 + (ledPayload[1] - '0') ; - uint8_t g = (ledPayload[2] - '0') * 10 + (ledPayload[3] - '0') ; - uint8_t b = (ledPayload[4] - '0') * 10 + (ledPayload[5] - '0') ; - setRgbColor(r, g, b) ; - } - } - } - } - } - else - { - // Not connected to a peer device - debugSerial.println("Not connected to a peer device") ; - } - // Delay inter connection polling - delay(3000) ; -} diff --git a/examples/BLE_Scan_all/BLE_Scan_all.ino b/examples/BLE_Scan_all/BLE_Scan_all.ino index 03d5dff..cda6c35 100644 --- a/examples/BLE_Scan_all/BLE_Scan_all.ino +++ b/examples/BLE_Scan_all/BLE_Scan_all.ino @@ -1,6 +1,7 @@ -// Scanner.ino -// Author: M16946 -// Date: 2017/01/13 +/* BLE_Scan_all + * Based on work by M16946 (2017/01/13) for Microchip. + * Modified by Brian Schmalz of Schmalz Haus LLC (brian@schmalzhaus.com) also for Microchip, Dec 2017 + */ /* (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this @@ -27,62 +28,17 @@ #include #include -#define debugSerial SerialUSB -#if defined(ARDUINO_SODAQ_EXPLORER) +#define debugSerial Serial #define bleSerial Serial1 -#else -#define bleSerial Serial -#endif #define SERIAL_TIMEOUT 10000 -void initLed() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(LED_BUILTIN, OUTPUT) ; - #endif - pinMode(LED_RED, OUTPUT) ; - pinMode(LED_GREEN, OUTPUT) ; - pinMode(LED_BLUE, OUTPUT) ; - pinMode(BUTTON, INPUT_PULLUP) ; -} - -void turnBlueLedOn() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, HIGH) ; - #endif -} - -void turnBlueLedOff() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, LOW) ; - #endif -} - -#define COMMON_ANODE // LED driving -void setRgbColor(uint8_t red, uint8_t green, uint8_t blue) -{ -#ifdef COMMON_ANODE - red = 255 - red ; - green = 255 - green ; - blue = 255 - blue ; -#endif - - analogWrite(LED_RED, red) ; - analogWrite(LED_GREEN, green) ; - analogWrite(LED_BLUE, blue) ; -} - void setup() { while ((!debugSerial) && (millis() < SERIAL_TIMEOUT)) ; debugSerial.begin(115200) ; - initLed() ; - // Set the optional debug stream rn487xBle.setDiag(debugSerial) ; // Initialize the BLE hardware @@ -94,12 +50,10 @@ void setup() // Finalize the init. process if (rn487xBle.swInit()) { - setRgbColor(0, 255, 0) ; debugSerial.println("Init. procedure done!") ; } else { - setRgbColor(255, 0, 0) ; debugSerial.println("Init. procedure failed!") ; while(1) ; } diff --git a/examples/BLE_Scan_specific/BLE_Scan_specific.ino b/examples/BLE_Scan_specific/BLE_Scan_specific.ino index 393d96f..05a209a 100644 --- a/examples/BLE_Scan_specific/BLE_Scan_specific.ino +++ b/examples/BLE_Scan_specific/BLE_Scan_specific.ino @@ -1,6 +1,7 @@ -// BLE_Scan_whiteList.ino -// Author: M16946 -// Date: 2017/01/13 +/* BLE_Scan_specific + * Based on work by M16946 (2017/01/13) for Microchip. + * Modified by Brian Schmalz of Schmalz Haus LLC (brian@schmalzhaus.com) also for Microchip, Dec 2017 + */ /* (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this @@ -27,64 +28,20 @@ #include #include -#define debugSerial SerialUSB -#if defined(ARDUINO_SODAQ_EXPLORER) +#define debugSerial Serial #define bleSerial Serial1 -#else -#define bleSerial Serial -#endif + #define SERIAL_TIMEOUT 10000 // MAC address added to the white list const char* peerAddressToScan = "F0A1B40302D3" ; -void initLed() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(LED_BUILTIN, OUTPUT) ; - #endif - pinMode(LED_RED, OUTPUT) ; - pinMode(LED_GREEN, OUTPUT) ; - pinMode(LED_BLUE, OUTPUT) ; - pinMode(BUTTON, INPUT_PULLUP) ; -} - -void turnBlueLedOn() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, HIGH) ; - #endif -} - -void turnBlueLedOff() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, LOW) ; - #endif -} - -#define COMMON_ANODE // LED driving -void setRgbColor(uint8_t red, uint8_t green, uint8_t blue) -{ -#ifdef COMMON_ANODE - red = 255 - red ; - green = 255 - green ; - blue = 255 - blue ; -#endif - - analogWrite(LED_RED, red) ; - analogWrite(LED_GREEN, green) ; - analogWrite(LED_BLUE, blue) ; -} - void setup() { while ((!debugSerial) && (millis() < SERIAL_TIMEOUT)) ; debugSerial.begin(115200) ; - initLed() ; - // Set the optional debug stream rn487xBle.setDiag(debugSerial) ; // Initialize the BLE hardware @@ -96,12 +53,10 @@ void setup() // Finalize the init. process if (rn487xBle.swInit()) { - setRgbColor(0, 255, 0) ; debugSerial.println("Init. procedure done!") ; } else { - setRgbColor(255, 0, 0) ; debugSerial.println("Init. procedure failed!") ; while(1) ; } diff --git a/examples/BLE_SensorApp/BLE_SensorApp.ino b/examples/BLE_SensorApp/BLE_SensorApp.ino new file mode 100644 index 0000000..b1c3920 --- /dev/null +++ b/examples/BLE_SensorApp/BLE_SensorApp.ino @@ -0,0 +1,267 @@ +/* Sample sketch for illustrating BLE communications with a mobile device app. + * Designed to be used with a chipKIT Fubarino Mini board, but can be used with any Arduino + * compatible board. Uses Microchip's RN4870 or RN4871 BLE module. + * See https://chipkit.net/wiki/index.php?title=Basic_BLE for a tutorial explaining this sketch. + * + * Written by Brian Schmalz (brian@schmalzhaus.com) for Microchip, fall 2017. + * Based on an example from https://github.com/SodaqMoja/Microchip_RN487x + * This sketch is in the public domain + */ + +#include +#include +#include + +/* These are the serial ports to use with a Fubarino Mini. Edit for your hardware setup. */ +#define debugSerial Serial // Serial is Fubarini Mini's USB port +#define bleSerial Serial1 // Serial1 is UART2 on pins 26 (TX) and 25 (RX) to BLE module + +/* Analog pin that temp sensor is connected to */ +#define TEMP_SENSOR A0 +/* Analog pin that pot is connected to */ +#define POT_SENSOR A2 +/* Maximuim number of milliseconds to wait for USB serial to get ready on boot */ +#define SERIAL_TIMEOUT_MS 5000 + +const char* myDeviceName = "FB Mini"; // Custom Device name +const char* myPrivateServiceUUID = "AD11CF40063F11E5BE3E0002A5D5C51B"; // Custom private service UUID + +// Light Sensor +const char* lightCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C501"; // custom characteristic GATT +const uint8_t lightCharacteristicLen = 2; // data length (in bytes) +const uint16_t lightHandle = 0x72; +char lightPayload[lightCharacteristicLen*2 + 1]; + +// Pot +const char* potCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C502"; // custom characteristic GATT +const uint8_t potCharacteristicLen = 2; // data length (in bytes) +const uint16_t potHandle = 0x75; +char potPayload[potCharacteristicLen*2 + 1]; + +// Switch/LED +const char* switchCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C503"; // custom characteristic GATT +const uint8_t switchCharacteristicLen = 20; // data length (in bytes) +const uint16_t switchHandle = 0x78; +char switchPayload[switchCharacteristicLen*2 + 1]; +const char* ledPayload; + +// Temp +const char* temperatureCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C504"; // custom characteristic GATT +const uint8_t temperatureCharacteristicLen = 2; // data length (in bytes) +const uint16_t temperatureHandle = 0x7B; +char temperaturePayload[temperatureCharacteristicLen*2 + 1]; + +// Battery +const char* batteryCharacteristicUUID = "BF3FBD80063F11E59E690002A5D5C505"; // custom characteristic GATT +const uint8_t batteryCharacteristicLen = 2; // data length (in bytes) +const uint16_t batteryHandle = 0x7E; +char batteryPayload[batteryCharacteristicLen*2 + 1]; + + +/** + * Read Activity Board temperature sensor in degrees C + */ +float getTemperature() +{ + float accumulator = 0; + + // Make 1000 analog conversions + for (int i=0; i < 1000; i++) + { + float sensorValue = analogRead(TEMP_SENSOR); + + // Convert them to raw volts (raw ADC is 0 to 1023), added fudge factor for accuracy + float voltage = (sensorValue * (3.3 / 1024.0)) + 0.0025; + + // Sum the raw volts value into the accumulator + accumulator += voltage; + } + + // Compute the average voltage over all conversions + float volt_ave = accumulator/1000.0; + + // Compute Celsius. Sensor reads in 10mV/deg C, with 500mV offset + float celsius = ((volt_ave * 1000.0) - 500.0) / 10.0; + + return (celsius); +} + +/** + * Read pot in milivolts + */ +int getPot() +{ + return ((analogRead(POT_SENSOR) * 3.3) / 1.023); +} + +void setup() +{ + + debugSerial.begin(115200); + + // Wait for PC to connect, give up after SERIAL_TIMEOUT_MS + while ((!debugSerial) && (millis() < SERIAL_TIMEOUT_MS)); + + // Set the optional debug stream + rn487xBle.setDiag(debugSerial); + // Initialize the BLE hardware + rn487xBle.hwInit(); + // Open the communication pipe with the BLE module + bleSerial.begin(rn487xBle.getDefaultBaudRate()); + // Assign the BLE serial port to the BLE library + rn487xBle.initBleStream(&bleSerial); + // Finalize the init. process + if (rn487xBle.swInit()) + { + debugSerial.println("Init. procedure done!"); + } + else + { + debugSerial.println("Init. procedure failed!"); + while(1); + } + + // Fist, enter into command mode + rn487xBle.enterCommandMode(); + // Stop advertising before starting the demo + rn487xBle.stopAdvertising(); + rn487xBle.clearPermanentAdvertising(); + rn487xBle.clearPermanentBeacon(); + rn487xBle.clearImmediateAdvertising(); + rn487xBle.clearImmediateBeacon(); + rn487xBle.clearAllServices(); + // Set the serialized device name + rn487xBle.setSerializedName(myDeviceName); + rn487xBle.setSupportedFeatures(0x4000); // Set to no prompt (no "CMD>") + rn487xBle.setDefaultServices(DEVICE_INFO_SERVICE); + // Set the advertising output power (range: min = 5, max = 0) + rn487xBle.setAdvPower(3); + rn487xBle.reboot(); + rn487xBle.enterCommandMode(); + rn487xBle.clearAllServices(); + // Set a private service ... + rn487xBle.setServiceUUID(myPrivateServiceUUID); + // which contains ... + // ...a light sensor (unused) characteristic; readable and can perform notification, 2-octets size + rn487xBle.setCharactUUID(lightCharacteristicUUID, NOTIFY_PROPERTY, lightCharacteristicLen); + // ...a pot characteristic; readable and can perform notification, 2-octets size + rn487xBle.setCharactUUID(potCharacteristicUUID, NOTIFY_PROPERTY, potCharacteristicLen); + // ...a LED/Switch characteristic; readable and can perform notification, 20-octets size + rn487xBle.setCharactUUID(switchCharacteristicUUID, WRITE_PROPERTY | NOTIFY_PROPERTY, switchCharacteristicLen); + // ...a temperature characteristic; readable and can perform notification, 2-octets size + rn487xBle.setCharactUUID(temperatureCharacteristicUUID, NOTIFY_PROPERTY, temperatureCharacteristicLen); + // ...a battery (unused) characteristic; readable and can perform notification, 2-octets size + rn487xBle.setCharactUUID(batteryCharacteristicUUID, NOTIFY_PROPERTY, batteryCharacteristicLen); + + rn487xBle.startPermanentAdvertising(AD_TYPE_FLAGS, "06"); + rn487xBle.startPermanentAdvertising(AD_TYPE_MANUFACTURE_SPECIFIC_DATA, "CD00FE14AD11CF40063F11E5BE3E0002A5D5C51B"); + + // take into account the settings by issuing a reboot + rn487xBle.reboot(); + rn487xBle.enterCommandMode(); + + rn487xBle.startCustomAdvertising(210); + + debugSerial.println("Fubarino Mini Activity Board as a Peripheral with private service"); + debugSerial.println("================================================"); + debugSerial.println("You can now establish a connection from the Microchip SmartDiscovery App"); + debugSerial.print("with the board: ") ; debugSerial.println(rn487xBle.getDeviceName()); +} + +void loop() +{ + // Check the connection status + if (rn487xBle.getConnectionStatus()) + { + // We are connected to a peer + debugSerial.print("Connected to a peer central "); + debugSerial.println(rn487xBle.getLastResponse()); + + // Light Sensor + // 1000d = 21 lux + // 2000d = 83 lux + // Since we don't have a light sensor, just hard-code this to a known value + sprintf(lightPayload, "%04X", 2000); + rn487xBle.writeLocalCharacteristic(lightHandle, lightPayload); + + // Temperature + /* Convert to units that the Phone app wants + * 1000d = -8.47 F (Apple) --- (Android) + * 1200d = 18.29 F (Apple) 39.76 F (Android) + * 1500d = 58.84 F (Apple) 85.24 F (Android) + * 1600d = 71.8 F (Apple) + * So to convert from Celcius to counts that the app needs, we mulitply by 13.32 and add 1302 (for Apple) + * Note that the two phone apps interpret this value differently, so we can't create one formula that will + * work properly for both. This math is set up for the iPhone app. + */ + sprintf(temperaturePayload, "%04X", (uint16_t)((getTemperature() * 13.32) + 1302.0)); + rn487xBle.writeLocalCharacteristic(temperatureHandle, temperaturePayload); + + // Pot + sprintf(potPayload, "%04X", getPot()); + rn487xBle.writeLocalCharacteristic(potHandle, potPayload); + + // Battery + // 2000 = 7% + // 3000 = 78% + // Since we don't have a battery sensor, just hard code this to be a known value + sprintf(batteryPayload, "%04X", 3000); + rn487xBle.writeLocalCharacteristic(batteryHandle, batteryPayload); + + // LED + // This one is the complicated one. Every time the user moves the LED slider on the phone + // app, the readLocalCharactistic will get a value like XXXXXXXX2CYYYYYYYY where XXXXXXXX + // and YYYYYYYY are four byte hex numbers encoded as ASCII values. (So 0x89AB would be + // 38394142) I'm not exactly sure what each value is for, but we just use the first + // one to dim the LED on the Fubarino. + if (rn487xBle.readLocalCharacteristic(switchHandle)) + { + ledPayload = rn487xBle.getLastResponse(); + if ((ledPayload != NULL) && (ledPayload[0] != 'N') && (strlen(ledPayload) >= 9)) // != "N/A" response + { + // The difficult thing here is that beacuse the value is encoded as ASCII values, we have + // to convert each of the 4 ASCII values into the 4 hex bytes, then interpret the hex + // value as a number. Also, for some reason "%2hhx" doesn't seem to work in this version + // of sscanf, so we can't directly convert the ASCII values into bytes, we have to have + // sscanf convert each 2-byte ASCII value into an int, then cast that into to a byte. + // Then the resulting four byte string can be converted to a 16-bit unsigned number. + // Seems like way too much work to go through just to get a 16 bit value from the phone. + uint32_t led = 0; + uint32_t hexstring_int[4]; + uint8_t hexstring[5]; + uint8_t i; + + for (i=0; i < 4; i++) + { + sscanf(&ledPayload[i*2], "%2x", (unsigned int *)&hexstring_int[i]); + hexstring[i] = hexstring_int[i]; + } + hexstring[4] = 0; + + // led = 500 when slider is all the way right (android) or 1750 (Apple) + // led = 0 when slider is all the way left (android and Apple) + // led = 26670 when slider is just a bit in from the left side, decreasing down to 500 on the right side (28221 Apple) + sscanf((char*)hexstring, "%x", (unsigned int *)&led); + SoftPWMServoPWMWrite(PIN_LED1, map(led, 28000, 500, 0, 255)); + } + } + + // Switch + // Note that because we use the same server characteristic for sending switch data to the phone as well + // as getting LED information back from the phone, we have to do things in this order (LED read first, + // then switch write) otherwise the LED read will always return "0001" or "0000" from the switch write. + sprintf(switchPayload, "000%1d", digitalRead(PIN_BTN1)); + rn487xBle.writeLocalCharacteristic(switchHandle, switchPayload); + + // Delay inter connection polling - when connected, update every 1/4 second + delay(250); + } + else + { + // Not connected to a peer device + debugSerial.println("Not connected to a peer device"); + + // Delay inter connection polling - when not connected, check for new connections ever 1 second + delay(1000); + } +} \ No newline at end of file diff --git a/examples/EddystoneURI/EddystoneURI.ino b/examples/EddystoneURI/EddystoneURI.ino index 72f14e1..c128886 100644 --- a/examples/EddystoneURI/EddystoneURI.ino +++ b/examples/EddystoneURI/EddystoneURI.ino @@ -1,6 +1,7 @@ -// Eddystone.ino -// Author: M16946 -// Date: 2017/01/13 +/* EddystoneURI + * Based on work by M16946 (2017/01/13) for Microchip. + * Modified by Brian Schmalz of Schmalz Haus LLC (brian@schmalzhaus.com) also for Microchip, Dec 2017 + */ /* (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this @@ -28,65 +29,20 @@ #include #include -#define debugSerial SerialUSB -#if defined(ARDUINO_SODAQ_EXPLORER) +#define debugSerial Serial #define bleSerial Serial1 -#else -#define bleSerial Serial -#endif #define SERIAL_TIMEOUT 10000 const char* myEddystoneURI = "http://www.microchip.com" ; const uint8_t myTxPower = 0xC5 ; -void initLed() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(LED_BUILTIN, OUTPUT) ; - #endif - pinMode(LED_RED, OUTPUT) ; - pinMode(LED_GREEN, OUTPUT) ; - pinMode(LED_BLUE, OUTPUT) ; - pinMode(BUTTON, INPUT_PULLUP) ; -} - -void turnBlueLedOn() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, HIGH) ; - #endif -} - -void turnBlueLedOff() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, LOW) ; - #endif -} - -#define COMMON_ANODE // LED driving -void setRgbColor(uint8_t red, uint8_t green, uint8_t blue) -{ -#ifdef COMMON_ANODE - red = 255 - red ; - green = 255 - green ; - blue = 255 - blue ; -#endif - - analogWrite(LED_RED, red) ; - analogWrite(LED_GREEN, green) ; - analogWrite(LED_BLUE, blue) ; -} - void setup() { while ((!debugSerial) && (millis() < SERIAL_TIMEOUT)) ; debugSerial.begin(115200) ; - initLed() ; - // Set the optional debug stream rn487xBle.setDiag(debugSerial) ; // Initialize the BLE hardware @@ -98,12 +54,10 @@ void setup() // Finalize the init. process if (rn487xBle.swInit()) { - setRgbColor(0, 255, 0) ; debugSerial.println("Init. procedure done!") ; } else { - setRgbColor(255, 0, 0) ; debugSerial.println("Init. procedure failed!") ; while(1) ; } diff --git a/examples/EddystoneUUID/EddystoneUUID.ino b/examples/EddystoneUUID/EddystoneUUID.ino index 9c3661e..34bf332 100644 --- a/examples/EddystoneUUID/EddystoneUUID.ino +++ b/examples/EddystoneUUID/EddystoneUUID.ino @@ -1,6 +1,7 @@ -// EddystoneUUID.ino -// Author: M16946 -// Date: 2017/01/13 +/* EddystoneUUID + * Based on work by M16946 (2017/01/13) for Microchip. + * Modified by Brian Schmalz of Schmalz Haus LLC (brian@schmalzhaus.com) also for Microchip, Dec 2017 + */ /* (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this @@ -28,64 +29,20 @@ #include #include -#define debugSerial SerialUSB -#if defined(ARDUINO_SODAQ_EXPLORER) +#define debugSerial Serial #define bleSerial Serial1 -#else -#define bleSerial Serial -#endif + #define SERIAL_TIMEOUT 10000 const char* myEddystoneUUID = "AD11CF40063F11E5BE3E0002A5D5C51B" ; const uint8_t myTxPower = 0xC5 ; -void initLed() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(LED_BUILTIN, OUTPUT) ; - #endif - pinMode(LED_RED, OUTPUT) ; - pinMode(LED_GREEN, OUTPUT) ; - pinMode(LED_BLUE, OUTPUT) ; - pinMode(BUTTON, INPUT_PULLUP) ; -} - -void turnBlueLedOn() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, HIGH) ; - #endif -} - -void turnBlueLedOff() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, LOW) ; - #endif -} - -#define COMMON_ANODE // LED driving -void setRgbColor(uint8_t red, uint8_t green, uint8_t blue) -{ -#ifdef COMMON_ANODE - red = 255 - red ; - green = 255 - green ; - blue = 255 - blue ; -#endif - - analogWrite(LED_RED, red) ; - analogWrite(LED_GREEN, green) ; - analogWrite(LED_BLUE, blue) ; -} - void setup() { while ((!debugSerial) && (millis() < SERIAL_TIMEOUT)) ; debugSerial.begin(115200) ; - initLed() ; - // Set the optional debug stream rn487xBle.setDiag(debugSerial) ; // Initialize the BLE hardware @@ -97,12 +54,10 @@ void setup() // Finalize the init. process if (rn487xBle.swInit()) { - setRgbColor(0, 255, 0) ; debugSerial.println("Init. procedure done!") ; } else { - setRgbColor(255, 0, 0) ; debugSerial.println("Init. procedure failed!") ; while(1) ; } diff --git a/examples/SerialPassthrough/SerialPassthrough.ino b/examples/SerialPassthrough/SerialPassthrough.ino new file mode 100644 index 0000000..8972b25 --- /dev/null +++ b/examples/SerialPassthrough/SerialPassthrough.ino @@ -0,0 +1,37 @@ +/* SerialPassthrough + * Written by Brian Schmalz of Schmalz Haus LLC (brian@schmalzhaus.com) for Microchip, Dec 2017 + * + * This sketch simply provides a way to directly talk to an RN4870 or RN4871 module. It assumes that + * the USB serial connection is Serial, and the serial connection to the BLE module is on Serial1. + * + * If you open up a terminal emulator like TeraTerm and connect to your board's serial port, you can + * talk through the microcontroller to the BLE module. This is very useful for figuring out what commands + * the BLE module understand, and debugging connection problems. + */ + +/* These pins are correct for RGB Station boards. Adjust to fit your hardware. */ +#define BLE_MODE_PIN 21 +#define BLE_RESET_PIN 7 + +void setup() { + pinMode(BLE_MODE_PIN, OUTPUT); + digitalWrite(BLE_MODE_PIN, HIGH); + pinMode(BLE_RESET_PIN, OUTPUT); + digitalWrite(BLE_RESET_PIN, HIGH); + + Serial.begin(115200); + Serial1.begin(115200); + + while (!Serial) { + ; // wait for serial port to connect. + } +} + +void loop() // run over and over +{ + if (Serial.available()) + Serial1.write(Serial.read()); + if (Serial1.available()) + Serial.write(Serial1.read()); +} + diff --git a/examples/iBeacon/iBeacon.ino b/examples/iBeacon/iBeacon.ino index 06c5a2a..ae73a7c 100644 --- a/examples/iBeacon/iBeacon.ino +++ b/examples/iBeacon/iBeacon.ino @@ -1,6 +1,7 @@ -// iBeacon.ino -// Author: M16946 -// Date: 2017/01/13 +/* iBeacon + * Based on work by M16946 (2017/01/13) for Microchip. + * Modified by Brian Schmalz of Schmalz Haus LLC (brian@schmalzhaus.com) also for Microchip, Dec 2017 + */ /* (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this @@ -28,12 +29,8 @@ #include #include -#define debugSerial SerialUSB -#if defined(ARDUINO_SODAQ_EXPLORER) +#define debugSerial Serial #define bleSerial Serial1 -#else -#define bleSerial Serial -#endif #define SERIAL_TIMEOUT 10000 @@ -42,53 +39,12 @@ const uint16_t myMajor = 0x0C ; const uint16_t myMinor = 0x0D ; const uint8_t myTxPower = 0xC5 ; -void initLed() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - pinMode(LED_BUILTIN, OUTPUT) ; - #endif - pinMode(LED_RED, OUTPUT) ; - pinMode(LED_GREEN, OUTPUT) ; - pinMode(LED_BLUE, OUTPUT) ; - pinMode(BUTTON, INPUT_PULLUP) ; -} - -void turnBlueLedOn() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, HIGH) ; - #endif -} - -void turnBlueLedOff() -{ - #if defined(ARDUINO_SODAQ_EXPLORER) - digitalWrite(LED_BUILTIN, LOW) ; - #endif -} - -#define COMMON_ANODE // LED driving -void setRgbColor(uint8_t red, uint8_t green, uint8_t blue) -{ -#ifdef COMMON_ANODE - red = 255 - red ; - green = 255 - green ; - blue = 255 - blue ; -#endif - - analogWrite(LED_RED, red) ; - analogWrite(LED_GREEN, green) ; - analogWrite(LED_BLUE, blue) ; -} - void setup() { while ((!debugSerial) && (millis() < SERIAL_TIMEOUT)) ; debugSerial.begin(115200) ; - initLed() ; - // Set the optional debug stream rn487xBle.setDiag(debugSerial) ; // Initialize the BLE hardware @@ -100,12 +56,10 @@ void setup() // Finalize the init. process if (rn487xBle.swInit()) { - setRgbColor(0, 255, 0) ; debugSerial.println("Init. procedure done!") ; } else { - setRgbColor(255, 0, 0) ; debugSerial.println("Init. procedure failed!") ; while(1) ; } diff --git a/keywords.txt b/keywords.txt index 2d4499b..43a3d3b 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,11 +1,11 @@ ####################################### -# Syntax Coloring Map For Microchip_RN487x +# Syntax Coloring Map For RN487x ####################################### ####################################### # Datatypes (KEYWORD1) ####################################### -Microchip_RN487x KEYWORD1 +RN487x KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) diff --git a/library.properties b/library.properties index 8fa2766..3edc7c8 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=Microchip_RN487x -version=1.0.0 -author=M16946,Microchip Technology (c) -maintainer=M16946 +name=RN487x +version=1.2.0 +author=M16946,Microchip Technology (c),Brian Schmalz +maintainer=Brian Schmalz sentence=An Arduino library for the Microchip RN487x -paragraph=It supports to enable BLE communication. +paragraph=Command mode support for NR487x BLE modules from Microchip. Updated to work with chipKIT boards. category=Communication -url=https://github.com/SodaqMoja/Microchip_RN487x +url=https://github.com/chipKIT32-libraries/RN487x architectures=* diff --git a/src/RN487x_BLE.cpp b/src/RN487x_BLE.cpp index 943fd98..7ae42a9 100644 --- a/src/RN487x_BLE.cpp +++ b/src/RN487x_BLE.cpp @@ -28,22 +28,11 @@ #include #include -#if defined(ARDUINO_SODAQ_ONE) - #define BLUETOOTH_WAKE (26u) // A6/D6 - #define BT_RESET (24u) //A2/D2 -#endif - -// Bluetooth Reset signal is supported from the BSP version SODAQ_SAMD_BOARD_1.6.10 -// Redefine the pin in case of using prior version than v1.6.9 -#ifndef BT_RESET - #define BT_RESET (46u) -#endif - //#define DEBUG #ifdef DEBUG -#define debugPrintLn(...) { if (this->diagStream) this->diagStream->println(__VA_ARGS__) ; } -#define debugPrint(...) { if (this->diagStream) this->diagStream->print(__VA_ARGS__) ; } +#define debugPrintLn(...) { if (this->diagStream) this->diagStream->println(__VA_ARGS__); } +#define debugPrint(...) { if (this->diagStream) this->diagStream->print(__VA_ARGS__); } #warning "Debug mode is ON" #else #define debugPrintLn(...) @@ -52,7 +41,7 @@ // ---------------------------------------- Private section ---------------------------------------- -Rn487xBle rn487xBle ; +Rn487xBle rn487xBle; // ********************************************************************************* // Constructor @@ -62,9 +51,9 @@ Rn487xBle rn487xBle ; // ********************************************************************************* Rn487xBle::Rn487xBle(void) { - uartBufferLen = DEFAULT_INPUT_BUFFER_SIZE ; - uartBuffer = new char[uartBufferLen] ; - memset(uartBuffer, 0, uartBufferLen) ; + uartBufferLen = DEFAULT_INPUT_BUFFER_SIZE; + uartBuffer = new char[uartBufferLen]; + memset(uartBuffer, 0, uartBufferLen); } // ********************************************************************************* @@ -77,8 +66,8 @@ Rn487xBle::~Rn487xBle() { if (uartBuffer != NULL) { - delete []uartBuffer ; - uartBuffer = NULL ; + delete []uartBuffer; + uartBuffer = NULL; } } @@ -90,13 +79,41 @@ Rn487xBle::~Rn487xBle() // ********************************************************************************* void Rn487xBle::hwInit(void) { - debugPrintLn("[hwInit]") ; + debugPrintLn("[hwInit]"); + + wakePin = -1; + resetPin = -1; + + // Hardware reset + hwReset(); + + // Place the 'wakePin' pin in Low level + hwWakeUp(); +} + +// ********************************************************************************* +// Hardware Init. procedure +// ********************************************************************************* +// Input : uint8_t resetBLEPin - the digital I/O pin number connected to the BLE +// module's reset pin. Use -1 to disable +// library's reset of BLE module +// Input : uint8_t wakeBLEPin - the digital I/O pin number connected to the BLE +// module's wake pin. Use -1 to disable library's +// use of wake pin +// Output: void +// ********************************************************************************* +void Rn487xBle::hwInit(uint8_t resetBLEPin, uint8_t wakeBLEPin) +{ + debugPrintLn("[hwInit]"); + wakePin = wakeBLEPin; + resetPin = resetBLEPin; + // Hardware reset - hwReset() ; + hwReset(); - // Place the BLUETOOTH_WAKE pin in Low level - hwWakeUp() ; + // Place the 'wakePin' pin in Low level + hwWakeUp(); } // ********************************************************************************* @@ -107,15 +124,15 @@ void Rn487xBle::hwInit(void) // ********************************************************************************* bool Rn487xBle::swInit(void) { - debugPrintLn("[swInit]") ; + debugPrintLn("[swInit]"); - bool initOk = false ; + bool initOk = false; if (reboot()) { // Set a known mode - setOperationMode(dataMode) ; - initOk = true ; + setOperationMode(dataMode); + initOk = true; } else { @@ -124,12 +141,12 @@ bool Rn487xBle::swInit(void) if (reboot()) { // Set a known mode - setOperationMode(dataMode) ; - initOk = true ; + setOperationMode(dataMode); + initOk = true; } } } - return initOk ; + return initOk; } // ********************************************************************************* @@ -142,13 +159,20 @@ bool Rn487xBle::swInit(void) // ********************************************************************************* void Rn487xBle::hwReset(void) { - debugPrintLn("[hwReset]") ; + if (resetPin != -1) + { + debugPrintLn("[hwReset]"); - pinMode(BT_RESET, OUTPUT) ; - digitalWrite(BT_RESET, LOW) ; - delay(1) ; - digitalWrite(BT_RESET, HIGH) ; - delay(500) ; + pinMode(resetPin, OUTPUT); + digitalWrite(resetPin, LOW); + delay(1); + digitalWrite(resetPin, HIGH); + delay(500); + } + else + { + debugPrintLn("[hwReset skipped]"); + } } // ********************************************************************************* @@ -161,11 +185,17 @@ void Rn487xBle::hwReset(void) // ********************************************************************************* void Rn487xBle::hwWakeUp(void) { - debugPrintLn("[wakeUp]") ; - - pinMode(BLUETOOTH_WAKE, OUTPUT) ; - digitalWrite(BLUETOOTH_WAKE, LOW) ; - delay(5) ; + if (wakePin != -1) + { + debugPrintLn("[wakeUp]"); + pinMode(wakePin, OUTPUT); + digitalWrite(wakePin, LOW); + delay(5); + } + else + { + debugPrintLn("[wakeUp - skipped]"); + } } // ********************************************************************************* @@ -178,11 +208,18 @@ void Rn487xBle::hwWakeUp(void) // ********************************************************************************* void Rn487xBle::hwSleep(void) { - debugPrintLn("[sleep]") ; + if (wakePin != -1) + { + debugPrintLn("[sleep]"); - pinMode(BLUETOOTH_WAKE, OUTPUT) ; - digitalWrite(BLUETOOTH_WAKE, HIGH) ; - delay(1) ; + pinMode(wakePin, OUTPUT); + digitalWrite(wakePin, HIGH); + delay(1); + } + else + { + debugPrintLn("[sleep - skipped]"); + } } @@ -195,18 +232,49 @@ void Rn487xBle::hwSleep(void) // ********************************************************************************* bool Rn487xBle::enterCommandMode(void) { - debugPrintLn("[enterCommandMode]") ; + debugPrintLn("[enterCommandMode]"); // To enter Command mode from Data mode, type $$$ character sequence after 100 ms delay before the first $ - delay(DELAY_BEFORE_CMD) ; + delay(DELAY_BEFORE_CMD); + + memset(uartBuffer, 0, uartBufferLen); // clear the buffer + cleanInputBuffer(); + + this->bleSerial->print(ENTER_CMD); + + // This command will reply with either "CMD> " or "CMD" depending on if + // the command prompt is turned on or off. This routine needs to detect which + // reply comes back, and set the commandPromptEnabled variable appropriately. This + // reply takes less than 15ms to arrive. Each string is 5 bytes long. + + debugPrintLn("[expectResponse] expecting CMD> or CMD"); - this->bleSerial->print(ENTER_CMD) ; - if (expectResponse(PROMPT, DEFAULT_CMD_TIMEOUT)) + unsigned long previous = millis(); + + while ((millis() - previous < 15) && (this->bleSerial->available() < 5)) { - setOperationMode(cmdMode) ; - return true ; + debugPrint("."); } - return false ; + + this->bleSerial->readBytes(this->uartBuffer, this->bleSerial->available()); + + debugPrint("("); + debugPrint(this->uartBuffer); + debugPrint(")"); + + if (strstr(this->uartBuffer, PROMPT) != NULL) + { + debugPrintLn(" found a match ! - Command prompts are enabled."); + setOperationMode(cmdMode); + return true; + } + else if (strstr(this->uartBuffer, PROMPT_CR) != NULL) + { + debugPrintLn(" found a match ! - Command prompts are disabled."); + setOperationMode(cmdMode); + return true; + } + return false; } // ********************************************************************************* @@ -222,15 +290,15 @@ bool Rn487xBle::enterCommandMode(void) // ********************************************************************************* bool Rn487xBle::enterDataMode(void) { - debugPrintLn("[enterDataMode]") ; + debugPrintLn("[enterDataMode]"); - sendCommand(EXIT_CMD) ; + sendCommand(EXIT_CMD); if (expectResponse(PROMPT_END, DEFAULT_CMD_TIMEOUT)) { - setOperationMode(dataMode) ; - return true ; + setOperationMode(dataMode); + return true; } - return false ; + return false; } // ********************************************************************************* @@ -247,18 +315,18 @@ bool Rn487xBle::enterDataMode(void) // ********************************************************************************* void Rn487xBle::sendCommand(String stream) { - debugPrint("[sendCommand] " ) ; - debugPrintLn(stream) ; + debugPrint("[sendCommand] " ); + debugPrintLn(stream); - this->flush() ; - cleanInputBuffer() ; - stream.concat(CR) ; - bleSerial->print(stream) ; + this->flush(); + cleanInputBuffer(); + stream.concat(CR); + bleSerial->print(stream); } void Rn487xBle::sendData(char *data, uint16_t dataLen) { - bleSerial->write(data, dataLen) ; + bleSerial->write(data, dataLen); } @@ -272,21 +340,21 @@ bool Rn487xBle::retrieveBtAddress(void) { if (getSettings(0, 6)) { - btAddress[0] = uartBuffer[10] ; - btAddress[1] = uartBuffer[11] ; - btAddress[2] = uartBuffer[8] ; - btAddress[3] = uartBuffer[9] ; - btAddress[4] = uartBuffer[6] ; - btAddress[5] = uartBuffer[7] ; - btAddress[6] = uartBuffer[4] ; - btAddress[7] = uartBuffer[5] ; - btAddress[8] = uartBuffer[2] ; - btAddress[9] = uartBuffer[3] ; - btAddress[10]= uartBuffer[0] ; - btAddress[11]= uartBuffer[1] ; - return true ; + btAddress[0] = uartBuffer[10]; + btAddress[1] = uartBuffer[11]; + btAddress[2] = uartBuffer[8]; + btAddress[3] = uartBuffer[9]; + btAddress[4] = uartBuffer[6]; + btAddress[5] = uartBuffer[7]; + btAddress[6] = uartBuffer[4]; + btAddress[7] = uartBuffer[5]; + btAddress[8] = uartBuffer[2]; + btAddress[9] = uartBuffer[3]; + btAddress[10]= uartBuffer[0]; + btAddress[11]= uartBuffer[1]; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -297,25 +365,25 @@ bool Rn487xBle::retrieveBtAddress(void) // ********************************************************************************* bool Rn487xBle::getFirmwareVersion(void) { - debugPrint("[getFirmwareVersion]") ; + debugPrint("[getFirmwareVersion]"); - uint16_t timeout = DEFAULT_CMD_TIMEOUT ; - unsigned long previous ; + uint16_t timeout = DEFAULT_CMD_TIMEOUT; + unsigned long previous; - sendCommand(DISPLAY_FW_VERSION) ; - previous = millis() ; + sendCommand(DISPLAY_FW_VERSION); + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (this->bleSerial->available() > 0) { if (readUntilCR() > 0) { - return true ; + return true; } } } - return false ; + return false; } // ********************************************************************************* @@ -326,8 +394,8 @@ bool Rn487xBle::getFirmwareVersion(void) // ********************************************************************************* bool Rn487xBle::disableBeacon(void) { - debugPrintLn("[disableBeacon]") ; - return(setBeaconFeatures(BEACON_OFF)) ; + debugPrintLn("[disableBeacon]"); + return(setBeaconFeatures(BEACON_OFF)); } // ********************************************************************************* @@ -338,8 +406,8 @@ bool Rn487xBle::disableBeacon(void) // ********************************************************************************* bool Rn487xBle::enableBeacon(void) { - debugPrintLn("[enableBeacon]") ; - return(setBeaconFeatures(BEACON_ON)) ; + debugPrintLn("[enableBeacon]"); + return(setBeaconFeatures(BEACON_ON)); } // ********************************************************************************* @@ -350,8 +418,8 @@ bool Rn487xBle::enableBeacon(void) // ********************************************************************************* bool Rn487xBle::enableBeaconAndAdv(void) { - debugPrintLn("[enableBeaconAndAdv]") ; - return(setBeaconFeatures(BEACON_ADV_ON)) ; + debugPrintLn("[enableBeaconAndAdv]"); + return(setBeaconFeatures(BEACON_ADV_ON)); } // ********************************************************************************* @@ -364,14 +432,14 @@ bool Rn487xBle::enableBeaconAndAdv(void) // ********************************************************************************* bool Rn487xBle::factoryReset(void) { - debugPrintLn("[factoryReset]") ; + debugPrintLn("[factoryReset]"); - sendCommand(FACTORY_RESET) ; + sendCommand(FACTORY_RESET); if (expectResponse(FACTORY_RESET_RESP, RESET_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -384,23 +452,32 @@ bool Rn487xBle::factoryReset(void) // ********************************************************************************* bool Rn487xBle::setAdvPower(uint8_t value) { - debugPrint("[setAdvPower] ") ; debugPrintLn(value) ; - - if (value < MIN_POWER_OUTPUT) value = MIN_POWER_OUTPUT ; - if (value > MAX_POWER_OUTPUT) value = MAX_POWER_OUTPUT ; - - uint8_t len = strlen(SET_ADV_POWER) ; - char c[1] ; - sprintf(c, "%d", value) ; - this->flush() ; - memcpy(uartBuffer, SET_ADV_POWER, len) ; - memcpy(&uartBuffer[len], c, 1) ; - sendCommand(uartBuffer) ; + debugPrint("[setAdvPower] "); + debugPrintLn(value); + +#if (MIN_POWER_OUTPUT != 0) + if (value < MIN_POWER_OUTPUT) + { + value = MIN_POWER_OUTPUT; + } +#endif + if (value > MAX_POWER_OUTPUT) + { + value = MAX_POWER_OUTPUT; + } + + uint8_t len = strlen(SET_ADV_POWER); + char c[1]; + sprintf(c, "%d", value); + this->flush(); + memcpy(uartBuffer, SET_ADV_POWER, len); + memcpy(&uartBuffer[len], c, 1); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -413,23 +490,32 @@ bool Rn487xBle::setAdvPower(uint8_t value) // ********************************************************************************* bool Rn487xBle::setConPower(uint8_t value) { - debugPrint("[setConnPower] ") ; debugPrintLn(value) ; + debugPrint("[setConnPower] "); + debugPrintLn(value); - if (value < MIN_POWER_OUTPUT) value = MIN_POWER_OUTPUT ; - if (value > MAX_POWER_OUTPUT) value = MAX_POWER_OUTPUT ; +#if (MIN_POWER_OUTPUT != 0) + if (value < MIN_POWER_OUTPUT) + { + value = MIN_POWER_OUTPUT; + } +#endif + if (value > MAX_POWER_OUTPUT) + { + value = MAX_POWER_OUTPUT; + } - uint8_t len = strlen(SET_CONN_POWER) ; - char c[1] ; - sprintf(c, "%d", value) ; - this->flush() ; - memcpy(uartBuffer, SET_CONN_POWER, len) ; - memcpy(&uartBuffer[len], c, 1) ; - sendCommand(uartBuffer) ; + uint8_t len = strlen(SET_CONN_POWER); + char c[1]; + sprintf(c, "%d", value); + this->flush(); + memcpy(uartBuffer, SET_CONN_POWER, len); + memcpy(&uartBuffer[len], c, 1); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -444,30 +530,30 @@ bool Rn487xBle::setConPower(uint8_t value) // ********************************************************************************* bool Rn487xBle::setSerializedName(const char *newName) { - debugPrint("[setSerializedName] ") ; - debugPrintLn(newName) ; + debugPrint("[setSerializedName] "); + debugPrintLn(newName); - uint8_t len = strlen(SET_SERIALIZED_NAME) ; - uint8_t newLen = strlen(newName) ; + uint8_t len = strlen(SET_SERIALIZED_NAME); + uint8_t newLen = strlen(newName); if (newLen > MAX_SERIALIZED_NAME_LEN) { - newLen = MAX_SERIALIZED_NAME_LEN ; - debugPrintLn(" Too many characters") ; + newLen = MAX_SERIALIZED_NAME_LEN; + debugPrintLn(" Too many characters"); } // Fill the device name without the last two bytes of the Bluetooth MAC address - memset(deviceName, 0, newLen) ; - memcpy(deviceName, newName, newLen) ; + memset(deviceName, 0, newLen); + memcpy(deviceName, newName, newLen); // Fill the buffer - this->flush() ; - memcpy(uartBuffer, SET_SERIALIZED_NAME, len) ; - memcpy(&uartBuffer[len], newName, newLen) ; - sendCommand(uartBuffer) ; + this->flush(); + memcpy(uartBuffer, SET_SERIALIZED_NAME, len); + memcpy(&uartBuffer[len], newName, newLen); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -479,30 +565,30 @@ bool Rn487xBle::setSerializedName(const char *newName) // ********************************************************************************* bool Rn487xBle::setDevName(const char *newName) { - debugPrint("[setDeviceName] ") ; - debugPrintLn(newName) ; + debugPrint("[setDeviceName] "); + debugPrintLn(newName); - uint8_t len = strlen(SET_DEVICE_NAME) ; - uint8_t newLen = strlen(newName) ; + uint8_t len = strlen(SET_DEVICE_NAME); + uint8_t newLen = strlen(newName); if (newLen > MAX_DEVICE_NAME_LEN) { - newLen = MAX_DEVICE_NAME_LEN ; - debugPrintLn(" Too many characters") ; + newLen = MAX_DEVICE_NAME_LEN; + debugPrintLn(" Too many characters"); } // Fill the device name - memset(deviceName, 0, newLen) ; - memcpy(deviceName, newName, newLen) ; + memset(deviceName, 0, newLen); + memcpy(deviceName, newName, newLen); // Fill the buffer - this->flush() ; - memcpy(uartBuffer, SET_DEVICE_NAME, len) ; - memcpy(&uartBuffer[len], newName, newLen) ; - sendCommand(uartBuffer) ; + this->flush(); + memcpy(uartBuffer, SET_DEVICE_NAME, len); + memcpy(&uartBuffer[len], newName, newLen); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -518,14 +604,14 @@ bool Rn487xBle::setDevName(const char *newName) // ********************************************************************************* bool Rn487xBle::enableLowPower(void) { - debugPrintLn("[enableLowPower]") ; + debugPrintLn("[enableLowPower]"); - sendCommand(SET_LOW_POWER_ON) ; + sendCommand(SET_LOW_POWER_ON); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -537,14 +623,14 @@ bool Rn487xBle::enableLowPower(void) // ********************************************************************************* bool Rn487xBle::disableLowPower(void) { - debugPrintLn("[disableLowPower]") ; + debugPrintLn("[disableLowPower]"); - sendCommand(SET_LOW_POWER_OFF) ; + sendCommand(SET_LOW_POWER_OFF); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -556,22 +642,22 @@ bool Rn487xBle::disableLowPower(void) // ********************************************************************************* bool Rn487xBle::setSupportedFeatures(uint16_t bitmap) { - debugPrint("[setSupportedFeatures]") ; + debugPrint("[setSupportedFeatures]"); - uint8_t len = strlen(SET_SUPPORTED_FEATURES) ; - char c[4] ; - sprintf(c, "%04X", bitmap) ; - uint8_t newLen = strlen(c) ; + uint8_t len = strlen(SET_SUPPORTED_FEATURES); + char c[4]; + sprintf(c, "%04X", bitmap); + uint8_t newLen = strlen(c); - this->flush() ; - memcpy(uartBuffer, SET_SUPPORTED_FEATURES, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - sendCommand(uartBuffer) ; + this->flush(); + memcpy(uartBuffer, SET_SUPPORTED_FEATURES, len); + memcpy(&uartBuffer[len], c, newLen); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -586,23 +672,23 @@ bool Rn487xBle::setSupportedFeatures(uint16_t bitmap) // ********************************************************************************* bool Rn487xBle::setDefaultServices(uint8_t bitmap) { - debugPrint("[setDefaultServices]") ; + debugPrint("[setDefaultServices]"); - uint8_t len = strlen(SET_DEFAULT_SERVICES) ; - char c[2] ; - sprintf(c, "%02X", bitmap) ; - uint8_t newLen = strlen(c) ; + uint8_t len = strlen(SET_DEFAULT_SERVICES); + char c[2]; + sprintf(c, "%02X", bitmap); + uint8_t newLen = strlen(c); - this->flush() ; - memcpy(uartBuffer, SET_DEFAULT_SERVICES, len) ; - memcpy(&uartBuffer[len], c, newLen) ; + this->flush(); + memcpy(uartBuffer, SET_DEFAULT_SERVICES, len); + memcpy(&uartBuffer[len], c, newLen); - sendCommand(uartBuffer) ; + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -615,14 +701,14 @@ bool Rn487xBle::setDefaultServices(uint8_t bitmap) // ********************************************************************************* bool Rn487xBle::clearAllServices(void) { - debugPrintLn("[cleanAllServices]") ; + debugPrintLn("[cleanAllServices]"); - sendCommand(CLEAR_ALL_SERVICES) ; + sendCommand(CLEAR_ALL_SERVICES); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -634,14 +720,75 @@ bool Rn487xBle::clearAllServices(void) // ********************************************************************************* bool Rn487xBle::startAdvertising(void) { - debugPrintLn("[startAdvertising]") ; + debugPrintLn("[startAdvertising]"); - sendCommand(START_DEFAULT_ADV) ; + sendCommand(START_DEFAULT_ADV); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; +} + +// ********************************************************************************* +// Start Custom Advertisement +// ********************************************************************************* +// The advertisement is undirect connectable. (note, with no second parameter, this +// function will use the form of the START_CUSTOM_ADV command where no second +// parameter is sent, thus making advertisements last forever) +// Input : interval - the number of milliseconds between advertisements +// Output: bool true if successfully executed +// ********************************************************************************* +bool Rn487xBle::startCustomAdvertising(uint16_t interval) +{ + debugPrintLn("[startCustomAdvertising]"); + + uint8_t len = strlen(START_CUSTOM_ADV); + char parameters[5]; + sprintf(parameters, "%04X", interval); + uint8_t newLen = strlen(parameters); + + this->flush(); + memcpy(uartBuffer, START_CUSTOM_ADV, len); + memcpy(&uartBuffer[len], parameters, newLen); + + sendCommand(uartBuffer); + + if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) + { + return true; + } + return false; +} + +// ********************************************************************************* +// Start Custom Advertisement +// ********************************************************************************* +// The advertisement is undirect connectable. +// Input : interval - the number of milliseconds between advertisements +// Input : totalAdTime - the number of 640ms ticks until advertisements stop +// Output: bool true if successfully executed +// ********************************************************************************* +bool Rn487xBle::startCustomAdvertising(uint16_t interval, uint16_t totalAdTime) +{ + debugPrintLn("[startCustomAdvertising]"); + + uint8_t len = strlen(START_CUSTOM_ADV); + char parameters[10]; + sprintf(parameters, "%04X,%04X", interval, totalAdTime); + uint8_t newLen = strlen(parameters); + + this->flush(); + memcpy(uartBuffer, START_CUSTOM_ADV, len); + memcpy(&uartBuffer[len], parameters, newLen); + + sendCommand(uartBuffer); + + if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) + { + return true; + } + return false; } // ********************************************************************************* @@ -653,14 +800,14 @@ bool Rn487xBle::startAdvertising(void) // ********************************************************************************* bool Rn487xBle::stopAdvertising(void) { - debugPrintLn("[stopAdvertising]") ; + debugPrintLn("[stopAdvertising]"); - sendCommand(STOP_ADV) ; + sendCommand(STOP_ADV); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -672,14 +819,14 @@ bool Rn487xBle::stopAdvertising(void) // ********************************************************************************* bool Rn487xBle::clearImmediateAdvertising(void) { - debugPrintLn("[clearImmediateAdvertising]") ; + debugPrintLn("[clearImmediateAdvertising]"); - sendCommand(CLEAR_IMMEDIATE_ADV) ; + sendCommand(CLEAR_IMMEDIATE_ADV); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -692,14 +839,14 @@ bool Rn487xBle::clearImmediateAdvertising(void) // ********************************************************************************* bool Rn487xBle::clearPermanentAdvertising(void) { - debugPrintLn("[clearPermanentAdvertising]") ; + debugPrintLn("[clearPermanentAdvertising]"); - sendCommand(CLEAR_PERMANENT_ADV) ; + sendCommand(CLEAR_PERMANENT_ADV); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -711,14 +858,14 @@ bool Rn487xBle::clearPermanentAdvertising(void) // ********************************************************************************* bool Rn487xBle::clearImmediateBeacon(void) { - debugPrintLn("[clearImmediateBeacon]") ; + debugPrintLn("[clearImmediateBeacon]"); - sendCommand(CLEAR_IMMEDIATE_BEACON) ; + sendCommand(CLEAR_IMMEDIATE_BEACON); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } @@ -732,14 +879,14 @@ bool Rn487xBle::clearImmediateBeacon(void) // ********************************************************************************* bool Rn487xBle::clearPermanentBeacon(void) { - debugPrintLn("[clearPermanentBeacon]") ; + debugPrintLn("[clearPermanentBeacon]"); - sendCommand(CLEAR_PERMANENT_BEACON) ; + sendCommand(CLEAR_PERMANENT_BEACON); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -753,24 +900,24 @@ bool Rn487xBle::clearPermanentBeacon(void) // ********************************************************************************* bool Rn487xBle::startImmediateAdvertising(uint8_t adType, const char adData[]) { - debugPrintLn("[startImmediateAdvertising]") ; - - uint8_t len = strlen(START_IMMEDIATE_ADV) ; - char c[2] ; - sprintf(c, "%02X", adType) ; - uint8_t newLen = strlen(c) ; - - this->flush() ; - memcpy(uartBuffer, START_IMMEDIATE_ADV, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)) ; - sendCommand(uartBuffer) ; + debugPrintLn("[startImmediateAdvertising]"); + + uint8_t len = strlen(START_IMMEDIATE_ADV); + char c[2]; + sprintf(c, "%02X", adType); + uint8_t newLen = strlen(c); + + this->flush(); + memcpy(uartBuffer, START_IMMEDIATE_ADV, len); + memcpy(&uartBuffer[len], c, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -785,24 +932,24 @@ bool Rn487xBle::startImmediateAdvertising(uint8_t adType, const char adData[]) // ********************************************************************************* bool Rn487xBle::startPermanentAdvertising(uint8_t adType, const char adData[]) { - debugPrintLn("[startPermanentAdvertising]") ; - - uint8_t len = strlen(START_PERMANENT_ADV) ; - char c[2] ; - sprintf(c, "%02X", adType) ; - uint8_t newLen = strlen(c) ; - - this->flush() ; - memcpy(uartBuffer, START_PERMANENT_ADV, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)) ; - sendCommand(uartBuffer) ; + debugPrintLn("[startPermanentAdvertising]"); + + uint8_t len = strlen(START_PERMANENT_ADV); + char c[2]; + sprintf(c, "%02X", adType); + uint8_t newLen = strlen(c); + + this->flush(); + memcpy(uartBuffer, START_PERMANENT_ADV, len); + memcpy(&uartBuffer[len], c, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -816,24 +963,24 @@ bool Rn487xBle::startPermanentAdvertising(uint8_t adType, const char adData[]) // ********************************************************************************* bool Rn487xBle::startImmediateBeacon(uint8_t adType, const char adData[]) { - debugPrintLn("[startImmediateBeacon]") ; - - uint8_t len = strlen(START_IMMEDIATE_BEACON) ; - char c[2] ; - sprintf(c, "%02X", adType) ; - uint8_t newLen = strlen(c) ; - - this->flush() ; - memcpy(uartBuffer, START_IMMEDIATE_BEACON, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)) ; - sendCommand(uartBuffer) ; + debugPrintLn("[startImmediateBeacon]"); + + uint8_t len = strlen(START_IMMEDIATE_BEACON); + char c[2]; + sprintf(c, "%02X", adType); + uint8_t newLen = strlen(c); + + this->flush(); + memcpy(uartBuffer, START_IMMEDIATE_BEACON, len); + memcpy(&uartBuffer[len], c, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -848,24 +995,24 @@ bool Rn487xBle::startImmediateBeacon(uint8_t adType, const char adData[]) // ********************************************************************************* bool Rn487xBle::startPermanentBeacon(uint8_t adType, const char adData[]) { - debugPrintLn("[startPermanentBeacon]") ; - - uint8_t len = strlen(START_PERMANENT_BEACON) ; - char c[2] ; - sprintf(c, "%02X", adType) ; - uint8_t newLen = strlen(c) ; - - this->flush() ; - memcpy(uartBuffer, START_PERMANENT_BEACON, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)) ; - sendCommand(uartBuffer) ; + debugPrintLn("[startPermanentBeacon]"); + + uint8_t len = strlen(START_PERMANENT_BEACON); + char c[2]; + sprintf(c, "%02X", adType); + uint8_t newLen = strlen(c); + + this->flush(); + memcpy(uartBuffer, START_PERMANENT_BEACON, len); + memcpy(&uartBuffer[len], c, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], adData, strlen(adData)); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -880,14 +1027,14 @@ bool Rn487xBle::startPermanentBeacon(uint8_t adType, const char adData[]) // ********************************************************************************* bool Rn487xBle::startScanning(void) { - debugPrintLn("[startScanning]") ; + debugPrintLn("[startScanning]"); - sendCommand(START_DEFAULT_SCAN) ; + sendCommand(START_DEFAULT_SCAN); if (expectResponse(SCANNING_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -906,26 +1053,26 @@ bool Rn487xBle::startScanning(void) // ********************************************************************************* bool Rn487xBle::startScanning(uint16_t scanInterval, uint16_t scanWindow) { - debugPrint("[startScanning2]") ; //debugPrint(" Interval = " + scanInterval) ; debugPrint(" Window = " + scanWindow) ; - - uint8_t len = strlen(START_CUSTOM_SCAN) ; - char c1[4] ; - sprintf(c1, "%04X", scanInterval) ; - uint8_t newLen = strlen(c1) ; - char c2[4] ; - sprintf(c2, "%04X", scanWindow) ; + debugPrint("[startScanning2]"); //debugPrint(" Interval = " + scanInterval) ; debugPrint(" Window = " + scanWindow) ; + + uint8_t len = strlen(START_CUSTOM_SCAN); + char c1[4]; + sprintf(c1, "%04X", scanInterval); + uint8_t newLen = strlen(c1); + char c2[4]; + sprintf(c2, "%04X", scanWindow); - this->flush() ; - memcpy(uartBuffer, START_CUSTOM_SCAN, len) ; - memcpy(&uartBuffer[len], c1, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], c2, strlen(c2)) ; - sendCommand(uartBuffer) ; + this->flush(); + memcpy(uartBuffer, START_CUSTOM_SCAN, len); + memcpy(&uartBuffer[len], c1, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], c2, strlen(c2)); + sendCommand(uartBuffer); if (expectResponse(SCANNING_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -937,14 +1084,14 @@ bool Rn487xBle::startScanning(uint16_t scanInterval, uint16_t scanWindow) // ********************************************************************************* bool Rn487xBle::stopScanning(void) { - debugPrintLn("[stopScanning]") ; + debugPrintLn("[stopScanning]"); - sendCommand(STOP_SCAN) ; + sendCommand(STOP_SCAN); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -965,47 +1112,47 @@ bool Rn487xBle::stopScanning(void) // ********************************************************************************* bool Rn487xBle::addMacAddrWhiteList(bool addrType, const char *addr) { - debugPrint("[addMacAddrWhiteList] ") ; + debugPrint("[addMacAddrWhiteList] "); - uint8_t len = strlen(ADD_WHITE_LIST) ; - uint8_t addrLen = strlen(addr) ; + uint8_t len = strlen(ADD_WHITE_LIST); + uint8_t addrLen = strlen(addr); if (addrLen != MAC_ADDRESS_LEN) { - debugPrintLn("MAC Address is not valid !") ; - return false ; + debugPrintLn("MAC Address is not valid !"); + return false; } - debugPrintLn(addrType) ; + debugPrintLn(addrType); - whiteListCnt ++ ; + whiteListCnt++; if (whiteListCnt >= MAX_WHITE_LIST_SIZE) { - whiteListCnt = MAX_WHITE_LIST_SIZE ; - debugPrintLn("White list is full, not possible to add new MAC address.") ; - return false ; + whiteListCnt = MAX_WHITE_LIST_SIZE; + debugPrintLn("White list is full, not possible to add new MAC address."); + return false; } // Fill the buffer - this->flush() ; - memcpy(uartBuffer, ADD_WHITE_LIST, len) ; + this->flush(); + memcpy(uartBuffer, ADD_WHITE_LIST, len); if (addrType) { - memcpy(&uartBuffer[len], PRIVATE_ADDRESS_TYPE, 1) ; + memcpy(&uartBuffer[len], PRIVATE_ADDRESS_TYPE, 1); } else { - memcpy(&uartBuffer[len], PUBLIC_ADDRESS_TYPE, 1) ; + memcpy(&uartBuffer[len], PUBLIC_ADDRESS_TYPE, 1); } - len += 1 ; - memcpy(&uartBuffer[len], ",", 1) ; - len += 1 ; - memcpy(&uartBuffer[len], addr, addrLen) ; - sendCommand(uartBuffer) ; + len += 1; + memcpy(&uartBuffer[len], ",", 1); + len += 1; + memcpy(&uartBuffer[len], addr, addrLen); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1022,14 +1169,14 @@ bool Rn487xBle::addMacAddrWhiteList(bool addrType, const char *addr) // ********************************************************************************* bool Rn487xBle::addBondedWhiteList(void) { - debugPrintLn("[addBondedWhiteList]") ; + debugPrintLn("[addBondedWhiteList]"); - sendCommand(ADD_BONDED_WHITE_LIST) ; + sendCommand(ADD_BONDED_WHITE_LIST); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1041,16 +1188,16 @@ bool Rn487xBle::addBondedWhiteList(void) // ********************************************************************************* bool Rn487xBle::clearWhiteList(void) { - debugPrintLn("[clearWhiteList]") ; + debugPrintLn("[clearWhiteList]"); - whiteListCnt = 0 ; + whiteListCnt = 0; - sendCommand(CLEAR_WHITE_LIST) ; + sendCommand(CLEAR_WHITE_LIST); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1062,14 +1209,14 @@ bool Rn487xBle::clearWhiteList(void) // ********************************************************************************* bool Rn487xBle::killConnection(void) { - debugPrintLn("[killConnection]") ; + debugPrintLn("[killConnection]"); - sendCommand(KILL_CONNECTION) ; + sendCommand(KILL_CONNECTION); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1083,20 +1230,20 @@ bool Rn487xBle::killConnection(void) // ********************************************************************************* bool Rn487xBle::getRSSI(void) { - debugPrint("[getRSSI]") ; + debugPrint("[getRSSI]"); - uint16_t timeout = DEFAULT_CMD_TIMEOUT ; - unsigned long previous ; - sendCommand(GET_RSSI_LEVEL) ; - previous = millis() ; + uint16_t timeout = DEFAULT_CMD_TIMEOUT; + unsigned long previous; + sendCommand(GET_RSSI_LEVEL); + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (this->bleSerial->available() > 0) { if (readUntilCR() > 0) { - return true ; + return true; } } } @@ -1113,15 +1260,15 @@ bool Rn487xBle::getRSSI(void) // ********************************************************************************* bool Rn487xBle::reboot(void) { - debugPrintLn("[reboot]") ; + debugPrintLn("[reboot]"); - sendCommand(REBOOT) ; + sendCommand(REBOOT); if (expectResponse(REBOOTING_RESP, RESET_CMD_TIMEOUT)) { - delay(RESET_CMD_TIMEOUT) ; // delay needed - return true ; + delay(RESET_CMD_TIMEOUT); // delay needed + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1137,37 +1284,37 @@ bool Rn487xBle::reboot(void) // ********************************************************************************* bool Rn487xBle::setServiceUUID(const char *uuid) { - debugPrint("[serServiceUUID]") ; - debugPrintLn(uuid) ; + debugPrint("[serServiceUUID]"); + debugPrintLn(uuid); - uint8_t len = strlen(DEFINE_SERVICE_UUID) ; - uint8_t newLen = strlen(uuid) ; + uint8_t len = strlen(DEFINE_SERVICE_UUID); + uint8_t newLen = strlen(uuid); if (newLen == 32) { // 128-bit => private service - debugPrintLn("128-bit length => private service") ; + debugPrintLn("128-bit length => private service"); } else if (newLen == 4) { // 16-bit => public service - debugPrintLn("16-bit length => public service") ; + debugPrintLn("16-bit length => public service"); } else { - debugPrintLn("UUID length is not correct") ; - return false ; + debugPrintLn("UUID length is not correct"); + return false; } - this->flush() ; - memcpy(uartBuffer, DEFINE_SERVICE_UUID, len) ; - memcpy(&uartBuffer[len], uuid, newLen) ; - sendCommand(uartBuffer) ; + this->flush(); + memcpy(uartBuffer, DEFINE_SERVICE_UUID, len); + memcpy(&uartBuffer[len], uuid, newLen); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1187,54 +1334,54 @@ bool Rn487xBle::setServiceUUID(const char *uuid) // ********************************************************************************* bool Rn487xBle::setCharactUUID(const char *uuid, uint8_t property, uint8_t octetLen) { - debugPrint("[setCharactUUID]") ; - debugPrintLn(uuid) ; + debugPrint("[setCharactUUID]"); + debugPrintLn(uuid); if (octetLen < 0x01) { - octetLen = 0x01 ; - debugPrintLn("Octet Length is out of range (0x01-0x14)") ; + octetLen = 0x01; + debugPrintLn("Octet Length is out of range (0x01-0x14)"); } else if (octetLen > 0x14) { - octetLen = 0x14 ; - debugPrintLn("Octet Length is out of range (0x01-0x14)") ; + octetLen = 0x14; + debugPrintLn("Octet Length is out of range (0x01-0x14)"); } - uint8_t len = strlen(DEFINE_CHARACT_UUID) ; - uint8_t newLen = strlen(uuid) ; + //uint8_t len = strlen(DEFINE_CHARACT_UUID); + uint8_t newLen = strlen(uuid); if (newLen == PRIVATE_SERVICE_LEN) { - debugPrintLn("128-bit length => private service") ; + debugPrintLn("128-bit length => private service"); } else if (newLen == PUBLIC_SERVICE_LEN) { // 16-bit => public service - debugPrintLn("16-bit length => public service") ; + debugPrintLn("16-bit length => public service"); } else { - debugPrintLn("UUID length is not correct") ; - return false ; + debugPrintLn("UUID length is not correct"); + return false; } - String str = DEFINE_CHARACT_UUID ; - char c[2] ; - str.concat(uuid) ; - str.concat(',') ; - sprintf(c, "%02X", property) ; - str.concat(c) ; - str.concat(',') ; - sprintf(c, "%02X", octetLen) ; - str.concat(c) ; - - sendCommand(str) ; + String str = DEFINE_CHARACT_UUID; + char c[2]; + str.concat(uuid); + str.concat(','); + sprintf(c, "%02X", property); + str.concat(c); + str.concat(','); + sprintf(c, "%02X", octetLen); + str.concat(c); + + sendCommand(str); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1248,24 +1395,24 @@ bool Rn487xBle::setCharactUUID(const char *uuid, uint8_t property, uint8_t octet // ********************************************************************************* bool Rn487xBle::writeLocalCharacteristic(uint16_t handle, const char value[]) { - debugPrint("[writeLocalCharacteristic]") ; - - uint8_t len = strlen(WRITE_LOCAL_CHARACT) ; - char c[4] ; - sprintf(c, "%04X", handle) ; - uint8_t newLen = strlen(c) ; - - this->flush() ; - memcpy(uartBuffer, WRITE_LOCAL_CHARACT, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], value, strlen(value)) ; - sendCommand(uartBuffer) ; + debugPrint("[writeLocalCharacteristic]"); + + uint8_t len = strlen(WRITE_LOCAL_CHARACT); + char c[4]; + sprintf(c, "%04X", handle); + uint8_t newLen = strlen(c); + + this->flush(); + memcpy(uartBuffer, WRITE_LOCAL_CHARACT, len); + memcpy(&uartBuffer[len], c, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], value, strlen(value)); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1279,29 +1426,29 @@ bool Rn487xBle::writeLocalCharacteristic(uint16_t handle, const char value[]) // ********************************************************************************* bool Rn487xBle::readLocalCharacteristic(uint16_t handle) { - debugPrint("[readLocalCharacteristic]") ; + debugPrint("[readLocalCharacteristic]"); - uint16_t timeout = DEFAULT_CMD_TIMEOUT ; - unsigned long previous ; + uint16_t timeout = DEFAULT_CMD_TIMEOUT; + unsigned long previous; - uint8_t len = strlen(READ_LOCAL_CHARACT) ; - char c[4] ; - sprintf(c, "%04X", handle) ; - uint8_t newLen = strlen(c) ; + uint8_t len = strlen(READ_LOCAL_CHARACT); + char c[4]; + sprintf(c, "%04X", handle); + uint8_t newLen = strlen(c); - this->flush() ; - memcpy(uartBuffer, READ_LOCAL_CHARACT, len) ; - memcpy(&uartBuffer[len], c, newLen) ; - sendCommand(uartBuffer) ; - previous = millis() ; + this->flush(); + memcpy(uartBuffer, READ_LOCAL_CHARACT, len); + memcpy(&uartBuffer[len], c, newLen); + sendCommand(uartBuffer); + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (this->bleSerial->available() > 0) { if (readUntilCR() > 0) { - return true ; + return true; } } } @@ -1324,17 +1471,17 @@ bool Rn487xBle::readLocalCharacteristic(uint16_t handle) // ********************************************************************************* int Rn487xBle::getConnectionStatus(void) { - debugPrint("[getConnectionStatus]") ; + debugPrint("[getConnectionStatus]"); - uint16_t timeout = DEFAULT_CMD_TIMEOUT ; - unsigned long previous ; + uint16_t timeout = DEFAULT_CMD_TIMEOUT; + unsigned long previous; - sendCommand(GET_CONNECTION_STATUS) ; + sendCommand(GET_CONNECTION_STATUS); - previous = millis() ; + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (this->bleSerial->available() > 0) { if (readUntilCR() > 0) @@ -1343,15 +1490,15 @@ int Rn487xBle::getConnectionStatus(void) if (strstr(this->uartBuffer, NONE_RESP) != NULL) { // Not connected - return false ; + return false; } // Connected - return true ; + return true; } } } - debugPrint("[getConnectionStatus] Timeout without a response !") ; - return -1 ; + debugPrint("[getConnectionStatus] Timeout without a response !"); + return -1; } // ---------------------------------------- Private section ---------------------------------------- @@ -1364,18 +1511,18 @@ int Rn487xBle::getConnectionStatus(void) // ********************************************************************************* bool Rn487xBle::setBeaconFeatures(const char *value) { - debugPrintLn("[setBeaconFeatures]") ; + debugPrintLn("[setBeaconFeatures]"); - uint8_t len = strlen(SET_BEACON_FEATURES) ; - this->flush() ; - memcpy(uartBuffer, SET_BEACON_FEATURES, len) ; - memcpy(&uartBuffer[len], value, 1) ; - sendCommand(uartBuffer) ; + uint8_t len = strlen(SET_BEACON_FEATURES); + this->flush(); + memcpy(uartBuffer, SET_BEACON_FEATURES, len); + memcpy(&uartBuffer[len], value, 1); + sendCommand(uartBuffer); if (expectResponse(AOK_RESP, DEFAULT_CMD_TIMEOUT)) { - return true ; + return true; } - return false ; + return false; } // ********************************************************************************* @@ -1387,40 +1534,43 @@ bool Rn487xBle::setBeaconFeatures(const char *value) // ********************************************************************************* bool Rn487xBle::getSettings(uint16_t addr, uint8_t sizeToRead) { - debugPrintLn("[getSettings]") ; - - if (sizeToRead > MAX_SETTINGS_LEN) sizeToRead = MAX_SETTINGS_LEN ; - - uint16_t timeout = DEFAULT_CMD_TIMEOUT ; - unsigned long previous ; - - uint8_t len = strlen(GET_SETTINGS) ; - char c1[4] ; - sprintf(c1, "%04X", addr) ; - uint8_t newLen = strlen(c1) ; - char c2[2] ; - sprintf(c2, "%02X", sizeToRead) ; - - this->flush() ; - memcpy(uartBuffer, GET_SETTINGS, len) ; - memcpy(&uartBuffer[len], c1, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], c2, strlen(c2)) ; - sendCommand(uartBuffer) ; + debugPrintLn("[getSettings]"); + + if (sizeToRead > MAX_SETTINGS_LEN) + { + sizeToRead = MAX_SETTINGS_LEN; + } + + uint16_t timeout = DEFAULT_CMD_TIMEOUT; + unsigned long previous; + + uint8_t len = strlen(GET_SETTINGS); + char c1[4]; + sprintf(c1, "%04X", addr); + uint8_t newLen = strlen(c1); + char c2[2]; + sprintf(c2, "%02X", sizeToRead); + + this->flush(); + memcpy(uartBuffer, GET_SETTINGS, len); + memcpy(&uartBuffer[len], c1, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], c2, strlen(c2)); + sendCommand(uartBuffer); - previous = millis() ; + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (this->bleSerial->available() > 0) { if (readUntilCR() > 0) { - return true ; + return true; } } } - return false ; + return false; } // ********************************************************************************* @@ -1434,41 +1584,41 @@ bool Rn487xBle::getSettings(uint16_t addr, uint8_t sizeToRead) // ********************************************************************************* bool Rn487xBle::setSettings(uint16_t addr, const char *data) { - debugPrintLn("[setSettings]") ; + debugPrintLn("[setSettings]"); - uint8_t dataLen = strlen(data) ; - debugPrintLn(data) ; - debugPrint("Len = ") ; - debugPrintLn(dataLen) ; + uint8_t dataLen = strlen(data); + debugPrintLn(data); + debugPrint("Len = "); + debugPrintLn(dataLen); - uint16_t timeout = DEFAULT_CMD_TIMEOUT ; - unsigned long previous ; - - uint8_t len = strlen(SET_SETTINGS) ; - char c1[4] ; - sprintf(c1, "%04X", addr) ; - uint8_t newLen = strlen(c1) ; - - this->flush() ; - memcpy(uartBuffer, SET_SETTINGS, len) ; - memcpy(&uartBuffer[len], c1, newLen) ; - memcpy(&uartBuffer[len+newLen], ",", 1) ; - memcpy(&uartBuffer[len+newLen+1], data, dataLen) ; - sendCommand(uartBuffer) ; + uint16_t timeout = DEFAULT_CMD_TIMEOUT; + unsigned long previous; + + uint8_t len = strlen(SET_SETTINGS); + char c1[4]; + sprintf(c1, "%04X", addr); + uint8_t newLen = strlen(c1); + + this->flush(); + memcpy(uartBuffer, SET_SETTINGS, len); + memcpy(&uartBuffer[len], c1, newLen); + memcpy(&uartBuffer[len+newLen], ",", 1); + memcpy(&uartBuffer[len+newLen+1], data, dataLen); + sendCommand(uartBuffer); - previous = millis() ; + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (this->bleSerial->available() > 0) { if (readUntilCR() > 0) { - return true ; + return true; } } } - return false ; + return false; } // ********************************************************************************* @@ -1479,8 +1629,13 @@ bool Rn487xBle::setSettings(uint16_t addr, const char *data) // ********************************************************************************* void Rn487xBle::flush(void) { - uartBufferLen = DEFAULT_INPUT_BUFFER_SIZE ; - memset(uartBuffer, 0, uartBufferLen) ; + uartBufferLen = DEFAULT_INPUT_BUFFER_SIZE; + // FOR DEBUGGING, PRINT OUT ANYTHING THAT'S IN THE BUFFER +// this->diagStream->print(" * Flushing :"); +// this->diagStream->print(uartBuffer); +// this->diagStream->println(":"); + + memset(uartBuffer, 0, uartBufferLen); } // ********************************************************************************* @@ -1493,7 +1648,7 @@ void Rn487xBle::cleanInputBuffer(void) { while (bleSerial->available() > 0) { - bleSerial->read() ; + bleSerial->read(); } } @@ -1505,7 +1660,7 @@ void Rn487xBle::cleanInputBuffer(void) // ********************************************************************************* void Rn487xBle::setOperationMode(operationMode_t newMode) { - operationMode = newMode ; + operationMode = newMode; } // ********************************************************************************* @@ -1516,7 +1671,7 @@ void Rn487xBle::setOperationMode(operationMode_t newMode) // ********************************************************************************* operationMode_t Rn487xBle::getOperationMode(void) { - return(operationMode) ; + return(operationMode); } @@ -1533,8 +1688,8 @@ operationMode_t Rn487xBle::getOperationMode(void) // ********************************************************************************* uint16_t Rn487xBle::readUntilCR(char* buffer, uint16_t size, uint16_t start) { - int len = this->bleSerial->readBytesUntil(CR, buffer + start, size) ; - return len ; + int len = this->bleSerial->readBytesUntil(LF, buffer + start, size); + return len; } @@ -1548,30 +1703,30 @@ uint16_t Rn487xBle::readUntilCR(char* buffer, uint16_t size, uint16_t start) // ********************************************************************************* bool Rn487xBle::expectResponse(const char* expectedResponse, uint16_t timeout) { - debugPrint("[expectResponse] expecting ") ; - debugPrintLn(expectedResponse) ; + debugPrint("[expectResponse] expecting "); + debugPrintLn(expectedResponse); - unsigned long previous ; + unsigned long previous; - memset(uartBuffer, 0, uartBufferLen) ; // clear the buffer - cleanInputBuffer() ; - previous = millis() ; + memset(uartBuffer, 0, uartBufferLen); // clear the buffer + cleanInputBuffer(); + previous = millis(); while (millis() - previous < timeout) { - debugPrint(".") ; + debugPrint("."); if (readUntilCR() > 0) { - debugPrint("(") ; - debugPrint(this->uartBuffer) ; - debugPrint(")") ; + debugPrint("("); + debugPrint(this->uartBuffer); + debugPrint(")"); if (strstr(this->uartBuffer, expectedResponse) != NULL) { - debugPrintLn(" found a match !") ; - return true ; + debugPrintLn(" found a match !"); + return true; } - return false ; + return false; } } - return false ; + return false; } diff --git a/src/RN487x_BLE.h b/src/RN487x_BLE.h index 99da0ab..e4919a7 100644 --- a/src/RN487x_BLE.h +++ b/src/RN487x_BLE.h @@ -24,13 +24,27 @@ TERMS. */ +/* TODO: + * add support for Scan Response commands + * add support for script commands (like stop and clear) + * Bug: Init sends two "R,1"s. Why? Only one is needed. + * Add support for Set Connection Parameters ("ST") + * Add support for Modify Current Connection Parameters ("T") + * BIG ONE: Add support for async notifications - like when the phone updates a local + server characteristic, and we get a "%WC," or "%WC," string from BLE module. Maybe + have a callback mechanism for this? + */ + + #ifndef __RN487x_BLE #define __RN487x_BLE #include "RN487x_CONST.h" #include #include -#include +#if !defined(__PIC32__) + #include +#endif #include #define DEFAULT_INPUT_BUFFER_SIZE 100 @@ -39,76 +53,79 @@ typedef enum { dataMode, cmdMode -} operationMode_t ; +} operationMode_t; class Rn487xBle { // ---------------------------------------- Public section ---------------------------------------- public: - Rn487xBle() ; - virtual ~Rn487xBle() ; - uint32_t getDefaultBaudRate(void) { return(DEFAULT_BAUDRATE) ; } ; - void setDiag(Stream& stream) { diagStream = &stream ; } ; - inline void initBleStream(Uart *stream) { this->bleSerial = stream ; cleanInputBuffer() ; } ; - bool swInit(void) ; - void hwInit(void) ; - void hwReset(void) ; - void hwWakeUp(void) ; - void hwSleep(void) ; - bool enterDataMode(void) ; - bool enterCommandMode(void) ; - void sendCommand(String stream) ; - void sendData(char *data, uint16_t dataLen) ; - bool disableBeacon(void) ; - bool enableBeacon(void) ; - bool enableBeaconAndAdv(void) ; - bool factoryReset(void) ; - bool setAdvPower(uint8_t value) ; - bool setConPower(uint8_t value) ; - bool setSerializedName(const char *newName) ; - bool setDevName(const char *newName) ; - bool enableLowPower(void) ; - bool disableLowPower(void) ; - bool setSupportedFeatures(uint16_t bitmap) ; - bool setDefaultServices(uint8_t bitmap) ; - bool retrieveBtAddress(void) ; - bool getFirmwareVersion(void) ; - bool clearAllServices(void) ; - bool startAdvertising(void) ; - bool stopAdvertising(void) ; - bool clearImmediateAdvertising(void) ; - bool clearPermanentAdvertising(void) ; - bool clearImmediateBeacon(void) ; - bool clearPermanentBeacon(void) ; - bool startImmediateAdvertising(uint8_t adType, const char adData[]) ; - bool startPermanentAdvertising(uint8_t adType, const char adData[]) ; - bool startImmediateBeacon(uint8_t adType, const char adData[]) ; - bool startPermanentBeacon(uint8_t adType, const char adData[]) ; - bool startScanning(void) ; - bool startScanning(uint16_t scanInterval, uint16_t scanWindow) ; - bool stopScanning(void) ; - bool addMacAddrWhiteList(bool addrType, const char *addr) ; - bool addBondedWhiteList(void) ; - bool clearWhiteList(void) ; - bool killConnection(void) ; - bool getRSSI(void) ; - bool reboot(void) ; - bool setServiceUUID(const char *uuid) ; - bool setCharactUUID(const char *uuid, uint8_t property, uint8_t octetLen) ; - bool writeLocalCharacteristic(uint16_t handle, const char value[]) ; - bool readLocalCharacteristic(uint16_t handle) ; - int getConnectionStatus(void) ; - inline const char* getPeerAddress() { return peerAddress ; } ; - inline const char* getBtAddress() { return btAddress ; } ; - inline const char* getDeviceName() { return deviceName ; } ; - inline const char* getLastResponse() { return uartBuffer ; } ; + Rn487xBle(); + virtual ~Rn487xBle(); + uint32_t getDefaultBaudRate(void) { return(DEFAULT_BAUDRATE);}; + void setDiag(Stream& stream) { diagStream = &stream;}; + inline void initBleStream(HardwareSerial *stream) { this->bleSerial = stream ; cleanInputBuffer();}; + bool swInit(void); + void hwInit(void); + void hwInit(uint8_t resetBLEPin, uint8_t sleepBLEPin); + void hwReset(void); + void hwWakeUp(void); + void hwSleep(void); + bool enterDataMode(void); + bool enterCommandMode(void); + void sendCommand(String stream); + void sendData(char *data, uint16_t dataLen); + bool disableBeacon(void); + bool enableBeacon(void); + bool enableBeaconAndAdv(void); + bool factoryReset(void); + bool setAdvPower(uint8_t value); + bool setConPower(uint8_t value); + bool setSerializedName(const char *newName); + bool setDevName(const char *newName); + bool enableLowPower(void); + bool disableLowPower(void); + bool setSupportedFeatures(uint16_t bitmap); + bool setDefaultServices(uint8_t bitmap); + bool retrieveBtAddress(void); + bool getFirmwareVersion(void); + bool clearAllServices(void); + bool startAdvertising(void); + bool startCustomAdvertising(uint16_t interval); + bool startCustomAdvertising(uint16_t interval, uint16_t totalAdTime); + bool stopAdvertising(void); + bool clearImmediateAdvertising(void); + bool clearPermanentAdvertising(void); + bool clearImmediateBeacon(void); + bool clearPermanentBeacon(void); + bool startImmediateAdvertising(uint8_t adType, const char adData[]); + bool startPermanentAdvertising(uint8_t adType, const char adData[]); + bool startImmediateBeacon(uint8_t adType, const char adData[]); + bool startPermanentBeacon(uint8_t adType, const char adData[]); + bool startScanning(void); + bool startScanning(uint16_t scanInterval, uint16_t scanWindow); + bool stopScanning(void); + bool addMacAddrWhiteList(bool addrType, const char *addr); + bool addBondedWhiteList(void); + bool clearWhiteList(void); + bool killConnection(void); + bool getRSSI(void); + bool reboot(void); + bool setServiceUUID(const char *uuid); + bool setCharactUUID(const char *uuid, uint8_t property, uint8_t octetLen); + bool writeLocalCharacteristic(uint16_t handle, const char value[]); + bool readLocalCharacteristic(uint16_t handle); + int getConnectionStatus(void); + inline const char* getPeerAddress() { return peerAddress;}; + inline const char* getBtAddress() { return btAddress;}; + inline const char* getDeviceName() { return deviceName;}; + inline const char* getLastResponse() { return uartBuffer;}; inline bool isInputBuffer() { - if (bleSerial->available() > 0) return true ; - return false ; + if (bleSerial->available() > 0) return true; + return false; } - inline char getInputBuffer(){ return bleSerial->read() ; } ; + inline char getInputBuffer(){ return bleSerial->read();}; // --------------------------------------- Protected section --------------------------------------- protected: @@ -116,31 +133,34 @@ class Rn487xBle // ---------------------------------------- Private section ---------------------------------------- private: - bool setBeaconFeatures(const char *value) ; - bool getSettings(uint16_t addr, uint8_t sizeToRead) ; - bool setSettings(uint16_t addr, const char *data) ; - void flush(void) ; - void cleanInputBuffer(void) ; - void setOperationMode(operationMode_t newMode) ; - operationMode_t getOperationMode(void) ; - uint16_t readUntilCR(char* buffer, uint16_t size, uint16_t start = 0) ; - uint16_t readUntilCR() { return readUntilCR(this->uartBuffer, this->uartBufferLen) ; } ; - bool expectResponse(const char* expectedResponse, uint16_t timeout) ; - - Uart *bleSerial ; - Stream* diagStream ; - char *uartBuffer ; - int uartBufferLen ; - char endStreamChar ; - operationMode_t operationMode ; - bool connectionStatus ; - char btAddress[12] ; - char peerAddress[6] ; - char deviceName[MAX_DEVICE_NAME_LEN] ; - uint8_t whiteListCnt ; + bool setBeaconFeatures(const char *value); + bool getSettings(uint16_t addr, uint8_t sizeToRead); + bool setSettings(uint16_t addr, const char *data); + void flush(void); + void cleanInputBuffer(void); + void setOperationMode(operationMode_t newMode); + operationMode_t getOperationMode(void); + uint16_t readUntilCR(char* buffer, uint16_t size, uint16_t start = 0); + uint16_t readUntilCR() { return readUntilCR(this->uartBuffer, this->uartBufferLen);}; + bool expectResponse(const char* expectedResponse, uint16_t timeout); + + HardwareSerial *bleSerial; + Stream* diagStream; + char *uartBuffer; + int uartBufferLen; + char endStreamChar; + operationMode_t operationMode; + bool connectionStatus; + char btAddress[12]; + char peerAddress[6]; + char deviceName[MAX_DEVICE_NAME_LEN]; + uint8_t whiteListCnt; + bool commandPromptEnabled; + int8_t wakePin; + int8_t resetPin; } ; // external variable used by the sketch -extern Rn487xBle rn487xBle ; +extern Rn487xBle rn487xBle; #endif diff --git a/src/RN487x_CONST.h b/src/RN487x_CONST.h index ce859a7..22a5e19 100644 --- a/src/RN487x_CONST.h +++ b/src/RN487x_CONST.h @@ -154,7 +154,8 @@ // ------------------- Response ----------------------- -#define PROMPT "CMD>" // exact prompt is "CMD> " (last char is a space) +#define PROMPT "CMD> " // exact prompt is "CMD> " (last char is a space) +#define PROMPT_CR "CMD\r\n" #define PROMPT_END "END" //-- Response diff --git a/uecide.json b/uecide.json new file mode 100644 index 0000000..f11e43f --- /dev/null +++ b/uecide.json @@ -0,0 +1,19 @@ +{ + "name": "RN487x", + "provides": "RN487x_BLE.h", + "license": "Readme.md", + "readme": "Readme.md", + "description": "Microchip RN487x BLE module", + "category": "Communications", + "subcategory": "Wireless", + "maintainer": "Brian Schmalz ", + "version": "1.2.0", + "family": "pic32", + "core": "chipkit", + "install": { + "examples": "/", + "src": "/", + "keywords.txt": "/", + "library.properties": "/" + } +}