diff --git a/3D Model/Thumbs.db b/3D Model/Thumbs.db new file mode 100644 index 0000000..5b01689 Binary files /dev/null and b/3D Model/Thumbs.db differ diff --git a/Documents/MATERIALS PRICING LIST.xlsx b/Documents/MATERIALS PRICING LIST.xlsx new file mode 100644 index 0000000..10d6510 Binary files /dev/null and b/Documents/MATERIALS PRICING LIST.xlsx differ diff --git a/Documents/Presentation.pptx b/Documents/Presentation.pptx new file mode 100644 index 0000000..6ad68c9 Binary files /dev/null and b/Documents/Presentation.pptx differ diff --git a/Documents/pcba quotation.pdf b/Documents/pcba quotation.pdf new file mode 100644 index 0000000..b087d08 Binary files /dev/null and b/Documents/pcba quotation.pdf differ diff --git a/firmware/KICKER_V1/KICKER_V1.ino b/Firmware Code/kicker/KICKER_V1.ino similarity index 83% rename from firmware/KICKER_V1/KICKER_V1.ino rename to Firmware Code/kicker/KICKER_V1.ino index 4ffcd15..c9d4052 100644 --- a/firmware/KICKER_V1/KICKER_V1.ino +++ b/Firmware Code/kicker/KICKER_V1.ino @@ -10,8 +10,8 @@ //====================================================== // HARDWARE SETUP & SELECTION //====================================================== -// Arduino Uno Or Nano Was The Hardware - #ifdef ARDUINO_AVR_UNO || ARDUINO_AVR_NANO + // Arduino MEGA + #ifdef ARDUINO_AVR_MEGA2560 //------------------------------------------------------ // Library Nessesary @@ -19,7 +19,41 @@ #include #endif - /* ARDUINO NANO DOESNOT HAVE A SECOND NATIVE + // Serial Terminal + #define Terminal Serial // SERIAL PORT USED AS TERMINAL WINDO FOR DEBUG + #define isTerminal Terminal.available() // Terminal Serial Buffer Available + #define flushTerminal while(isTerminal) { Terminal.read(); } + + // Bluetooth Terminal + #define Bluetooth Serial1 // We will Connect The HC-05 To Hardware Serial1 In Arduino Mega + #define isBluetooth Bluetooth.available() // Bluetooth Serial Buffer Available + #define flushBluetooth while(isBluetooth) { Bluetooth.read(); } + + // JSON Object & Memory + #define CAPACITY 100 + DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer + + // LED Strip + #define LED_STRIP 53 // LED STRIP PIN NUMBER + #define NUM_PIXELS 14 // NUMBER OF LED'S IN NEO PIXEL STRIP + Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, LED_STRIP, NEO_GRB + NEO_KHZ800); + + // Impact Detection + #define VTH 14 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR + #define SENSOR_PIN A0 // IMPACT SENSOR + #define RANDOM_SOURCE A7 // RANDOM NUMBER GENERATOR SOURCE + +//------------------------------------------------------ + // Arduino Uno / Nano + #elif ARDUINO_AVR_UNO || ARDUINO_AVR_NANO +//------------------------------------------------------ + + // Library Nessesary + #ifdef __AVR__ + #include + #endif + + /* ARDUINO NANO DOESNOT HAVE A SECOND NATIVE SERIAL PORT SO WE USE SOFTWARE SERIAL LIBRARY */ #include @@ -67,7 +101,7 @@ * SPI PIN : CS 5, SCK 18, MISO 19, MOSI 23 (DIGITAL) * BOOST CONTROL PIN : 14 (DIGITAL) OUTPUT ON PADS (TP1 +5V, TP2 GND) * LED PIN : 13 (DIGITAL) - * BATTERY MONITOR PIN : 35 (ANALOG) + * BATTERY MONITOR PIN : 35 (ANALOG) */ /* ESP32 HAVE A NATIVE BLUETOOTH MODULE @@ -102,7 +136,7 @@ #define VTH 14 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR #define SENSOR_PIN 39 // IMPACT SENSOR #define RANDOM_SOURCE 34 // RANDOM NUMBER GENERATOR SOURCE - + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Exclusive Features Of TAKEONE BOARD //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -110,7 +144,7 @@ /* ESP32 TAKEONE Board has some unique hardware features * 1. Battery Voltage Level Monitoring Via Analog Pin 35 * 2. Boost Converter In Case We Need 5V Supply From Li-Ion Battery - * 3. I2C : Motion Sensor IMU/MPU9250 9 Degrees Of Fredom + * 3. I2C : Motion Sensor IMU/MPU9250 9 Degrees Of Fredom * 4. SPI : SDCARD Reader */ // Boost Converter @@ -171,7 +205,7 @@ //====================================================== // READING THE IMPACT - int readImpact() + int readImpact() { int value = analogRead(SENSOR_PIN); return value; @@ -181,7 +215,7 @@ // MAIN HARDWARE SETUP //====================================================== - void setup() + void setup() { // Communications Terminal.begin(9600); @@ -217,10 +251,10 @@ // MAIN PROGRAM LOOP //====================================================== - void loop() + void loop() { // Reading From Bluetooth - if(isBluetooth) + if(isBluetooth) { // Reading Message From Bluetooth String msg = Bluetooth.readStringUntil('\n'); @@ -229,7 +263,7 @@ // Display On Serial Monitor For Debuging terminal(msg); - + // Deserialize the JSON document DeserializationError error = deserializeJson(JSON, msg); @@ -245,7 +279,7 @@ // Clearing JSON Buffer JSON.clear(); - + // Entering To Game Selector game_selector(game, settings); } diff --git a/firmware/KICKER_V1/communication.ino b/Firmware Code/kicker/communication.ino similarity index 86% rename from firmware/KICKER_V1/communication.ino rename to Firmware Code/kicker/communication.ino index 5aea8e3..1d5a9e5 100644 --- a/firmware/KICKER_V1/communication.ino +++ b/Firmware Code/kicker/communication.ino @@ -2,17 +2,17 @@ // TERMINAL WINDOW - NATIVE USB //====================================================== - void terminal(String msg) + void terminal(String msg) { msg += "\n"; Terminal.print(msg); } - + //====================================================== // BLUETOOTH WINDOW - NATIVE/VERTUAL USB //====================================================== - void bluetooth(String msg) + void bluetooth(String msg) { msg += "\n"; Bluetooth.print(msg); @@ -22,7 +22,7 @@ // BLUETOOTH WINDOW - NATIVE/VERTUAL USB //====================================================== - void dualcomm(String msg) + void dualcomm(String msg) { terminal(msg); bluetooth(msg); diff --git a/firmware/KICKER_V1/game_counter.ino b/Firmware Code/kicker/game_counter.ino similarity index 100% rename from firmware/KICKER_V1/game_counter.ino rename to Firmware Code/kicker/game_counter.ino diff --git a/firmware/KICKER_V1/game_reaction.ino b/Firmware Code/kicker/game_reaction.ino similarity index 100% rename from firmware/KICKER_V1/game_reaction.ino rename to Firmware Code/kicker/game_reaction.ino diff --git a/firmware/KICKER_V1/game_selector.ino b/Firmware Code/kicker/game_selector.ino similarity index 88% rename from firmware/KICKER_V1/game_selector.ino rename to Firmware Code/kicker/game_selector.ino index 101df6c..5a9f5d4 100644 --- a/firmware/KICKER_V1/game_selector.ino +++ b/Firmware Code/kicker/game_selector.ino @@ -3,7 +3,7 @@ //====================================================== /* game selector is the main function that tell the game groutine - * which game to be JSONed and at what parameters + * which game to be JSONed and at what parameters */ void game_selector(String game, String settings) @@ -18,7 +18,7 @@ // Time Attack Game else if(game == "ta") { terminal(GM_TATTACK); - time_attack_bluetooth(settings); + game_reaction_bluetooth(settings); return; } diff --git a/firmware/KICKER_V1/game_time_attack.ino b/Firmware Code/kicker/game_time_attack.ino similarity index 95% rename from firmware/KICKER_V1/game_time_attack.ino rename to Firmware Code/kicker/game_time_attack.ino index ec47241..606a917 100644 --- a/firmware/KICKER_V1/game_time_attack.ino +++ b/Firmware Code/kicker/game_time_attack.ino @@ -2,17 +2,17 @@ // TIME ATTACK GAME MAIN ROUTINE //====================================================== - /* This Game Can Be Called From + /* This Game Can Be Called From * Stand Alone Mode / Bluetooth Connection * The primary mode is the standalone but * if the bluetooth is connected it has the priority * so it will take over the control of the device - * + * * If you want to control the game via bluetooth * you need to call : time_attack_bluetooth(JSON String) * If you want to use the stand alone mode * you need to call : time_attack_standalone() - * + * * the game returns a float point number which is * in seconds. so the athlete know how long he takes to react */ @@ -24,11 +24,11 @@ void time_attack_standalone() { // Variables - uint16_t time = 0; - uint16_t timer = 0; - uint16_t limit = 0; + uint16_t time = 0; + uint16_t timer = 0; + uint16_t limit = 0; bool limitEnable = 0; - + // Display Screen Menu And Button Actions // If The Menu Number 1 -> We Set The Value Of Min Delay // If The Menu Number 2 -> We Set The Value Of Max Delay @@ -44,7 +44,7 @@ /* TIME ATTACK GAME SETTINGS PARAMETERS NOTE: * ------------------------------------------ - * + * * FORMAT : * -------- * {"tm": 10, "le": false, "lm": 10} @@ -52,22 +52,22 @@ * tm : count down timer starting value * le : stands for limit enable, if is TRUE the game end if target value is meet * lm : targeted amount of kicks - * + * * THINGS THAT ENDS THE GAME : * --------------------------- * 1. BY COUNT DOWN "tm" REACH TO ZERO * 2. BY A COMMAND "FROM APP VIA BLUETOOTH" * 3. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE" - * + * * CALCULATING RESULTS : * --------------------- * Rapid Kick Speed = Number Of Kickes Made / Elasped Time In Sec * Delay Between Kicks = Time Of Current Kick - Time Of Last Kick - * + * * RETURNNING JSON FORMAT : * ------------------------ * {"tm" : 82, "ct" : 10, "dl" : 1234, "st" : 585} - * + * * tm : timer count in Sec * ct : strike counter (number of kicks) * dl : delay between strikes @@ -75,7 +75,7 @@ */ void time_attack_bluetooth(String settings) - { + { // Deserialize the JSON document DeserializationError error = deserializeJson(JSON, settings); // the main JSON body container @@ -102,7 +102,7 @@ // Play Time Atack Game //====================================================== - void game_timeAttack(uint16_t time, uint16_t timer, uint16_t limit, bool limitEnable) + void game_timeAttack(uint16_t time, uint16_t timer, uint16_t limit, bool limitEnable) { // Building Timers 1000mSec -> 1Sec TimeTrigger sec_tick(1000); @@ -122,7 +122,7 @@ // staring Of time stamp unsigned long startStamp = millis(); - + // store the time of the previous kick unsigned long lastStamp = 0; @@ -141,7 +141,7 @@ String msg = Bluetooth.readStringUntil('\n'); flushBluetooth; msg.trim(); - if(msg == CM_STOP) + if(msg == CM_STOP) { dualcomm(GAME_OVER); // Grean Light In @@ -161,9 +161,8 @@ LED_SIGNAL_RESET(); } } - + // Every Kick ---------------------------->>> - if(readImpact() > VTH) { counter++; @@ -173,13 +172,12 @@ } // Every Second ---------------------------->>> - if(sec_tick.Trigger()) { timer--; dualcomm(timeAttack_JSON_json(timer, counter, 0, 0)); } - + // If Limits Are Enabled And Meet if(limitEnable == true && counter == limit) { @@ -207,25 +205,25 @@ //====================================================== String timeAttack_JSON_json(unsigned int RunningTime, unsigned int KickCount, unsigned int LastStamp, unsigned int TimeStamp) - { + { // Building The Buffer JSON["tm"] = RunningTime; JSON["ct"] = KickCount; // Calculations - if(TimeStamp > 0) + if(TimeStamp > 0) { // Calculate Time Stamp In Seconds float st = TimeStamp; st /= 1000; JSON["st"] = String(st, 3).toFloat(); - + // Calculate Strike Delay In Seconds float dl = TimeStamp - LastStamp; dl /= 1000; JSON["dl"] = String(dl, 3).toFloat(); } - + String output; serializeJson(JSON, output); JSON.clear(); diff --git a/firmware/KICKER_V1/neo_pixel.ino b/Firmware Code/kicker/neo_pixel.ino similarity index 100% rename from firmware/KICKER_V1/neo_pixel.ino rename to Firmware Code/kicker/neo_pixel.ino diff --git a/firmware/TOBOARD/FUNCTIONS.ino b/Firmware Code/takeone_board/FUNCTIONS.ino similarity index 100% rename from firmware/TOBOARD/FUNCTIONS.ino rename to Firmware Code/takeone_board/FUNCTIONS.ino diff --git a/firmware/TOBOARD/G_COUNTER.ino b/Firmware Code/takeone_board/G_COUNTER.ino similarity index 100% rename from firmware/TOBOARD/G_COUNTER.ino rename to Firmware Code/takeone_board/G_COUNTER.ino diff --git a/firmware/TOBOARD/G_DECISION.ino b/Firmware Code/takeone_board/G_DECISION.ino similarity index 100% rename from firmware/TOBOARD/G_DECISION.ino rename to Firmware Code/takeone_board/G_DECISION.ino diff --git a/firmware/TOBOARD/G_FOCUSE.ino b/Firmware Code/takeone_board/G_FOCUSE.ino similarity index 100% rename from firmware/TOBOARD/G_FOCUSE.ino rename to Firmware Code/takeone_board/G_FOCUSE.ino diff --git a/firmware/TOBOARD/G_REACTION.ino b/Firmware Code/takeone_board/G_REACTION.ino similarity index 100% rename from firmware/TOBOARD/G_REACTION.ino rename to Firmware Code/takeone_board/G_REACTION.ino diff --git a/firmware/TOBOARD/G_STAMINA.ino b/Firmware Code/takeone_board/G_STAMINA.ino similarity index 100% rename from firmware/TOBOARD/G_STAMINA.ino rename to Firmware Code/takeone_board/G_STAMINA.ino diff --git a/firmware/TOBOARD/G_TIMEATTACK.ino b/Firmware Code/takeone_board/G_TIMEATTACK.ino similarity index 100% rename from firmware/TOBOARD/G_TIMEATTACK.ino rename to Firmware Code/takeone_board/G_TIMEATTACK.ino diff --git a/firmware/TOBOARD/MENU.ino b/Firmware Code/takeone_board/MENU.ino similarity index 100% rename from firmware/TOBOARD/MENU.ino rename to Firmware Code/takeone_board/MENU.ino diff --git a/firmware/TOBOARD/NEOPIXEL.ino b/Firmware Code/takeone_board/NEOPIXEL.ino similarity index 100% rename from firmware/TOBOARD/NEOPIXEL.ino rename to Firmware Code/takeone_board/NEOPIXEL.ino diff --git a/firmware/TOBOARD/OLED.ino b/Firmware Code/takeone_board/OLED.ino similarity index 100% rename from firmware/TOBOARD/OLED.ino rename to Firmware Code/takeone_board/OLED.ino diff --git a/firmware/TOBOARD/SDCARD.ino b/Firmware Code/takeone_board/SDCARD.ino similarity index 100% rename from firmware/TOBOARD/SDCARD.ino rename to Firmware Code/takeone_board/SDCARD.ino diff --git a/firmware/TOBOARD/TOBOARD.ino b/Firmware Code/takeone_board/takeone_board.ino similarity index 99% rename from firmware/TOBOARD/TOBOARD.ino rename to Firmware Code/takeone_board/takeone_board.ino index 06f234b..b719c6b 100644 --- a/firmware/TOBOARD/TOBOARD.ino +++ b/Firmware Code/takeone_board/takeone_board.ino @@ -9,7 +9,6 @@ * NEOPIXEL LED STRIP : A0/GPIO 26 * PIEZO SENSOR : A2/GPIO 34 - ANALOG ONLY INPUT * RANDOM SEED : A3/GPIO 39 - ANALOG ONLY INPUT - * https://www.aliexpress.com/item/32813561581.html?spm=a2g0s.9042311.0.0.48644c4dfH5L8o * BUTTONS : TLB (35), BLB (15), CB (33), BRB (27), TRB(12) * I2C PIN : SDA 21, SCL 22 (DIGITAL) * SPI PIN : CS 5, SCK 18, MISO 19, MOSI 23 (DIGITAL) diff --git a/Pictures/Thumbs.db b/Pictures/Thumbs.db new file mode 100644 index 0000000..7b21df0 Binary files /dev/null and b/Pictures/Thumbs.db differ diff --git a/Pictures/components/Thumbs.db b/Pictures/components/Thumbs.db new file mode 100644 index 0000000..b700e34 Binary files /dev/null and b/Pictures/components/Thumbs.db differ diff --git a/Pictures/contributers/Thumbs.db b/Pictures/contributers/Thumbs.db new file mode 100644 index 0000000..0716151 Binary files /dev/null and b/Pictures/contributers/Thumbs.db differ diff --git a/Pictures/the-app/Thumbs.db b/Pictures/the-app/Thumbs.db new file mode 100644 index 0000000..57c778a Binary files /dev/null and b/Pictures/the-app/Thumbs.db differ diff --git a/Pictures/v2/Thumbs.db b/Pictures/v2/Thumbs.db new file mode 100644 index 0000000..3463ca6 Binary files /dev/null and b/Pictures/v2/Thumbs.db differ diff --git a/firmware/KICKER_V2/COMM.ino b/firmware/KICKER_V2/COMM.ino deleted file mode 100644 index ed0e1e9..0000000 --- a/firmware/KICKER_V2/COMM.ino +++ /dev/null @@ -1,40 +0,0 @@ -//====================================================== -// COMMUNICATION PORTS FUNCTIONS -//====================================================== -// TERMINAL WINDOW - NATIVE USB -//------------------------------------------------------ - void terminal(String msg) - { - msg += "\n"; - Terminal.print(msg); - } -//------------------------------------------------------ -// BLUETOOTH WINDOW - NATIVE -//------------------------------------------------------ - void bluetooth(String msg) - { - msg += "\n"; - Bluetooth.print(msg); - } -//------------------------------------------------------ -// BLUETOOTH CONNECTION STATUS -//------------------------------------------------------ - void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) - { - if(event == ESP_SPP_SRV_OPEN_EVT) { - BLUETOOTH_STATUS = true; - terminal(BLUETOOTH_CONNECTED); - } - if(event == ESP_SPP_CLOSE_EVT ) { - BLUETOOTH_STATUS = false; - terminal(STAND_ALONE_MODE); - } - } -//------------------------------------------------------ -// TERMINAL & BLUETOOTH WINDOW - NATIVE -//------------------------------------------------------ - void dualcomm(String msg) - { - terminal(msg); - bluetooth(msg); - } diff --git a/firmware/KICKER_V2/FUNC.ino b/firmware/KICKER_V2/FUNC.ino deleted file mode 100644 index e93fb8d..0000000 --- a/firmware/KICKER_V2/FUNC.ino +++ /dev/null @@ -1,22 +0,0 @@ -//====================================================== -// THIS PAGE IS FOR GENERAL FUNCTIONS AND METHODES -//====================================================== -// Floting Point Mapping -//------------------------------------------------------ - double mapf(double val, double in_min, double in_max, double out_min, double out_max) { - return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; - } -//------------------------------------------------------ -// MONITOR THE CENTER BUTTON RELEASE STATE -//------------------------------------------------------ - void DETECT_LONG_PRESS() { - // Resetting The Timer For Long Press - POWER_PRESS.Reset(); - - // Loop If the Person Didnt Release The Button - while(!BTN_CENTER.released()) { - if(POWER_PRESS.Trigger()) { - OLED_POWERING_DOWN(); - } - } - } diff --git a/firmware/KICKER_V2/GCNT.ino b/firmware/KICKER_V2/GCNT.ino deleted file mode 100644 index 71dd5cf..0000000 --- a/firmware/KICKER_V2/GCNT.ino +++ /dev/null @@ -1,264 +0,0 @@ -//====================================================== -// MAIN COUNTER GAME LOOP -//====================================================== - - /* This Game Can Be Called From - * Stand Alone Mode / Bluetooth Connection - * The primary mode is the standalone but - * if the bluetooth is connected it has the priority - * so it will take over the control of the device - * - * If you want to control the game via bluetooth - * you need to call : game_counter_bluetooth(JSON String) - * If you want to use the stand alone mode - * you need to call : game_counter_standalone() - * - * the game returns a float point number which is - * in seconds. so the athlete know how long he takes to react - */ - -//====================================================== -// THIS IS THE STAND ALONE CALL FOR THE GAME -//====================================================== - - void game_counter_standalone() - { - // Variables Of The Game - uint16_t limit = 10; - bool limitEnable = true; - - // Play The Game - game_counter(limit, limitEnable); - - // Give Permision To Change Display - DISPLAY_CHANGED = false; - } - -//====================================================== -// THIS IS THE BLUETOOTH CALL FOR THE GAME -//====================================================== - - /* COUNTER GAME SETTINGS PARAMETERS NOTE: - * -------------------------------------- - * - * FORMAT : - * -------- - * {"le": false, "lm": 10} - * - * MEANNING : - * ---------- - * ct : count - * le : stands for limit enable, if is TRUE the game end if target value is meet - * lm : targeted amount of kicks - * - * THINGS THAT ENDS THE GAME : - * --------------------------- - * 1. BY A COMMAND "FROM APP VIA BLUETOOTH" - * 2. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE" - * - * WHAT JSON TO BE COLLECTED : - * --------------------------- - * 1. FOR EVERY KICK YOU RECEIVE THE COUNTER DISJSON AND TIMESTAMP - * WE NEED TO COLLECT TIMESTAMPS AS AN ARRAY IN JSON FORMAT - * - * CALCULATING RESULTS : - * --------------------- - * No calculation required, Its directly the count - */ - - void game_counter_bluetooth(String settings) - { - //------------------------------------------------------ - // START OF READING THE SETTINGS - //------------------------------------------------------ - - // Deserialize the JSON document - DeserializationError error = deserializeJson(JSON, settings); // the main JSON body container - - // JSON ERROR - if(error) { - dualcomm(JSON_ERROR); - return; - } - - // PUBLIC VARIABLES - uint16_t limit = JSON["lm"]; // Kick Target Limit - bool limitEnable = JSON["le"]; // Enable Kick Target Limit - - // Clearing Buffer - JSON.clear(); - - // Play The Game - game_counter(limit, limitEnable); - - // Give Permision To Change Display - DISPLAY_CHANGED = false; - } - -//====================================================== -// COUNTER JSON JSON -> To Send Back To Server -//====================================================== - - void game_counter(uint16_t limit, bool limitEnable) - { - // Kick Counter - uint16_t counter = 0; - - // Game Start Lights - //LED_SIGNAL_START(); - - // Display On OLED - GAME_COUNTER_DISPLAY(0, limit); - - //------------------------- - // PREPARE FOR GAME START - //------------------------- - - // staring Of time stamp - unsigned long startStamp = millis(); - - while(1) - { - // Time Stamp - unsigned long timeStamp = millis() - startStamp; - - // If Stop Command Came From Smart Phone - if(isBluetooth) - { - String msg = Bluetooth.readStringUntil('\n'); - flushBluetooth; - msg.trim(); - if(msg == CM_STOP) - { - dualcomm(GAME_OVER); - // Grean Light In - //LED_SIGNAL_END(); - // RESET - return; - } - else if(msg == CM_RESET) - { - // Counter Reset To Zero - counter = 0; - - // Starting Stamp From Now - startStamp = millis(); - - // Time Stamp Is Now - timeStamp = startStamp; - - // LED STRIP LED STRIP RESET SIGNAL - //LED_SIGNAL_RESET(); - } - } - - // Reset The Counter - if(BTN_INCREASE.pressed()) { - counter = 0; - startStamp = millis(); - timeStamp = startStamp; - GAME_COUNTER_DISPLAY(counter, limit); - } - - // Will Exit The Game - if(BTN_CENTER.pressed()) { - // Send Game Over JSON Signal - dualcomm(GAME_OVER); - - // Give Permition To Change OLED - DISPLAY_CHANGED = false; - - // Return To Main Menu - return; - } - - // If Limits Are Enabled And Meet - if(limitEnable == true && counter == limit) { - // END GAME - dualcomm(GAME_OVER); - - // Celebration - //LED_SIGNAL_CELEBRATION(); - - // Display On OLED - GAME_RESULT_DISPLAY(counter, limit); - - // RESET - return; - } - - // Read Impact - if(PIEZO_MAP >= VTH) - { - counter++; - GAME_COUNTER_DISPLAY(counter, limit); - dualcomm(counter_JSON_json(counter, timeStamp)); - delay(100); - } - } - } - -//====================================================== -// COUNTER JSON -> To Send Back To Mobile -//====================================================== - - String counter_JSON_json(unsigned int ct, unsigned int st) - { - // Convert Int To Float - float stamp = st; - stamp /= 1000; - - // Assignning JSONset - JSON["ct"] = ct; - JSON["st"] = String(stamp, 3).toFloat(); - - String output; - serializeJson(JSON, output); - JSON.clear(); - return output; - } - -//------------------------------------------------------ -// OLED - GAME COUNTER PLAY -//------------------------------------------------------ - - void GAME_COUNTER_DISPLAY(uint16_t count, uint16_t limit) - { - OLED_CLEAR(); - drawTextCenter(128/2, 0, 2, "KICKS"); - drawTextCenter(128/2, 20, 3, String(count) + "/" + String(limit)); - - // Exit Button Command Only Via Stand Alone Mode - if(BLUETOOTH_STATUS == false) { - drawTextCenter(128/2, 50, 1, "<< EXIT >>"); - } - - OLED_SHOW(); - } - -//------------------------------------------------------ -// OLED - GAME COUNTER RESULT -//------------------------------------------------------ - - void GAME_RESULT_DISPLAY(uint16_t count, uint16_t limit) - { - OLED_CLEAR(); - drawTextCenter(128/2, 0, 2, "FINISHED"); - drawTextCenter(128/2, 20, 3, String(count) + "/" + String(limit)); - - // Exit Button Command Only Via Stand Alone Mode - if(BLUETOOTH_STATUS == false) { - drawTextCenter(128/2, 50, 1, "<< EXIT >>"); - } - - // Show Data On OLED - OLED_SHOW(); - - // Waiting For Center Button To Move On - while(1){ - if(BTN_CENTER.pressed()) { - break; - } - } - } - diff --git a/firmware/KICKER_V2/GREA.ino b/firmware/KICKER_V2/GREA.ino deleted file mode 100644 index 7aaf426..0000000 --- a/firmware/KICKER_V2/GREA.ino +++ /dev/null @@ -1,346 +0,0 @@ -//====================================================== -// REACTION GAME MAIN ROUTINE -//====================================================== - - /* This Game Can Be Called From - * Stand Alone Mode / Bluetooth Connection - * The primary mode is the standalone but - * if the bluetooth is connected it has the priority - * so it will take over the control of the device - * - * If you want to control the game via bluetooth - * you need to call : game_reaction_bluetooth(JSON String) - * If you want to use the stand alone mode - * you need to call : game_reaction_standalone() - * - * the game returns a float point number which is - * in seconds. so the athlete know how long he takes to react - */ - -//------------------------------------------------------ -// Request From Stand Alone Buttons -//------------------------------------------------------ - - void game_reaction_standalone() - { - // Variables - uint8_t minDelay = 1; - uint8_t maxDelay = 3; - uint8_t trials = 10; - - // Call the Game Play - play_reaction(minDelay, maxDelay, trials); - - // Give Permision To Change Display - DISPLAY_CHANGED = false; - } - -//------------------------------------------------------ -// Request From Bluetooth Via JSON -//------------------------------------------------------ - - /* REACTION GAME SETTINGS PARAMETERS NOTE: - * ------------------------------------------ - * - * FORMAT : - * -------- - * {"tr": 10, "mn": 1, "mx": 2} - * - * MEANNING : - * ---------- - * tr : trials pre counter - * mn : minimum delay, between trials - * mx : maximum delay, between trials - * - * THINGS THAT ENDS THE GAME : - * --------------------------- - * 1. BY COUNT DOWN "tr" REACH TO ZERO - * 2. BY A COMMAND "FROM APP VIA BLUETOOTH" - * - * CALCULATING RESULTS : - * --------------------- - * Rapid Kick Speed = Number Of Kickes Made / Elasped Time In Sec - */ - - void game_reaction_bluetooth(String settings) - { - //------------------------------------------------------ - // START OF READING THE SETTINGS - //------------------------------------------------------ - - // Deserialize the JSON document - DeserializationError error = deserializeJson(JSON, settings); - - // JSON ERROR - if(error) { - dualcomm(JSON_ERROR); - return; - } - - // PUBLIC VARIABLES - uint8_t minDelay = JSON["mn"]; - uint8_t maxDelay = JSON["mx"]; - uint16_t trials = JSON["lm"]; - - // Fix Random Error - maxDelay += 1; - - // Clearing Buffer - JSON.clear(); - - // Play The Game - play_reaction(minDelay, maxDelay, trials); - - // Give Permision To Change Display - DISPLAY_CHANGED = false; - } - -//------------------------------------------------------ -// Play The Game -//------------------------------------------------------ - - void play_reaction(uint8_t minDelay, uint8_t maxDelay, uint16_t trials) - { - // PUBLIC VARIABLES - double totalRes = 0.0; - - // Fix Random Error - maxDelay += 1; - - // Clearing Buffer - JSON.clear(); - - //------------------------------------------------------ - // PREPARE FOR GAME START - //------------------------------------------------------ - - // DisJSON Welcome Message - terminal(""); - terminal("trials : " + String(trials) + " Strikes"); - terminal("minDelay : " + String(minDelay) + " Seconds"); - terminal("maxDelay : " + String(maxDelay) + " Seconds"); - terminal("2 Seconds To Start Get Ready & Good Luck !!"); - terminal(""); - - // Main Variables - uint16_t sdelay = 0; - uint16_t power = 0; - uint16_t response = 0; - unsigned long startTime = 0; - unsigned long stopTime = 0; - - // Ready Signal - //LED_SIGNAL_REACTION_START(); - - // Display On OLED - GAME_REACTION_DISPLAY(0, 0); - - //------------------------- - // PREPARE FOR GAME START - //------------------------- - - // Processing Results - for(int i=0; i Get Ready !!"); - - // Set Random Delay Time - sdelay = random(minDelay, maxDelay); - sdelay *= 1000; - delay(sdelay); - - // Light Up Green - //LED_SET_COLOR(0, 255, 0, 255); - - // Start Timer - startTime = millis(); - - // Sensing Strike Power - while(power < VTH) - { - // Reading The Strike - power = PIEZO_MAP; - - // If Stop Command Came From Smart Phone - if(isBluetooth) - { - String msg = Bluetooth.readStringUntil('\n'); - flushBluetooth; - msg.trim(); - if(msg == CM_STOP) { - dualcomm(GAME_OVER); - // LightUp - //LED_SIGNAL_END(); - // RESET - return; - } - else if(msg == CM_RESET) { - //LED_SIGNAL_REACTION_RESET(); - i = 0; - sdelay = 0; - power = 0; - response = 0; - startTime = millis(); - stopTime = millis(); - totalRes = 0; - DISPLAY_CHANGED = false; - GAME_REACTION_DISPLAY(i, response); - //break; - } - } - - // Reset The Counter - if(BTN_INCREASE.pressed()) { - //LED_SIGNAL_REACTION_RESET(); - i = 0; - sdelay = 0; - power = 0; - response = 0; - startTime = millis(); - stopTime = millis(); - totalRes = 0; - DISPLAY_CHANGED = false; - GAME_REACTION_DISPLAY(i, response); - } - - // Will Exit The Game - if(BTN_CENTER.pressed()) { - dualcomm(GAME_OVER); - DISPLAY_CHANGED = false; - return; - } - } - - // Stop Timer - stopTime = millis(); - - // Stop Light - //LED_SET_COLOR(255, 0, 0, 255); - - // Calculating Response Time - response = stopTime - startTime - 1; - totalRes = totalRes + ((float)response/1000); - - // Create Json JSON - String msg = reaction_JSON_json(i+1, power, response, sdelay); - - // Display On OLED - GAME_REACTION_DISPLAY(i+1, response); - - // Print To Terminal - dualcomm(msg); - - // Clear All - sdelay = 0; - power = 0; - response = 0; - } - - // Red Light Delay - delay(500); - - // END GAME - dualcomm(GAME_OVER); - - // Blink Red - //LED_SIGNAL_CELEBRATION(); - - // Display Result - GAME_REACTION_RESULT(trials, totalRes); - - // Return To Game Selector - return; - } - -//------------------------------------------------------ -// REACTION JSON -> To Send Back To Mobile Device -//------------------------------------------------------ - - String reaction_JSON_json(unsigned int count, unsigned int power, unsigned int response, unsigned int startDelay) - { - // Convert To Seconds Unit - float re = response; - re /= 1000; - - // Asignning Values - JSON["ct"] = count; // Strike Number - JSON["pw"] = power; // Strike Power In Analog Read - JSON["sd"] = startDelay/1000; // LED Strip Start Delay in Seconds - JSON["re"] = String(re, 3).toFloat(); // Strike Reaction Time In Milli Sec - - String output; - serializeJson(JSON, output); - JSON.clear(); - return output; - } - -//------------------------------------------------------ -// REACTION GAME START LED SIGNAL -//------------------------------------------------------ - - void LED_SIGNAL_REACTION_START() - { - // Cross fade the white signal to get ready - //LED_CROSS_FADE(255, 255, 255, 3); - - // Set the LED strip color to red - //LED_SET_COLOR(255, 0, 0, 255); - } - -//------------------------------------------------------ -// REACTION GAME RESET LED SIGNAL -//------------------------------------------------------ - - void LED_SIGNAL_REACTION_RESET() - { - // Light Bright Blue - //LED_BLINK(0, 0, 255, 2); - - // Wait For 1/4 Second - //delay(250); - - // Fade Out The Blue - //LED_SET_COLOR(0, 255, 0, 255); - } - -//------------------------------------------------------ -// OLED GAME PLAY REACTION -//------------------------------------------------------ - - void GAME_REACTION_DISPLAY(uint16_t count, float reatime) - { - OLED_CLEAR(); - drawTextCenter(128/2, 0, 2, "KICK : " + String(count)); - drawTextCenter(128/2, 20, 3, "TIME : " + String(((float)reatime/1000), 2)); - - // Exit Button Command Only Via Stand Alone Mode - if(BLUETOOTH_STATUS == false) { - drawTextCenter(128/2, 50, 1, "<< EXIT >>"); - } - - OLED_SHOW(); - } - -//------------------------------------------------------ -// OLED - GAME TIMEATTACK RESULT -//------------------------------------------------------ - - void GAME_REACTION_RESULT(uint16_t trials, uint16_t total_reaction) - { - OLED_CLEAR(); - float avgReaction = 0.0; - avgReaction = (float)total_reaction/trials; - drawTextCenter(128/2, 0, 2, "RESULT"); - drawTextCenter(128/2, 20, 2, String(avgReaction, 3) + " s"); - drawTextCenter(128/2, 50, 1, "<< EXIT >>"); - OLED_SHOW(); - - // Waiting For Center Button To Move On - while(1){ - if(BTN_CENTER.pressed()) { - break; - } - } - } diff --git a/firmware/KICKER_V2/GSEL.ino b/firmware/KICKER_V2/GSEL.ino deleted file mode 100644 index 1b9f3a9..0000000 --- a/firmware/KICKER_V2/GSEL.ino +++ /dev/null @@ -1,70 +0,0 @@ -//====================================================== -// MAIN PROGRAM LOOP -//====================================================== - - /* game selector is the main function that tell the game groutine - * which game to be JSONed and at what parameters - */ - - void bluetooth_game_selector(String game, String settings) - { - // Kick Counter Game - if(game == "ct") { - terminal(GM_COUNTER); - game_counter_bluetooth(settings); - return; - } - - // Time Attack Game - else if(game == "ta") { - terminal(GM_TATTACK); - time_attack_bluetooth(settings); - return; - } - - // Time Attack Game - else if(game == "ra") { - terminal(GM_REACTION); - game_reaction_bluetooth(settings); - return; - } - - // Unknown Game - else { - dualcomm(UNKNOWN_GAME); - return; - } - } -//====================================================== -// GAME SELECTOR CODE -//====================================================== -// SELECTOR ROUTINE -//------------------------------------------------------ - void standalone_game_selector() - { - // Check Bluetooth - if(isBluetooth) - { - // Reading The Message From Bluetooth - String message = Bluetooth.readStringUntil('\n'); - // Cleaning Bluetooth Receive Buffer - flushBluetooth; - // Cleaning The Message - message.trim(); - // Cleaning JSON Document - JSON.clear(); - } - } -//------------------------------------------------------ -// DISPLAY MENU TITLE FUNCTION -//------------------------------------------------------ - void GAME_TITLE_DISPLAY(uint8_t Number, String Title) - { - // Starting The First Code - OLED_CLEAR(); - drawTextCenter(128/2, 5, 1, "GAME #" + String(Number)); - drawTextCenter(128/2, 22, 2, " - " + Title + " - "); - drawTextCenter(128/2, 43, 1, "<< SELECT >>"); - OLED_SHOW(); - DISPLAY_CHANGED = true; - } diff --git a/firmware/KICKER_V2/GTAT.ino b/firmware/KICKER_V2/GTAT.ino deleted file mode 100644 index 6f59ea7..0000000 --- a/firmware/KICKER_V2/GTAT.ino +++ /dev/null @@ -1,316 +0,0 @@ -//====================================================== -// TIME ATTACK GAME MAIN ROUTINE -//====================================================== - - /* This Game Can Be Called From - * Stand Alone Mode / Bluetooth Connection - * The primary mode is the standalone but - * if the bluetooth is connected it has the priority - * so it will take over the control of the device - * - * If you want to control the game via bluetooth - * you need to call : time_attack_bluetooth(JSON String) - * If you want to use the stand alone mode - * you need to call : time_attack_standalone() - * - * the game returns a float point number which is - * in seconds. so the athlete know how long he takes to react - */ - -//====================================================== -// Request From Stand Alone Buttons -//====================================================== - - void time_attack_standalone() - { - // Variables - uint16_t time = 30; - uint16_t limit = 10; - bool limitEnable = true; - - // Call the Game Play - game_timeAttack(time, limit, limitEnable); - - // Give Permision To Change Display - DISPLAY_CHANGED = false; - } - -//====================================================== -// Request From Bluetooth Via JSON -//====================================================== - - /* TIME ATTACK GAME SETTINGS PARAMETERS NOTE: - * ------------------------------------------ - * - * FORMAT : - * -------- - * {"tm": 10, "le": false, "lm": 10} - * - * tm : count down timer starting value - * le : stands for limit enable, if is TRUE the game end if target value is meet - * lm : targeted amount of kicks - * - * THINGS THAT ENDS THE GAME : - * --------------------------- - * 1. BY COUNT DOWN "tm" REACH TO ZERO - * 2. BY A COMMAND "FROM APP VIA BLUETOOTH" - * 3. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE" - * - * CALCULATING RESULTS : - * --------------------- - * Rapid Kick Speed = Number Of Kickes Made / Elasped Time In Sec - * Delay Between Kicks = Time Of Current Kick - Time Of Last Kick - * - * RETURNNING JSON FORMAT : - * ------------------------ - * {"tm" : 82, "ct" : 10, "dl" : 1234, "st" : 585} - * - * tm : timer count in Sec - * ct : strike counter (number of kicks) - * dl : delay between strikes - * st : time stampe of the strike in milli Seconds - */ - - void time_attack_bluetooth(String settings) - { - // Deserialize the JSON document - DeserializationError error = deserializeJson(JSON, settings); // the main JSON body container - - // JSON ERROR - if(error) { - dualcomm(JSON_ERROR); - return; - } - - // PUBLIC VARIABLES - const uint16_t time = JSON["tm"]; // Time Window To JSON - uint16_t limit = JSON["lm"]; // Kick Target Limit - bool limitEnable = JSON["le"]; // Enable Kick Target Limit - - // Clearing Buffer - JSON.clear(); - - // Play The Game - game_timeAttack(time, limit, limitEnable); - - // Give Permision To Change Display - DISPLAY_CHANGED = false; - } - -//====================================================== -// Play Time Atack Game -//====================================================== - - void game_timeAttack(uint16_t time, uint16_t limit, bool limitEnable) - { - // Building Timers 1000mSec -> 1Sec - TimeTrigger sec_tick(1000); - - // Kick Counter - uint16_t counter = 0; // This is what counts your kicks - uint16_t timer = time; // This is what your running timer - - // Start LED Signal - //LED_SIGNAL_START(); - - // Initial Display Of Game Data Before Start - GAME_TIMEATTACK_DISPLAY(timer, 0); - - // Send Initial DisJSON - dualcomm(timeAttack_JSON_json(timer, counter, 0, 0)); - - //------------------------- - // PREPARE FOR GAME START - //------------------------- - - // staring Of time stamp - unsigned long startStamp = millis(); - - // store the time of the previous kick - unsigned long lastStamp = 0; - - // reseting time ticker - sec_tick.Reset(); - - // While The Game Is Still On - while(timer != 0) - { - // Time Stamp - unsigned long timeStamp = millis() - startStamp; - - // If Stop Command Came From Smart Phone - if(isBluetooth) - { - String msg = Bluetooth.readStringUntil('\n'); - flushBluetooth; - msg.trim(); - if(msg == CM_STOP) - { - dualcomm(GAME_OVER); - // Grean Light In - //LED_SIGNAL_END(); - // Return - return; - } - else if(msg == CM_RESET) - { - timer = time; - counter = 0; - startStamp = millis(); - timeStamp = startStamp; - lastStamp = timeStamp; - sec_tick.Reset(); - GAME_TIMEATTACK_DISPLAY(counter, timer); - //LED_SIGNAL_RESET(); - } - } - - // Reset The Counter - if(BTN_INCREASE.pressed()) { - timer = time; - counter = 0; - startStamp = millis(); - timeStamp = startStamp; - lastStamp = timeStamp; - sec_tick.Reset(); - GAME_TIMEATTACK_DISPLAY(counter, timer); - } - - // Will Exit The Game - if(BTN_CENTER.pressed()) { - dualcomm(GAME_OVER); - DISPLAY_CHANGED = false; - return; - } - - // Every Kick ---------------------------->>> - if(PIEZO_MAP > VTH) - { - // Count As A Strike - counter++; - - // Display On OLED - GAME_TIMEATTACK_DISPLAY(counter, timer); - - // Send JSON String Out - dualcomm(timeAttack_JSON_json(timer, counter, lastStamp, timeStamp)); - - // Time Snap Shot - lastStamp = timeStamp; - - // Wait For Analog Sampler To by pass the strike - delay(100); - } - - // Every Second ---------------------------->>> - if(sec_tick.Trigger()) - { - // Decrement Time After Every Second - timer--; - - // Display Time And Count Every Second - GAME_TIMEATTACK_DISPLAY(counter, timer); - - // Send JSON String Out - dualcomm(timeAttack_JSON_json(timer, counter, 0, 0)); - } - - // If Limits Are Enabled And Meet - if(limitEnable == true && counter == limit) - { - // END GAME - dualcomm(GAME_OVER); - - // Time Difference Between Start & Count Down Timer - const uint16_t diff = time - timer; - - // Display The Game Result - GAME_TIMEATTACK_RESULT(counter, diff); - - // Celebrate - //LED_SIGNAL_CELEBRATION(); - - // Return - return; - } - } - - // Send End Game Signal To Smart Phone - dualcomm(GAME_OVER); - - // Display The Result - GAME_TIMEATTACK_RESULT(counter, time); - - // LightUp - //LED_FADEIN(255, 0, 0); // RED Color - //delay(2000); // Delay 2000 - //LED_CLEAR(); // CLEAR OFF - - // Return - return; - } - -//====================================================== -// TIME ATTACK KICK JSON -> To Send Back To Mobile -//====================================================== - - String timeAttack_JSON_json(unsigned int RunningTime, unsigned int KickCount, unsigned int LastStamp, unsigned int TimeStamp) - { - // Building The Buffer - JSON["tm"] = RunningTime; - JSON["ct"] = KickCount; - - // Calculations - if(TimeStamp > 0) - { - // Calculate Time Stamp In Seconds - float st = TimeStamp; - st /= 1000; - JSON["st"] = String(st, 3).toFloat(); - - // Calculate Strike Delay In Seconds - float dl = TimeStamp - LastStamp; - dl /= 1000; - JSON["dl"] = String(dl, 3).toFloat(); - } - - String output; - serializeJson(JSON, output); - JSON.clear(); - return output; - } - -//------------------------------------------------------ -// OLED - GAME TIMEATTACK PLAY -//------------------------------------------------------ - - void GAME_TIMEATTACK_DISPLAY(uint16_t count, uint16_t time) - { - OLED_CLEAR(); - drawTextCenter(128/2, 0, 2, "TIME ( " + String(time) + " ) Sec"); - drawTextCenter(128/2, 20, 2, "KICKS ( " + String(count) + " )"); - drawTextCenter(128/2, 50, 1, "<< EXIT >>"); - OLED_SHOW(); - } - -//------------------------------------------------------ -// OLED - GAME TIMEATTACK RESULT -//------------------------------------------------------ - - void GAME_TIMEATTACK_RESULT(uint16_t count, uint16_t time) - { - OLED_CLEAR(); - float avgSpeed = 0.0; - avgSpeed = (float)count/time; - drawTextCenter(128/2, 0, 2, "RESULT"); - drawTextCenter(128/2, 20, 2, String(avgSpeed, 2) + " K/s"); - drawTextCenter(128/2, 50, 1, "<< EXIT >>"); - OLED_SHOW(); - - // Waiting For Center Button To Move On - while(1){ - if(BTN_CENTER.pressed()) { - break; - } - } - } diff --git a/firmware/KICKER_V2/KICKER_V2.ino b/firmware/KICKER_V2/KICKER_V2.ino deleted file mode 100644 index f1b391a..0000000 --- a/firmware/KICKER_V2/KICKER_V2.ino +++ /dev/null @@ -1,382 +0,0 @@ - /* =============================================== - * - THIS IS TAKEONE ESP32 BOARD - - * =============================================== - * MPU9250 Address : 0X69 (ADDRESS) - * OLED 128x64 Address : 0X3C (ADDRESS) - * ----------------------------------------------- - * Description : PIN GPIO# - * ----------------------------------------------- - * NEOPIXEL LED STRIP : A0/GPIO 26 - * PIEZO SENSOR : A2/GPIO 34 - ANALOG ONLY INPUT - * RANDOM SEED : A3/GPIO 39 - ANALOG ONLY INPUT - * BUTTONS : TLB (35), BLB (15), CB (33), BRB (27), TRB(12) - * I2C PIN : SDA 21, SCL 22 (DIGITAL) - * SPI PIN : CS 5, SCK 18, MISO 19, MOSI 23 (DIGITAL) - * BOOST CONTROL PIN : 14 (DIGITAL) OUTPUT ON PADS (TP1 +5V, TP2 GND) - * LED PIN : 13 (DIGITAL) - * BATTERY MONITOR PIN : 35 (ANALOG) - * ----------------------------------------------- - * BUTTONS PINOUTS : PIN GPIO - * ----------------------------------------------- - * TOP LEFT BUTTON : 15 - SWITCH PREVIOUS MENU / CHANGE PARAMETER - * TOP RIGHT BUTTON : 12 - SWITCH NEXT MENU / CHANGE PARAMETER - * BOTTOM LEFT BUTTON : 32 - POWER INC & BACK & INC PARAMETER - * BOTTOM RIGHT BUTTON : 27 - POWER DEC & SAVE & DEC PARAMETER - * CENTER BUTTON : 33 - POWER ON & SELECT - * ----------------------------------------------- - * Exclusive Features Of TAKEONE BOARD - * ----------------------------------------------- - * ESP32 TAKEONE Board has some unique hardware features - * 1. Battery Voltage Level Monitoring Via Analog Pin 35 - * 2. Boost Converter In Case We Need 5V Supply From Li-Ion Battery - * 3. I2C : Motion Sensor IMU/MPU9250 9 Degrees Of Fredom - * 4. SPI : SDCARD Reader */ -//====================================================== -// LIBRARIES -//====================================================== - #include - #include - #include - #include - #include - #include - #include -//====================================================== -// OVER THE AIR PROGRAMMING -//====================================================== -// #include -// #include -// #include -// #include -//====================================================== -// PUBLIC VARIABLES -//====================================================== - uint8_t MENU_COUNT = 1; - bool BLUETOOTH_STATUS = false; - bool CHARGE_STATE = false; - bool DISPLAY_CHANGED = false; -//====================================================== -// HARDWARE DEFINITIONS -//====================================================== - // Nessesary Definition For Bluetooth Library - #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) - #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it - #endif -//------------------------------------------------------ -// Serial Terminal -//------------------------------------------------------ - #define Terminal Serial // SERIAL PORT USED AS TERMINAL WINDO FOR DEBUG - #define isTerminal Terminal.available() // Terminal Serial Buffer Available - #define flushTerminal while(isTerminal) { Terminal.read(); } -//------------------------------------------------------ -// Bluetooth Terminal -//------------------------------------------------------ - BluetoothSerial Bluetooth; // Here We Use the Native Bluetooth In The ESP32 - #define isBluetooth Bluetooth.available() // Bluetooth Serial Buffer Available - #define flushBluetooth while(isBluetooth) { Bluetooth.read(); } -//------------------------------------------------------ -// Buttons -//------------------------------------------------------ - Button BTN_PREVIOUS(15); // TL : 15 - SWITCH PREVIOUS MENU / CHANGE PARAMETER - Button BTN_NEXT(12); // TR : 12 - SWITCH NEXT MENU / CHANGE PARAMETER - Button BTN_CENTER(33); // CT : 33 - POWER INC & BACK & INC PARAMETER - Button BTN_INCREASE(32); // BL : 32 - POWER DEC & SAVE & DEC PARAMETER - Button BTN_DECREASE(27); // BR : 27 - POWER ON & SELECT -//------------------------------------------------------ -// Boost 3V3 To 5V -//------------------------------------------------------ - #define BOOST_PIN 14 - #define BOOST_SETUP pinMode(BOOST_PIN, OUTPUT) - #define BOOST_ON digitalWrite(BOOST_PIN, HIGH) - #define BOOST_OFF digitalWrite(BOOST_PIN, LOW) - #define BOOST_STU digitalRead(BOOST_PIN) -//------------------------------------------------------ -// Keep Power On -//------------------------------------------------------ - #define POWER_PIN 13 - #define POWER_SETUP pinMode(POWER_PIN, OUTPUT) - #define POWER_OFF digitalWrite(POWER_PIN, LOW) - #define POWER_ON digitalWrite(POWER_PIN, HIGH) - TimeTrigger POWER_PRESS(4000); // The Interval In mSeconds -//------------------------------------------------------ -// Piezo Transducer -//------------------------------------------------------ - #define VTH 15 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR - #define PIEZO_PIN 34 // IMPACT SENSOR - #define RANDOM_SOURCE 39 // RANDOM NUMBER GENERATOR SOURCE - #define PIEZO_READ analogRead(PIEZO_PIN) - #define PIEZO_MAP map(PIEZO_READ, VTH, 4095, 0, 100) -//------------------------------------------------------ -// Battery Level Monitoring -//------------------------------------------------------ - #define BATTERY_PIN 35 - #define BATTERY (float)(((analogRead(BATTERY_PIN) * (3.3 / 4096)) * 2) + 0.31) - #define CHARGE round(mapf(BATTERY, 3.27, 4.31, 0, 100), 1) -//------------------------------------------------------ -// Power Charging Status -//------------------------------------------------------ - #define STAT_PIN 25 - #define STAT_SETUP pinMode(STAT_PIN, INPUT) - #define STAT_READ digitalRead(STAT_PIN) -//------------------------------------------------------ -// Neo Pixel LED Strip -//------------------------------------------------------ - #ifdef __AVR__ - #include // Required for 16 MHz Adafruit Trinket - #endif - #define PIN 6 // On Trinket or Gemma, suggest changing this to 1 - #define NUMPIXELS 16 // Number Of LED's - Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); -//------------------------------------------------------ -// JSON Object & Memory -//------------------------------------------------------ - #define CAPACITY 200 - DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer -// FIXED OPERATION MODE MESSAGES ~~~~~~~~~~~~~~~~~~~~~~ - #define BLUETOOTH_START "{\"status\":\"BLUETOOTH STARTED\"}" - #define BLUETOOTH_FAIL "{\"status\":\"BLUETOOTH FAILED\"}" - #define BLUETOOTH_CONNECTED "{\"status\":\"BLUETOOTH CONNECTED\"}" - #define BLUETOOTH_DISCONNECTED "{\"status\":\"BLUETOOTH DISCONNECTED\"}" - #define STAND_ALONE_MODE "{\"status\":\"STAND ALONE MODE\"}" -// FIXED MESSAGES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - #define POWERUP "{\"status\":\"POWER UP\"}" - #define POWEROFF "{\"status\":\"POWER OFF\"}" - #define UNDERSTOOD "{\"status\":\"OK\"}" - #define JSON_ERROR "{\"status\":\"ERROR JSON\"}" - #define TARGET_MET "{\"status\":\"TARGET MEET\"}" - #define GAME_OVER "{\"status\":\"GAME OVER\"}" - #define TIME_OVER "{\"status\":\"TIME OVER\"}" - #define UNKNOWN_GAME "{\"status\":\"UNKNOWN GAME\"}" -// GAME NAMES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - #define GM_COUNTER "{\"gm\":\"COUNTER\"}" - #define GM_TATTACK "{\"gm\":\"TIME ATTACK\"}" - #define GM_REACTION "{\"gm\":\"REACTION\"}" - #define GM_DECISION "{\"gm\":\"DECISION\"}" - #define GM_STAMINA "{\"gm\":\"STAMINA\"}" -// COMMAND LIST ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - #define CM_START "{\"cm\":\"START\"}" - #define CM_RESET "{\"cm\":\"RESET\"}" - #define CM_STOP "{\"cm\":\"STOP\"}" - #define CM_EXIT "{\"cm\":\"EXIT\"}" -//====================================================== -// MAIN SETUP -//====================================================== - void setup() - { - // Power Hold - POWER_SETUP; - POWER_ON; - - // Charging Status Pin Setup - STAT_SETUP; - - // I2C Module & OLED - Wire.begin(); - delay(5); - OLED_INIT(); - OLED_CLEAR(); - OLED_SHOW(); - - // IF Charger Connected Dont Allow Any One To Play - - - // Turn On Booster - BOOST_SETUP; - BOOST_ON; - - // Start Buttons Function - BTN_PREVIOUS.begin(); - BTN_NEXT.begin(); - BTN_CENTER.begin(); - BTN_INCREASE.begin(); - BTN_DECREASE.begin(); - - // Communication Ports - Terminal.begin(9600); Terminal.println(); - - // To Detect Connection / Disconnection Event - Bluetooth.register_callback(callback); - - // Starting Bluetooth Wireless With Name (KICKER) - if(!Bluetooth.begin("KICKER")) { - terminal(POWERUP); - terminal(BLUETOOTH_FAIL); - } else { - dualcomm(POWERUP); - dualcomm(BLUETOOTH_START); - } - - // The Random Number Source - randomSeed(analogRead(RANDOM_SOURCE)); - - // Display Welcome Screen - KICKER_LOGO(); - delay(2000); - } -//====================================================== -// MAIN PROGRAM LOOP -//====================================================== - void loop() - { - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // This Is For Bluetooth Mode - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - if(BLUETOOTH_STATUS == true) { - // Initialization Of Bluetooth Connected Mode - OLED_BLUETOOTH_MODE(); // Display Bluetooth Connected Mode - DISPLAY_CHANGED = false; // Give Permition To Change The Content - delay(3000); // Hold The Display Content For 3 Seconds - - // While You Are On Bluetooth Connected Mode - while(BLUETOOTH_STATUS == true) { - ListenToBluetooth(); // Reading Only From Bluetooth - } - - // Give Permition To Change The Content - DISPLAY_CHANGED = false; - } - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // This Is For Stand Alone Mode - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - else { - // Initialization Of Stand Alone Mode - OLED_STANDALONE_MODE(); // Display Stand Alone Mode - DISPLAY_CHANGED = false; // Give Permition To Change The Content - delay(3000); // Hold The Display Content For 3 Seconds - - // While You Are On Stand Alone Mode - while(BLUETOOTH_STATUS == false) { - ListenToStandAlone(); // Enter Listen To Stand Alone Buttons - } - - // Once The Stand Alone Mode Is Over - DISPLAY_CHANGED = false; // Give Permition To Change The Display - } - } -//------------------------------------------------------ -// LISTEN TO BLUETOOTH -//------------------------------------------------------ - void ListenToBluetooth() - { - if(isBluetooth) - { - // Reading Message From Bluetooth - String msg = Bluetooth.readStringUntil('\n'); - flushBluetooth; - msg.trim(); - - // Display On Serial Monitor For Debuging - terminal(msg); - - // If It Was A Command To Power OFf - if(msg == POWEROFF) { - OLED_POWERING_DOWN(); - } - - // Deserialize the JSON document - DeserializationError error = deserializeJson(JSON, msg); - - // If The System Understood The Message Clearly - if(!error) - { - // Sending Status Message - dualcomm(UNDERSTOOD); - - // Reading Game Name & Settings - String game = JSON["gm"]; - String settings = JSON["set"]; - - // Clearing JSON Buffer - JSON.clear(); - - // Entering To Game Selector - bluetooth_game_selector(game, settings); - } - else - { - terminal(JSON_ERROR); - } - } - } -//------------------------------------------------------ -// LISTEN TO STAND ALONE -//------------------------------------------------------ - void ListenToStandAlone() - { - // SHIFT TO PREVIOUS GAME MENU - if(BTN_PREVIOUS.pressed()) - { - // Checking The Condition Of Order Number - if(MENU_COUNT == 1 || MENU_COUNT < 1) { - MENU_COUNT = 3; // If The Value Equals To Zero Then Roll Back To 4 - } else { - MENU_COUNT -= 1; - } - - // Give Permition To Change The Screen - DISPLAY_CHANGED = false; - } - - // SHIFT TO NEXT GAME MENU - else if(BTN_NEXT.pressed()) - { - // Checking The Condition Of Order Number - if(MENU_COUNT == 3 || MENU_COUNT > 3) - { - MENU_COUNT = 1; // If The Value Exceeds 4 Then Roll Back To 1 - } else { - MENU_COUNT += 1; - } - - // Give Permition To Change The Screen - DISPLAY_CHANGED = false; - } - - // SELECT CURRENT DISPLAYED MENU - else if(BTN_CENTER.pressed()) - { - // IF LONG PRESS -> POWER OFF KICKER - DETECT_LONG_PRESS(); - - // IF SHORT PRESS -> PLAY GAME CORESPONDING TO NUMBER - switch(MENU_COUNT) - { - case 1: // Play Counter Game - Terminal.println("SELECTED -> GAME COUNTER"); - game_counter_standalone(); - break; - case 2: // Play Time Attack Game - Terminal.println("SELECTED -> GAME TIME ATTACK"); - time_attack_standalone(); - break; - case 3: // Play Reaction Game - Terminal.println("SELECTED -> GAME REACTION"); - game_reaction_standalone(); - break; - } - } - - // Display The Game Pages - if(DISPLAY_CHANGED == false) - { - // IF Previous / Next Buttons Are Pressed -> Display Menu Selection On Terminal - switch(MENU_COUNT) - { - case 1: // Play Counter Game - //Terminal.println("MENU #" + String(MENU_COUNT) + " - " + "GAME COUNTER"); - GAME_TITLE_DISPLAY(MENU_COUNT, "COUNTER"); - break; - case 2: // Play Time Attack Game - //Terminal.println("MENU #" + String(MENU_COUNT) + " - " + "GAME TIME ATTACK"); - GAME_TITLE_DISPLAY(MENU_COUNT, "TIME ATTACK"); - break; - case 3: // Play Reaction Game - //Terminal.println("MENU #" + String(MENU_COUNT) + " - " + "GAME REACTION"); - GAME_TITLE_DISPLAY(MENU_COUNT, "REACTION"); - break; - } - } - } diff --git a/firmware/KICKER_V2/NPXL.ino b/firmware/KICKER_V2/NPXL.ino deleted file mode 100644 index 2896415..0000000 --- a/firmware/KICKER_V2/NPXL.ino +++ /dev/null @@ -1,247 +0,0 @@ -//====================================================== -// NEO PIXEL LED STRIP -//====================================================== -// PUBLIC DEFINITIONS -//------------------------------------------------------ - #define BETWEEN_FADE 15 - #define FADE_RATE 15 - #define BLINK_RATE 250 - #define ColorSaturation 128 -//------------------------------------------------------ -// Clearing The LED Strip -//------------------------------------------------------ - void LED_CLEAR() - { - // Clear The Strip Color - PIXEL_STRIP.clear(); - - // Show On LED Strip - LED_SHOW(); - } -//------------------------------------------------------ -// DISPLAY ON STRIP -//------------------------------------------------------ - void LED_SHOW() - { - // Pass It To The LED Strip - PIXEL_STRIP.show(); - } -//------------------------------------------------------ -// Set LED Brightness -//------------------------------------------------------ - void LED_SET_BRIGHTNESS(uint8_t Value) - { - // Set The Brightness - PIXEL_STRIP.setBrightness(Value); - } -//------------------------------------------------------ -// Set LED Color -//------------------------------------------------------ - void LED_SET_COLOR(uint8_t R, uint8_t G, uint8_t B, uint8_t Intensity) - { - // Set Intensity - LED_SET_BRIGHTNESS(Intensity); - - // Loop - for(int i=0; i=0; i--) - { - PIXEL_STRIP.setBrightness(i); - for(int j=0; j - #include - - // Display Instance - SSD1306Wire display(0x3c, 21, 22); - -//------------------------------------------------------ -// OLED INITIALIZATION -//------------------------------------------------------ - - void OLED_INIT() { - display.init(); - display.flipScreenVertically(); - display.setFont(ArialMT_Plain_10); - } - -//------------------------------------------------------ -// OLED CLEAR DISPLAY -//------------------------------------------------------ - - void OLED_CLEAR() { - display.clear(); - } - -//------------------------------------------------------ -// OLED CLEAN DISPLAY -//------------------------------------------------------ - - void OLED_CLEAN() { - OLED_CLEAR(); - OLED_SHOW(); - } - -//------------------------------------------------------ -// OLED SHOW NEW DATA -//------------------------------------------------------ - - void OLED_SHOW() { - display.display(); - } - -//------------------------------------------------------ -// OLED DISPLAY KICKER WELCOME MESSAGE -//------------------------------------------------------ - - void KICKER_LOGO() { - // Starting The First Code - OLED_CLEAR(); - drawTextCenter(128/2, 5, 3, "TAKEONE"); - drawTextCenter(128/2, 30, 1, " - T E C H N O L O G Y - "); - drawTextCenter(128/2, 43, 2, "<< KICKER >>"); - OLED_SHOW(); - } - -//------------------------------------------------------ -// OLED DISPLAY KICKER POWERING OFF MESSAGE -//------------------------------------------------------ - - void OLED_POWERING_DOWN() { - dualcomm(POWEROFF); - OLED_CLEAR(); - drawTextCenter(128/2, 5, 3, "POWER"); - drawTextCenter(128/2, 30, 1, "- T U R N I N G O F F -"); - drawTextCenter(128/2, 43, 2, "SEE YOU AGAIN"); - OLED_SHOW(); - BOOST_OFF; - delay(2000); - OLED_CLEAN(); - delay(250); - POWER_OFF; - } - -//------------------------------------------------------ -// OLED Display Text -//------------------------------------------------------ - - void drawTextFlowDemo(String Text) { - display.setFont(ArialMT_Plain_10); - display.setTextAlignment(TEXT_ALIGN_LEFT); - display.drawStringMaxWidth(0, 0, 128, Text); - } - -//------------------------------------------------------ -// OLED LEFT TEXT Display -//------------------------------------------------------ - - void drawTextLeft() { - display.setFont(ArialMT_Plain_10); - display.setTextAlignment(TEXT_ALIGN_LEFT); - display.drawString(0, 10, "Left aligned (0,10)"); - } - -//------------------------------------------------------ -// OLED CENTER TEXT Display -//------------------------------------------------------ - - void drawTextCenter(int X, int Y, int Size, String Text) { - //display.setFont(ArialMT_Plain_10); - - if(Size == 1) { - display.setFont(ArialMT_Plain_10); - } else if(Size == 2) { - display.setFont(ArialMT_Plain_16); - } else if(Size == 3) { - display.setFont(ArialMT_Plain_24); - } else { - display.setFont(ArialMT_Plain_10); - } - - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.drawString(X, Y, Text); - } - -//------------------------------------------------------ -// OLED RIGHT TEXT DISPLAY -//------------------------------------------------------ - - // OLED Display - void drawTextRight() { - display.setFont(ArialMT_Plain_10); - display.setTextAlignment(TEXT_ALIGN_RIGHT); - display.drawString(128, 33, "Right aligned (128,33)"); - } - -//------------------------------------------------------ -// OLED DRAW RECTANGLE -//------------------------------------------------------ - - void drawRectDemo() { - // Draw a pixel at given position - for (int i = 0; i < 10; i++) { - display.setPixel(i, i); - display.setPixel(10 - i, i); - } - display.drawRect(12, 12, 20, 20); - - // Fill the rectangle - display.fillRect(14, 14, 17, 17); - - // Draw a line horizontally - display.drawHorizontalLine(0, 40, 20); - - // Draw a line horizontally - display.drawVerticalLine(40, 0, 20); - } - -//------------------------------------------------------ -// OLED DRAW CIRCLE -//------------------------------------------------------ - - void drawCircleDemo() { - for (int i=1; i < 8; i++) { - display.setColor(WHITE); - display.drawCircle(32, 32, i*3); - if (i % 2 == 0) { - display.setColor(BLACK); - } - display.fillCircle(96, 32, 32 - i* 3); - } - } - -//------------------------------------------------------ -// OLED DRAW PROGRESS BAR -//------------------------------------------------------ - - void drawProgressBarDemo(int Value) { - int progress = Value; - // draw the progress bar - display.drawProgressBar(0, 50, 120, 10, progress); - - // draw the percentage as String - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.drawString(64, 35, String(progress) + "%"); - } - -//------------------------------------------------------ -// I2C DECIVES SCANNER -//------------------------------------------------------ - - void scanI2C() - { - byte error, address; - int nDevices; - - Serial.println(" -> Scanning I2C Devices ..."); - - nDevices = 0; - for(address = 1; address < 127; address++ ) - { - // The i2c_scanner uses the return value of - // the Write.endTransmisstion to see if - // a device did acknowledge to the address. - Wire.beginTransmission(address); - error = Wire.endTransmission(); - - if (error == 0) - { - Serial.print(" --> Device Found At Address 0x"); - if (address<16) - Serial.print("0"); - Serial.print(address,HEX); - Serial.println(" !"); - - nDevices++; - } - else if (error==4) - { - Serial.print(" --> Unknown error at address 0x"); - if (address<16) - Serial.print("0"); - Serial.println(address,HEX); - } - } - if (nDevices == 0) - Serial.println(" --> No I2C devices found\n"); - else - Serial.println(" --> done"); - } - -//------------------------------------------------------ -// WAITING FOR BLUETOOTH CONNECTION -//------------------------------------------------------ - - void OLED_BLUETOOTH_MODE() - { - // Starting The First Code - OLED_CLEAR(); - drawTextCenter(128/2, 5, 3, "KICKER"); - drawTextCenter(128/2, 30, 1, " - B L U E T O O T H - "); - if(BLUETOOTH_STATUS == true) { - drawTextCenter(128/2, 43, 2, "< CONNECTED >"); - } else { - drawTextCenter(128/2, 43, 2, "< WAITING >"); - } - OLED_SHOW(); - } - -//------------------------------------------------------ -// WAITING FOR BLUETOOTH CONNECTION -//------------------------------------------------------ - - void OLED_STANDALONE_MODE() - { - // Starting The First Code - OLED_CLEAR(); - drawTextCenter(128/2, 5, 3, "KICKER"); - drawTextCenter(128/2, 30, 1, " - S T A N D A L O N E - "); - drawTextCenter(128/2, 43, 2, "< MODE >"); - OLED_SHOW(); - } - -//------------------------------------------------------ -// GAME SLIDER SELECTOR -//------------------------------------------------------ - - void GAME_PAGE(uint8_t MenuNumber, String Title) { - if(DISPLAY_CHANGED == false) { - OLED_CLEAR(); - drawTextCenter(128/2, 5, 3, "< GAME #" + String(MenuNumber) + " >"); - drawTextCenter(128/2, 30, 1, " - " + Title + " - "); - drawTextCenter(128/2, 43, 2, "<< SELECT >>"); - OLED_SHOW(); - DISPLAY_CHANGED = true; - } - }