This is our rendition of popular labyrinth games. We use readings from the IMU accelerometer to move a little yellow ball around the screen. We have created a maze of walls and holes that will end the game if the user runs into either of these.
Dependencies: 4DGL-uLCD-SE mbed
main.cpp@0:7b4bbd744f6d, 2015-10-20 (annotated)
- Committer:
- dbegasse
- Date:
- Tue Oct 20 00:42:42 2015 +0000
- Revision:
- 0:7b4bbd744f6d
- Child:
- 1:2250e33823e2
starting this project
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dbegasse | 0:7b4bbd744f6d | 1 | //Most of the Credit goes to jimblom and Judah Okeleye |
dbegasse | 0:7b4bbd744f6d | 2 | #include "LSM9DS0.h" |
dbegasse | 0:7b4bbd744f6d | 3 | #include "mbed.h" |
dbegasse | 0:7b4bbd744f6d | 4 | #include "uLCD_4DGL.h" |
dbegasse | 0:7b4bbd744f6d | 5 | #include <stdio.h> |
dbegasse | 0:7b4bbd744f6d | 6 | #include <stdlib.h> |
dbegasse | 0:7b4bbd744f6d | 7 | |
dbegasse | 0:7b4bbd744f6d | 8 | // SDO_XM and SDO_G are both grounded, so our addresses are: |
dbegasse | 0:7b4bbd744f6d | 9 | #define LSM9DS0_XM 0x1D // Would be 0x1E if SDO_XM is LOW |
dbegasse | 0:7b4bbd744f6d | 10 | #define LSM9DS0_G 0x6B // Would be 0x6A if SDO_G is LOW |
dbegasse | 0:7b4bbd744f6d | 11 | |
dbegasse | 0:7b4bbd744f6d | 12 | |
dbegasse | 0:7b4bbd744f6d | 13 | LSM9DS0 dof(p9, p10,LSM9DS0_G, LSM9DS0_XM); |
dbegasse | 0:7b4bbd744f6d | 14 | uLCD_4DGL uLCD(p28, p27, p30); //create a global lcd project |
dbegasse | 0:7b4bbd744f6d | 15 | |
dbegasse | 0:7b4bbd744f6d | 16 | |
dbegasse | 0:7b4bbd744f6d | 17 | //Uncomment If you want to use interrupts |
dbegasse | 0:7b4bbd744f6d | 18 | /*DigitalIn pinDRDYG(p14); |
dbegasse | 0:7b4bbd744f6d | 19 | DigitalIn pinINTG(p13); |
dbegasse | 0:7b4bbd744f6d | 20 | DigitalIn pinINT1_XM(p14); |
dbegasse | 0:7b4bbd744f6d | 21 | DigitalIn pinINT2_XM(p15);*/ |
dbegasse | 0:7b4bbd744f6d | 22 | |
dbegasse | 0:7b4bbd744f6d | 23 | #define PRINT_CALCULATED |
dbegasse | 0:7b4bbd744f6d | 24 | #define PRINT_SPEED 500 // 500 ms between prints |
dbegasse | 0:7b4bbd744f6d | 25 | |
dbegasse | 0:7b4bbd744f6d | 26 | //Init Serial port and LSM9DS0 chip |
dbegasse | 0:7b4bbd744f6d | 27 | void setup() |
dbegasse | 0:7b4bbd744f6d | 28 | { |
dbegasse | 0:7b4bbd744f6d | 29 | // Use the begin() function to initialize the LSM9DS0 library. |
dbegasse | 0:7b4bbd744f6d | 30 | // You can either call it with no parameters (the easy way): |
dbegasse | 0:7b4bbd744f6d | 31 | uint16_t status = dof.begin(); |
dbegasse | 0:7b4bbd744f6d | 32 | |
dbegasse | 0:7b4bbd744f6d | 33 | |
dbegasse | 0:7b4bbd744f6d | 34 | //Make sure communication is working |
dbegasse | 0:7b4bbd744f6d | 35 | pc.printf("LSM9DS0 WHO_AM_I's returned: 0x"); |
dbegasse | 0:7b4bbd744f6d | 36 | pc.printf("%x\n",status); |
dbegasse | 0:7b4bbd744f6d | 37 | pc.printf("Should be 0x49D4\n"); |
dbegasse | 0:7b4bbd744f6d | 38 | pc.printf("\n"); |
dbegasse | 0:7b4bbd744f6d | 39 | } |
dbegasse | 0:7b4bbd744f6d | 40 | |
dbegasse | 0:7b4bbd744f6d | 41 | //This function prints the temperature |
dbegasse | 0:7b4bbd744f6d | 42 | void printTemp() |
dbegasse | 0:7b4bbd744f6d | 43 | { |
dbegasse | 0:7b4bbd744f6d | 44 | dof.readTemp(); |
dbegasse | 0:7b4bbd744f6d | 45 | //pc.printf("Temperature: "); |
dbegasse | 0:7b4bbd744f6d | 46 | //pc.printf("%2f",dof.calcTemp(dof.temperature)); |
dbegasse | 0:7b4bbd744f6d | 47 | //pc.printf("\n"); |
dbegasse | 0:7b4bbd744f6d | 48 | |
dbegasse | 0:7b4bbd744f6d | 49 | //rs232.printf("Temperature: "); |
dbegasse | 0:7b4bbd744f6d | 50 | |
dbegasse | 0:7b4bbd744f6d | 51 | } |
dbegasse | 0:7b4bbd744f6d | 52 | |
dbegasse | 0:7b4bbd744f6d | 53 | //This funtion get the accelerometer data and returns it |
dbegasse | 0:7b4bbd744f6d | 54 | //I call this function in the main function to get the data and then send it to the lcd |
dbegasse | 0:7b4bbd744f6d | 55 | float getAccel() |
dbegasse | 0:7b4bbd744f6d | 56 | { |
dbegasse | 0:7b4bbd744f6d | 57 | |
dbegasse | 0:7b4bbd744f6d | 58 | dof.readAccel(); |
dbegasse | 0:7b4bbd744f6d | 59 | pc.printf("%2f",dof.calcAccel(dof.ax) - dof.abias[0]); |
dbegasse | 0:7b4bbd744f6d | 60 | return dof.calcAccel(dof.ax) - dof.abias[0]; |
dbegasse | 0:7b4bbd744f6d | 61 | } |
dbegasse | 0:7b4bbd744f6d | 62 | |
dbegasse | 0:7b4bbd744f6d | 63 | void printGyro() |
dbegasse | 0:7b4bbd744f6d | 64 | { |
dbegasse | 0:7b4bbd744f6d | 65 | // To read from the gyroscope, you must first call the |
dbegasse | 0:7b4bbd744f6d | 66 | // readGyro() funct ion. When this exits, it'll update the |
dbegasse | 0:7b4bbd744f6d | 67 | // gx, gy, and gz variables with the most current data. |
dbegasse | 0:7b4bbd744f6d | 68 | |
dbegasse | 0:7b4bbd744f6d | 69 | //Uncomment code if you plan on using interrupts |
dbegasse | 0:7b4bbd744f6d | 70 | /*while(pinDRDYG == 0) |
dbegasse | 0:7b4bbd744f6d | 71 | { |
dbegasse | 0:7b4bbd744f6d | 72 | ; |
dbegasse | 0:7b4bbd744f6d | 73 | }*/ |
dbegasse | 0:7b4bbd744f6d | 74 | |
dbegasse | 0:7b4bbd744f6d | 75 | |
dbegasse | 0:7b4bbd744f6d | 76 | dof.readGyro(); |
dbegasse | 0:7b4bbd744f6d | 77 | |
dbegasse | 0:7b4bbd744f6d | 78 | // Now we can use the gx, gy, and gz variables as we please. |
dbegasse | 0:7b4bbd744f6d | 79 | // Either print them as raw ADC values, or calculated in DPS. |
dbegasse | 0:7b4bbd744f6d | 80 | pc.printf("Gyroscope: "); |
dbegasse | 0:7b4bbd744f6d | 81 | //uLCD.printf("Gyroscope: "); |
dbegasse | 0:7b4bbd744f6d | 82 | #ifdef PRINT_CALCULATED |
dbegasse | 0:7b4bbd744f6d | 83 | // If you want to print calculated values, you can use the |
dbegasse | 0:7b4bbd744f6d | 84 | // calcGyro helper function to convert a raw ADC value to |
dbegasse | 0:7b4bbd744f6d | 85 | // DPS. Give the function the value that you want to convert. |
dbegasse | 0:7b4bbd744f6d | 86 | //pc.printf("The bias: %2f, %2f, %2f \n", dof.gbias[0], dof.gbias[1], dof.gbias[2]); |
dbegasse | 0:7b4bbd744f6d | 87 | pc.printf("%2f",dof.calcGyro(dof.gx) - dof.gbias[0]); |
dbegasse | 0:7b4bbd744f6d | 88 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 89 | pc.printf("%2f",dof.calcGyro(dof.gy) - dof.gbias[1]); |
dbegasse | 0:7b4bbd744f6d | 90 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 91 | pc.printf("%2f\n",dof.calcGyro(dof.gz) - dof.gbias[2]); |
dbegasse | 0:7b4bbd744f6d | 92 | #elif defined PRINT_RAW |
dbegasse | 0:7b4bbd744f6d | 93 | pc.printf("%d", dof.gx); |
dbegasse | 0:7b4bbd744f6d | 94 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 95 | pc.printf("%d",dof.gy); |
dbegasse | 0:7b4bbd744f6d | 96 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 97 | pc.printf("%d\n",dof.gz); |
dbegasse | 0:7b4bbd744f6d | 98 | #endif |
dbegasse | 0:7b4bbd744f6d | 99 | } |
dbegasse | 0:7b4bbd744f6d | 100 | |
dbegasse | 0:7b4bbd744f6d | 101 | void printAccel() |
dbegasse | 0:7b4bbd744f6d | 102 | { |
dbegasse | 0:7b4bbd744f6d | 103 | //Uncomment code if you plan on using interrupts |
dbegasse | 0:7b4bbd744f6d | 104 | /*while(pinINT1_XM == 0) |
dbegasse | 0:7b4bbd744f6d | 105 | { |
dbegasse | 0:7b4bbd744f6d | 106 | ; |
dbegasse | 0:7b4bbd744f6d | 107 | }*/ |
dbegasse | 0:7b4bbd744f6d | 108 | |
dbegasse | 0:7b4bbd744f6d | 109 | |
dbegasse | 0:7b4bbd744f6d | 110 | dof.readAccel(); |
dbegasse | 0:7b4bbd744f6d | 111 | |
dbegasse | 0:7b4bbd744f6d | 112 | |
dbegasse | 0:7b4bbd744f6d | 113 | // Now we can use the ax, ay, and az variables as we please. |
dbegasse | 0:7b4bbd744f6d | 114 | // Either print them as raw ADC values, or calculated in g's. |
dbegasse | 0:7b4bbd744f6d | 115 | pc.printf("Accellerometer Data: "); |
dbegasse | 0:7b4bbd744f6d | 116 | //#ifdef PRINT_CALCULATED |
dbegasse | 0:7b4bbd744f6d | 117 | // If you want to print calculated values, you can use the |
dbegasse | 0:7b4bbd744f6d | 118 | // calcAccel helper function to convert a raw ADC value to |
dbegasse | 0:7b4bbd744f6d | 119 | // g's. Give the function the value that you want to convert. |
dbegasse | 0:7b4bbd744f6d | 120 | //pc.printf("The bias: %2f, %2f, %2f \n", dof.abias[0], dof.abias[1], dof.abias[2]); |
dbegasse | 0:7b4bbd744f6d | 121 | pc.printf("%2f\n",dof.calcAccel(dof.ax) - dof.abias[0]); |
dbegasse | 0:7b4bbd744f6d | 122 | //pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 123 | //pc.printf("%2f",dof.calcAccel(dof.ay) - dof.abias[1]); |
dbegasse | 0:7b4bbd744f6d | 124 | //pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 125 | //pc.printf("%2f\n",dof.calcAccel(dof.az) - dof.abias[2]); |
dbegasse | 0:7b4bbd744f6d | 126 | //#elif defined PRINT_RAW |
dbegasse | 0:7b4bbd744f6d | 127 | //pc.printf("%d",dof.ax); |
dbegasse | 0:7b4bbd744f6d | 128 | // pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 129 | //pc.printf("%d",dof.ay); |
dbegasse | 0:7b4bbd744f6d | 130 | //pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 131 | //pc.printf("%d\n",dof.az); |
dbegasse | 0:7b4bbd744f6d | 132 | //#endif |
dbegasse | 0:7b4bbd744f6d | 133 | |
dbegasse | 0:7b4bbd744f6d | 134 | } |
dbegasse | 0:7b4bbd744f6d | 135 | |
dbegasse | 0:7b4bbd744f6d | 136 | void printMag() |
dbegasse | 0:7b4bbd744f6d | 137 | { |
dbegasse | 0:7b4bbd744f6d | 138 | //Uncomment code if you plan on using interrupts |
dbegasse | 0:7b4bbd744f6d | 139 | /*while(pinINT2_XM == 0) |
dbegasse | 0:7b4bbd744f6d | 140 | { |
dbegasse | 0:7b4bbd744f6d | 141 | ; |
dbegasse | 0:7b4bbd744f6d | 142 | }*/ |
dbegasse | 0:7b4bbd744f6d | 143 | |
dbegasse | 0:7b4bbd744f6d | 144 | // To read from the magnetometer, you must first call the |
dbegasse | 0:7b4bbd744f6d | 145 | // readMag() function. When this exits, it'll update the |
dbegasse | 0:7b4bbd744f6d | 146 | // mx, my, and mz variables with the most current data. |
dbegasse | 0:7b4bbd744f6d | 147 | dof.readMag(); |
dbegasse | 0:7b4bbd744f6d | 148 | |
dbegasse | 0:7b4bbd744f6d | 149 | // Now we can use the mx, my, and mz variables as we please. |
dbegasse | 0:7b4bbd744f6d | 150 | // Either print them as raw ADC values, or calculated in Gauss. |
dbegasse | 0:7b4bbd744f6d | 151 | pc.printf("M: "); |
dbegasse | 0:7b4bbd744f6d | 152 | #ifdef PRINT_CALCULATED |
dbegasse | 0:7b4bbd744f6d | 153 | // If you want to print calculated values, you can use the |
dbegasse | 0:7b4bbd744f6d | 154 | // calcMag helper function to convert a raw ADC value to |
dbegasse | 0:7b4bbd744f6d | 155 | // Gauss. Give the function the value that you want to convert. |
dbegasse | 0:7b4bbd744f6d | 156 | pc.printf("%2f",dof.calcMag(dof.mx)); |
dbegasse | 0:7b4bbd744f6d | 157 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 158 | pc.printf("%2f",dof.calcMag(dof.my)); |
dbegasse | 0:7b4bbd744f6d | 159 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 160 | pc.printf("%2f\n",dof.calcMag(dof.mz)); |
dbegasse | 0:7b4bbd744f6d | 161 | #elif defined PRINT_RAW |
dbegasse | 0:7b4bbd744f6d | 162 | pc.printf("%d", dof.mx); |
dbegasse | 0:7b4bbd744f6d | 163 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 164 | pc.printf("%d", dof.my); |
dbegasse | 0:7b4bbd744f6d | 165 | pc.printf(", "); |
dbegasse | 0:7b4bbd744f6d | 166 | pc.printf("%d\n", dof.mz); |
dbegasse | 0:7b4bbd744f6d | 167 | #endif |
dbegasse | 0:7b4bbd744f6d | 168 | } |
dbegasse | 0:7b4bbd744f6d | 169 | |
dbegasse | 0:7b4bbd744f6d | 170 | void loop() |
dbegasse | 0:7b4bbd744f6d | 171 | { |
dbegasse | 0:7b4bbd744f6d | 172 | //pc.printf("\n\nDATA READINGS\n"); |
dbegasse | 0:7b4bbd744f6d | 173 | //printGyro(); // Print "G: gx, gy, gz" |
dbegasse | 0:7b4bbd744f6d | 174 | //printAccel(); // Print "A: ax, ay, az" |
dbegasse | 0:7b4bbd744f6d | 175 | //printMag(); // Print "M: mx, my, mz" |
dbegasse | 0:7b4bbd744f6d | 176 | //printTemp(); |
dbegasse | 0:7b4bbd744f6d | 177 | //wait_ms(PRINT_SPEED); |
dbegasse | 0:7b4bbd744f6d | 178 | |
dbegasse | 0:7b4bbd744f6d | 179 | } |
dbegasse | 0:7b4bbd744f6d | 180 | |
dbegasse | 0:7b4bbd744f6d | 181 | |
dbegasse | 0:7b4bbd744f6d | 182 | int main() |
dbegasse | 0:7b4bbd744f6d | 183 | { |
dbegasse | 0:7b4bbd744f6d | 184 | setup(); //Setup sensor and Serial |
dbegasse | 0:7b4bbd744f6d | 185 | //int content; |
dbegasse | 0:7b4bbd744f6d | 186 | |
dbegasse | 0:7b4bbd744f6d | 187 | |
dbegasse | 0:7b4bbd744f6d | 188 | |
dbegasse | 0:7b4bbd744f6d | 189 | |
dbegasse | 0:7b4bbd744f6d | 190 | |
dbegasse | 0:7b4bbd744f6d | 191 | //************************************************ |
dbegasse | 0:7b4bbd744f6d | 192 | //Below is the code for the uLCD bubble level |
dbegasse | 0:7b4bbd744f6d | 193 | int circlex = 0; |
dbegasse | 0:7b4bbd744f6d | 194 | int circley = 60; |
dbegasse | 0:7b4bbd744f6d | 195 | int circler = 15; |
dbegasse | 0:7b4bbd744f6d | 196 | int last_circlex = 0; |
dbegasse | 0:7b4bbd744f6d | 197 | float accel; |
dbegasse | 0:7b4bbd744f6d | 198 | |
dbegasse | 0:7b4bbd744f6d | 199 | |
dbegasse | 0:7b4bbd744f6d | 200 | |
dbegasse | 0:7b4bbd744f6d | 201 | while (true) |
dbegasse | 0:7b4bbd744f6d | 202 | { |
dbegasse | 0:7b4bbd744f6d | 203 | |
dbegasse | 0:7b4bbd744f6d | 204 | dof.readAccel(); |
dbegasse | 0:7b4bbd744f6d | 205 | accel = dof.calcAccel(dof.ax) - dof.abias[0]; |
dbegasse | 0:7b4bbd744f6d | 206 | //pc.printf("%2f\n", accel); |
dbegasse | 0:7b4bbd744f6d | 207 | wait(0.05); |
dbegasse | 0:7b4bbd744f6d | 208 | |
dbegasse | 0:7b4bbd744f6d | 209 | |
dbegasse | 0:7b4bbd744f6d | 210 | |
dbegasse | 0:7b4bbd744f6d | 211 | uLCD.filled_circle(last_circlex, circley, circler, BLACK); |
dbegasse | 0:7b4bbd744f6d | 212 | circlex = (1 + accel) * 64; |
dbegasse | 0:7b4bbd744f6d | 213 | last_circlex = circlex; |
dbegasse | 0:7b4bbd744f6d | 214 | uLCD.filled_circle(circlex, circley, circler, 0xFFFF00); |
dbegasse | 0:7b4bbd744f6d | 215 | |
dbegasse | 0:7b4bbd744f6d | 216 | } |
dbegasse | 0:7b4bbd744f6d | 217 | |
dbegasse | 0:7b4bbd744f6d | 218 | //************************************************* |
dbegasse | 0:7b4bbd744f6d | 219 | } |
dbegasse | 0:7b4bbd744f6d | 220 |