ArduIMU Circuit

Notes

- 6 analog inputs, but two don”t have internal pull/up resistors!
- 6 BS: A0-A3, A5, A6, GND
- power??? 5V regulator? direct form lip? wire lipo directly 5V input to bypass 5V linear regulator to avoid voltage dropout.
- cut DTR line on Bluetooth module
- solder male right-angle headers to ArduIMU with gap so that Bluetooth module does not short out pins! heat-shrink Bluetooth radio for isolation?
- wiring for i2C LED
- strain-relief for wired connection!
- charging on gloves and charges when wired to wireless connector?

Only 6 Bend Sensors (or only 4???)

Because the ArduIMU only has 6 analog inputs.
A0 = Thumb
A1 = Index (hand knuckle)
A2 = Index (finger knuckle)
A3 = Middle (hand knuckle)
A4 = Middle (finger knuckle)
A5 = Ring (hand knuckle)

Updated circuit diagram and image by Seb:

Code for sending sensor data from ArduIMU to Glover software:

//==============================================================================
// Send.cpp
//==============================================================================
/*

Assumes that Serial.begin has already been called.

Date Author Notes
dd/mm/yyyy Seb Madgwick Initial release
*/
//==============================================================================

//——————————————————————————
// Includes

#include “AHRS.h”
#include
#include “Calibration.h”
#include “FlexSensors.h”
#include “Send.h”
#include
#include
#include

extern AHRS ahrs;

//——————————————————————————
// Definitions

typedef union {
int intVal;
struct {
char lsb;
char msb;
};
} IntUnion;

//#define SEND_ASCII_PACKETS // comment out this line to send binary packets

//——————————————————————————
// Functions - Public

void Send::character(const char c) {
Serial.write(c);
}

void Send::errorMessage(void) {
char string[] = “ERROR\r”;
Serial.write((uint8_t*)string, strlen(string));
}

void Send::okMessage(void) {
char string[] = “OK\r”;
Serial.write((uint8_t*)string, strlen(string));
}

void Send::calibrationRegisters(void) {
char packet[128];
sprintf(packet, “GYR_SENS_X %d\r”, Calibration::reg[REG_GYR_SENS_X]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “GYR_SENS_Y %d\r”, Calibration::reg[REG_GYR_SENS_Y]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “GYR_SENS_Z %d\r”, Calibration::reg[REG_GYR_SENS_Z]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “GYR_BIAS_X %d\r”, Calibration::reg[REG_GYR_BIAS_X]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “GYR_BIAS_Y %d\r”, Calibration::reg[REG_GYR_BIAS_Y]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “GYR_BIAS_Z %d\r”, Calibration::reg[REG_GYR_BIAS_Z]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “ACC_SENS_X %d\r”, Calibration::reg[REG_ACC_SENS_X]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “ACC_SENS_Y %d\r”, Calibration::reg[REG_ACC_SENS_Y]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “ACC_SENS_Z %d\r”, Calibration::reg[REG_ACC_SENS_Z]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “ACC_BIAS_X %d\r”, Calibration::reg[REG_ACC_BIAS_X]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “ACC_BIAS_Y %d\r”, Calibration::reg[REG_ACC_BIAS_Y]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “ACC_BIAS_Z %d\r”, Calibration::reg[REG_ACC_BIAS_Z]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_XX %d\r”, Calibration::reg[REG_MAG_SOFT_XX]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_XY %d\r”, Calibration::reg[REG_MAG_SOFT_XY]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_XZ %d\r”, Calibration::reg[REG_MAG_SOFT_XZ]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_YX %d\r”, Calibration::reg[REG_MAG_SOFT_YX]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_YY %d\r”, Calibration::reg[REG_MAG_SOFT_YY]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_YZ %d\r”, Calibration::reg[REG_MAG_SOFT_YZ]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_ZX %d\r”, Calibration::reg[REG_MAG_SOFT_ZX]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_ZY %d\r”, Calibration::reg[REG_MAG_SOFT_ZY]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_SOFT_ZZ %d\r”, Calibration::reg[REG_MAG_SOFT_ZZ]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_HARD_X %d\r”, Calibration::reg[REG_MAG_HARD_X]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_HARD_Y %d\r”, Calibration::reg[REG_MAG_HARD_Y]); Serial.write((uint8_t*)packet, strlen(packet));
sprintf(packet, “MAG_HARD_Z %d\r”, Calibration::reg[REG_MAG_HARD_Z]); Serial.write((uint8_t*)packet, strlen(packet));
}

void Send::flexSensorData() {
char packet[64];
int packetLength = 0;
IntUnion intUnion;
FlexSensors::read(); // read sensors before sending
#ifdef SEND_ASCII_PACKETS
packet[packetLength++] = ‘F’;
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, FlexSensors::channel[0]);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, FlexSensors::channel[1]);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, FlexSensors::channel[2]);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, FlexSensors::channel[3]);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, FlexSensors::channel[4]);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, FlexSensors::channel[5]);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, calcChecksum(packet, packetLength));
packet[packetLength++] = ‘\r’;
#else
packet[packetLength++] = ‘F’;
intUnion.intVal= (int)FlexSensors::channel[0];
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)FlexSensors::channel[1];
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)FlexSensors::channel[2];
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)FlexSensors::channel[3];
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)FlexSensors::channel[4];
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)FlexSensors::channel[5];
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.lsb = calcChecksum(packet, packetLength);
packet[packetLength++] = intUnion.lsb;
#endif
Serial.write((uint8_t*)packet, packetLength);
}

void Send::sensorData() {
char packet[128];
int packetLength = 0;
IntUnion intUnion;
#ifdef SEND_ASCII_PACKETS
packet[packetLength++] = ‘S’;
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::gyrX);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::gyrY);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::gyrZ);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::accX);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::accY);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::accZ);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::magX);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::magY);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, Calibration::magZ);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, calcChecksum(packet, packetLength));
packet[packetLength++] = ‘\r’;
#else
packet[packetLength++] = ‘S’;
intUnion.intVal= Calibration::gyrX;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::gyrY;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::gyrZ;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::accX;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::accY;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::accZ;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::magX;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::magY;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= Calibration::magZ;
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.lsb = calcChecksum(packet, packetLength);
packet[packetLength++] = intUnion.lsb;
#endif
Serial.write((uint8_t*)packet, packetLength);
}

void Send::quaternionData() {
char packet[64];
int packetLength = 0;
IntUnion intUnion;
#ifdef SEND_ASCII_PACKETS
packet[packetLength++] = ‘Q’;
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, 10000.0f * ahrs.q0);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, 10000.0f * ahrs.q1);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, 10000.0f * ahrs.q2);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, 10000.0f * ahrs.q3);
packet[packetLength++] = ‘,’;
intToChars(packet, &packetLength, calcChecksum(packet, packetLength));
packet[packetLength++] = ‘\r’;
#else
packet[packetLength++] = ‘Q’;
intUnion.intVal= (int)(10000.0f * ahrs.q0);
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)(10000.0f * ahrs.q1);
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)(10000.0f * ahrs.q2);
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.intVal= (int)(10000.0f * ahrs.q3);
packet[packetLength++] = intUnion.msb;
packet[packetLength++] = intUnion.lsb;
intUnion.lsb = calcChecksum(packet, packetLength);
packet[packetLength++] = intUnion.lsb;
#endif
Serial.write((uint8_t*)packet, packetLength);
}

//——————————————————————————
// Functions - Private

void Send::intToChars(char* const charArray, int* const index, int i) {
const char asciiDigits[10] = { ’0′, ’1′, ’2′, ’3′, ’4′, ’5′, ’6′, ’7′, ’8′, ’9′, };
div_t n;
int print = 0;
if(i < 0) {
charArray[(*index)++] = '-';
i = -i;
}
if(i >= 10000) {
n = div(i, 10000);
charArray[(*index)++] = asciiDigits[n.quot];
i = n.rem;
print = 1;
}
if(i >= 1000 || print) {
n = div(i, 1000);
charArray[(*index)++] = asciiDigits[n.quot];
i = n.rem;
print = 1;
}
if(i >= 100 || print) {
n = div(i, 100);
charArray[(*index)++] = asciiDigits[n.quot];
i = n.rem;
print = 1;
}
if(i >= 10 || print) {
n = div(i, 10);
charArray[(*index)++] = asciiDigits[n.quot];
i = n.rem;
}
charArray[(*index)++] = asciiDigits[i];
}

char Send::calcChecksum(const char* const packet, const int packetLength) {
int i = 0;
char checksum = 0;
while(i < packetLength) {
checksum ^= packet[i++];
}
return checksum;
}

//==============================================================================
// End of file
//==============================================================================

Leave a Reply