Go Down

Topic: void loop stops when using motion sensor and bluetooth (Read 1 time) previous topic - next topic

blayze

I got my Ardunio not too long ago and I have been working on a project that needs information from the motion sensor (CurieIMU) and data from the bluetooth (CurieBLE) that is sent form an Android phone.

The problem that I am having is when I send data at a fairly high rate (120ms - 5ms), after a random number of reads (3-40+) from the bluetooth, the void loop function will stop getting called. However the bluetooth still is able to read and print the data sent to it.

When the motion sensor and bluetooth are used used separately with the same code they work without a problem.

Edit: It seems to be crashing when CurieIMU.readMotionSensor is called. After looking into that function it seems to crash on a call to ss_spi_xfer in ss_spi.c.

I have pulled out the relevant code from my project.
Code: [Select]
#include <CurieIMU.h>
#include <CurieBLE.h>

BLEPeripheral blePeripheral;
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214");
BLEFloatCharacteristic rollChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLEWrite); //Roll;

//Gyro timing
unsigned long microsPerReading, microsPrevious, microsNow;

//Settings
float gRange, gyroRange;

//Raw gyro values
int gix, giy, giz;
int aix, aiy, aiz;

void setup() {
  Serial.begin(9600);
  Serial.println("Starting");
  setupGyro();
  setupBluetooth();
}

void loop() {
  Serial.println("-");
  checkGyro();
  Serial.println("+");
}

void checkGyro(){
  //If its time to update
  microsNow = micros();
  if (microsNow - microsPrevious >= microsPerReading) {
    CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);
    microsPrevious = microsPrevious + microsPerReading;
  }
}

void setupBluetooth(){
  // set the local name peripheral advertises
  blePeripheral.setLocalName("Ardunio");
  
  // set the UUID for the service this peripheral advertises
  blePeripheral.setAdvertisedServiceUuid(ledService.uuid());

  // add service and characteristic
  blePeripheral.addAttribute(ledService);
  blePeripheral.addAttribute(rollChar);
  
  // assign event handlers for connected, disconnected to peripheral
  blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  // assign event handlers for characteristic
  rollChar.setEventHandler(BLEWritten, rollRead);
  rollChar.setValue(0);

  // advertise the service
  blePeripheral.begin();
  Serial.println(("Bluetooth device active, waiting for connections..."));
}

void setupGyro(){
  int gyroUpdateRate = 800;    // supported values: 12.5, 25, 50, 100, 200, 400, 800, 1600 (Hz)
  int gRangeValue = 2;        // supported values: 2, 4, 8, 16 (G)
  int gyroRangeValue = 250;   // supported values: 125, 250, 500, 1000, 2000 (?)

  // Start the IMU and filter
  CurieIMU.begin();
  CurieIMU.setGyroRate(gyroUpdateRate);
  CurieIMU.setAccelerometerRate(gyroUpdateRate);

  // Set the ranges
  CurieIMU.setAccelerometerRange(gRangeValue);
  CurieIMU.setGyroRange(gyroRangeValue);

  // initialize variables to pace updates to correct rate
  microsPerReading = 1000000 / gyroUpdateRate; //1000000 micros = 1 second
  microsPrevious = micros();
}


void blePeripheralConnectHandler(BLECentral& central) {
  // central connected event handler
  Serial.print("Connected event, central: ");
  Serial.println(central.address());
}

void blePeripheralDisconnectHandler(BLECentral& central) {
  // central disconnected event handler
  Serial.print("Disconnected event, central: ");
  Serial.println(central.address());
}

void rollRead(BLECentral& central, BLECharacteristic& characteristic) {
  Serial.print("Roll read ");
  Serial.print(rollChar.value());
  Serial.println("");
}


The following is what is printed
Code: [Select]

.....
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
Roll read 2.00
-
+
Roll read 2.00

-
+Roll read 2.00

-
+
-
+
-
+
-
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00
Roll read 2.00



Any advice or information would be greatly appreciated

blayze

I think I found a solution to this problem. From what I can tell the problem happens when BLE send an interrupt during the readMotionSensor function call, causing it to causing it to crash or hang. The solution that worked for me was to stop interrupts before the motion sensor read and enable them again once its finished (see the code below).

Code: [Select]

    ...
    noInterrupts();
    CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);
    interrupts();
    ...

ajahearn

Thanks. This workaround of disabling interrupts helped me with using the Adafruit GPS/uSD shield.  It was also hanging and I traced it to the CurieIMU.readMotionSensor function for the Arduino 101.

Go Up