I am using a 9-axis accelerator on an Arduino Uno (Atmega 328P processor) with a BLE Nordic rRF8001 chipset.
I am trying to send the accelerometer data via bluetooth to a smart phone (android).
The problem I am having is that the data shown on the serial monitor (which is correct, is not the data that is received via bluetooth. I think it has something to do with either the casting of the variables or that I am screwing up when converting the formats. Below is where I'm currently at and what I have tried.
The error I'm having is that the accelerometer data shown on the serial monitor screen (which is correct):
- A_x: -0.12 A_y: 0.53 A_z: 0.83
- A_x: -0.12 A_y: 0.53 A_z: 0.83
- A_x: -0.12 A_y: 0.53 A_z: 0.83
Does not agree with what the smart phone receives: (See image 1)
If I hard code in the x,y,z values in the arduino sketch
- float x = (float) 0.52;
- float y = (float) 0.52;
- float z = (float) 0.52;
I get the following results (see image 2):
And here is the Arduino sketch I am working with:
//-------------------------------------------------------------------------------
// TinyCircuits 9 Axis and Nordic BLE TinyShield Example Sketch
#include <Wire.h>
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "RTFusionRTQF.h"
#include <SPI.h>
#include "lib_aci.h"
#include "aci_setup.h"
#include "uart_over_ble.h"
#include "services.h"
#if defined (ARDUINO_ARCH_AVR)
#define SerialMonitorInterface Serial
#elif defined(ARDUINO_ARCH_SAMD)
#define SerialMonitorInterface SerialUSB
#endif
#define DISPLAY_INTERVAL 100
RTIMU *imu; // the IMU object
RTFusionRTQF fusion; // the fusion object
RTIMUSettings settings; // the settings object
unsigned long displayInterval = 50;
unsigned long lastDisplay;
unsigned long lastRate;
int sampleCount;
#define BLE_DEBUG false
uint8_t ble_rx_buffer[21];
volatile uint8_t ble_rx_buffer_len = 0;
volatile uint8_t ble_can_sleep = false;
volatile uint8_t ble_connection_state = false;
#ifdef SERIAL_POR_MONITOR
#define SerialMonitor SERIAL_PORT_MONITOR
#else
#define SerialMonitor Serial
#endif
void setup(void)
{
// SerialMonitorInterface.begin(230400);
SerialMonitor.begin(230400);
int errcode;
while (!SerialMonitor);
Wire.begin();
imu = RTIMU::createIMU(&settings); // create the imu object
SerialMonitorInterface.print("ArduinoIMU starting using device "); SerialMonitorInterface.println(imu->IMUName());
if ((errcode = imu->IMUInit()) < 0) {
SerialMonitorInterface.print("Failed to init IMU: "); SerialMonitorInterface.println(errcode);
}
if (imu->getCalibrationValid())
SerialMonitorInterface.println("Using compass calibration");
else
SerialMonitorInterface.println("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);
BLEsetup();
}
void loop() {
aci_loop();//Process any ACI commands or events from the NRF8001- main BLE handler, must run often. Keep main loop short.
unsigned long now = millis();
unsigned long delta;
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) >= 1000) {
/*SerialMonitorInterface.print("Sample rate: "); SerialMonitorInterface.print(sampleCount);
if (imu->IMUGyroBiasValid())
SerialMonitorInterface.println(", gyro bias valid");
else
SerialMonitorInterface.println(", calculating gyro bias - don't move IMU!!");
*/
sampleCount = 0;
lastRate = now;
}
if ((now - lastDisplay) >= displayInterval) {
lastDisplay = now;
RTVector3 accelData = imu->getAccel();
RTVector3 gyroData = imu->getGyro();
RTVector3 compassData = imu->getCompass();
RTVector3 fusionData = fusion.getFusionPose();
char sendBuffer[30] = " ";
uint8_t sendLength = 0;
//displayAxis("Accel:", accelData.x(), accelData.y(), accelData.z()); // accel data
//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
float x = (float)(accelData.x() );//* RTMATH_RAD_TO_DEGREE);
float y = (float)(accelData.y() );//* RTMATH_RAD_TO_DEGREE);
float z = (float)(accelData.z() );// * RTMATH_RAD_TO_DEGREE);
// float x = (float) 0.52;
// float y = (float) 0.52;
// float z = (float) 0.52;
sendLength = sprintf(sendBuffer, "% 2.3d % 2.3d % 2.3d", x, y, z);
if (sendLength > 20)sendLength = 20;
if (!lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, (uint8_t*)sendBuffer, sendLength))
{
SerialMonitorInterface.println(F("TX dropped!"));
}
SerialMonitorInterface.println();
SerialMonitor.print(" A_x: "); SerialMonitor.print(x);
SerialMonitor.print(" A_y: "); SerialMonitor.print(y);
SerialMonitor.print(" A_z: "); SerialMonitor.println(z);
}
}
}
Any thoughts on why the data sent over BLE is incorrect?