Hi all,
I am trying to combine 2 sketches to integrate an IMU with LE Bluetooth communication on a Tinyduino. I have succesfully combined the sketches which work as expected up to the point of sending data from the Serial Monitor. At that point, the data from the IMU stops being received. Both sending and recieving data via BLE continues to work. My main sketch is shown below.
/*
* IMU Bluetooth
*
* Reads the values from the IMU and transmits them via
* bluetooth using the LE Bluetooth module.
*/
//
// *************** S T A R T OF B L E D E F I N I T I O N S E C T I O N *****************
#include <SPI.h>
#include <STBLE.h>
//Debug output adds extra flash and memory requirements!
#ifndef BLE_DEBUG
#define BLE_DEBUG true
#endif
#if defined (ARDUINO_ARCH_AVR)
#define SerialMonitorInterface Serial
#elif defined(ARDUINO_ARCH_SAMD)
#define SerialMonitorInterface SerialUSB
#endif
uint8_t ble_rx_buffer[21];
uint8_t ble_rx_buffer_len = 0;
uint8_t ble_connection_state = false;
#define PIPE_UART_OVER_BTLE_UART_TX_TX 0
// *************** E N D OF B L E D E F I N I T I O N S E C T I O N *****************
//
// *************** S T A R T OF I M U D E F I N I T I O N S E C T I O N *****************
#include <Wire.h>
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "RTFusionRTQF.h"
#ifndef ARDUINO_ARCH_SAMD
#include <EEPROM.h>
#endif
RTIMU *imu; // the IMU object
RTFusionRTQF fusion; // the fusion object
RTIMUSettings settings; // the settings object
// DISPLAY_INTERVAL sets the rate at which results are displayed
#define DISPLAY_INTERVAL 2000 // interval between pose displays
// SERIAL_PORT_SPEED defines the speed to use for the debug serial port
#define SERIAL_PORT_SPEED 250000
#ifdef SERIAL_PORT_MONITOR
#define SerialMonitor SERIAL_PORT_MONITOR
#else
#define SerialMonitor Serial
#endif
unsigned long lastDisplay;
unsigned long lastRate;
int sampleCount;
// *************** E N D OF I M U D E F I N I T I O N S E C T I O N *****************
//
void setup() {
//
// *************** S T A R T OF B L E S E T U P S E C T I O N *****************
SerialMonitorInterface.begin(250000);
while (!SerialMonitorInterface); //This line will block until a serial monitor is opened with TinyScreen+!
BLEsetup();
// *************** E N D OF B L E S E T U P S E C T I O N *****************
//
//
// *************** S T A R T OF I M U S E T U P S E C T I O N ************
int errcode;
SerialMonitor.begin(SERIAL_PORT_SPEED);
while(!SerialMonitor);
Wire.begin();
imu = RTIMU::createIMU(&settings); // create the imu object
SerialMonitor.println(F("Post IMU Object creation"));
SerialMonitor.print(F("ArduinoIMU starting using device ")); SerialMonitor.println(imu->IMUName());
if ((errcode = imu->IMUInit()) < 0) {
SerialMonitor.print(F("Failed to init IMU: ")); SerialMonitor.println(errcode);
}
if (imu->getCalibrationValid())
SerialMonitor.println(F("Using compass calibration"));
else
SerialMonitor.println(F("No valid compass calibration data"));
lastDisplay = lastRate = millis();
sampleCount = 0;
// Slerp power controls the fusion and can be between 0 and 1
// 0 means that only gyros are used, 1 means that only accels/compass are used
// In-between gives the fusion mix.
fusion.setSlerpPower(0.02);
// use of sensors in the fusion algorithm can be controlled here
// change any of these to false to disable that sensor
fusion.setGyroEnable(true);
fusion.setAccelEnable(true);
fusion.setCompassEnable(true);
// *************** E N D OF I M U S E T U P S E C T I O N ************
//
}
void loop() {
//
// *************** S T A R T OF B L E & I M U L O O P S E C T I O N ************
unsigned long now = millis();
unsigned long delta;
// This section is the BLE Loop
//Serial.println(F("Start of BLE LOOP"));
aci_loop();//Process any ACI commands or events from the NRF8001- main BLE handler, must run often. Keep main loop short.
//The following lines send/receive data via bluetooth to the serial monitor
if (ble_rx_buffer_len) {//Check if data is available from other bluetooth device
SerialMonitorInterface.print(ble_rx_buffer_len);
SerialMonitorInterface.print(" : ");
SerialMonitorInterface.println((char*)ble_rx_buffer);
ble_rx_buffer_len = 0;//clear afer reading
}
if (SerialMonitorInterface.available()) {//Check if serial input is available to send from tinyduino
delay(10);//should catch input
uint8_t sendBuffer[21];
uint8_t sendLength = 0;
while (SerialMonitorInterface.available() && sendLength < 19) {
sendBuffer[sendLength] = SerialMonitorInterface.read();
sendLength++;
}
if (SerialMonitorInterface.available()) {
SerialMonitorInterface.print("Input truncated, dropped: ");
if (SerialMonitorInterface.available()) {
SerialMonitorInterface.write(SerialMonitorInterface.read());
}
}
sendBuffer[sendLength] = '\0'; //Terminate string
sendLength++;
if (!lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, (uint8_t*)sendBuffer, sendLength))
{
SerialMonitorInterface.println("TX dropped!");
}
}
// This section is the IMU Loop
// Serial.println(imu->IMURead());
if (imu->IMURead()) { // get the latest data if ready yet
fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
sampleCount++;
if ((delta = now - lastRate) >= 2000) {
SerialMonitor.print(F("Sample rate: ")); SerialMonitor.print(sampleCount);
if (imu->IMUGyroBiasValid())
SerialMonitor.println(F(", gyro bias valid"));
else
SerialMonitor.println(F(", calculating gyro bias - don't move IMU!!"));
sampleCount = 0;
lastRate = now;
}
if ((now - lastDisplay) >= DISPLAY_INTERVAL) {
lastDisplay = now;
RTVector3 accelData=imu->getAccel();
RTVector3 gyroData=imu->getGyro();
RTVector3 compassData=imu->getCompass();
RTVector3 fusionData=fusion.getFusionPose();
displayAxis("Accel:", accelData.x(), accelData.y(), accelData.z()); // accel data
SerialMonitor.println();
//displayAxis("Gyro:", gyroData.x(), gyroData.y(), gyroData.z()); // gyro data
//displayAxis("Mag:", compassData.x(), compassData.y(), compassData.z()); // compass data
//displayDegrees("Pose:", fusionData.x(), fusionData.y(), fusionData.z()); // fused output
//SerialMonitor.println();
}
}
// *************** E N D OF BLE & I M U L O O P S E C T I O N ************
//
}
//
// Functions
void displayAxis(const char *label, float x, float y, float z)
{
SerialMonitor.print(label);
SerialMonitor.print(" x:"); SerialMonitor.print(x);
SerialMonitor.print(" y:"); SerialMonitor.print(y);
SerialMonitor.print(" z:"); SerialMonitor.print(z);
}
void displayDegrees(const char *label, float x, float y, float z)
{
SerialMonitor.print(label);
SerialMonitor.print(" x:"); SerialMonitor.print(x * RTMATH_RAD_TO_DEGREE);
SerialMonitor.print(" y:"); SerialMonitor.print(y * RTMATH_RAD_TO_DEGREE);
SerialMonitor.print(" z:"); SerialMonitor.print(z * RTMATH_RAD_TO_DEGREE);
}
//
It would appear that after sending data, the line "if (imu->IMURead())" is always returning 0. Why would this only happen after sending data? P.S my code is based on the Arduino sample code for the TinyDuino 9-Axis (MPU9150) IMU - Link and the TinyDuino Bluetooth Low Energy TinyShield (ST) - Link
Any help would be most appreciated.
Many Thanks