CROTUS / Mbed 2 deprecated ProjetCasque

Dependencies:   mbed CROTUS_XBee mbed-rtos Crotus_Com

Committer:
libv2001
Date:
Sun Mar 12 14:58:06 2017 +0000
Revision:
0:28d5622d1a3e
Child:
1:3591e7df4ff4
Lecture et conversion des donn?es de l'acc?l?rom?tre et du magn?tom?tre.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
libv2001 0:28d5622d1a3e 1 #include "Magneto.h"
libv2001 0:28d5622d1a3e 2
libv2001 0:28d5622d1a3e 3 #define PI 3.14159265358979323f
libv2001 0:28d5622d1a3e 4
libv2001 0:28d5622d1a3e 5 namespace {
libv2001 0:28d5622d1a3e 6 char cmd[2];
libv2001 0:28d5622d1a3e 7 char buffer[6];
libv2001 0:28d5622d1a3e 8
libv2001 0:28d5622d1a3e 9 Ticker calibrationTicker;
libv2001 0:28d5622d1a3e 10
libv2001 0:28d5622d1a3e 11 int16_t minX = OR_MAX_VALUE; // The maximum value is put in the min so real values will always be smaller
libv2001 0:28d5622d1a3e 12 int16_t maxX = OR_MIN_VALUE; // The minimum value is put in the max so real values will always be bigger
libv2001 0:28d5622d1a3e 13 int16_t minY = OR_MAX_VALUE; // The maximum value is put in the min so real values will always be smaller
libv2001 0:28d5622d1a3e 14 int16_t maxY = OR_MIN_VALUE; // The minimum value is put in the max so real values will always be bigger
libv2001 0:28d5622d1a3e 15
libv2001 0:28d5622d1a3e 16 int16_t offsetX = 0;
libv2001 0:28d5622d1a3e 17 int16_t offsetY = 0;
libv2001 0:28d5622d1a3e 18
libv2001 0:28d5622d1a3e 19 int16_t scaleX = 0;
libv2001 0:28d5622d1a3e 20 int16_t scaleY = 0;
libv2001 0:28d5622d1a3e 21
libv2001 0:28d5622d1a3e 22 void _UpdateScaleAndOffset(){
libv2001 0:28d5622d1a3e 23 offsetX = (maxX + minX)/2;
libv2001 0:28d5622d1a3e 24 scaleX = maxX - offsetX;
libv2001 0:28d5622d1a3e 25
libv2001 0:28d5622d1a3e 26 offsetY = (maxY + minY)/2;
libv2001 0:28d5622d1a3e 27 scaleY = maxY - offsetY;
libv2001 0:28d5622d1a3e 28 }
libv2001 0:28d5622d1a3e 29
libv2001 0:28d5622d1a3e 30 void _UpdateCalibration(int16_t x, int16_t y){
libv2001 0:28d5622d1a3e 31 bool changed = false;
libv2001 0:28d5622d1a3e 32
libv2001 0:28d5622d1a3e 33 if (x < minX){
libv2001 0:28d5622d1a3e 34 minX = x;
libv2001 0:28d5622d1a3e 35 changed = true;
libv2001 0:28d5622d1a3e 36 }
libv2001 0:28d5622d1a3e 37 if (x > maxX){
libv2001 0:28d5622d1a3e 38 maxX = x;
libv2001 0:28d5622d1a3e 39 changed = true;
libv2001 0:28d5622d1a3e 40 }
libv2001 0:28d5622d1a3e 41
libv2001 0:28d5622d1a3e 42 if (y < minY){
libv2001 0:28d5622d1a3e 43 minY = y;
libv2001 0:28d5622d1a3e 44 changed = true;
libv2001 0:28d5622d1a3e 45 }
libv2001 0:28d5622d1a3e 46 if (y > maxY){
libv2001 0:28d5622d1a3e 47 maxY = y;
libv2001 0:28d5622d1a3e 48 changed = true;
libv2001 0:28d5622d1a3e 49 }
libv2001 0:28d5622d1a3e 50
libv2001 0:28d5622d1a3e 51 if(changed || true){
libv2001 0:28d5622d1a3e 52 _UpdateScaleAndOffset();
libv2001 0:28d5622d1a3e 53 }
libv2001 0:28d5622d1a3e 54 }
libv2001 0:28d5622d1a3e 55
libv2001 0:28d5622d1a3e 56 LocalFileSystem local("local");
libv2001 0:28d5622d1a3e 57
libv2001 0:28d5622d1a3e 58 void _LoadCalibration(){
libv2001 0:28d5622d1a3e 59 FILE *fp = fopen("/local/magneto.cfg", "r"); // Open "out.txt" on the local file system for writing
libv2001 0:28d5622d1a3e 60 // File doesn't exist
libv2001 0:28d5622d1a3e 61 if (fp == 0){
libv2001 0:28d5622d1a3e 62 printf("File doesn't exist!!\r\n");
libv2001 0:28d5622d1a3e 63 return;
libv2001 0:28d5622d1a3e 64 }
libv2001 0:28d5622d1a3e 65
libv2001 0:28d5622d1a3e 66 fscanf(fp,"%04X %04X %04X %04X", &minX, &maxX, &minY, &maxY);
libv2001 0:28d5622d1a3e 67 fclose(fp);
libv2001 0:28d5622d1a3e 68
libv2001 0:28d5622d1a3e 69 _UpdateScaleAndOffset();
libv2001 0:28d5622d1a3e 70 }
libv2001 0:28d5622d1a3e 71
libv2001 0:28d5622d1a3e 72 void _SaveCalibration(){
libv2001 0:28d5622d1a3e 73 FILE *fp = fopen("/local/magneto.cfg", "w"); // Open "out.txt" on the local file system for writing
libv2001 0:28d5622d1a3e 74 fprintf(fp, "%04X %04X %04X %04X", minX & 0xFFFF, maxX & 0xFFFF, minY & 0xFFFF, maxY & 0xFFFF);
libv2001 0:28d5622d1a3e 75 fclose(fp);
libv2001 0:28d5622d1a3e 76 }
libv2001 0:28d5622d1a3e 77 };
libv2001 0:28d5622d1a3e 78
libv2001 0:28d5622d1a3e 79 Magneto::Magneto(I2C & i2c) :
libv2001 0:28d5622d1a3e 80 _i2c(&i2c)
libv2001 0:28d5622d1a3e 81 {
libv2001 0:28d5622d1a3e 82 _LoadCalibration();
libv2001 0:28d5622d1a3e 83
libv2001 0:28d5622d1a3e 84 // Every 10 minutes
libv2001 0:28d5622d1a3e 85 calibrationTicker.attach(_SaveCalibration, 6);
libv2001 0:28d5622d1a3e 86 }
libv2001 0:28d5622d1a3e 87
libv2001 0:28d5622d1a3e 88 bool Magneto::Test(){
libv2001 0:28d5622d1a3e 89 cmd[0] = MAGNETO_RA_ID_A;
libv2001 0:28d5622d1a3e 90
libv2001 0:28d5622d1a3e 91 _i2c->write(MAGNETO_ADDRESS, cmd, 1, true);
libv2001 0:28d5622d1a3e 92 _i2c->read(MAGNETO_ADDRESS, buffer, 3);
libv2001 0:28d5622d1a3e 93
libv2001 0:28d5622d1a3e 94 return (buffer[0] == IR_A_VALUE) &&
libv2001 0:28d5622d1a3e 95 (buffer[1] == IR_B_VALUE) &&
libv2001 0:28d5622d1a3e 96 (buffer[2] == IR_C_VALUE);
libv2001 0:28d5622d1a3e 97 }
libv2001 0:28d5622d1a3e 98
libv2001 0:28d5622d1a3e 99 void Magneto::ActivateDevice(){
libv2001 0:28d5622d1a3e 100 cmd[0] = MAGNETO_RA_CONFIG_A;
libv2001 0:28d5622d1a3e 101 cmd[1] = (CRA_SAMPLE_AVG_8 << CRA_SAMPLE_AVG_BIT) | (CRA_DATA_RATE_15 << CRA_DATA_RATE_BIT);
libv2001 0:28d5622d1a3e 102
libv2001 0:28d5622d1a3e 103 _i2c->write(MAGNETO_ADDRESS, cmd, 2, false);
libv2001 0:28d5622d1a3e 104
libv2001 0:28d5622d1a3e 105 cmd[0] = MAGNETO_RA_CONFIG_B;
libv2001 0:28d5622d1a3e 106 cmd[1] = CRB_GAIN_130 << CRB_GAIN_BIT;
libv2001 0:28d5622d1a3e 107
libv2001 0:28d5622d1a3e 108 _i2c->write(MAGNETO_ADDRESS, cmd, 2, false);
libv2001 0:28d5622d1a3e 109
libv2001 0:28d5622d1a3e 110 cmd[0] = MAGNETO_RA_MODE;
libv2001 0:28d5622d1a3e 111 cmd[1] = MR_MODE_CONTINUOUS << MR_MODE_BIT;
libv2001 0:28d5622d1a3e 112
libv2001 0:28d5622d1a3e 113 _i2c->write(MAGNETO_ADDRESS, cmd, 2, false);
libv2001 0:28d5622d1a3e 114 }
libv2001 0:28d5622d1a3e 115
libv2001 0:28d5622d1a3e 116 void Magneto::ReadXZY(int16_t* raw){
libv2001 0:28d5622d1a3e 117 cmd[0] = MAGNETO_RA_X_MSB;
libv2001 0:28d5622d1a3e 118
libv2001 0:28d5622d1a3e 119 _i2c->write(MAGNETO_ADDRESS, cmd, 1, true);
libv2001 0:28d5622d1a3e 120 _i2c->read(MAGNETO_ADDRESS, buffer, 6);
libv2001 0:28d5622d1a3e 121
libv2001 0:28d5622d1a3e 122 for(int i = 0; i < 6; i += 2){
libv2001 0:28d5622d1a3e 123 int16_t value = buffer[i];
libv2001 0:28d5622d1a3e 124 value = (value << 8) | buffer[i+1];
libv2001 0:28d5622d1a3e 125 raw[i >> 1] = value;
libv2001 0:28d5622d1a3e 126 }
libv2001 0:28d5622d1a3e 127 }
libv2001 0:28d5622d1a3e 128
libv2001 0:28d5622d1a3e 129 int16_t Magneto::GetHeadingXY(){
libv2001 0:28d5622d1a3e 130 int16_t data[3] = {0};
libv2001 0:28d5622d1a3e 131
libv2001 0:28d5622d1a3e 132 ReadXZY(data);
libv2001 0:28d5622d1a3e 133
libv2001 0:28d5622d1a3e 134 int16_t x = data[0];
libv2001 0:28d5622d1a3e 135 int16_t y = data[2];
libv2001 0:28d5622d1a3e 136
libv2001 0:28d5622d1a3e 137 _UpdateCalibration(x, y);
libv2001 0:28d5622d1a3e 138
libv2001 0:28d5622d1a3e 139 if (scaleX == 0 || scaleY == 0){
libv2001 0:28d5622d1a3e 140 return HEADING_ERROR;
libv2001 0:28d5622d1a3e 141 }
libv2001 0:28d5622d1a3e 142
libv2001 0:28d5622d1a3e 143 float scaledX = (float)(x - offsetX) / (float) scaleX; // Scaled value between -1 and 1
libv2001 0:28d5622d1a3e 144 float scaledY = (float)(y - offsetY) / (float) scaleY; // Scaled value between -1 and 1
libv2001 0:28d5622d1a3e 145
libv2001 0:28d5622d1a3e 146 int16_t heading = atan2(scaledY, scaledX) * 180.0f / PI;
libv2001 0:28d5622d1a3e 147
libv2001 0:28d5622d1a3e 148 if (heading < 0) {
libv2001 0:28d5622d1a3e 149 heading += 360;
libv2001 0:28d5622d1a3e 150 } else if (heading > 360) {
libv2001 0:28d5622d1a3e 151 heading -= 360;
libv2001 0:28d5622d1a3e 152 }
libv2001 0:28d5622d1a3e 153
libv2001 0:28d5622d1a3e 154 return heading;
libv2001 0:28d5622d1a3e 155 }
libv2001 0:28d5622d1a3e 156
libv2001 0:28d5622d1a3e 157
libv2001 0:28d5622d1a3e 158 void Magneto::ResetDevice(){
libv2001 0:28d5622d1a3e 159 minX = OR_MAX_VALUE;
libv2001 0:28d5622d1a3e 160 maxX = OR_MIN_VALUE;
libv2001 0:28d5622d1a3e 161 minY = OR_MAX_VALUE;
libv2001 0:28d5622d1a3e 162 maxY = OR_MIN_VALUE;
libv2001 0:28d5622d1a3e 163
libv2001 0:28d5622d1a3e 164 offsetX = 0;
libv2001 0:28d5622d1a3e 165 offsetY = 0;
libv2001 0:28d5622d1a3e 166
libv2001 0:28d5622d1a3e 167 scaleX = 0;
libv2001 0:28d5622d1a3e 168 scaleY = 0;
libv2001 0:28d5622d1a3e 169 }