Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed mbed-rtos 4DGL-uLCD-SE X_NUCLEO_53L0A1
main.cpp@4:44b4158fc494, 2019-04-18 (annotated)
- Committer:
- alexhrao
- Date:
- Thu Apr 18 16:43:34 2019 +0000
- Revision:
- 4:44b4158fc494
- Parent:
- 3:efb572ef5f15
- Child:
- 5:b566bcb20d94
Remove LED completely
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
alexhrao | 0:fc7ce4e596ff | 1 | #include "mbed.h" |
alexhrao | 0:fc7ce4e596ff | 2 | #include "rtos.h" |
alexhrao | 0:fc7ce4e596ff | 3 | #include <stdio.h> |
alexhrao | 0:fc7ce4e596ff | 4 | #include "uLCD_4DGL.h" |
alexhrao | 0:fc7ce4e596ff | 5 | #include "XNucleo53L0A1.h" |
alexhrao | 1:e82997c13013 | 6 | #include <time.h> |
alexhrao | 0:fc7ce4e596ff | 7 | |
alexhrao | 0:fc7ce4e596ff | 8 | #define VL53L0_I2C_SDA p28 |
alexhrao | 0:fc7ce4e596ff | 9 | #define VL53L0_I2C_SCL p27 |
alexhrao | 0:fc7ce4e596ff | 10 | |
alexhrao | 2:54e1a301de72 | 11 | // We need this for being able to reset the MBED (similar to watch dogs) |
alexhrao | 3:efb572ef5f15 | 12 | // extern "C" void mbed_reset(); |
alexhrao | 0:fc7ce4e596ff | 13 | |
alexhrao | 2:54e1a301de72 | 14 | // Game Data |
alexhrao | 1:e82997c13013 | 15 | volatile int num_points = 0; |
alexhrao | 0:fc7ce4e596ff | 16 | volatile int time_left = 0; |
alexhrao | 0:fc7ce4e596ff | 17 | volatile bool is_point = false; |
alexhrao | 0:fc7ce4e596ff | 18 | |
alexhrao | 0:fc7ce4e596ff | 19 | // LIDAR |
alexhrao | 0:fc7ce4e596ff | 20 | static XNucleo53L0A1* lidar = NULL; |
alexhrao | 0:fc7ce4e596ff | 21 | uint32_t dist; |
alexhrao | 0:fc7ce4e596ff | 22 | DigitalOut shdn(p26); |
alexhrao | 0:fc7ce4e596ff | 23 | |
alexhrao | 0:fc7ce4e596ff | 24 | // LCD |
alexhrao | 0:fc7ce4e596ff | 25 | Mutex lcd_lock; |
alexhrao | 2:54e1a301de72 | 26 | // **NOTE**: do NOT use p9, p10, p11 |
alexhrao | 1:e82997c13013 | 27 | // There is a bug in LIDAR system and uLCD system - they can't BOTH BE ON |
alexhrao | 1:e82997c13013 | 28 | // I2C! It just so happens, p9 and p10 are I2C, so the systems will get |
alexhrao | 2:54e1a301de72 | 29 | // confused, and you'll get weird hangs with the uLCD screen! |
alexhrao | 1:e82997c13013 | 30 | uLCD_4DGL uLCD(p13, p14, p15); // serial tx, serial rx, reset pin; |
alexhrao | 0:fc7ce4e596ff | 31 | |
alexhrao | 0:fc7ce4e596ff | 32 | // Speaker |
alexhrao | 0:fc7ce4e596ff | 33 | PwmOut speaker(p25); |
alexhrao | 0:fc7ce4e596ff | 34 | |
alexhrao | 0:fc7ce4e596ff | 35 | // Threads |
alexhrao | 0:fc7ce4e596ff | 36 | Thread sound_thread; |
alexhrao | 0:fc7ce4e596ff | 37 | Thread time_thread; |
alexhrao | 0:fc7ce4e596ff | 38 | Thread points_thread; |
alexhrao | 0:fc7ce4e596ff | 39 | |
alexhrao | 0:fc7ce4e596ff | 40 | // Debugging |
alexhrao | 2:54e1a301de72 | 41 | Serial pc(USBTX, USBRX); |
alexhrao | 0:fc7ce4e596ff | 42 | DigitalOut err_led(LED1); |
alexhrao | 1:e82997c13013 | 43 | |
alexhrao | 0:fc7ce4e596ff | 44 | void time(void) { |
alexhrao | 0:fc7ce4e596ff | 45 | while (1) { |
alexhrao | 0:fc7ce4e596ff | 46 | // every second, change LED and update screen |
alexhrao | 0:fc7ce4e596ff | 47 | if (time_left > 0) { |
alexhrao | 0:fc7ce4e596ff | 48 | lcd_lock.lock(); |
alexhrao | 1:e82997c13013 | 49 | uLCD.locate(4, 5); |
alexhrao | 0:fc7ce4e596ff | 50 | uLCD.text_height(2); |
alexhrao | 0:fc7ce4e596ff | 51 | uLCD.text_width(2); |
alexhrao | 1:e82997c13013 | 52 | uLCD.color(RED); |
alexhrao | 1:e82997c13013 | 53 | uLCD.printf("%02d", time_left); |
alexhrao | 0:fc7ce4e596ff | 54 | lcd_lock.unlock(); |
alexhrao | 0:fc7ce4e596ff | 55 | Thread::wait(1000); |
alexhrao | 1:e82997c13013 | 56 | time_left--; |
alexhrao | 0:fc7ce4e596ff | 57 | } else { |
alexhrao | 0:fc7ce4e596ff | 58 | break; |
alexhrao | 0:fc7ce4e596ff | 59 | } |
alexhrao | 0:fc7ce4e596ff | 60 | } |
alexhrao | 2:54e1a301de72 | 61 | |
alexhrao | 0:fc7ce4e596ff | 62 | lcd_lock.lock(); |
alexhrao | 3:efb572ef5f15 | 63 | uLCD.locate(0, 5); |
alexhrao | 0:fc7ce4e596ff | 64 | uLCD.text_height(2); |
alexhrao | 0:fc7ce4e596ff | 65 | uLCD.text_width(2); |
alexhrao | 1:e82997c13013 | 66 | uLCD.color(RED); |
alexhrao | 3:efb572ef5f15 | 67 | uLCD.printf("GAME OVER"); |
alexhrao | 0:fc7ce4e596ff | 68 | lcd_lock.unlock(); |
alexhrao | 2:54e1a301de72 | 69 | // We're done - thread will die |
alexhrao | 0:fc7ce4e596ff | 70 | } |
alexhrao | 0:fc7ce4e596ff | 71 | void sound(void) { |
alexhrao | 0:fc7ce4e596ff | 72 | int is_new = 1; |
alexhrao | 0:fc7ce4e596ff | 73 | speaker.period(1.0 / 900.0); |
alexhrao | 0:fc7ce4e596ff | 74 | while (1) { |
alexhrao | 2:54e1a301de72 | 75 | // if we have a point, sound |
alexhrao | 2:54e1a301de72 | 76 | // If there's no more time left, die |
alexhrao | 2:54e1a301de72 | 77 | if (time_left <= 0) { |
alexhrao | 2:54e1a301de72 | 78 | break; |
alexhrao | 2:54e1a301de72 | 79 | } else if (is_point && is_new == 1) { |
alexhrao | 0:fc7ce4e596ff | 80 | is_new = 0; |
alexhrao | 0:fc7ce4e596ff | 81 | // sound that |
alexhrao | 1:e82997c13013 | 82 | speaker = 0.5; |
alexhrao | 1:e82997c13013 | 83 | Thread::wait(100); |
alexhrao | 1:e82997c13013 | 84 | speaker = 0; |
alexhrao | 0:fc7ce4e596ff | 85 | } else if (!is_point) { |
alexhrao | 2:54e1a301de72 | 86 | // We've engaged, get ready for next |
alexhrao | 0:fc7ce4e596ff | 87 | is_new = 1; |
alexhrao | 0:fc7ce4e596ff | 88 | } |
alexhrao | 0:fc7ce4e596ff | 89 | Thread::wait(10); |
alexhrao | 0:fc7ce4e596ff | 90 | } |
alexhrao | 0:fc7ce4e596ff | 91 | } |
alexhrao | 0:fc7ce4e596ff | 92 | |
alexhrao | 1:e82997c13013 | 93 | void points(void) { |
alexhrao | 1:e82997c13013 | 94 | int prev_points = -1; |
alexhrao | 3:efb572ef5f15 | 95 | bool prev_is_point = false; |
alexhrao | 0:fc7ce4e596ff | 96 | while (1) { |
alexhrao | 2:54e1a301de72 | 97 | if (time_left <= 0) { |
alexhrao | 1:e82997c13013 | 98 | break; |
alexhrao | 2:54e1a301de72 | 99 | } else if (num_points != prev_points) { |
alexhrao | 0:fc7ce4e596ff | 100 | lcd_lock.lock(); |
alexhrao | 1:e82997c13013 | 101 | uLCD.locate(4, 2); |
alexhrao | 0:fc7ce4e596ff | 102 | uLCD.text_width(2); |
alexhrao | 0:fc7ce4e596ff | 103 | uLCD.text_height(2); |
alexhrao | 0:fc7ce4e596ff | 104 | uLCD.color(GREEN); |
alexhrao | 1:e82997c13013 | 105 | uLCD.printf("%d", num_points); |
alexhrao | 0:fc7ce4e596ff | 106 | lcd_lock.unlock(); |
alexhrao | 1:e82997c13013 | 107 | prev_points = num_points; |
alexhrao | 0:fc7ce4e596ff | 108 | } |
alexhrao | 3:efb572ef5f15 | 109 | if (is_point && !prev_is_point) { |
alexhrao | 3:efb572ef5f15 | 110 | // changed from no to yes |
alexhrao | 3:efb572ef5f15 | 111 | lcd_lock.lock(); |
alexhrao | 3:efb572ef5f15 | 112 | uLCD.filled_circle(8, 0, 1, GREEN); |
alexhrao | 3:efb572ef5f15 | 113 | lcd_lock.unlock(); |
alexhrao | 3:efb572ef5f15 | 114 | } else if (!is_point && prev_is_point) { |
alexhrao | 3:efb572ef5f15 | 115 | lcd_lock.lock(); |
alexhrao | 3:efb572ef5f15 | 116 | uLCD.filled_circle(8, 0, 1, BLACK); |
alexhrao | 3:efb572ef5f15 | 117 | lcd_lock.unlock(); |
alexhrao | 3:efb572ef5f15 | 118 | } |
alexhrao | 0:fc7ce4e596ff | 119 | Thread::wait(100); |
alexhrao | 0:fc7ce4e596ff | 120 | } |
alexhrao | 3:efb572ef5f15 | 121 | lcd_lock.lock(); |
alexhrao | 3:efb572ef5f15 | 122 | uLCD.filled_circle(8, 0, 1, RED); |
alexhrao | 3:efb572ef5f15 | 123 | lcd_lock.unlock(); |
alexhrao | 0:fc7ce4e596ff | 124 | } |
alexhrao | 0:fc7ce4e596ff | 125 | |
alexhrao | 0:fc7ce4e596ff | 126 | int main() { |
alexhrao | 0:fc7ce4e596ff | 127 | // Tell the user we're spinning up |
alexhrao | 0:fc7ce4e596ff | 128 | uLCD.cls(); |
alexhrao | 0:fc7ce4e596ff | 129 | uLCD.text_height(2); |
alexhrao | 0:fc7ce4e596ff | 130 | uLCD.text_width(2); |
alexhrao | 2:54e1a301de72 | 131 | uLCD.locate(0, 0); |
alexhrao | 0:fc7ce4e596ff | 132 | uLCD.color(RED); |
alexhrao | 2:54e1a301de72 | 133 | uLCD.printf("SPINNING\nUP"); |
alexhrao | 2:54e1a301de72 | 134 | |
alexhrao | 2:54e1a301de72 | 135 | // Initialize |
alexhrao | 3:efb572ef5f15 | 136 | int threshold = 100; |
alexhrao | 3:efb572ef5f15 | 137 | time_left = 60; |
alexhrao | 3:efb572ef5f15 | 138 | is_point = false; |
alexhrao | 0:fc7ce4e596ff | 139 | |
alexhrao | 0:fc7ce4e596ff | 140 | DevI2C* device_i2c = new DevI2C(VL53L0_I2C_SDA, VL53L0_I2C_SCL); |
alexhrao | 0:fc7ce4e596ff | 141 | lidar = XNucleo53L0A1::instance(device_i2c, A2, D8, D2); |
alexhrao | 1:e82997c13013 | 142 | |
alexhrao | 0:fc7ce4e596ff | 143 | // Reset shdn (?): |
alexhrao | 0:fc7ce4e596ff | 144 | shdn = 0; |
alexhrao | 0:fc7ce4e596ff | 145 | wait(0.1); |
alexhrao | 0:fc7ce4e596ff | 146 | shdn = 1; |
alexhrao | 0:fc7ce4e596ff | 147 | wait(0.1); |
alexhrao | 0:fc7ce4e596ff | 148 | |
alexhrao | 0:fc7ce4e596ff | 149 | int status = lidar->init_board(); |
alexhrao | 0:fc7ce4e596ff | 150 | while (status) { |
alexhrao | 2:54e1a301de72 | 151 | err_led = 1; |
alexhrao | 0:fc7ce4e596ff | 152 | status = lidar->init_board(); |
alexhrao | 0:fc7ce4e596ff | 153 | wait(1); |
alexhrao | 0:fc7ce4e596ff | 154 | } |
alexhrao | 2:54e1a301de72 | 155 | err_led = 0; |
alexhrao | 2:54e1a301de72 | 156 | |
alexhrao | 1:e82997c13013 | 157 | uLCD.cls(); |
alexhrao | 1:e82997c13013 | 158 | uLCD.locate(0, 0); |
alexhrao | 1:e82997c13013 | 159 | uLCD.color(GREEN); |
alexhrao | 1:e82997c13013 | 160 | uLCD.text_height(2); |
alexhrao | 1:e82997c13013 | 161 | uLCD.text_width(2); |
alexhrao | 2:54e1a301de72 | 162 | uLCD.printf("Want To\nPlay?"); |
alexhrao | 2:54e1a301de72 | 163 | |
alexhrao | 4:44b4158fc494 | 164 | // Wait for the LIDAR |
alexhrao | 3:efb572ef5f15 | 165 | while(true){ |
alexhrao | 3:efb572ef5f15 | 166 | if(lidar->sensor_centre->get_distance(&dist) == VL53L0X_ERROR_NONE){ |
alexhrao | 3:efb572ef5f15 | 167 | if(dist<100){ |
alexhrao | 3:efb572ef5f15 | 168 | break; |
alexhrao | 3:efb572ef5f15 | 169 | } |
alexhrao | 3:efb572ef5f15 | 170 | } |
alexhrao | 3:efb572ef5f15 | 171 | } |
alexhrao | 3:efb572ef5f15 | 172 | |
alexhrao | 1:e82997c13013 | 173 | uLCD.cls(); |
alexhrao | 1:e82997c13013 | 174 | uLCD.text_width(2); |
alexhrao | 1:e82997c13013 | 175 | uLCD.text_height(2); |
alexhrao | 1:e82997c13013 | 176 | uLCD.locate(1, 1); |
alexhrao | 1:e82997c13013 | 177 | uLCD.color(GREEN); |
alexhrao | 1:e82997c13013 | 178 | uLCD.printf("POINTS"); |
alexhrao | 2:54e1a301de72 | 179 | |
alexhrao | 1:e82997c13013 | 180 | uLCD.locate(2, 4); |
alexhrao | 1:e82997c13013 | 181 | uLCD.color(RED); |
alexhrao | 1:e82997c13013 | 182 | uLCD.printf("TIME"); |
alexhrao | 2:54e1a301de72 | 183 | |
alexhrao | 2:54e1a301de72 | 184 | // Start up threads |
alexhrao | 1:e82997c13013 | 185 | time_thread.start(time); |
alexhrao | 1:e82997c13013 | 186 | points_thread.start(points); |
alexhrao | 1:e82997c13013 | 187 | sound_thread.start(sound); |
alexhrao | 1:e82997c13013 | 188 | |
alexhrao | 0:fc7ce4e596ff | 189 | // Continually measure distance |
alexhrao | 0:fc7ce4e596ff | 190 | while (1) { |
alexhrao | 1:e82997c13013 | 191 | status = lidar->sensor_centre->get_distance(&dist); |
alexhrao | 1:e82997c13013 | 192 | if (status == VL53L0X_ERROR_NONE) { |
alexhrao | 2:54e1a301de72 | 193 | |
alexhrao | 1:e82997c13013 | 194 | // Determine if we've hit the threshold (4 cases): |
alexhrao | 1:e82997c13013 | 195 | // 1. NOT in the threshold, current distance is above |
alexhrao | 1:e82997c13013 | 196 | // 2. NOT in the threshold, current distance is below |
alexhrao | 1:e82997c13013 | 197 | // 3. IN the threshold, current distance is above |
alexhrao | 1:e82997c13013 | 198 | // 4. IN the threshold, current distance is below |
alexhrao | 1:e82997c13013 | 199 | //pc.printf("D=%ld mm\r\n", dist); |
alexhrao | 1:e82997c13013 | 200 | if (!is_point && dist <= threshold) { |
alexhrao | 3:efb572ef5f15 | 201 | // We don't need to check this every time - save our previous |
alexhrao | 3:efb572ef5f15 | 202 | // loop time! |
alexhrao | 1:e82997c13013 | 203 | if (time_left == 0) |
alexhrao | 1:e82997c13013 | 204 | break; |
alexhrao | 1:e82997c13013 | 205 | // increment our points |
alexhrao | 1:e82997c13013 | 206 | ++num_points; |
alexhrao | 1:e82997c13013 | 207 | is_point = true; |
alexhrao | 1:e82997c13013 | 208 | } else if (is_point && dist > threshold) { |
alexhrao | 1:e82997c13013 | 209 | is_point = false; |
alexhrao | 1:e82997c13013 | 210 | } |
alexhrao | 1:e82997c13013 | 211 | } else { |
alexhrao | 0:fc7ce4e596ff | 212 | is_point = false; |
alexhrao | 0:fc7ce4e596ff | 213 | } |
alexhrao | 0:fc7ce4e596ff | 214 | } |
alexhrao | 3:efb572ef5f15 | 215 | // We have nothing left to do... Just wait |
alexhrao | 3:efb572ef5f15 | 216 | while(1); |
alexhrao | 2:54e1a301de72 | 217 | } |