
SPI slave program to enable communication between the FPGA and the STM32L432 board.
main.cpp@5:155d224d855c, 2019-02-24 (annotated)
- Committer:
- Zbyszek
- Date:
- Sun Feb 24 16:49:06 2019 +0000
- Revision:
- 5:155d224d855c
- Parent:
- 4:e36c7042d3bb
- Child:
- 6:0ebecfecadc9
Added code to calculate bias offsets for calibration of the Gyro and Accelerometer
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Zbyszek | 0:8e367d6d8f03 | 1 | #include "mbed.h" |
Zbyszek | 0:8e367d6d8f03 | 2 | #include "SPI.h" |
Zbyszek | 4:e36c7042d3bb | 3 | #include "Quaternions.h" |
Zbyszek | 0:8e367d6d8f03 | 4 | DigitalOut myled(LED1); |
Zbyszek | 0:8e367d6d8f03 | 5 | Serial pc(USBTX, USBRX); |
Zbyszek | 0:8e367d6d8f03 | 6 | |
Zbyszek | 0:8e367d6d8f03 | 7 | int masterRx = 0; |
Zbyszek | 3:e33697420c4a | 8 | int16_t slaveRx = 0; |
Zbyszek | 3:e33697420c4a | 9 | int i = 2; |
Zbyszek | 3:e33697420c4a | 10 | int k = 0; |
Zbyszek | 3:e33697420c4a | 11 | int16_t zgHigher = 0; |
Zbyszek | 3:e33697420c4a | 12 | int16_t zgLower = 0; |
Zbyszek | 3:e33697420c4a | 13 | int16_t zGyro = 0; |
Zbyszek | 3:e33697420c4a | 14 | int countx = 0; |
Zbyszek | 3:e33697420c4a | 15 | int p = 32776; |
Zbyszek | 5:155d224d855c | 16 | double const SSF = 0.00763358778625954198473282442748f; //FSEL = 0: 0.00763358778625954198473282442748, FSEL = 3: 0.06097560975609756097560975609756f |
Zbyszek | 3:e33697420c4a | 17 | |
Zbyszek | 4:e36c7042d3bb | 18 | Timer t; |
Zbyszek | 4:e36c7042d3bb | 19 | float dTime = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 20 | |
Zbyszek | 4:e36c7042d3bb | 21 | vector vertical; |
Zbyszek | 4:e36c7042d3bb | 22 | vector globalAccel; |
Zbyszek | 4:e36c7042d3bb | 23 | vector correctionGlobalAccel; |
Zbyszek | 4:e36c7042d3bb | 24 | vector correctionBodyAccel; |
Zbyszek | 4:e36c7042d3bb | 25 | Quaternion gyroQ; |
Zbyszek | 4:e36c7042d3bb | 26 | vector Eangles; |
Zbyszek | 5:155d224d855c | 27 | Quaternion CF; |
Zbyszek | 5:155d224d855c | 28 | vector intGyro; |
Zbyszek | 5:155d224d855c | 29 | vector GyroVals; |
Zbyszek | 5:155d224d855c | 30 | vector AccelVals; |
Zbyszek | 5:155d224d855c | 31 | vector accelTilt; |
Zbyszek | 5:155d224d855c | 32 | Quaternion accelQ; |
Zbyszek | 5:155d224d855c | 33 | |
Zbyszek | 5:155d224d855c | 34 | void calibrateOffset(); |
Zbyszek | 4:e36c7042d3bb | 35 | |
Zbyszek | 4:e36c7042d3bb | 36 | |
Zbyszek | 4:e36c7042d3bb | 37 | float xx; |
Zbyszek | 4:e36c7042d3bb | 38 | float yy; |
Zbyszek | 4:e36c7042d3bb | 39 | float zz; |
Zbyszek | 4:e36c7042d3bb | 40 | |
Zbyszek | 4:e36c7042d3bb | 41 | |
Zbyszek | 3:e33697420c4a | 42 | |
Zbyszek | 3:e33697420c4a | 43 | /* |
Zbyszek | 3:e33697420c4a | 44 | |
Zbyszek | 3:e33697420c4a | 45 | */ |
Zbyszek | 3:e33697420c4a | 46 | //------------------Printing-All-values----------------------// |
Zbyszek | 3:e33697420c4a | 47 | int16_t IMUarray[12]; //Store each separate reading in an array |
Zbyszek | 3:e33697420c4a | 48 | uint16_t IDarray[12]; //Holds the identification of each data piece |
Zbyszek | 3:e33697420c4a | 49 | char idx = 0; //IMUarray Pointer |
Zbyszek | 3:e33697420c4a | 50 | char dataCount = 0; //Keeps track of how many data points have been read in using SPI |
Zbyszek | 3:e33697420c4a | 51 | uint16_t id = 0; //Used to store extracted data ID |
Zbyszek | 3:e33697420c4a | 52 | |
Zbyszek | 3:e33697420c4a | 53 | void ProcessAndPrint(); |
Zbyszek | 3:e33697420c4a | 54 | //------------------Printing-All-values----------------------// |
Zbyszek | 3:e33697420c4a | 55 | |
Zbyszek | 4:e36c7042d3bb | 56 | //-------------Testing-Variables-Remove-Later----------------// |
Zbyszek | 4:e36c7042d3bb | 57 | int blinkCounter = 0; |
Zbyszek | 4:e36c7042d3bb | 58 | //-------------Testing-Variables-Remove-Later----------------// |
Zbyszek | 0:8e367d6d8f03 | 59 | |
Zbyszek | 0:8e367d6d8f03 | 60 | int main() { |
Zbyszek | 4:e36c7042d3bb | 61 | pc.baud (115200); |
Zbyszek | 3:e33697420c4a | 62 | IDarray[0] = 1; |
Zbyszek | 3:e33697420c4a | 63 | IDarray[1] = 0; |
Zbyszek | 3:e33697420c4a | 64 | IDarray[2] = 9; |
Zbyszek | 3:e33697420c4a | 65 | IDarray[3] = 8; |
Zbyszek | 3:e33697420c4a | 66 | IDarray[4] = 17; |
Zbyszek | 3:e33697420c4a | 67 | IDarray[5] = 16; |
Zbyszek | 3:e33697420c4a | 68 | IDarray[6] = 3; |
Zbyszek | 4:e36c7042d3bb | 69 | IDarray[7] = 2; //2 |
Zbyszek | 3:e33697420c4a | 70 | IDarray[8] = 11; |
Zbyszek | 3:e33697420c4a | 71 | IDarray[9] = 10; |
Zbyszek | 3:e33697420c4a | 72 | IDarray[10] = 19; |
Zbyszek | 3:e33697420c4a | 73 | IDarray[11] = 18; |
Zbyszek | 3:e33697420c4a | 74 | |
Zbyszek | 4:e36c7042d3bb | 75 | init_spi1(); |
Zbyszek | 4:e36c7042d3bb | 76 | t.start(); |
Zbyszek | 3:e33697420c4a | 77 | |
Zbyszek | 4:e36c7042d3bb | 78 | gyroQ.w = 1; |
Zbyszek | 4:e36c7042d3bb | 79 | gyroQ.x = 0.0001; |
Zbyszek | 4:e36c7042d3bb | 80 | gyroQ.y = 0.0001; |
Zbyszek | 4:e36c7042d3bb | 81 | gyroQ.z = 0.0001; |
Zbyszek | 4:e36c7042d3bb | 82 | |
Zbyszek | 5:155d224d855c | 83 | CF.w = 1; |
Zbyszek | 5:155d224d855c | 84 | CF.x = 0.0001; |
Zbyszek | 5:155d224d855c | 85 | CF.y = 0.0001; |
Zbyszek | 5:155d224d855c | 86 | CF.z = 0.0001; |
Zbyszek | 4:e36c7042d3bb | 87 | |
Zbyszek | 4:e36c7042d3bb | 88 | |
Zbyszek | 4:e36c7042d3bb | 89 | gyroQ = normaliseQuaternion(gyroQ); |
Zbyszek | 5:155d224d855c | 90 | CF = normaliseQuaternion(CF); |
Zbyszek | 4:e36c7042d3bb | 91 | |
Zbyszek | 4:e36c7042d3bb | 92 | vertical.x = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 93 | vertical.y = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 94 | vertical.z = 1.0f; |
Zbyszek | 4:e36c7042d3bb | 95 | |
Zbyszek | 3:e33697420c4a | 96 | pc.printf("Begin \n\r"); |
Zbyszek | 0:8e367d6d8f03 | 97 | |
Zbyszek | 0:8e367d6d8f03 | 98 | while(1) { |
Zbyszek | 3:e33697420c4a | 99 | if(i == 1) { |
Zbyszek | 0:8e367d6d8f03 | 100 | for(int x = 1; x < 128; x *= 2) { |
Zbyszek | 0:8e367d6d8f03 | 101 | slaveRx = transfer_spi_slave(x); |
Zbyszek | 3:e33697420c4a | 102 | //pc.putc(slaveRx); |
Zbyszek | 3:e33697420c4a | 103 | pc.printf("%d \n\r",slaveRx); |
Zbyszek | 0:8e367d6d8f03 | 104 | } |
Zbyszek | 0:8e367d6d8f03 | 105 | for(int x = 128; x > 1; x /= 2) { |
Zbyszek | 0:8e367d6d8f03 | 106 | slaveRx = transfer_spi_slave(x); |
Zbyszek | 3:e33697420c4a | 107 | //pc.putc(slaveRx); |
Zbyszek | 3:e33697420c4a | 108 | pc.printf("%d \n\r",slaveRx); |
Zbyszek | 2:4cc880ea466d | 109 | } |
Zbyszek | 3:e33697420c4a | 110 | }//if(i == 1) |
Zbyszek | 3:e33697420c4a | 111 | |
Zbyszek | 3:e33697420c4a | 112 | |
Zbyszek | 3:e33697420c4a | 113 | |
Zbyszek | 3:e33697420c4a | 114 | //------------------------------------------------------------------------------ |
Zbyszek | 3:e33697420c4a | 115 | if(i == 0) { |
Zbyszek | 3:e33697420c4a | 116 | slaveRx = transfer_spi_slave(10); |
Zbyszek | 3:e33697420c4a | 117 | countx++; |
Zbyszek | 3:e33697420c4a | 118 | if(countx == 1) { |
Zbyszek | 3:e33697420c4a | 119 | k = slaveRx; |
Zbyszek | 3:e33697420c4a | 120 | k &= ~(255 << 8); |
Zbyszek | 3:e33697420c4a | 121 | k = k << 8; |
Zbyszek | 3:e33697420c4a | 122 | // if(k == 19) { |
Zbyszek | 3:e33697420c4a | 123 | zgHigher = k; |
Zbyszek | 3:e33697420c4a | 124 | //zgHigher = zgHigher << 8; |
Zbyszek | 3:e33697420c4a | 125 | //}//if(k == 19) |
Zbyszek | 3:e33697420c4a | 126 | }//if(count == 11) |
Zbyszek | 3:e33697420c4a | 127 | |
Zbyszek | 3:e33697420c4a | 128 | |
Zbyszek | 3:e33697420c4a | 129 | else if(countx == 2) { |
Zbyszek | 3:e33697420c4a | 130 | k = slaveRx; |
Zbyszek | 3:e33697420c4a | 131 | k &= ~(255 << 8); |
Zbyszek | 3:e33697420c4a | 132 | //k = k << 8; |
Zbyszek | 3:e33697420c4a | 133 | //if(k == 18) { |
Zbyszek | 3:e33697420c4a | 134 | zgLower = k; |
Zbyszek | 3:e33697420c4a | 135 | //zgLower = zgLower << 8; |
Zbyszek | 3:e33697420c4a | 136 | zGyro = zgHigher + zgLower; |
Zbyszek | 3:e33697420c4a | 137 | pc.printf("%+d \n\r",zGyro); |
Zbyszek | 3:e33697420c4a | 138 | //}//if(k == 19) |
Zbyszek | 3:e33697420c4a | 139 | countx = 0; |
Zbyszek | 3:e33697420c4a | 140 | }//else if(count == 12) |
Zbyszek | 3:e33697420c4a | 141 | |
Zbyszek | 3:e33697420c4a | 142 | }//if(i == 0) |
Zbyszek | 3:e33697420c4a | 143 | //------------------------------------------------------------------------------ |
Zbyszek | 3:e33697420c4a | 144 | |
Zbyszek | 3:e33697420c4a | 145 | if(i == 2) { |
Zbyszek | 4:e36c7042d3bb | 146 | slaveRx = transfer_spi_slave(10); //get IMU data |
Zbyszek | 4:e36c7042d3bb | 147 | |
Zbyszek | 4:e36c7042d3bb | 148 | |
Zbyszek | 4:e36c7042d3bb | 149 | id = slaveRx; //Save sample to id for id extraction |
Zbyszek | 4:e36c7042d3bb | 150 | id &= ~(255); //get rid of the actual data to only be left with the id |
Zbyszek | 4:e36c7042d3bb | 151 | id = id >> 8; //shift the id to the right for comparison |
Zbyszek | 4:e36c7042d3bb | 152 | |
Zbyszek | 4:e36c7042d3bb | 153 | //pc.printf("ID: %d \n\r", id); //Print each id to see what sequence is obtained. Only the correct sequence will make the code run/ |
Zbyszek | 4:e36c7042d3bb | 154 | |
Zbyszek | 4:e36c7042d3bb | 155 | if(IDarray[dataCount] == id) { //compare if the order of data is right and if not wait until it is. |
Zbyszek | 4:e36c7042d3bb | 156 | dataCount++; //Increase dataCount as new value has been read in. |
Zbyszek | 4:e36c7042d3bb | 157 | IMUarray[idx] = slaveRx; //save the newly read value to current free space in the array |
Zbyszek | 4:e36c7042d3bb | 158 | idx++; //increment the pointer to point to next free space in the array |
Zbyszek | 3:e33697420c4a | 159 | |
Zbyszek | 3:e33697420c4a | 160 | if(dataCount == 12) { |
Zbyszek | 3:e33697420c4a | 161 | //reset idx and dataCount |
Zbyszek | 3:e33697420c4a | 162 | dataCount = 0; |
Zbyszek | 3:e33697420c4a | 163 | idx = 0; |
Zbyszek | 5:155d224d855c | 164 | ProcessAndPrint(); |
Zbyszek | 5:155d224d855c | 165 | //calibrateOffset(); |
Zbyszek | 4:e36c7042d3bb | 166 | |
Zbyszek | 4:e36c7042d3bb | 167 | t.stop(); |
Zbyszek | 4:e36c7042d3bb | 168 | dTime = t.read(); |
Zbyszek | 4:e36c7042d3bb | 169 | t.reset(); |
Zbyszek | 4:e36c7042d3bb | 170 | t.start(); |
Zbyszek | 3:e33697420c4a | 171 | }//if(dataCount == 12) |
Zbyszek | 3:e33697420c4a | 172 | }//if(IDarray[dataCount] == id) |
Zbyszek | 4:e36c7042d3bb | 173 | else { |
Zbyszek | 4:e36c7042d3bb | 174 | //-----Code-Used-For-Testing-----// |
Zbyszek | 4:e36c7042d3bb | 175 | //pc.printf("Failed at: %d \n\r", dataCount); //Print an error if there is one |
Zbyszek | 4:e36c7042d3bb | 176 | if(blinkCounter == 10) { //Slow the blinking down to make it visible if there are errors |
Zbyszek | 4:e36c7042d3bb | 177 | myled = !myled; //Change state of the LED if error occurs |
Zbyszek | 4:e36c7042d3bb | 178 | blinkCounter = 0; //Reset Blink counter |
Zbyszek | 4:e36c7042d3bb | 179 | } |
Zbyszek | 4:e36c7042d3bb | 180 | else { |
Zbyszek | 4:e36c7042d3bb | 181 | blinkCounter++; |
Zbyszek | 4:e36c7042d3bb | 182 | } |
Zbyszek | 4:e36c7042d3bb | 183 | //-----Code-Used-For-Testing-----// |
Zbyszek | 4:e36c7042d3bb | 184 | |
Zbyszek | 4:e36c7042d3bb | 185 | dataCount = 0; //ID sequence is worng so reset the counter |
Zbyszek | 4:e36c7042d3bb | 186 | idx = 0; //ID sequence is worng so reset the counter |
Zbyszek | 4:e36c7042d3bb | 187 | } |
Zbyszek | 3:e33697420c4a | 188 | }//if(i == 2) |
Zbyszek | 3:e33697420c4a | 189 | |
Zbyszek | 3:e33697420c4a | 190 | |
Zbyszek | 3:e33697420c4a | 191 | |
Zbyszek | 0:8e367d6d8f03 | 192 | } |
Zbyszek | 0:8e367d6d8f03 | 193 | } |
Zbyszek | 3:e33697420c4a | 194 | |
Zbyszek | 3:e33697420c4a | 195 | |
Zbyszek | 3:e33697420c4a | 196 | |
Zbyszek | 4:e36c7042d3bb | 197 | |
Zbyszek | 4:e36c7042d3bb | 198 | /* |
Zbyszek | 4:e36c7042d3bb | 199 | -The purpose of this function |
Zbyszek | 4:e36c7042d3bb | 200 | */ |
Zbyszek | 3:e33697420c4a | 201 | void ProcessAndPrint() { |
Zbyszek | 3:e33697420c4a | 202 | int16_t MSB = 0; //Store Most Significant Byte of data piece in this variable for processing |
Zbyszek | 3:e33697420c4a | 203 | int16_t LSB = 0; //Store Least Significant Byte of data piece in this variable for processing |
Zbyszek | 3:e33697420c4a | 204 | char arrPointer = 0; //Array Pointer |
Zbyszek | 4:e36c7042d3bb | 205 | |
Zbyszek | 3:e33697420c4a | 206 | //-----------Concatentated-Data-Pieces------------------------------------------ |
Zbyszek | 3:e33697420c4a | 207 | int16_t gyroX = 0; |
Zbyszek | 3:e33697420c4a | 208 | int16_t gyroY = 0; |
Zbyszek | 3:e33697420c4a | 209 | int16_t gyroZ = 0; |
Zbyszek | 3:e33697420c4a | 210 | |
Zbyszek | 3:e33697420c4a | 211 | int16_t accelX = 0; |
Zbyszek | 3:e33697420c4a | 212 | int16_t accelY = 0; |
Zbyszek | 3:e33697420c4a | 213 | int16_t accelZ = 0; |
Zbyszek | 4:e36c7042d3bb | 214 | |
Zbyszek | 4:e36c7042d3bb | 215 | float faccelX = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 216 | float faccelY = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 217 | float faccelZ = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 218 | |
Zbyszek | 4:e36c7042d3bb | 219 | float fgyroX = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 220 | float fgyroY = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 221 | float fgyroZ = 0.0f; |
Zbyszek | 4:e36c7042d3bb | 222 | |
Zbyszek | 3:e33697420c4a | 223 | //-----------Concatentated-Data-Pieces------------------------------------------ |
Zbyszek | 3:e33697420c4a | 224 | for(char x = 0; x <= 5; x++) { |
Zbyszek | 4:e36c7042d3bb | 225 | MSB = IMUarray[arrPointer]; //Odd data pieces are MSBs |
Zbyszek | 4:e36c7042d3bb | 226 | MSB &= ~(255<<8); //Mask the MSB bits as they are not part of data |
Zbyszek | 4:e36c7042d3bb | 227 | MSB = MSB << 8; //Shift the Value as its the MSB of the data piece |
Zbyszek | 4:e36c7042d3bb | 228 | arrPointer++; //Increment array pointer |
Zbyszek | 4:e36c7042d3bb | 229 | LSB = IMUarray[arrPointer]; //Even data pieces are LSBs |
Zbyszek | 4:e36c7042d3bb | 230 | LSB &= ~(255 << 8); //Mask the MSB bits as they are not part of data |
Zbyszek | 4:e36c7042d3bb | 231 | arrPointer++; //Increment array pointer |
Zbyszek | 3:e33697420c4a | 232 | |
Zbyszek | 3:e33697420c4a | 233 | switch(x) { |
Zbyszek | 3:e33697420c4a | 234 | case 0: |
Zbyszek | 4:e36c7042d3bb | 235 | accelX = MSB + LSB; //Combine Accelerometer x-axis data |
Zbyszek | 4:e36c7042d3bb | 236 | faccelX = (float)accelX * 0.00006103515625f; //Multiply the acceleration by sensitivity scale factor to get it into g 1/16,384 |
Zbyszek | 3:e33697420c4a | 237 | break; |
Zbyszek | 3:e33697420c4a | 238 | case 1: |
Zbyszek | 4:e36c7042d3bb | 239 | accelY = MSB + LSB; //Combine Accelerometer y-axis data |
Zbyszek | 4:e36c7042d3bb | 240 | faccelY = (float)accelY * 0.00006103515625f; //Multiply the acceleration by sensitivity scale factor to get it into g 1/16,384 |
Zbyszek | 3:e33697420c4a | 241 | break; |
Zbyszek | 3:e33697420c4a | 242 | case 2: |
Zbyszek | 4:e36c7042d3bb | 243 | accelZ = MSB + LSB; //Combine Accelerometer z-axis data |
Zbyszek | 4:e36c7042d3bb | 244 | faccelZ = (float)accelZ * 0.00006103515625f; //Multiply the acceleration by sensitivity scale factor to get it into g 1/16,384 |
Zbyszek | 3:e33697420c4a | 245 | break; |
Zbyszek | 3:e33697420c4a | 246 | case 3: |
Zbyszek | 4:e36c7042d3bb | 247 | gyroX = MSB + LSB; //Combine Gyroscope x-axis data |
Zbyszek | 5:155d224d855c | 248 | fgyroX = (float)gyroX * SSF; //Multiply the sample by sensitivity scale factor to get it into degress per second 1/16.4 |
Zbyszek | 4:e36c7042d3bb | 249 | |
Zbyszek | 3:e33697420c4a | 250 | break; |
Zbyszek | 3:e33697420c4a | 251 | case 4: |
Zbyszek | 4:e36c7042d3bb | 252 | gyroY = MSB + LSB; //Combine Gyroscope y-axis data |
Zbyszek | 5:155d224d855c | 253 | fgyroY = (float)gyroY * SSF; //Multiply the sample by sensitivity scale factor to get it into degress per second 1/16.4 |
Zbyszek | 4:e36c7042d3bb | 254 | |
Zbyszek | 3:e33697420c4a | 255 | break; |
Zbyszek | 3:e33697420c4a | 256 | case 5: |
Zbyszek | 4:e36c7042d3bb | 257 | gyroZ = MSB + LSB; //Combine Gyroscope z-axis data |
Zbyszek | 5:155d224d855c | 258 | fgyroZ = (float)gyroZ * SSF; //Multiply the sample by sensitivity scale factor to get it into degress per second 1/16.4 |
Zbyszek | 3:e33697420c4a | 259 | break; |
Zbyszek | 3:e33697420c4a | 260 | default: |
Zbyszek | 3:e33697420c4a | 261 | break; |
Zbyszek | 3:e33697420c4a | 262 | }//switch(x) |
Zbyszek | 3:e33697420c4a | 263 | }//for(char x = 0; x <= 5; x++) |
Zbyszek | 4:e36c7042d3bb | 264 | |
Zbyszek | 4:e36c7042d3bb | 265 | //Quaternion-Gyro-Integration-------------------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 266 | //Get the Gyro and Accel values-------------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 267 | //Convert these vales to radians per second and store them in the vector |
Zbyszek | 4:e36c7042d3bb | 268 | GyroVals.x = fgyroX * 0.0174533; |
Zbyszek | 4:e36c7042d3bb | 269 | GyroVals.y = fgyroY * 0.0174533; |
Zbyszek | 4:e36c7042d3bb | 270 | GyroVals.z = fgyroZ * 0.0174533; |
Zbyszek | 4:e36c7042d3bb | 271 | |
Zbyszek | 5:155d224d855c | 272 | intGyro.x = (fgyroX * dTime); |
Zbyszek | 5:155d224d855c | 273 | intGyro.y = (fgyroY * dTime); |
Zbyszek | 5:155d224d855c | 274 | intGyro.z = (fgyroZ * dTime); |
Zbyszek | 5:155d224d855c | 275 | |
Zbyszek | 4:e36c7042d3bb | 276 | AccelVals.x = faccelX; |
Zbyszek | 4:e36c7042d3bb | 277 | AccelVals.y = faccelY; |
Zbyszek | 4:e36c7042d3bb | 278 | AccelVals.z = faccelZ; |
Zbyszek | 4:e36c7042d3bb | 279 | //Get the Gyro and Accel values-------------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 280 | |
Zbyszek | 5:155d224d855c | 281 | CF = updateQuaternion(CF, GyroVals, dTime); |
Zbyszek | 5:155d224d855c | 282 | CF = normaliseQuaternion(CF); |
Zbyszek | 5:155d224d855c | 283 | Eangles = eulerA(CF); |
Zbyszek | 4:e36c7042d3bb | 284 | //Quaternion-Gyro-Integration-------------------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 285 | |
Zbyszek | 4:e36c7042d3bb | 286 | |
Zbyszek | 4:e36c7042d3bb | 287 | //Angle-Calculations-Based-on-Accalerometer------------------------------------------------ |
Zbyszek | 4:e36c7042d3bb | 288 | //https://www.dfrobot.com/wiki/index.php/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing |
Zbyszek | 4:e36c7042d3bb | 289 | |
Zbyszek | 5:155d224d855c | 290 | accelTilt.x = (atan2f(AccelVals.y, AccelVals.z) * 57.29577951f); |
Zbyszek | 5:155d224d855c | 291 | accelTilt.y = (atan2f((-AccelVals.x), sqrt(pow(AccelVals.y, 2) + pow(AccelVals.z, 2) )) * 57.29577951f); |
Zbyszek | 5:155d224d855c | 292 | //pc.printf("%+6f, %+6f ", accelTilt.x, accelTilt.y); |
Zbyszek | 4:e36c7042d3bb | 293 | //Canntot calculate accel tilt for Z. Gyro date in combination with magnetometer have to be used to obtain reliable z-axis tilt. |
Zbyszek | 5:155d224d855c | 294 | //Angle-Calculations-Based-on-Accalerometer------------------------------------------------ |
Zbyszek | 5:155d224d855c | 295 | //pc.printf("%+6f, %+6f, %+6f ", CF.x, CF.y, CF.z); |
Zbyszek | 5:155d224d855c | 296 | |
Zbyszek | 5:155d224d855c | 297 | |
Zbyszek | 5:155d224d855c | 298 | //Complementary-Filter--------------------------------------------------------------------- |
Zbyszek | 5:155d224d855c | 299 | CF.x = 0.98f*(Eangles.x) + 0.02f*accelTilt.x; |
Zbyszek | 5:155d224d855c | 300 | CF.y = 0.98f*(Eangles.y) + 0.02f*accelTilt.y; |
Zbyszek | 5:155d224d855c | 301 | CF.z = 0.98f*(Eangles.z) + 0.02f*accelTilt.z; |
Zbyszek | 5:155d224d855c | 302 | |
Zbyszek | 5:155d224d855c | 303 | //CF.x = 0.98f*(CF.x + intGyro.x) + 0.02f*accelTilt.x; |
Zbyszek | 5:155d224d855c | 304 | //CF.y = 0.98f*(CF.y + intGyro.y) + 0.02f*accelTilt.y; |
Zbyszek | 5:155d224d855c | 305 | //CF.z = 0.98f*(CF.z + intGyro.z) + 0.02f*accelTilt.z; |
Zbyszek | 5:155d224d855c | 306 | //Complementary-Filter--------------------------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 307 | |
Zbyszek | 4:e36c7042d3bb | 308 | //Add the correction to gyro readings and update the quaternion------------------------ |
Zbyszek | 4:e36c7042d3bb | 309 | //pc.printf("%+6f, %+6f, %+6f %+6f\n\r ", xx, yy, zz, dTime); |
Zbyszek | 5:155d224d855c | 310 | //pc.printf("%+6f, %+6f, %+6f, %+6f, %+6f, %+6f, %+6f\n\r ", gyroQ.w, gyroQ.x, gyroQ.y, gyroQ.z, CF.x, CF.y, Eangles.z); |
Zbyszek | 5:155d224d855c | 311 | //pc.printf("%+6f, %+6f, %+6f ", CF.x, CF.y, CF.z); |
Zbyszek | 5:155d224d855c | 312 | CF.x *= 0.0174533f; |
Zbyszek | 5:155d224d855c | 313 | CF.y *= 0.0174533f; |
Zbyszek | 5:155d224d855c | 314 | CF.z *= 0.0174533f; |
Zbyszek | 5:155d224d855c | 315 | CF = euler2Quaternion(CF); |
Zbyszek | 5:155d224d855c | 316 | CF = normaliseQuaternion(CF); |
Zbyszek | 4:e36c7042d3bb | 317 | //pc.printf("%+6f, %+6f, %+6f\n\r ",Eangles.x, Eangles.y, Eangles.z); |
Zbyszek | 5:155d224d855c | 318 | pc.printf("Accel X: %+6f, Accel Y: %+6f, Accel Z: %+6f, Gyro X: %+6f, Gyro Y: %+6f, Gyro Z: %+6f\n\r", faccelX, faccelY, faccelZ, fgyroX, fgyroY, fgyroZ); |
Zbyszek | 3:e33697420c4a | 319 | |
Zbyszek | 3:e33697420c4a | 320 | }//void ProcessAndPrint() |
Zbyszek | 3:e33697420c4a | 321 | |
Zbyszek | 4:e36c7042d3bb | 322 | |
Zbyszek | 4:e36c7042d3bb | 323 | |
Zbyszek | 5:155d224d855c | 324 | void calibrateOffset() { |
Zbyszek | 5:155d224d855c | 325 | |
Zbyszek | 5:155d224d855c | 326 | int16_t MSB = 0; //Store Most Significant Byte of data piece in this variable for processing |
Zbyszek | 5:155d224d855c | 327 | int16_t LSB = 0; //Store Least Significant Byte of data piece in this variable for processing |
Zbyszek | 5:155d224d855c | 328 | char arrPointer = 0; //Array Pointer |
Zbyszek | 5:155d224d855c | 329 | |
Zbyszek | 5:155d224d855c | 330 | //-----------Concatentated-Data-Pieces------------------------------------------ |
Zbyszek | 5:155d224d855c | 331 | int16_t gyroX = 0; |
Zbyszek | 5:155d224d855c | 332 | int16_t gyroY = 0; |
Zbyszek | 5:155d224d855c | 333 | int16_t gyroZ = 0; |
Zbyszek | 5:155d224d855c | 334 | |
Zbyszek | 5:155d224d855c | 335 | int16_t accelX = 0; |
Zbyszek | 5:155d224d855c | 336 | int16_t accelY = 0; |
Zbyszek | 5:155d224d855c | 337 | int16_t accelZ = 0; |
Zbyszek | 5:155d224d855c | 338 | |
Zbyszek | 5:155d224d855c | 339 | vector accelRaw; |
Zbyszek | 5:155d224d855c | 340 | vector accelG; |
Zbyszek | 5:155d224d855c | 341 | vector gyroRaw; |
Zbyszek | 5:155d224d855c | 342 | vector gyroDPS; |
Zbyszek | 5:155d224d855c | 343 | |
Zbyszek | 5:155d224d855c | 344 | static unsigned int sampleCounter = 1; |
Zbyszek | 5:155d224d855c | 345 | static vector accelRawAvg; |
Zbyszek | 5:155d224d855c | 346 | static vector accelGAvg; |
Zbyszek | 5:155d224d855c | 347 | static vector gyroRawAvg; |
Zbyszek | 5:155d224d855c | 348 | static vector gyroDPSAvg; |
Zbyszek | 5:155d224d855c | 349 | |
Zbyszek | 5:155d224d855c | 350 | |
Zbyszek | 5:155d224d855c | 351 | for(char x = 0; x <= 5; x++) { |
Zbyszek | 5:155d224d855c | 352 | MSB = IMUarray[arrPointer]; //Odd data pieces are MSBs |
Zbyszek | 5:155d224d855c | 353 | MSB &= ~(255<<8); //Mask the MSB bits as they are not part of data |
Zbyszek | 5:155d224d855c | 354 | MSB = MSB << 8; //Shift the Value as its the MSB of the data piece |
Zbyszek | 5:155d224d855c | 355 | arrPointer++; //Increment array pointer |
Zbyszek | 5:155d224d855c | 356 | LSB = IMUarray[arrPointer]; //Even data pieces are LSBs |
Zbyszek | 5:155d224d855c | 357 | LSB &= ~(255 << 8); //Mask the MSB bits as they are not part of data |
Zbyszek | 5:155d224d855c | 358 | arrPointer++; //Increment array pointer |
Zbyszek | 5:155d224d855c | 359 | |
Zbyszek | 5:155d224d855c | 360 | switch(x) { |
Zbyszek | 5:155d224d855c | 361 | case 0: |
Zbyszek | 5:155d224d855c | 362 | accelX = MSB + LSB; //Combine Accelerometer x-axis data |
Zbyszek | 5:155d224d855c | 363 | accelRaw.x = (double)accelX; //accelRaw |
Zbyszek | 5:155d224d855c | 364 | accelG.x = (double)accelX * 0.00006103515625f; //accelSSF |
Zbyszek | 5:155d224d855c | 365 | |
Zbyszek | 5:155d224d855c | 366 | break; |
Zbyszek | 5:155d224d855c | 367 | case 1: |
Zbyszek | 5:155d224d855c | 368 | accelY = MSB + LSB; //Combine Accelerometer y-axis data |
Zbyszek | 5:155d224d855c | 369 | accelRaw.y = (double)accelY; |
Zbyszek | 5:155d224d855c | 370 | accelG.y = (double)accelY * 0.00006103515625f; |
Zbyszek | 5:155d224d855c | 371 | break; |
Zbyszek | 5:155d224d855c | 372 | case 2: |
Zbyszek | 5:155d224d855c | 373 | accelZ = MSB + LSB; //Combine Accelerometer z-axis data |
Zbyszek | 5:155d224d855c | 374 | accelRaw.z = (double)accelZ; |
Zbyszek | 5:155d224d855c | 375 | accelG.z = (double)accelZ * 0.00006103515625f; |
Zbyszek | 5:155d224d855c | 376 | break; |
Zbyszek | 5:155d224d855c | 377 | case 3: |
Zbyszek | 5:155d224d855c | 378 | gyroX = MSB + LSB; //Combine Gyroscope x-axis data |
Zbyszek | 5:155d224d855c | 379 | gyroRaw.x = (double)gyroX; //gyroRaw |
Zbyszek | 5:155d224d855c | 380 | gyroDPS.x = (double)gyroX * SSF; //gyroSSF |
Zbyszek | 5:155d224d855c | 381 | |
Zbyszek | 5:155d224d855c | 382 | break; |
Zbyszek | 5:155d224d855c | 383 | case 4: |
Zbyszek | 5:155d224d855c | 384 | gyroY = MSB + LSB; //Combine Gyroscope y-axis data |
Zbyszek | 5:155d224d855c | 385 | gyroRaw.y = (double)gyroY; |
Zbyszek | 5:155d224d855c | 386 | gyroDPS.y = (double)gyroY * SSF; |
Zbyszek | 4:e36c7042d3bb | 387 | |
Zbyszek | 5:155d224d855c | 388 | break; |
Zbyszek | 5:155d224d855c | 389 | case 5: |
Zbyszek | 5:155d224d855c | 390 | gyroZ = MSB + LSB; //Combine Gyroscope z-axis data |
Zbyszek | 5:155d224d855c | 391 | gyroRaw.z = (double)gyroZ; |
Zbyszek | 5:155d224d855c | 392 | gyroDPS.z = (double)gyroZ * SSF; |
Zbyszek | 5:155d224d855c | 393 | break; |
Zbyszek | 5:155d224d855c | 394 | default: |
Zbyszek | 5:155d224d855c | 395 | break; |
Zbyszek | 5:155d224d855c | 396 | }//switch(x) |
Zbyszek | 5:155d224d855c | 397 | }//for(char x = 0; x <= 5; x++) |
Zbyszek | 5:155d224d855c | 398 | |
Zbyszek | 5:155d224d855c | 399 | //Take-Running-Averages------------------------------------------------------------------------ |
Zbyszek | 5:155d224d855c | 400 | //Raw accel averages |
Zbyszek | 5:155d224d855c | 401 | accelRawAvg.x = accelRawAvg.x + ((accelRaw.x - accelRawAvg.x)/sampleCounter); |
Zbyszek | 5:155d224d855c | 402 | accelRawAvg.y = accelRawAvg.y + ((accelRaw.y - accelRawAvg.y)/sampleCounter); |
Zbyszek | 5:155d224d855c | 403 | accelRawAvg.z = accelRawAvg.z + ((accelRaw.z - accelRawAvg.z)/sampleCounter); |
Zbyszek | 5:155d224d855c | 404 | |
Zbyszek | 5:155d224d855c | 405 | //SSF accel averages |
Zbyszek | 5:155d224d855c | 406 | accelGAvg.x = accelGAvg.x + ((accelG.x - accelGAvg.x)/sampleCounter); |
Zbyszek | 5:155d224d855c | 407 | accelGAvg.y = accelGAvg.y + ((accelG.y - accelGAvg.y)/sampleCounter); |
Zbyszek | 5:155d224d855c | 408 | accelGAvg.z = accelGAvg.z + ((accelG.z - accelGAvg.z)/sampleCounter); |
Zbyszek | 5:155d224d855c | 409 | |
Zbyszek | 5:155d224d855c | 410 | //Raw gyroo averages |
Zbyszek | 5:155d224d855c | 411 | gyroRawAvg.x = gyroRawAvg.x + ((gyroRaw.x - gyroRawAvg.x)/sampleCounter); |
Zbyszek | 5:155d224d855c | 412 | gyroRawAvg.y = gyroRawAvg.y + ((gyroRaw.y - gyroRawAvg.y)/sampleCounter); |
Zbyszek | 5:155d224d855c | 413 | gyroRawAvg.z = gyroRawAvg.z + ((gyroRaw.z - gyroRawAvg.z)/sampleCounter); |
Zbyszek | 5:155d224d855c | 414 | |
Zbyszek | 5:155d224d855c | 415 | //SSF gyro averages |
Zbyszek | 5:155d224d855c | 416 | gyroDPSAvg.x = gyroDPSAvg.x + ((gyroDPS.x - gyroDPSAvg.x)/sampleCounter); |
Zbyszek | 5:155d224d855c | 417 | gyroDPSAvg.y = gyroDPSAvg.y + ((gyroDPS.y - gyroDPSAvg.y)/sampleCounter); |
Zbyszek | 5:155d224d855c | 418 | gyroDPSAvg.z = gyroDPSAvg.z + ((gyroDPS.z - gyroDPSAvg.z)/sampleCounter); |
Zbyszek | 5:155d224d855c | 419 | //Take-Running-Averages------------------------------------------------------------------------ |
Zbyszek | 4:e36c7042d3bb | 420 | |
Zbyszek | 5:155d224d855c | 421 | //Print Messages------------------------------------------------------------------------------- |
Zbyszek | 5:155d224d855c | 422 | if(sampleCounter == 1) { |
Zbyszek | 5:155d224d855c | 423 | pc.printf("Collecting Raw and Sensitivity Scale Factor multiplied Gyroscope and Accelerometer Offsets...\n\r"); |
Zbyszek | 5:155d224d855c | 424 | }; |
Zbyszek | 5:155d224d855c | 425 | |
Zbyszek | 5:155d224d855c | 426 | |
Zbyszek | 5:155d224d855c | 427 | if(sampleCounter == 5000) { |
Zbyszek | 5:155d224d855c | 428 | pc.printf("RawAX RawAY RawAZ RawGX RawGY RawGZ SampleN\n\r"); |
Zbyszek | 5:155d224d855c | 429 | pc.printf("%+-6.2f %+-6.2f %+-6.2f %+-6.2f %+-6.2f %+-6.2f %-10d\n\r", accelRawAvg.x, accelRawAvg.y, accelRawAvg.z, gyroRawAvg.x, gyroRawAvg.y, gyroRawAvg.z, sampleCounter); |
Zbyszek | 5:155d224d855c | 430 | pc.printf("\n\r"); |
Zbyszek | 5:155d224d855c | 431 | pc.printf("\n\r"); |
Zbyszek | 5:155d224d855c | 432 | pc.printf("\n\r"); |
Zbyszek | 5:155d224d855c | 433 | |
Zbyszek | 5:155d224d855c | 434 | //Add the sensitivity scale factor multiplied data |
Zbyszek | 5:155d224d855c | 435 | pc.printf("SSFAX SSFAY SSFAZ SSFGX SSFGY SSFGZ SampleN\n\r"); |
Zbyszek | 5:155d224d855c | 436 | pc.printf("%+-6.2f %+-6.2f %+-6.2f %+-6.2f %+-6.2f %+-6.2f %-10d\n\r", accelGAvg.x, accelGAvg.y, accelGAvg.z, gyroDPSAvg.x, gyroDPSAvg.y, gyroDPSAvg.z, sampleCounter); |
Zbyszek | 5:155d224d855c | 437 | |
Zbyszek | 5:155d224d855c | 438 | }; |
Zbyszek | 5:155d224d855c | 439 | sampleCounter++; |
Zbyszek | 5:155d224d855c | 440 | //Print Messages------------------------------------------------------------------------------- |
Zbyszek | 5:155d224d855c | 441 | } |
Zbyszek | 4:e36c7042d3bb | 442 | |
Zbyszek | 4:e36c7042d3bb | 443 | |
Zbyszek | 4:e36c7042d3bb | 444 | |
Zbyszek | 4:e36c7042d3bb | 445 | |
Zbyszek | 4:e36c7042d3bb | 446 | |
Zbyszek | 4:e36c7042d3bb | 447 | |
Zbyszek | 4:e36c7042d3bb | 448 | |
Zbyszek | 4:e36c7042d3bb | 449 | |
Zbyszek | 4:e36c7042d3bb | 450 | //------------------------------------------Artifacts---------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 451 | |
Zbyszek | 4:e36c7042d3bb | 452 | //----------------------Insert Whole--------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 453 | //Rotate the accel data Global reference frame by qvq*--------------------------------- |
Zbyszek | 4:e36c7042d3bb | 454 | //globalAccel = rotateGlobal(AccelVals, gyroQ); |
Zbyszek | 4:e36c7042d3bb | 455 | //Rotate the accel data Global reference frame by qvq*--------------------------------- |
Zbyszek | 4:e36c7042d3bb | 456 | |
Zbyszek | 4:e36c7042d3bb | 457 | //get the correction values and rotate back to IMU reference--------------------------- |
Zbyszek | 4:e36c7042d3bb | 458 | // correctionGlobalAccel = crossProduct(globalAccel, vertical); |
Zbyszek | 4:e36c7042d3bb | 459 | // correctionBodyAccel = rotateLocal(correctionGlobalAccel, gyroQ); |
Zbyszek | 4:e36c7042d3bb | 460 | //get the correction values and rotate back to IMU reference--------------------------- |
Zbyszek | 4:e36c7042d3bb | 461 | |
Zbyszek | 4:e36c7042d3bb | 462 | //Add the correction to gyro readings and update the quaternion------------------------ |
Zbyszek | 4:e36c7042d3bb | 463 | //GyroVals = sumVector(GyroVals, correctionBodyAccel); |
Zbyszek | 4:e36c7042d3bb | 464 | //incRot = toQuaternionNotation123(GyroVals, dTime); |
Zbyszek | 4:e36c7042d3bb | 465 | //gyroQ = getQuaternionProduct(gyroQ, incRot); |
Zbyszek | 4:e36c7042d3bb | 466 | //gyroQ = normaliseQuaternion(gyroQ); |
Zbyszek | 4:e36c7042d3bb | 467 | //----------------------Insert Whole--------------------------------------------------- |
Zbyszek | 4:e36c7042d3bb | 468 | |
Zbyszek | 4:e36c7042d3bb | 469 | //------------------------------------------Artifacts---------------------------------------- |