Closed nicolocarpignoli closed 7 years ago
First of all, you have a lot of characteristics for this service and usually performance gets affected when you have that much. I did not check thoroughly but make sure you are using all of them further down the code. Will your central app be querying/subscribing to all those characteristics?
Hello, There...
The sketch provided exercises a large amount of code (libraries) and several h/w features. It would be helpful to nail down the suspicious area to locate the source of the problem - the divide and conquer strategy. There are several areas that can be singled out to verify its operation.
Verify if the IMU interrupt mechanism is good. Comment out the BLE related code. Use the USB serial interface to dump out the IMU data instead of the BLE. Perform the same shaking test to see if the system can hold up.
Verify if the BLE interface section. First, comment out the eventHandler/interrupt driven code. Then, in the loop(), perform a, CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz). And set each characteristic to see if the system can hold up. Use a Central to check on the values. The IMU is capable of generating data at 100 Hz. With each piece of IMU data as an individual characteristic, it is certain that the Central will not be able to pull out IMU data at 100 Hz.
The IMU interrupt mechanism is good, I've done that try. The only way that I could got this thing work with my shacking test is with the following code:
#include "CurieIMU.h"
#include "CurieBLE.h"
#include <stdio.h> /* puts, printf */
int aix, aiy, aiz; // raw accelerometer values
int gix, giy, giz; // raw gyro values
bool flag = false;
BLEPeripheral blePeripheral;
BLEService sensorService("19B10010-E8F2-537E-4F6C-D104768A1214");
BLEUnsignedLongCharacteristic stepCharacteristic("19B10011-E8F2-537E-4F6C-D104768A1214", BLERead); // stepcount
BLEFloatCharacteristic axCharacteristic("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // acc.in x in g
BLEFloatCharacteristic ayCharacteristic("19B10013-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // acc.in y in g
BLEFloatCharacteristic azCharacteristic("19B10014-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // acc.in z in g
BLEFloatCharacteristic gxCharacteristic("19B10015-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // rot.in x in deg/s
BLEFloatCharacteristic gyCharacteristic("19B10016-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // rot.in y in deg/s
BLEFloatCharacteristic gzCharacteristic("19B10017-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // rot.in z in deg/s
BLEIntCharacteristic shockCharacteristic("19B10018-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify); // true if shock sensed
BLEIntCharacteristic modeCharacteristic("19B10019-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); // sensing mode
BLEIntCharacteristic srangeCharacteristic("19B10020-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); // shock range
BLEIntCharacteristic arangeCharacteristic("19B10021-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); // acc. range
BLEIntCharacteristic grangeCharacteristic("9B100122-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); // gyro range
BLEIntCharacteristic calibCharacteristic("9B100123-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); // 1 if calibration is on, otherwise 0
void setup()
{
//Serial.begin(9600);
//while (!Serial); // wait for the serial port to open
// Serial.println("Initializing IMU device...");
CurieIMU.begin();
// configure Bluetooth
blePeripheral.setLocalName("MOOVBIT");
blePeripheral.setAdvertisedServiceUuid(sensorService.uuid());
blePeripheral.addAttribute(sensorService);
blePeripheral.addAttribute(stepCharacteristic);
blePeripheral.addAttribute(axCharacteristic);
blePeripheral.addAttribute(ayCharacteristic);
blePeripheral.addAttribute(azCharacteristic);
blePeripheral.addAttribute(gxCharacteristic);
blePeripheral.addAttribute(gyCharacteristic);
blePeripheral.addAttribute(gzCharacteristic);
blePeripheral.addAttribute(shockCharacteristic);
/*blePeripheral.addAttribute(modeCharacteristic);
blePeripheral.addAttribute(arangeCharacteristic);
blePeripheral.addAttribute(srangeCharacteristic);
blePeripheral.addAttribute(grangeCharacteristic);
blePeripheral.addAttribute(calibCharacteristic);*/
// set initial characteristics values
stepCharacteristic.setValue(0);
shockCharacteristic.setValue(0);
modeCharacteristic.setValue(0);
arangeCharacteristic.setValue(4);
srangeCharacteristic.setValue(4);
grangeCharacteristic.setValue(250);
calibCharacteristic.setValue(1);
blePeripheral.begin();
// Configure sensors
CurieIMU.setAccelerometerRange(arangeCharacteristic.value());
CurieIMU.setGyroRange(grangeCharacteristic.value());
CurieIMU.setStepDetectionMode(CURIE_IMU_STEP_MODE_SENSITIVE);
CurieIMU.setStepCountEnabled(true);
/*CurieIMU.setDetectionThreshold(CURIE_IMU_TAP, 750); // (750mg)
CurieIMU.setDetectionThreshold(CURIE_IMU_DOUBLE_TAP, 750); // (750mg)
CurieIMU.interrupts(CURIE_IMU_TAP);
CurieIMU.interrupts(CURIE_IMU_DOUBLE_TAP);*/
CurieIMU.setDetectionThreshold(CURIE_IMU_SHOCK, srangeCharacteristic.value() * 500); // 1g = 1000 mg
CurieIMU.setDetectionDuration(CURIE_IMU_SHOCK, 50); // 50ms or 75ms
CurieIMU.interrupts(CURIE_IMU_SHOCK);
//CurieIMU.interrupts(CURIE_IMU_MOTION);
CurieIMU.attachInterrupt(eventCallback);
}
void loop()
{
if(!flag){
CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);
flag = true;
}else{
if(!axCharacteristic.setValue(convertRawAcceleration(aix))
|| !ayCharacteristic.setValue(convertRawAcceleration(aiy))
|| !azCharacteristic.setValue(convertRawAcceleration(aiz))
|| !gxCharacteristic.setValue(convertRawGyro(gix))
|| !gyCharacteristic.setValue(convertRawGyro(giy))
|| !gzCharacteristic.setValue(convertRawGyro(giz))){
// do nothing
}
stepCharacteristic.setValue(CurieIMU.getStepCount());
shockCharacteristic.setValue(0);
flag = false;
}
delay(1000);
}
void eventCallback() {
if (CurieIMU.getInterruptStatus(CURIE_IMU_SHOCK)) {
shockCharacteristic.setValue(1);
}
}
// converted values based on accelerometer range
float convertRawAcceleration(int aRaw) {
float a = (aRaw * float(arangeCharacteristic.value()) / 32768.0); // output values from -16.0 to +16.0
return a;
}
// converted values based on gyro range
float convertRawGyro(int gRaw) {
float g = (gRaw * float(grangeCharacteristic.value()) / 32768.0); // output values from -2000.0 to +2000.0
return g;
}
@nicolocarpignoli, can you do us a favour and tell us what you changed to make it work? instead of posting the whole sketch for us to figure out....
this precise part:
void loop()
{
if(!flag){
CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);
flag = true;
}else{
if(!axCharacteristic.setValue(convertRawAcceleration(aix))
|| !ayCharacteristic.setValue(convertRawAcceleration(aiy))
|| !azCharacteristic.setValue(convertRawAcceleration(aiz))
|| !gxCharacteristic.setValue(convertRawGyro(gix))
|| !gyCharacteristic.setValue(convertRawGyro(giy))
|| !gzCharacteristic.setValue(convertRawGyro(giz))){
// do nothing
}
stepCharacteristic.setValue(CurieIMU.getStepCount());
shockCharacteristic.setValue(0);
flag = false;
}
delay(1000);
reading in the first step of the loop cycle and writing characteristics in the following step made the trick
Thanks @nicolocarpignoli !
Hi, i'm seeing a randomly strange behaviour of the Arduino101. If I don't move the board everything works fine, but when I start shacking and moving constantly the board it randomly gets stucked. This means that you can not see anymore the BLE Arduino device when scanning, and the only way to work again with it it's to restart the board. When facing this issue, the power on the arduino is still ok. Again I repeat, it seems something related with shacking the board for a while.
I put here my code hoping that you can help me understand the possible reasons for that (maybe some problem about performance or the way I handle interrupts).