Kevin Abraham
/
MobileArcade
Platform controller for the Mobile Arcade project
main.cpp
- Committer:
- abraha2d
- Date:
- 2018-12-11
- Revision:
- 3:7e5233f883c7
- Parent:
- 2:774edcf60939
File content as of revision 3:7e5233f883c7:
#include "mbed.h" #include "Motor.h" #include "APA102.h" #define NUM_LEDS 72 #define TAIL_BLINKER_START 0 #define NUM_TAIL_BLINKER 3 #define TAIL_REVERSE_START 3 #define NUM_TAIL_REVERSE 2 #define GLOW_START 6 #define NUM_GLOW 21 #define HEAD_FOG_START 28 #define NUM_HEAD_FOG 1 #define HEAD_BLINKER_START 30 #define NUM_HEAD_BLINKER 2 #define HEAD_LIGHT_START 32 #define NUM_HEAD_LIGHT 3 #define GAME_START 51 #define NUM_GAME 19 #define COLOR_GAME_MENU CRGB(32, 32, 32) #define COLOR_GAME_GAME CRGB(0, 64, 128) #define COLOR_GAME_NUM 3 #define COLOR_GAME_DEN 3 #define COLOR_HEADLIGHT_DIM CRGB(8, 8, 8) #define COLOR_HEADLIGHT_ON CRGB(32, 32, 32) #define COLOR_FOGLIGHT CRGB(64, 64, 0) #define COLOR_TAILLIGHT CRGB(32, 0, 0) #define COLOR_BRAKELIGHT CRGB(128, 0, 0) #define COLOR_REVERSE CRGB(64, 64, 64) #define COLOR_UNDERGLOW CRGB(0, 16, 0) #define COLOR_BLINKER CRGB(128, 32, 0) #define BLINK_DELAY 0.5 #define BLINKER_L 1 #define BLINKER_R 2 #define FOGLIGHT 4 #define REVERSE 8 #define UNDERGLOW 16 #define HEADLIGHT 32 #define BRAKELIGHT 64 uint8_t lights = 0; CRGB l_leds[NUM_LEDS]; CRGB r_leds[NUM_LEDS]; int numGame = 0; CRGB gameColor = COLOR_GAME_MENU; double gameBrightness = 0; SPI l_strip(p5, p6, p7); SPI r_strip(p11, p12, p13); Motor l_motor(p21, p23, p22); // PWMA, AI1, AI2 Motor r_motor(p26, p24, p25); // PWMB, BI1, BI2 float l_vel = 0; float r_vel = 0; Serial bt(p28, p27); // Bluefruit RX, TX Serial pc(USBTX, USBRX); Thread pcThread; Thread btThread; Thread blinkerThread; Thread gameThread; void pc_thread() { for(;;) { while (!pc.readable()) wait(0.1); switch (pc.getc()) { case 's': // Switch to game while(pc.getc() != '\n'); // Flush rest of command while (gameBrightness > 0.1250168966) wait(0.01); // Wait for dim before switch for (int i = 0; i < 100; i++) { gameColor = CRGB( (COLOR_GAME_GAME.r - COLOR_GAME_MENU.r) * (i / 100.0) + COLOR_GAME_MENU.r, (COLOR_GAME_GAME.g - COLOR_GAME_MENU.g) * (i / 100.0) + COLOR_GAME_MENU.g, (COLOR_GAME_GAME.b - COLOR_GAME_MENU.b) * (i / 100.0) + COLOR_GAME_MENU.b ); wait(0.01); } gameColor = COLOR_GAME_GAME; break; case 'e': // Switch to menu while(pc.getc() != '\n'); // Flush rest of command while (gameBrightness > 0.1250168966) wait(0.01); // Wait for dim before switch for (int i = 0; i < 100; i++) { gameColor = CRGB( (COLOR_GAME_MENU.r - COLOR_GAME_GAME.r) * (i / 100.0) + COLOR_GAME_GAME.r, (COLOR_GAME_MENU.g - COLOR_GAME_GAME.g) * (i / 100.0) + COLOR_GAME_GAME.g, (COLOR_GAME_MENU.b - COLOR_GAME_GAME.b) * (i / 100.0) + COLOR_GAME_GAME.b ); wait(0.01); } gameColor = COLOR_GAME_MENU; break; case 'b': // Starting up while (numGame < NUM_GAME) { numGame++; wait(0.05); } lights = FOGLIGHT | UNDERGLOW | BRAKELIGHT; break; case 'h': // Shutting down lights = 0; while (numGame > 0) { numGame--; wait(0.05); } break; } } } void bt_thread() { char bnum = 0; char bhit = 0; for(;;) { while (!bt.readable()) wait(0.1); if (bt.getc() == '!' && bt.getc() == 'B') { bnum = bt.getc(); // button number bhit = bt.getc(); // '1' = hit, '0' = release if (bt.getc() == char(~('!' + 'B' + bnum + bhit))) { pc.printf("%i\n", bnum); if (bnum == 53 && bhit == '1') { // UP l_vel += 0.25f; r_vel += 0.25f; } else if (bnum == 54 && bhit == '1') { // DOWN l_vel -= 0.25f; r_vel -= 0.25f; } else if (bnum == 55 && bhit == '1') { // LEFT l_vel += 0.25f; r_vel -= 0.25f; } else if (bnum == 56 && bhit == '1') { // RIGHT l_vel -= 0.25f; r_vel += 0.25f; } else if (bnum == '2' && bhit == '1') { lights ^= FOGLIGHT; } l_motor.speed(l_vel); r_motor.speed(r_vel); if (bnum == '1' && bhit == '1') { l_vel = 0; r_vel = 0; l_motor.brake(1); r_motor.brake(1); } if (l_vel + r_vel > 0.01f) { lights &= ~(BRAKELIGHT | REVERSE); lights |= HEADLIGHT; } else if (l_vel + r_vel < -0.01f) { lights &= ~(BRAKELIGHT | HEADLIGHT); lights |= REVERSE; } else { lights &= ~(HEADLIGHT | REVERSE); lights |= BRAKELIGHT; } if (l_vel - r_vel > 0.01f) { lights &= ~BLINKER_R; lights |= BLINKER_L; } else if (r_vel - l_vel > 0.01f) { lights &= ~BLINKER_L; lights |= BLINKER_R; } else { lights &= ~(BLINKER_L | BLINKER_R); } } } } } void blinker_thread() { for (;;) { while (!(lights & (BLINKER_L | BLINKER_R))) { wait(0.1); } if (lights & BLINKER_L) { fill_solid(&(l_leds[HEAD_BLINKER_START]), NUM_HEAD_BLINKER, COLOR_BLINKER); fill_solid(&(l_leds[TAIL_BLINKER_START]), NUM_TAIL_BLINKER, COLOR_BLINKER); } if (lights & BLINKER_R) { fill_solid(&(r_leds[HEAD_BLINKER_START]), NUM_HEAD_BLINKER, COLOR_BLINKER); fill_solid(&(r_leds[TAIL_BLINKER_START]), NUM_TAIL_BLINKER, COLOR_BLINKER); } wait(BLINK_DELAY); if (l_leds[HEAD_BLINKER_START] == COLOR_BLINKER) { fill_solid(&(l_leds[HEAD_BLINKER_START]), NUM_HEAD_BLINKER, CRGB::Black); fill_solid(&(l_leds[TAIL_BLINKER_START]), NUM_TAIL_BLINKER, CRGB::Black); } if (r_leds[HEAD_BLINKER_START] == COLOR_BLINKER) { fill_solid(&(r_leds[HEAD_BLINKER_START]), NUM_HEAD_BLINKER, CRGB::Black); fill_solid(&(r_leds[TAIL_BLINKER_START]), NUM_TAIL_BLINKER, CRGB::Black); } wait(BLINK_DELAY); } } void game_thread() { int bCtr = 0; for(;;) { gameBrightness = (exp(sin(bCtr*0.01570796327))-0.3678794412)*0.3722766811+0.125; bCtr = ++bCtr % 400; pc.printf("%i\r\n", bCtr); wait(0.01); } } // main() runs in its own thread in the OS int main() { // Jack up the SPI frequency l_strip.frequency(4000000); r_strip.frequency(4000000); // Clear out the strip fill_solid(l_leds, NUM_LEDS, CRGB::Black); fill_solid(r_leds, NUM_LEDS, CRGB::Black); APA102_write(l_strip, l_leds, NUM_LEDS); APA102_write(r_strip, r_leds, NUM_LEDS); // Start threads pcThread.start(pc_thread); btThread.start(bt_thread); blinkerThread.start(blinker_thread); gameThread.start(game_thread); for(;;) { if (lights) { fill_solid(&(l_leds[HEAD_LIGHT_START]), NUM_HEAD_LIGHT, lights & HEADLIGHT ? COLOR_HEADLIGHT_ON : COLOR_HEADLIGHT_DIM); fill_solid(&(r_leds[HEAD_LIGHT_START]), NUM_HEAD_LIGHT, lights & HEADLIGHT ? COLOR_HEADLIGHT_ON : COLOR_HEADLIGHT_DIM); if (!(lights & BLINKER_L)) { fill_solid(&(l_leds[HEAD_BLINKER_START]), NUM_HEAD_BLINKER, lights & HEADLIGHT ? COLOR_HEADLIGHT_ON : COLOR_HEADLIGHT_DIM); fill_solid(&(l_leds[TAIL_BLINKER_START]), NUM_TAIL_BLINKER, lights & BRAKELIGHT ? COLOR_BRAKELIGHT : COLOR_TAILLIGHT); } if (!(lights & BLINKER_R)) { fill_solid(&(r_leds[HEAD_BLINKER_START]), NUM_HEAD_BLINKER, lights & HEADLIGHT ? COLOR_HEADLIGHT_ON : COLOR_HEADLIGHT_DIM); fill_solid(&(r_leds[TAIL_BLINKER_START]), NUM_TAIL_BLINKER, lights & BRAKELIGHT ? COLOR_BRAKELIGHT : COLOR_TAILLIGHT); } fill_solid(&(l_leds[HEAD_FOG_START]), NUM_HEAD_FOG, lights & FOGLIGHT ? COLOR_FOGLIGHT : CRGB::Black); fill_solid(&(r_leds[HEAD_FOG_START]), NUM_HEAD_FOG, lights & FOGLIGHT ? COLOR_FOGLIGHT : CRGB::Black); fill_solid(&(l_leds[GLOW_START]), NUM_GLOW, lights & UNDERGLOW ? COLOR_UNDERGLOW : CRGB::Black); fill_solid(&(r_leds[GLOW_START]), NUM_GLOW, lights & UNDERGLOW ? COLOR_UNDERGLOW : CRGB::Black); fill_solid(&(l_leds[TAIL_REVERSE_START]), NUM_TAIL_REVERSE, lights & REVERSE ? COLOR_REVERSE : lights & BRAKELIGHT ? COLOR_BRAKELIGHT : COLOR_TAILLIGHT); fill_solid(&(r_leds[TAIL_REVERSE_START]), NUM_TAIL_REVERSE, lights & REVERSE ? COLOR_REVERSE : lights & BRAKELIGHT ? COLOR_BRAKELIGHT : COLOR_TAILLIGHT); } else { fill_solid(&(l_leds[0]), NUM_LEDS, CRGB::Black); fill_solid(&(r_leds[0]), NUM_LEDS, CRGB::Black); } if (numGame != NUM_GAME) { fill_solid(&(l_leds[GAME_START]), NUM_GAME, CRGB::Black); fill_solid(&(r_leds[GAME_START]), NUM_GAME, CRGB::Black); } fill_solid(&(l_leds[GAME_START]), numGame, gameColor * gameBrightness); fill_solid(&(r_leds[GAME_START]), numGame, gameColor * gameBrightness); APA102_write(l_strip, l_leds, NUM_LEDS); APA102_write(r_strip, r_leds, NUM_LEDS); wait(0); } }