Simple implementation of goal counter for table football using laser diode and phototransistor.
Dependencies: GoalCounter WS2812 PixelArray
main.cpp@6:a93ee22232f2, 2019-01-14 (annotated)
- Committer:
- nxf46245
- Date:
- Mon Jan 14 17:48:30 2019 +0000
- Revision:
- 6:a93ee22232f2
- Parent:
- 5:95cb2348af01
Code cleaning, added winner animation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nxf46245 | 0:24f846b68c77 | 1 | #include "mbed.h" |
nxf46245 | 0:24f846b68c77 | 2 | #include "WS2812.h" |
nxf46245 | 0:24f846b68c77 | 3 | #include "PixelArray.h" |
nxf46245 | 0:24f846b68c77 | 4 | #include "GoalCounter.h" |
nxf46245 | 0:24f846b68c77 | 5 | |
nxf46245 | 6:a93ee22232f2 | 6 | #define WS2812_BUF 10 |
nxf46245 | 6:a93ee22232f2 | 7 | #define NUM_COLORS 6 |
nxf46245 | 0:24f846b68c77 | 8 | #define NUM_LEDS_PER_COLOR 2 |
nxf46245 | 6:a93ee22232f2 | 9 | #define COLOR 0x2f2020 |
nxf46245 | 0:24f846b68c77 | 10 | |
nxf46245 | 6:a93ee22232f2 | 11 | //Initialize instances of Timers for goal counters |
nxf46245 | 4:5a11a84fac69 | 12 | Timer timer1; |
nxf46245 | 5:95cb2348af01 | 13 | Timer timer2; |
nxf46245 | 3:d74c47d2e933 | 14 | |
nxf46245 | 6:a93ee22232f2 | 15 | // Initialize instace of a pixel array for LED strip 1 and 2 |
nxf46245 | 1:ffac56d434b3 | 16 | PixelArray px1(WS2812_BUF); |
nxf46245 | 5:95cb2348af01 | 17 | PixelArray px2(WS2812_BUF); |
nxf46245 | 0:24f846b68c77 | 18 | |
nxf46245 | 1:ffac56d434b3 | 19 | // The given numbers are calculated for the K64F MCU |
nxf46245 | 1:ffac56d434b3 | 20 | WS2812 ws1(D4, WS2812_BUF, 0, 5, 5, 0); |
nxf46245 | 5:95cb2348af01 | 21 | WS2812 ws2(D5, WS2812_BUF, 0, 5, 5, 0); |
nxf46245 | 0:24f846b68c77 | 22 | |
nxf46245 | 6:a93ee22232f2 | 23 | // For printing information to serial console |
nxf46245 | 4:5a11a84fac69 | 24 | Serial pc(USBTX, USBRX); |
nxf46245 | 3:d74c47d2e933 | 25 | |
nxf46245 | 6:a93ee22232f2 | 26 | GoalCounter gc1(D2, &timer1); |
nxf46245 | 5:95cb2348af01 | 27 | GoalCounter gc2(D3, &timer2); |
nxf46245 | 1:ffac56d434b3 | 28 | |
nxf46245 | 2:f04959a6fd61 | 29 | float balltime1 = 0; |
nxf46245 | 2:f04959a6fd61 | 30 | float speed1 = 0; |
nxf46245 | 1:ffac56d434b3 | 31 | |
nxf46245 | 2:f04959a6fd61 | 32 | float balltime2 = 0; |
nxf46245 | 2:f04959a6fd61 | 33 | float speed2 = 0; |
nxf46245 | 2:f04959a6fd61 | 34 | |
nxf46245 | 2:f04959a6fd61 | 35 | uint8_t score1 = 0; |
nxf46245 | 2:f04959a6fd61 | 36 | uint8_t score2 = 0; |
nxf46245 | 1:ffac56d434b3 | 37 | |
nxf46245 | 6:a93ee22232f2 | 38 | // This function sets 1 - 10 to ws2812 led strip |
nxf46245 | 4:5a11a84fac69 | 39 | void set_score(uint8_t score, PixelArray * px, WS2812 * ws) { |
nxf46245 | 6:a93ee22232f2 | 40 | px->SetAll(0); // null pixel array |
nxf46245 | 4:5a11a84fac69 | 41 | |
nxf46245 | 1:ffac56d434b3 | 42 | for (int i=0; i < score; i++) { |
nxf46245 | 6:a93ee22232f2 | 43 | px->Set(i, COLOR); // set pixels to correspondig score |
nxf46245 | 1:ffac56d434b3 | 44 | } |
nxf46245 | 1:ffac56d434b3 | 45 | |
nxf46245 | 6:a93ee22232f2 | 46 | px->SetAllI(0x0f); // set intensity |
nxf46245 | 6:a93ee22232f2 | 47 | ws->write(px->getBuf()); // write buffer to the led strip |
nxf46245 | 0:24f846b68c77 | 48 | } |
nxf46245 | 1:ffac56d434b3 | 49 | |
nxf46245 | 2:f04959a6fd61 | 50 | void print_score(uint8_t score, float balltime, float speed) { |
nxf46245 | 2:f04959a6fd61 | 51 | pc.printf("Score : %d \n\r", score); |
nxf46245 | 2:f04959a6fd61 | 52 | pc.printf("Time of ball pass : %f seconds\n\r", balltime); |
nxf46245 | 2:f04959a6fd61 | 53 | pc.printf("Speed of ball (34 mm diameter) : %f kph\n\r", speed); |
nxf46245 | 2:f04959a6fd61 | 54 | } |
nxf46245 | 2:f04959a6fd61 | 55 | |
nxf46245 | 6:a93ee22232f2 | 56 | // get information about score, balltime and speed from the GoalCounter |
nxf46245 | 4:5a11a84fac69 | 57 | void get_info(uint8_t * score, float * balltime, float * speed, GoalCounter * gc) { |
nxf46245 | 4:5a11a84fac69 | 58 | *score = gc->get_score(); |
nxf46245 | 4:5a11a84fac69 | 59 | *balltime = gc->get_balltime(); |
nxf46245 | 4:5a11a84fac69 | 60 | *speed = gc->get_ballspeed(); |
nxf46245 | 2:f04959a6fd61 | 61 | } |
nxf46245 | 0:24f846b68c77 | 62 | |
nxf46245 | 6:a93ee22232f2 | 63 | // Play animation for the winner, use pixel array 1, target strip passed as pointer |
nxf46245 | 6:a93ee22232f2 | 64 | void winner_animation(WS2812 * ws) { |
nxf46245 | 6:a93ee22232f2 | 65 | // This function is modified and taken from the Brian Daniels WS2812 example |
nxf46245 | 6:a93ee22232f2 | 66 | // set up the colours we want to draw with |
nxf46245 | 6:a93ee22232f2 | 67 | int colorbuf[NUM_COLORS] = {0x2f0000,0x2f2f00,0x002f00,0x002f2f,0x00002f,0x2f002f}; |
nxf46245 | 6:a93ee22232f2 | 68 | |
nxf46245 | 6:a93ee22232f2 | 69 | // for each of the colours (j) write out 10 of them |
nxf46245 | 6:a93ee22232f2 | 70 | // the pixels are written at the colour*10, plus the colour position |
nxf46245 | 6:a93ee22232f2 | 71 | // all modulus 60 so it wraps around |
nxf46245 | 6:a93ee22232f2 | 72 | for (int i = 0; i < WS2812_BUF; i++) { |
nxf46245 | 6:a93ee22232f2 | 73 | px1.Set(i, colorbuf[(i / NUM_LEDS_PER_COLOR) % NUM_COLORS]); |
nxf46245 | 6:a93ee22232f2 | 74 | } |
nxf46245 | 6:a93ee22232f2 | 75 | |
nxf46245 | 6:a93ee22232f2 | 76 | // now all the colours are computed, add a fade effect using intensity scaling |
nxf46245 | 6:a93ee22232f2 | 77 | // compute and write the II value for each pixel |
nxf46245 | 6:a93ee22232f2 | 78 | for (int j=0; j<WS2812_BUF; j++) { |
nxf46245 | 6:a93ee22232f2 | 79 | // px.SetI(pixel position, II value) |
nxf46245 | 6:a93ee22232f2 | 80 | px1.SetI(j%WS2812_BUF, 0xf+(0xf*(j%NUM_LEDS_PER_COLOR))); |
nxf46245 | 6:a93ee22232f2 | 81 | } |
nxf46245 | 6:a93ee22232f2 | 82 | |
nxf46245 | 6:a93ee22232f2 | 83 | |
nxf46245 | 6:a93ee22232f2 | 84 | // Now the buffer is written, rotate it |
nxf46245 | 6:a93ee22232f2 | 85 | // by writing it out with an increasing offset |
nxf46245 | 6:a93ee22232f2 | 86 | // |
nxf46245 | 6:a93ee22232f2 | 87 | for (int i=0; i < 1000 ; i++) { |
nxf46245 | 6:a93ee22232f2 | 88 | for (int z=WS2812_BUF; z >= 0 ; z--) { |
nxf46245 | 6:a93ee22232f2 | 89 | ws->write_offsets(px1.getBuf(),z,z,z); |
nxf46245 | 6:a93ee22232f2 | 90 | wait(0.075); |
nxf46245 | 6:a93ee22232f2 | 91 | } |
nxf46245 | 6:a93ee22232f2 | 92 | } |
nxf46245 | 6:a93ee22232f2 | 93 | |
nxf46245 | 6:a93ee22232f2 | 94 | } |
nxf46245 | 4:5a11a84fac69 | 95 | |
nxf46245 | 0:24f846b68c77 | 96 | int main() |
nxf46245 | 0:24f846b68c77 | 97 | { |
nxf46245 | 6:a93ee22232f2 | 98 | // use global intensity scaling |
nxf46245 | 6:a93ee22232f2 | 99 | ws1.useII(WS2812::GLOBAL); |
nxf46245 | 6:a93ee22232f2 | 100 | ws2.useII(WS2812::GLOBAL); |
nxf46245 | 6:a93ee22232f2 | 101 | |
nxf46245 | 6:a93ee22232f2 | 102 | pc.printf("Initialization of the game... \n\r"); |
nxf46245 | 1:ffac56d434b3 | 103 | |
nxf46245 | 0:24f846b68c77 | 104 | while(1) { |
nxf46245 | 6:a93ee22232f2 | 105 | // polling - checking if goal was detected |
nxf46245 | 6:a93ee22232f2 | 106 | if (gc1.is_goal == 1) { |
nxf46245 | 6:a93ee22232f2 | 107 | get_info(&score1, &balltime1, &speed1, &gc1); |
nxf46245 | 4:5a11a84fac69 | 108 | set_score(score1, &px1, &ws1); |
nxf46245 | 6:a93ee22232f2 | 109 | pc.printf("Side 1 score \n\r"); |
nxf46245 | 4:5a11a84fac69 | 110 | print_score(score1, balltime1, speed1); |
nxf46245 | 6:a93ee22232f2 | 111 | gc1.is_goal = 0; |
nxf46245 | 2:f04959a6fd61 | 112 | } |
nxf46245 | 5:95cb2348af01 | 113 | else if (gc2.is_goal == 1) { |
nxf46245 | 5:95cb2348af01 | 114 | get_info(&score2, &balltime2, &speed2, &gc2); |
nxf46245 | 5:95cb2348af01 | 115 | set_score(score2, &px2, &ws2); |
nxf46245 | 6:a93ee22232f2 | 116 | pc.printf("Side 2 score \n\r"); |
nxf46245 | 5:95cb2348af01 | 117 | print_score(score2, balltime2, speed2); |
nxf46245 | 5:95cb2348af01 | 118 | gc2.is_goal = 0; |
nxf46245 | 5:95cb2348af01 | 119 | } |
nxf46245 | 6:a93ee22232f2 | 120 | // when game is over, print game replay and winning animation |
nxf46245 | 6:a93ee22232f2 | 121 | if (score1 >= 10 || score2 >= 10) { |
nxf46245 | 4:5a11a84fac69 | 122 | pc.printf("Game over \n\r"); |
nxf46245 | 6:a93ee22232f2 | 123 | pc.printf(((score1 > score2) ? "Team 1 is winner" : "Team 2 is winner")); |
nxf46245 | 6:a93ee22232f2 | 124 | |
nxf46245 | 6:a93ee22232f2 | 125 | pc.printf("\n Game score Team 1 : \n\r"); |
nxf46245 | 6:a93ee22232f2 | 126 | |
nxf46245 | 6:a93ee22232f2 | 127 | for (int i=1; i<= score1; i++) { |
nxf46245 | 6:a93ee22232f2 | 128 | balltime1 = gc1.get_balltime(i); |
nxf46245 | 6:a93ee22232f2 | 129 | speed1 = gc1.get_ballspeed(i); |
nxf46245 | 4:5a11a84fac69 | 130 | print_score(i, balltime1, speed1); |
nxf46245 | 4:5a11a84fac69 | 131 | } |
nxf46245 | 6:a93ee22232f2 | 132 | |
nxf46245 | 6:a93ee22232f2 | 133 | pc.printf("Game score Team 2 : \n\r"); |
nxf46245 | 6:a93ee22232f2 | 134 | |
nxf46245 | 6:a93ee22232f2 | 135 | for (int i=1; i<= score2; i++) { |
nxf46245 | 6:a93ee22232f2 | 136 | balltime2 = gc2.get_balltime(i); |
nxf46245 | 6:a93ee22232f2 | 137 | speed2 = gc2.get_ballspeed(i); |
nxf46245 | 6:a93ee22232f2 | 138 | print_score(i, balltime2, speed2); |
nxf46245 | 6:a93ee22232f2 | 139 | } |
nxf46245 | 6:a93ee22232f2 | 140 | |
nxf46245 | 6:a93ee22232f2 | 141 | // play winner animation on winning team's LED strip |
nxf46245 | 6:a93ee22232f2 | 142 | winner_animation(((score1 > score2) ? &ws1 : &ws2)); |
nxf46245 | 6:a93ee22232f2 | 143 | |
nxf46245 | 4:5a11a84fac69 | 144 | return 0; |
nxf46245 | 4:5a11a84fac69 | 145 | } |
nxf46245 | 4:5a11a84fac69 | 146 | |
nxf46245 | 0:24f846b68c77 | 147 | } |
nxf46245 | 0:24f846b68c77 | 148 | } |