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