I have the following code which I want to use on a xenon as peripheral device to update batt voltage to an Argon. The problem is it only runs on Argons the service does not show up on Xenons. I have also noticed it does not run on all Argons I have a few of them all with 1.4.4 but some of them I cant conenct to or they dont show up on the list. It does not run at all on the new OS 1.5-RC1 (goes into safe mode) . It is based on the HTM example which I see is also not working on all devices. Is there something missing,
#include "Particle.h"
float battVoltage;//holds the local battery voltage
SerialLogHandler logHandler(LOG_LEVEL_TRACE);
const unsigned long UPDATE_INTERVAL_MS = 2000;
unsigned long lastUpdate = 0;
float getTempC();
uint32_t ieee11073_from_float(float temperature);
const char* xenonBattService = "b4250400-fb4b-4746-b2b0-93f0e61122c6"; //service
BleUuid xenonBattBleService(xenonBattService);
BleCharacteristic batteryMeasurementCharacteristic("bat", BleCharacteristicProperty::NOTIFY, BleUuid(0x2A19), xenonBattService);
void setup() {
(void)logHandler; // Does nothing, just to eliminate the unused variable warning
BLE.on();
//BLE.setAdvertisingTimeout(500); // 1000 * 10 ms // time period of the the detonation period (how long it get transmitted)
Particle.keepAlive(20);
Serial.begin(115200);
pinMode(BATT, INPUT); // argon battery
BLE.setTxPower(0); // Use lower power // Use lower power -20, -16, -12, -8, -4, 0, 4, 8.
// set initial IO states
pinMode(BATT, INPUT);
BLE.addCharacteristic(batteryMeasurementCharacteristic);
BleAdvertisingData advData;
advData.appendServiceUUID(xenonBattService);
BLE.advertise(&advData);
}
void loop() {
if (millis() - lastUpdate >= UPDATE_INTERVAL_MS) {
lastUpdate = millis();
if (BLE.connected()) {
uint8_t buf[6];
battVoltage = analogRead(BATT) * 0.0011224;
//battVoltage = analogRead(BATT) * 0.0011224 / 3.7 * 100; /// in percentage
buf[0] = 0x01;
memcpy(&buf[1], &battVoltage, 5);
batteryMeasurementCharacteristic.setValue(buf, sizeof(buf));
}
}
}
You need to put in SYSTEM_MODE(MANUAL); after the #include “Particle.h”. Otherwise the Xenon (and the Argon) will be looking to connect to a Mesh network and a WiFi network and will be flash green on the LED and blocking getting out of setup().
The battery level characteristic reports a percentage 0-100 as a single byte and not a float. I put in something like this:
uint8_t value;
value = (uint8_t) (analogRead(BATT) * 0.0011224 * 100 / 4.2); //battery voltage as a float as a percentage of 4.2V typecast to an unsigned 8-bit int
batteryMeasurementCharacteristic.setValue(&value, 1);
If you want to send back battery voltage then maybe a custom service and characteristic? You will need to read the battery voltage as a float and then convert into a 4 byte array to send. Maybe you had not included but you would also need to define the float conversion function.
uint32_t ieee11073_from_float(float temperature)
{
// This code is from the ARM mbed temperature demo:
// https://github.com/ARMmbed/ble/blob/master/ble/services/HealthThermometerService.h
// I'm pretty sure this only works for positive values of temperature, but that's OK for the health thermometer.
uint8_t exponent = 0xFE; // Exponent is -2
uint32_t mantissa = (uint32_t)(temperature * 100);
return (((uint32_t)exponent) << 24) | mantissa;
}
It works fine, ie. the battery level as a percentage on a Xenon on 1.4.4 and 1.5.0-rc.1.
Note: there is an error with the enumerator value for battery service - I believe the value should be 0x180F. The code that works for me is below.
#include "Particle.h"
SYSTEM_MODE(MANUAL); //to stop mesh connection blocking
const unsigned long UPDATE_INTERVAL_MS = 2000UL;
unsigned long lastUpdate = 0;
// The battery level service allows the battery level to be monitored 0x180F
BleUuid batteryLevelService(0x180F);
// The battery_level characteristic shows the battery level of
BleCharacteristic batteryLevelCharacteristic("battery level", BleCharacteristicProperty::READ, BleUuid(0x2A19), batteryLevelService);
void setup()
{
Serial.begin();
Serial.println("BLE battery level example");
BLE.on();
BLE.addCharacteristic(batteryLevelCharacteristic);
BleAdvertisingData advData;
advData.appendServiceUUID(batteryLevelService);
BLE.advertise(&advData);
}
void loop()
{
if (millis() - lastUpdate >= UPDATE_INTERVAL_MS)
{
lastUpdate = millis();
if (BLE.connected())
{
uint8_t value;
value = (uint8_t) (analogRead(BATT) * 0.0011224 * 100 / 4.2); //battery voltage as a float as a percentage of 4.2V typecast to an unsigned 8-bit int
if (value > 100) value = 100;
Serial.printlnf("Battery Level %% %i", value);
batteryLevelCharacteristic.setValue(&value, 1);
}
}
}
I discovered the following. From a batch of 4 Argons and 10 Xenons I found the code dit not work on 1 Argon and also did not work on 3 Xenons. These came back with , BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION
Closer investigation lead me to the following. All the particles when put into listening mode with the COM port open returns a Device ID, Device secret and serial no, they are all working
The ones that are not working only show device is as per below.
I am very sure these that are not connecting are the ones that at some stage had the Nordic SDK installed. Is this possible?
As for v1.5.0-rc
Im also at a loss when compile in VS Particle Workbench if I compile and stay on the tab “Welcome to particle workbench” after selecting “configure for device” I receive error below
openthread/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c:72:1: fatal error: opening dependency file …/…/build/target/openthread/platform-12-/./openthread/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.o.d: No such file or directory
}
^
compilation terminated.
If go to “Project.INO” tab and then compile it compiles successfully. The code however does not run.
Tried the suggestions. particle serial inspect shows differences on
User Module one is v5 (misbehaving) and one v6 (working)
NCP module one is v 5 (misbehaving) and the other v3 (working)
. Adafruit BLE has the same results it does not connect to the misbehaving devices. Both apps does show the batt service but as soon as you connect it disconnects with invalid handle.
using OS v1.4.4
I ran particle update I dont know if this updates the soft device as well
Decided to compare using nrf_Programmer. Definitely not the same. Once I copied the working hex file across I can connect again. I will try the same with the Xenons tonight. Thank you for the assistance.
Morning. Looks like im back at square 1. Copying the code from working Xenons and Argons did not revive the misbehaving ones. I did notice this morning that I can connect to the misbehaving ones when they are in listening mode. In listening mode strangely they all show the Batt service and the char value of the batt.