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
00001 #include "mbed.h" 00002 #include "rtos.h" 00003 #include <stdio.h> 00004 #include "uLCD_4DGL.h" 00005 #include "XNucleo53L0A1.h" 00006 #include <time.h> 00007 00008 #define VL53L0_I2C_SDA p28 00009 #define VL53L0_I2C_SCL p27 00010 #define INIT_TIME 90 00011 #define THRESHOLD 100 00012 00013 // We need this for being able to reset the MBED (similar to watch dogs) 00014 extern "C" void mbed_reset(); 00015 00016 // Game Data 00017 volatile int num_points = 0; 00018 volatile int time_left = INIT_TIME; 00019 volatile bool is_point = false; 00020 volatile int player_1 = 0; 00021 volatile int player_2 = 0; 00022 00023 int player_1_color = GREEN + RED; 00024 int player_2_color = RED + (.707 * GREEN); 00025 00026 volatile int player_color = GREEN; 00027 00028 00029 00030 // LIDAR 00031 static XNucleo53L0A1* lidar = NULL; 00032 uint32_t dist; 00033 DigitalOut shdn(p26); 00034 00035 // LCD 00036 Mutex lcd_lock; 00037 // **NOTE**: do NOT use p9, p10, p11 00038 // There is a bug in LIDAR system and uLCD system - they can't BOTH BE ON 00039 // I2C! It just so happens, p9 and p10 are I2C, so the systems will get 00040 // confused, and you'll get weird hangs with the uLCD screen! 00041 uLCD_4DGL uLCD(p13, p14, p15); // serial tx, serial rx, reset pin; 00042 00043 // Speaker 00044 PwmOut speaker(p25); 00045 00046 // Threads 00047 Thread sound_thread; 00048 Thread time_thread; 00049 Thread points_thread; 00050 00051 // Debugging 00052 Serial pc(USBTX, USBRX); 00053 DigitalOut err_led(LED1); 00054 00055 void time(void) { 00056 while (1) { 00057 // every second, change LED and update screen 00058 if (time_left > 0) { 00059 lcd_lock.lock(); 00060 uLCD.locate(4, 6); 00061 uLCD.text_height(2); 00062 uLCD.text_width(2); 00063 uLCD.color(RED); 00064 uLCD.printf("%03d", time_left); 00065 lcd_lock.unlock(); 00066 Thread::wait(1000); 00067 time_left--; 00068 } else { 00069 break; 00070 } 00071 } 00072 lcd_lock.lock(); 00073 uLCD.locate(4, 6); 00074 uLCD.text_height(2); 00075 uLCD.text_width(2); 00076 uLCD.color(RED); 00077 uLCD.printf("000"); 00078 lcd_lock.unlock(); 00079 // We're done - thread will die 00080 } 00081 void sound(void) { 00082 int is_new = 1; 00083 speaker.period(1.0 / 500.0); 00084 speaker = 0.5; 00085 Thread::wait(250); 00086 speaker = 0.0; 00087 Thread::wait(100); 00088 speaker = 0.5; 00089 Thread::wait(250); 00090 speaker = 0.0; 00091 speaker.period(1.0 / 900.0); 00092 while (1) { 00093 // if we have a point, sound 00094 // If there's no more time left, die 00095 if (time_left <= 0) { 00096 break; 00097 } else if (is_point && is_new == 1) { 00098 is_new = 0; 00099 // sound that 00100 speaker = 0.5; 00101 Thread::wait(100); 00102 speaker = 0; 00103 } else if (!is_point) { 00104 // We've engaged, get ready for next 00105 is_new = 1; 00106 } 00107 Thread::wait(10); 00108 } 00109 speaker.period(1.0 / 100.0); 00110 speaker = 0.5; 00111 Thread::wait(2000); 00112 speaker = 0.0; 00113 } 00114 00115 void points(void) { 00116 int prev_points = -1; 00117 lcd_lock.lock(); 00118 uLCD.circle(110, 10, 10, player_color); 00119 lcd_lock.unlock(); 00120 while (1) { 00121 if (time_left <= 0) { 00122 break; 00123 } else if (num_points != prev_points) { 00124 lcd_lock.lock(); 00125 uLCD.locate(4, 3); 00126 uLCD.text_width(2); 00127 uLCD.text_height(2); 00128 uLCD.color(player_color); 00129 uLCD.printf("%d", num_points); 00130 lcd_lock.unlock(); 00131 prev_points = num_points; 00132 } 00133 if (is_point) { 00134 // changed from no to yes 00135 lcd_lock.lock(); 00136 uLCD.filled_circle(110, 10, 9, player_color); 00137 lcd_lock.unlock(); 00138 } else { 00139 lcd_lock.lock(); 00140 uLCD.filled_circle(110, 10, 9, BLACK); 00141 lcd_lock.unlock(); 00142 } 00143 Thread::wait(10); 00144 } 00145 } 00146 00147 void run_game() { 00148 // Initialize 00149 time_left = INIT_TIME; 00150 is_point = false; 00151 00152 uLCD.text_width(2); 00153 uLCD.text_height(2); 00154 uLCD.locate(1, 2); 00155 uLCD.color(player_color); 00156 uLCD.printf("POINTS"); 00157 00158 uLCD.locate(2, 5); 00159 uLCD.color(RED); 00160 uLCD.printf("TIME"); 00161 00162 // Start up threads 00163 time_thread.start(time); 00164 points_thread.start(points); 00165 sound_thread.start(sound); 00166 00167 // Continually measure distance 00168 Thread::wait(2000); 00169 while (1) { 00170 if (time_left == 0) 00171 break; 00172 int status = lidar->sensor_centre->get_distance(&dist); 00173 if (status == VL53L0X_ERROR_NONE) { 00174 00175 // Determine if we've hit the threshold (4 cases): 00176 // 1. NOT in the threshold, current distance is above 00177 // 2. NOT in the threshold, current distance is below 00178 // 3. IN the threshold, current distance is above 00179 // 4. IN the threshold, current distance is below 00180 //pc.printf("D=%ld mm\r\n", dist); 00181 if (!is_point && dist <= THRESHOLD) { 00182 // We don't need to check this every time - save our previous 00183 // loop time! 00184 if (time_left == 0) 00185 break; 00186 // increment our points 00187 ++num_points; 00188 is_point = true; 00189 } else if (is_point && dist > THRESHOLD) { 00190 is_point = false; 00191 } 00192 } else { 00193 is_point = false; 00194 } 00195 } 00196 // wait for time_left (should be handled above, but just in case? 00197 } 00198 int main() { 00199 // Tell the user we're spinning up 00200 uLCD.cls(); 00201 uLCD.text_height(2); 00202 uLCD.text_width(2); 00203 uLCD.locate(0, 0); 00204 uLCD.color(RED); 00205 uLCD.printf("SPINNING\nUP"); 00206 00207 DevI2C* device_i2c = new DevI2C(VL53L0_I2C_SDA, VL53L0_I2C_SCL); 00208 lidar = XNucleo53L0A1::instance(device_i2c, A2, D8, D2); 00209 00210 // Reset shdn (?): 00211 shdn = 0; 00212 wait(0.1); 00213 shdn = 1; 00214 wait(0.1); 00215 00216 int status = lidar->init_board(); 00217 while (status) { 00218 err_led = 1; 00219 status = lidar->init_board(); 00220 wait(1); 00221 } 00222 err_led = 0; 00223 // We have nothing left to do... Just wait 00224 // Wait for the LIDAR 00225 player_color = player_1_color; 00226 uLCD.cls(); 00227 uLCD.locate(0, 0); 00228 uLCD.color(player_color); 00229 uLCD.text_height(2); 00230 uLCD.text_width(2); 00231 uLCD.printf("Ready\nPlayer\n1"); 00232 00233 // Wait for the LIDAR 00234 while(true){ 00235 if(lidar->sensor_centre->get_distance(&dist) == VL53L0X_ERROR_NONE){ 00236 if(dist<THRESHOLD){ 00237 break; 00238 } 00239 } 00240 } 00241 uLCD.cls(); 00242 uLCD.locate(0, 0); 00243 uLCD.color(player_color); 00244 uLCD.text_width(2); 00245 uLCD.text_height(2); 00246 uLCD.printf("P1"); 00247 run_game(); 00248 player_1 = num_points; 00249 Thread::wait(5000); 00250 player_color = player_2_color; 00251 num_points = 0; 00252 lcd_lock.lock(); 00253 uLCD.cls(); 00254 uLCD.locate(0, 0); 00255 uLCD.color(player_color); 00256 uLCD.text_height(2); 00257 uLCD.text_width(2); 00258 uLCD.printf("Ready\nPlayer\n2"); 00259 lcd_lock.unlock(); 00260 // Wait for the LIDAR 00261 while(true){ 00262 if(lidar->sensor_centre->get_distance(&dist) == VL53L0X_ERROR_NONE){ 00263 if(dist<THRESHOLD){ 00264 break; 00265 } 00266 } 00267 } 00268 uLCD.cls(); 00269 uLCD.locate(0, 0); 00270 uLCD.color(player_color); 00271 uLCD.text_width(2); 00272 uLCD.text_height(2); 00273 uLCD.printf("P2"); 00274 run_game(); 00275 player_2 = num_points; 00276 00277 lcd_lock.lock(); 00278 // Lock foever 00279 uLCD.cls(); 00280 uLCD.color(GREEN); 00281 uLCD.locate(0, 0); 00282 uLCD.text_width(3); 00283 uLCD.text_height(3); 00284 if (player_1 > player_2) { 00285 uLCD.text_string("Player", 0, 0, FONT_7X8, player_1_color); 00286 uLCD.text_string("1", 0, 1, FONT_7X8, player_1_color); 00287 uLCD.text_string("Wins!", 0, 2, FONT_7X8, player_1_color); 00288 } else if (player_2 > player_1) { 00289 uLCD.text_string("Player", 0, 0, FONT_7X8, player_2_color); 00290 uLCD.text_string("2", 0, 1, FONT_7X8, player_2_color); 00291 uLCD.text_string("Wins!", 0, 2, FONT_7X8, player_2_color); 00292 } else { 00293 uLCD.printf("Draw!"); 00294 } 00295 uLCD.locate(0, 3); 00296 uLCD.color(player_1_color); 00297 uLCD.printf("P1: %d", player_1); 00298 uLCD.locate(0, 4); 00299 uLCD.color(player_2_color); 00300 uLCD.printf("P2: %d", player_2); 00301 lcd_lock.unlock(); 00302 00303 Thread::wait(5000); 00304 while(true){ 00305 if(lidar->sensor_centre->get_distance(&dist) == VL53L0X_ERROR_NONE){ 00306 if(dist<THRESHOLD){ 00307 break; 00308 } 00309 } 00310 } 00311 mbed_reset(); 00312 }
Generated on Thu Aug 4 2022 01:24:13 by
1.7.2