Compare commits

...

26 Commits
v2 ... master

Author SHA1 Message Date
8cdf95aec1
uploaded the firmware file that alejandro built 2022-11-24 00:07:11 +03:00
b780cedae8
Update SIGNALS.md 2020-05-25 15:51:04 +03:00
7eac4601f4 updating the repository 2020-05-25 14:02:42 +03:00
3c3f3a4657
Update SIGNALS.md 2020-05-25 13:51:57 +03:00
2b6c2c59a9
Update SIGNALS.md 2020-05-25 13:19:16 +03:00
223c49a21e
Update Signals
This is to explain the signals and their meanning
2020-05-25 13:14:24 +03:00
138c5d91bc updateing 2020-05-25 05:01:08 +03:00
ecbffd73dd update 2020-05-25 04:56:48 +03:00
6b0cd678c1 uploading kicker terminology 2020-05-24 15:19:28 +03:00
b0086daea5 updating and renaming folders 2020-05-22 09:38:28 +03:00
417b22e36e updating kicker v1 2020-05-22 09:33:27 +03:00
1302316362 update 2020-04-03 14:31:20 +03:00
29fe2f705c update info 2020-04-03 14:28:36 +03:00
8fb3b3e0d2 putting bac the led strip library 2020-03-22 00:59:44 +03:00
84539fecfc putting bac the led strip library 2020-03-22 00:58:38 +03:00
46e0d169bc image missing 2020-03-17 03:29:53 +03:00
2b03e0641f correcting main header 2020-03-17 03:23:06 +03:00
b67efc6d13 correct the url of the landing page image url 2020-03-17 02:58:26 +03:00
8b960ab1e4 added one componente to compensate for the 5v signal 2020-03-08 04:56:28 +03:00
e63980f6b4 fixed some broken links & explained 2020-02-16 15:36:46 +04:00
2a088af286 fixed some broken links & explained 2020-02-16 15:34:33 +04:00
38794e59d8 fixed some broken links & explained 2020-02-16 15:07:06 +04:00
a4ec6f14f6 fixed some broken links 2020-02-16 09:42:55 +04:00
5b1fee6857 done some changes on the page 2020-02-16 09:38:58 +04:00
9f86415b9a kicker update on the read me document 2020-02-12 10:04:15 +04:00
33d6f41787
Created A Wiki Page
This page displays the operations of the kicker
2020-02-12 08:35:40 +04:00
167 changed files with 327 additions and 2110 deletions

BIN
3D Model/Thumbs.db Normal file

Binary file not shown.

BIN
Datasheets/TXS0102.pdf Normal file

Binary file not shown.

Binary file not shown.

BIN
Documents/Presentation.pptx Normal file

Binary file not shown.

Binary file not shown.

View File

@ -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);
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<trials; i++)
{
// Reading Kick JSON
terminal(" ------ Trial Number (" + String(i + 1) + ") ------");
terminal(" -> 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;
}
}
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -1,370 +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 <Wire.h>
#include <EEPROM.h>
#include <Button.h>
#include <TimeTrigger.h>
#include <ArduinoJson.h>
#include <NeoPixelBus.h>
#include <BluetoothSerial.h>
//======================================================
// 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
//------------------------------------------------------
#define PIXEL_COUNT 21 // make sure to set this to the number of pixels in your strip
#define PIXEL_PIN 26 // make sure to set this to the correct pin, ignored for Esp8266
// three element pixels, in different order and speeds
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> PIXEL_STRIP(PIXEL_COUNT, PIXEL_PIN);
//------------------------------------------------------
// 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;
// Turn On Booster
BOOST_SETUP;
BOOST_OFF;
// Charging Status Pin
STAT_SETUP;
// I2C Module & OLED
Wire.begin();
delay(5);
OLED_INIT();
OLED_CLEAR();
OLED_SHOW();
// 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;
}
}
}

View File

@ -1,295 +0,0 @@
////======================================================
//// NEO PIXEL LED STRIP
////======================================================
//// PUBLIC DEFINITIONS
////------------------------------------------------------
// #define BETWEEN_FADE 15
// #define FADE_RATE 15
// #define BLINK_RATE 250
// #define ColorSaturation 128
////------------------------------------------------------
//// PURE COLOR
////------------------------------------------------------
// RgbColor red(colorSaturation, 0, 0);
// RgbColor green(0, colorSaturation, 0);
// RgbColor blue(0, 0, colorSaturation);
// RgbColor white(colorSaturation);
// RgbColor black(0);
////------------------------------------------------------
//// HSL COLOR
////------------------------------------------------------
// HslColor hslRed(red);
// HslColor hslGreen(green);
// HslColor hslBlue(blue);
// HslColor hslWhite(white);
// HslColor hslBlack(black);
////------------------------------------------------------
//// Clearing The LED Strip
////------------------------------------------------------
// void LED_CLEAR()
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Clear The Strip Color
// PIXEL_STRIP.clear();
//
// // Show On LED Strip
// LED_SHOW();
// }
////------------------------------------------------------
//// DISPLAY ON STRIP
////------------------------------------------------------
// void LED_SHOW()
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Pass It To The LED Strip
// PIXEL_STRIP.show();
// }
////------------------------------------------------------
//// Set LED Brightness
////------------------------------------------------------
// void LED_SET_BRIGHTNESS(uint8_t Value)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // 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)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Set Intensity
// LED_SET_BRIGHTNESS(Intensity);
//
// // Loop
// for(int i=0; i<NUM_PIXELS; i++) {
// PIXEL_STRIP.setPixelColor(i, PIXEL_STRIP.Color(R, G, B));
// }
//
// // Show The Colors On LED Strip
// LED_SHOW();
// }
////------------------------------------------------------
//// BLINK
////------------------------------------------------------
// void LED_BLINK(uint8_t R, uint8_t G, uint8_t B, int Times)
// {
// for(int i=0; i<Times; i++)
// {
// LED_SET_COLOR(R, G, B, 255);
// delay(BLINK_RATE);
// LED_CLEAR();
// delay(BLINK_RATE);
// }
// }
////------------------------------------------------------
//// COLOR WHIPE
////------------------------------------------------------
// // Fill the dots one after the other with a color
// void LED_COLOR_WIPE(uint32_t c, uint8_t wait)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Work Loop
// for(uint16_t i=0; i<NUM_PIXELS; i++)
// {
// PIXEL_STRIP.setPixelColor(i, c);
// LED_SHOW();
// delay(wait);
// }
// }
////------------------------------------------------------
//// END GAME LIGHTING SIGNAL
////------------------------------------------------------
// // Slightly different, this makes the rainbow equally distributed throughout
// void LED_RAINBOW_CYCLE(uint8_t wait)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Loop Variables
// uint16_t i, j;
//
// // The Loop
// for(j=0; j<256*5; j++)
// {
// // 5 cycles of all colors on WHEEL
// for(i=0; i< PIXEL_STRIP.numPixels(); i++)
// {
// PIXEL_STRIP.setPixelColor(i, LED_COLOR_WHEEL(((i * 256 / PIXEL_STRIP.numPixels()) + j) & 255));
// }
//
// LED_SHOW();
// delay(wait);
// }
// }
////------------------------------------------------------
//// END GAME LIGHTING SIGNAL
////------------------------------------------------------
// // Input a value 0 to 255 to get a color value.
// // The colours are a transition r - g - b - back to r.
// uint32_t LED_COLOR_WHEEL(byte WHEELPos)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Wheel Sequance
// WHEELPos = 255 - WHEELPos;
//
// if(WHEELPos < 85)
// {
// return PIXEL_STRIP.Color(255 - WHEELPos * 3, 0, WHEELPos * 3);
// }
// if(WHEELPos < 170)
// {
// WHEELPos -= 85;
// return PIXEL_STRIP.Color(0, WHEELPos * 3, 255 - WHEELPos * 3);
// }
// WHEELPos -= 170;
// return PIXEL_STRIP.Color(WHEELPos * 3, 255 - WHEELPos * 3, 0);
// }
////------------------------------------------------------
//// Set Color Fade In
////------------------------------------------------------
// void LED_FADEIN(uint8_t R, uint8_t G, uint8_t B)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Loop For Fade
// for(int i=0; i<=255; i++)
// {
// PIXEL_STRIP.setBrightness(i);
// for(int j=0; j<NUM_PIXELS; j++)
// {
// PIXEL_STRIP.setPixelColor(j, PIXEL_STRIP.Color(R, G, B));
// }
//
// LED_SHOW();
// delay(4);
// }
// }
////------------------------------------------------------
//// Set Color Fade Out
////------------------------------------------------------
// void LED_FADEOUT(uint8_t R, uint8_t G, uint8_t B)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// // Loop For Fade Out
// for(int i=255; i>=0; i--)
// {
// PIXEL_STRIP.setBrightness(i);
// for(int j=0; j<NUM_PIXELS; j++)
// {
// PIXEL_STRIP.setPixelColor(j, PIXEL_STRIP.Color(R, G, B));
// }
//
// LED_SHOW();
// delay(4);
// }
// }
////------------------------------------------------------
//// Set LED Color Cross Fade
////------------------------------------------------------
// void LED_CROSS_FADE(uint8_t R, uint8_t G, uint8_t B, unsigned int Times)
// {
// // Make Sure Boost Is On
// BOOST_ON;
//
// for(int i=0; i<Times; i++)
// {
// LED_FADEIN(R, G, B);
// LED_FADEOUT(R, G, B);
// delay(BETWEEN_FADE);
// }
// }
////------------------------------------------------------
//// REACTION GAME START LED SIGNAL
////------------------------------------------------------
// void LED_SIGNAL_START()
// {
// // Cross Fade White Color To Get ready 3 Times
// LED_CROSS_FADE(255, 255, 255, 3);
//
// // Set Strip Color Green
// LED_SET_COLOR(0, 255, 0, 255);
// }
////------------------------------------------------------
//// REACTION GAME END SINGNAL LED SIGNAL
////------------------------------------------------------
// void LED_SIGNAL_END()
// {
// // Blink Red Twice
// LED_BLINK(255, 0, 0, 2);
//
// // Fade The Red Color To Nothing
// LED_FADEOUT(255, 0, 0);
// }
////------------------------------------------------------
//// REACTION GAME START LED CELEBRATION
////------------------------------------------------------
// void LED_SIGNAL_CELEBRATION()
// {
// // Display Rainbow Twice
// LED_RAINBOW_CYCLE(2);
//
// // Grean Light OUT
// LED_FADEOUT(0, 255, 0);
// }
////------------------------------------------------------
//// REACTION GAME RESET LED SIGNAL
////------------------------------------------------------
// void LED_SIGNAL_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);
//
// // Set Strip Color Green
// LED_SET_COLOR(0, 255, 0, 255);
// }
////------------------------------------------------------
//// DISPLAY BAHRAIN FLAG
////------------------------------------------------------
// void LED_BAHRAIN_FLAG()
// {
// BOOST_ON;
// LED_SET_BRIGHTNESS(255);
// LED_COLOR_WIPE(PIXEL_STRIP.Color(255, 255, 255), 30); // White
// delay(250);
// LED_COLOR_WIPE(PIXEL_STRIP.Color(255, 0, 0), 30); // Red
// delay(250);
// LED_FADEOUT(255, 0, 0);
// }
////------------------------------------------------------
//// DISPLAY COLOMBIA FLAG
////------------------------------------------------------
// void LED_COLOMBIA_FLAG()
// {
// BOOST_ON;
// LED_SET_BRIGHTNESS(255);
// LED_COLOR_WIPE(PIXEL_STRIP.Color(255, 255, 0), 30); // Yellow
// delay(250);
// LED_COLOR_WIPE(PIXEL_STRIP.Color(0, 0, 255), 30); // Blue
// delay(250);
// LED_COLOR_WIPE(PIXEL_STRIP.Color(255, 0, 0), 30); // Red
// delay(250);
// LED_FADEOUT(255, 0, 0);
// }

View File

@ -1,272 +0,0 @@
//======================================================
// OLED DISPLAY
//======================================================
// LIBRARY INCLUDE
//------------------------------------------------------
// Include Libraries
#include <Wire.h>
#include <SSD1306Wire.h>
// 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;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

BIN
Pictures/Thumbs.db Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Pictures/the-app/Thumbs.db Normal file

Binary file not shown.

BIN
Pictures/v2/Thumbs.db Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -1,2 +1,72 @@
# Kicker ![](./images/v2/kickerv2.jpg)
TAKEONE Product Named Kicker
TAKEONE Kicker, Hi-tech state of the art equipment, that will encourage you to be better to stay at the top of your game. equipped with modern design and digital electronics. Made to convert you into a champions.
## History Of Kicking Target
Kicking target is originally used in TaeKwonDo martial arts for light training where its meant to increase your focus, timing and speed, However the targets was a piece of equipment compulsory like the heavy bag for boxers, they are just a target for striking without any intelligence. it could not tell anything about the striker not measure the capabilities. So TAKEONE team took the step forward to convert this target into a technological state of the art gadget to accurately measure and keep track of the performance of the athletes utilizing its high tech features. This gadget can work standalone or via Bluetooth operated by a phone with great visualization of striking data and archiving the history.
![](./images/explanatory/kidstrainning.jpg)
## The Science Behind TAKEONE Kicker
since we have a striking sport that is going to use it, I would like to explain the methodology of kicker measurement by an example. lets begin,
#### imagine
Just imagine with me, you are closing your eyes and suddenly you listen to a person knocking the door on a slow pace, then if you ignore the knock's, the person tries harder so he knock's back again harder and on a faster pace. if you com to think of it now how did your ears and brain differentiate between weak and slow, fast and hard knock's.
#### answer
the answer is, that you ears listen to the knock's but your brain indirectly is measuring the knock's amplitude to differentiate weak or hard and the time space between every knock (slow rep knocking) or (fast rep knocking)
## The Science Behind The Kicker
The science behind the kicker, is the basic understanding of martial arts training terminology and converting them to algorithms. Its based on registering the strikes magnitude and register their timestamp. This will open opportunities to calculate and measure the athletes capabilities and skills, not to mention that it can keep track of their progress. with the addition of an RGB interactive element it expands the possibilities to be able to measure skills that are related to your brain activity like reflex time, decision making and much more.
### Key Components
##### Strike Sensing
Strikes are sensed with vibration sensor it gives an alternating voltage when struck and the amplitude increases proportionally with the force of the strike. how ever we don't measure the force of the strike accurately, so we give it a threshold in case this threshold is crossed that is considers a valid strike.
##### Interactive Indication
Interactive indication is important so that user could understand the signals and knows what's going on. we use addressable RGB Neo Pixel Strip, to light up the strip with different patterns to signal the user to interact with the device.
##### Device Controller
in order to do accurate timing and measuring of the event of the games and the capabilities of the athletes who are using the device, we need and powerful brain that's is accurate and reliable with expandable memory wireless connectivity and can run a display and manage power consumption intelligently and keep the battery in safe conditions that will expand its life span. that brain is [TAKEONE Board (ESP32)](https://github.com/GhassanYusuf/takeone-esp32-board)
##### Circuit Diagram
=======
#### conclusion
therefore we conclude that if we register the amplitude of the strike power and time stamp of each strike hitting target. we get the following shape of data.
```
{
strike_number : 5, // This tells the current strike count
amplitude : 50, // This tells how hard was it struck
timestamp : 2.45 // This tells the time in seconds of the strike
}
```
#### Click The Picture For Live Demo
[![](./images/v2/IsaCircuitBoardKicker.png)](https://youtu.be/ycsHNqcLSlA)
## Circuit Diagram
![](./images/components/schematicv2.png)
### Key Components
#### Strike Sensing
Strikes are sensed with vibration sensor it gives an alternating voltage when struck and the amplitude increases proportionally with the force of the strike. how ever we don't measure the force of the strike accurately, so we give it a threshold in case this threshold is crossed that is considers a valid strike.
<p align="center">
<img src="./Pictures/components/piezodisk.jpg" alt="Image"/>
</p>
#### Interactive Indication
Interactive indication is important so that user could understand the signals and knows what's going on. we use addressable RGB Neo Pixel Strip, to light up the strip with different patterns to signal the user to interact with the device.
![](./images/components/newpixelstrip.jpg)
#### Device Controller
in order to do accurate timing and measuring of the event of the games and the capabilities of the athletes who are using the device, we need and powerful brain that's is accurate and reliable with expandable memory wireless connectivity and can run a display and manage power consumption intelligently and keep the battery in safe conditions that will expand its life span. that brain is [TAKEONE Board (ESP32 Weroom)](https://github.com/GhassanYusuf/takeone-esp32-board)
>>>>>>> 46e0d169bc8b2b8bc7dae1666a5a513553e98e19
![](./images/components/pcb01.jpg "TAKEONE ESP32 Board")

225
SIGNALS.md Normal file
View File

@ -0,0 +1,225 @@
# Kicker Signaling
details about communication protocol between mobile phone app and kicker
## How To Connect To KICKER ?
in order to connect to kicker, you need to enable ***Bluetooth*** connection. and try to connect via two methods
* Scan For Bluetooth Devices And Add Manually
* Scan A QR Code With JSON Content
### QR Code JSON Content
```
{"request":"pair_kicker","device-name":"KICKER","device-mac":"98:D3:31:60:4E:A5"}
```
### Fixed Messages, Responses, Commands
Here we will discuss all sorts of fixed commands, messages, responses - what do they do and what do they mean, and how to use them in our firmware. Ghassan Yusuf built this protocol carefully for high accuracy data arbitration.
#### Game Selection Indicators
When the user selects a game and the data is being sent to the kicker, the kicker confirms the selection and responses back with a message to indicate the game type selected.
*When counter game is selected*
```
{"gm":"COUNTER"}
```
*When time attack game is selected*
```
{"gm":"TIME ATTACK"}
```
*When reaction game is selected*
```
{"gm":"REACTION"}
```
*When decision game is selected*
```
{"gm":"DECISION"}
```
*When stamina game is selected*
```
{"gm":"STAMINA"}
```
#### Messages
These messages are for notifying the mobile device with the status of the events occurring within its firmware, like reporting back specific events.
*When you power on the first thing it does is to send the following signal informing the user that the kicker is on. (Note) at the moment of powering on the Bluetooth goes off to so its no longer connected this message will show on the serial terminal only.*
```
{"status":"POWER UP"}
```
*When the user sends a game selection or command, if the signal was recognized and understood by the firmware it send back the following response*
```
{"status":"OK"}
```
*When the user sends a game selection or command, if the signal JSON data get corrupted due to lack of memory or interference then it send back the following response*
```
{"status":"ERROR JSON"}
```
*When the user playes a game and the game ends because the user didnt cach up with the limits he set or the user send a quit command {"cm":"STOP"}, Then it send the following command - it means you quit the game or you could not keep up with the game and ended in loss*
```
{"status":"GAME OVER"}
```
*When the user sends a JSON formated signal in game selection routine, if the signal was not recognized or not understood by the firmware it send back the following response*
```
{"status":"UNKNOWN GAME"}
```
#### Commands
*In some cases after passing the game type and parameters, the kicker waits for a start signal to start the game for playing, so by sending this json the game will start*
```
{"cm":"START"}
```
*While the user is playing the game already - there are some odd casses they want to start all over again, so they send a reset json to start over the count and time*
```
{"cm":"RESET"}
```
*When the user is playing a game and all of a sudden wanted to quit the game, he have to send this json to stop the game*
```
{"cm":"STOP"}
```
<HR>
## Games Selection
In order to select a specific game, the kicker should be not engaged with any running game, Then only it can receive game selection signal and pass the game parameters.
<HR>
### Counter Game
* Open Counter
* Close Counter With Count Trials
#### The JSON Format (setting is a nested JSON)
```
{"gm":"ct", "set": {"le":true, "lm": 10}}
ct : Kick Counter Game
le : Previous Games Results (Action One Result, Action Two Result)
lm : Kick Limit Amount
```
This mean that the player wants to play a counter game with limit feature enabled, limited number of kicks are 10, then the game stops counting.
#### Strike Signal
```
{"ct":1,"st":5.215}
ct : Kick Count
st : Time Of The Kick In Milliseconds
```
#### Result Calculations
```
number of kicks = maximum number of kicks the user made on the target
```
<HR>
### Time Attack Game
Open Kick Counter Limited By Time Window
Closed Kick Counter Limited By Trials Count Or Time Window
#### The JSON Format (setting is a nested JSON)
```
{"gm":"ta", "set": {"tm": 60, "lm": 10, "le": true}}
ta : Decision Time Measurement Game
tm : Game Play Time
lm : Kick Trial Amount
le : Enable End Game When Limits It Meet
```
This mean that the player wants to play a Time Attack game for 60s and enabled kick limits to 200 kicks.
#### Strike Signal
```
{"tm":5,"ct":2,"st":0.289,"dl":0.289}
tm : Count Down Display Time (in Seconds)
ct : Kick Count (Number Of Kicks)
st : Time Of Each Strike (In Milliseconds)
dl : Diviation Between Kicks (In Milliseconds)
```
#### Result Calculations
```
timeattack = (number of kicks)/(time taken to finish the game) = Kicks Per Second
```
<HR>
### Reaction Game
Open Reaction Game With No Trials Limit
Open Reaction Game With No Trials Limit With Time Limit
Closed Reaction Game With Trials Limit Without Time Limit
#### The JSON Format (setting is a nested JSON)
```
{"gm":"ra", "set": {"lm": 10, "mn": 1, "mx": 3}}
ra : Reaction/Reflex Measurement Game
lm : Kick Trial Amount
mn : Minimum Delay Between Signals
mx : Maximum Delay Between Signals
```
This mean that the player wants to play a reaction game for a strike named “Front Kick” with enables trials of 10 kicks with delay spacing between trials (1s up to 3s) without time limits.
#### Strike Signal
```
{"ct":3,"pw":65467,"sd":3,"re":0.005}
ct : kick count
pw : kick power
sd : sconds delay between light trigger
re : reaction time in milli seconds
```
#### Result Calculations
```
avarage reaction= (sum of all reaction time (sum re))/(total number of trials (max〖ct)〗 )=milli seconds
```
<HR>
### Decision Making Game
( This game is locked & unlock only if you have records with different kinds of reaction trials with different actions )
Closed Decision Making Game With Trials Limit
Closed Decision Making Game With Time Limit
#### The JSON Format (setting is a nested JSON with action array)
```
{"gm":"de", "set":{“pr”: [<action1>, <action2>], "lm": 10, "mn": 1, "mx": 3}}
de : Decision Time Measurement Game
pr : Previous Games Results (Action One Result, Action Two Result)
lm : Kick Trial Amount
mn : Minimum Delay Between Signals
mx : Maximum Delay Between Signals
```
This mean that the player wants to play a reaction game for a strike named “Front Kick” with enables trials of 10 kicks with delay spacing between trials (1s up to 3s) without time limits.
<HR>
### Stamina Measurement Game
* Open stamina measurement
* Closed stamina measurement to Time Limit
#### The JSON Format (setting is a nested JSON with action array)
```
{"game":"st", "set":{“le”: true, “lm”: 20, “tm”: 30, "mx":120 }}
st : Stamina Measurement Game
le : Enable Limit Number Of Kicks
lm : Kick Limit Amount
tm : Game Time In Seconds
mx : Max Strike Deviation in Milliseconds (Spacing Between Strikes)
```
This mean that the player wants to play a stamina game for a strike named “Front Kick” with enables time limit of 120s.

View File

@ -18,11 +18,11 @@
// Time Attack Game // Time Attack Game
else if(game == "ta") { else if(game == "ta") {
terminal(GM_TATTACK); terminal(GM_TATTACK);
game_reaction_bluetooth(settings); time_attack_bluetooth(settings);
return; return;
} }
// Time Attack Game // Time Reaction Game
else if(game == "ra") { else if(game == "ra") {
terminal(GM_REACTION); terminal(GM_REACTION);
game_reaction_bluetooth(settings); game_reaction_bluetooth(settings);

View File

@ -87,7 +87,7 @@
// PUBLIC VARIABLES // PUBLIC VARIABLES
uint16_t time = JSON["tm"]; // Time Window To JSON uint16_t time = JSON["tm"]; // Time Window To JSON
uint16_t timer = time; uint16_t timer = time; // Time
uint16_t limit = JSON["lm"]; // Kick Target Limit uint16_t limit = JSON["lm"]; // Kick Target Limit
bool limitEnable = JSON["le"]; // Enable Kick Target Limit bool limitEnable = JSON["le"]; // Enable Kick Target Limit

View File

@ -10,42 +10,8 @@
//====================================================== //======================================================
// HARDWARE SETUP & SELECTION // HARDWARE SETUP & SELECTION
//====================================================== //======================================================
// Arduino MEGA
#ifdef ARDUINO_AVR_MEGA2560
//------------------------------------------------------
// Library Nessesary
#ifdef __AVR__
#include <avr/power.h>
#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
#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 // Arduino Uno / Nano
#elif ARDUINO_AVR_UNO || ARDUINO_AVR_NANO #ifdef ARDUINO_AVR_UNO || ARDUINO_AVR_NANO
//------------------------------------------------------ //------------------------------------------------------
// Library Nessesary // Library Nessesary
@ -68,13 +34,20 @@
#define flushBluetooth while(isBluetooth) { Bluetooth.read(); } #define flushBluetooth while(isBluetooth) { Bluetooth.read(); }
// JSON Object & Memory // JSON Object & Memory
#define CAPACITY 100 #define CAPACITY 150
DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer
// LED Strip // LED Strip
#define LED_STRIP 2 // LED STRIP PIN NUMBER #define LED_STRIP 2 // LED STRIP PIN NUMBER
#define NUM_PIXELS 14 // NUMBER OF LED'S IN NEO PIXEL STRIP #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); Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, LED_STRIP, NEO_GRB + NEO_KHZ800);
// Power Holding Pin
#define POWER_PIN 13
#define POWER_SETUP pinMode(POWER_PIN, OUTPUT)
#define POWER_ON digitalWrite(POWER_PIN, HIGH)
#define POWER_OFF digitalWrite(POWER_PIN, LOW)
#define POWER_STU digitalRead(POWER_PIN)
// Impact Detection // Impact Detection
#define VTH 14 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR #define VTH 14 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR
@ -128,7 +101,7 @@
DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer
// LED Strip // LED Strip
#define LED_STRIP 33 // LED STRIP PIN NUMBER #define LED_STRIP 33 // LED STRIP PIN NUMBER
#define NUM_PIXELS 14 // NUMBER OF LED'S IN NEO PIXEL STRIP #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); Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, LED_STRIP, NEO_GRB + NEO_KHZ800);
@ -154,6 +127,13 @@
#define BOOST_OFF digitalWrite(BOOST_PIN, LOW) #define BOOST_OFF digitalWrite(BOOST_PIN, LOW)
#define BOOST_STU digitalRead(BOOST_PIN) #define BOOST_STU digitalRead(BOOST_PIN)
// Power Holding Pin
#define POWER_PIN 13
#define POWER_SETUP pinMode(POWER_PIN, OUTPUT)
#define POWER_ON digitalWrite(POWER_PIN, HIGH)
#define POWER_OFF digitalWrite(POWER_PIN, LOW)
#define POWER_STU digitalRead(POWER_PIN)
// Battery Level Monitoring // Battery Level Monitoring
#define BATTERY_PIN 35 #define BATTERY_PIN 35
#define BATTERY (float)(((analogRead(BATTERY_PIN) * (3.3 / 4096)) * 2) + 0.31) #define BATTERY (float)(((analogRead(BATTERY_PIN) * (3.3 / 4096)) * 2) + 0.31)
@ -182,9 +162,7 @@
#define POWERUP "{\"status\":\"POWER UP\"}" #define POWERUP "{\"status\":\"POWER UP\"}"
#define UNDERSTOOD "{\"status\":\"OK\"}" #define UNDERSTOOD "{\"status\":\"OK\"}"
#define JSON_ERROR "{\"status\":\"ERROR JSON\"}" #define JSON_ERROR "{\"status\":\"ERROR JSON\"}"
#define TARGET_MET "{\"status\":\"TARGET MEET\"}"
#define GAME_OVER "{\"status\":\"GAME OVER\"}" #define GAME_OVER "{\"status\":\"GAME OVER\"}"
#define TIME_OVER "{\"status\":\"TIME OVER\"}"
#define UNKNOWN_GAME "{\"status\":\"UNKNOWN GAME\"}" #define UNKNOWN_GAME "{\"status\":\"UNKNOWN GAME\"}"
// GAME NAMES // GAME NAMES
@ -198,7 +176,6 @@
#define CM_START "{\"cm\":\"START\"}" #define CM_START "{\"cm\":\"START\"}"
#define CM_RESET "{\"cm\":\"RESET\"}" #define CM_RESET "{\"cm\":\"RESET\"}"
#define CM_STOP "{\"cm\":\"STOP\"}" #define CM_STOP "{\"cm\":\"STOP\"}"
#define CM_EXIT "{\"cm\":\"EXIT\"}"
//====================================================== //======================================================
// READING IMPACT POWER FROM ANALOG PINS // READING IMPACT POWER FROM ANALOG PINS
@ -223,6 +200,8 @@
// Make Sure Of The Core // Make Sure Of The Core
#ifdef ESP32 #ifdef ESP32
Bluetooth.begin("KICKER"); // Bluetooth device name Bluetooth.begin("KICKER"); // Bluetooth device name
POWER_SETUP; // Boost Pin Setup
POWER_ON; // Turn Power On - And Keep On
BOOST_SETUP; // Boost Pin Setup BOOST_SETUP; // Boost Pin Setup
BOOST_OFF; // Turn It Off BOOST_OFF; // Turn It Off
#else #else
@ -274,7 +253,7 @@
dualcomm(UNDERSTOOD); dualcomm(UNDERSTOOD);
// Reading Game Name & Settings // Reading Game Name & Settings
String game = JSON["gm"]; String game = JSON["gm"];
String settings = JSON["set"]; String settings = JSON["set"];
// Clearing JSON Buffer // Clearing JSON Buffer
@ -285,9 +264,12 @@
} }
else else
{ {
// Send Back A Signal
terminal(JSON_ERROR); terminal(JSON_ERROR);
} }
Bluetooth.flush();
// Clear Bluetooth Buffer
flushBluetooth;
} }
} }

View File

@ -7,12 +7,7 @@
//------------------------------------------------------ //------------------------------------------------------
void LED_CLEAR() void LED_CLEAR()
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Clear The Strip Color // Clear The Strip Color
pixels.clear(); pixels.clear();
@ -23,11 +18,6 @@
// Show On LED Strip // Show On LED Strip
LED_SHOW(); LED_SHOW();
// Make Sure Of The Core
#ifdef ESP32
BOOST_OFF;
#endif
} }
//------------------------------------------------------ //------------------------------------------------------
@ -36,11 +26,6 @@
void LED_SHOW() void LED_SHOW()
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Pass It To The LED Strip // Pass It To The LED Strip
pixels.show(); pixels.show();
} }
@ -51,11 +36,6 @@
void LED_SET_BRIGHTNESS(uint8_t Value) void LED_SET_BRIGHTNESS(uint8_t Value)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Set The Brightness // Set The Brightness
pixels.setBrightness(Value); pixels.setBrightness(Value);
} }
@ -66,11 +46,6 @@
void LED_SET_COLOR(uint8_t R, uint8_t G, uint8_t B, uint8_t Intensity) void LED_SET_COLOR(uint8_t R, uint8_t G, uint8_t B, uint8_t Intensity)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Set Intensity // Set Intensity
LED_SET_BRIGHTNESS(Intensity); LED_SET_BRIGHTNESS(Intensity);
@ -105,11 +80,6 @@
// Fill the dots one after the other with a color // Fill the dots one after the other with a color
void LED_COLOR_WIPE(uint32_t c, uint8_t wait) void LED_COLOR_WIPE(uint32_t c, uint8_t wait)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Work Loop // Work Loop
for(uint16_t i=0; i<NUM_PIXELS; i++) for(uint16_t i=0; i<NUM_PIXELS; i++)
{ {
@ -126,11 +96,6 @@
// Slightly different, this makes the rainbow equally distributed throughout // Slightly different, this makes the rainbow equally distributed throughout
void LED_RAINBOW_CYCLE(uint8_t wait) void LED_RAINBOW_CYCLE(uint8_t wait)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Loop Variables // Loop Variables
uint16_t i, j; uint16_t i, j;
@ -156,11 +121,6 @@
// The colours are a transition r - g - b - back to r. // The colours are a transition r - g - b - back to r.
uint32_t LED_COLOR_WHEEL(byte WHEELPos) uint32_t LED_COLOR_WHEEL(byte WHEELPos)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Wheel Sequance // Wheel Sequance
WHEELPos = 255 - WHEELPos; WHEELPos = 255 - WHEELPos;
@ -183,11 +143,6 @@
void LED_FADEIN(uint8_t R, uint8_t G, uint8_t B) void LED_FADEIN(uint8_t R, uint8_t G, uint8_t B)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Loop For Fade // Loop For Fade
for(int i=0; i<=255; i++) for(int i=0; i<=255; i++)
{ {
@ -208,11 +163,6 @@
void LED_FADEOUT(uint8_t R, uint8_t G, uint8_t B) void LED_FADEOUT(uint8_t R, uint8_t G, uint8_t B)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Loop For Fade Out // Loop For Fade Out
for(int i=255; i>=0; i--) for(int i=255; i>=0; i--)
{ {
@ -232,12 +182,7 @@
//------------------------------------------------------ //------------------------------------------------------
void LED_CROSS_FADE(uint8_t R, uint8_t G, uint8_t B, unsigned int Times) void LED_CROSS_FADE(uint8_t R, uint8_t G, uint8_t B, unsigned int Times)
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
for(int i=0; i<Times; i++) for(int i=0; i<Times; i++)
{ {
LED_FADEIN(R, G, B); LED_FADEIN(R, G, B);
@ -310,11 +255,6 @@
void LED_BAHRAIN_FLAG() void LED_BAHRAIN_FLAG()
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
LED_SET_BRIGHTNESS(255); LED_SET_BRIGHTNESS(255);
LED_COLOR_WIPE(pixels.Color(255, 255, 255), 30); // White LED_COLOR_WIPE(pixels.Color(255, 255, 255), 30); // White
delay(250); delay(250);
@ -329,11 +269,6 @@
void LED_COLOMBIA_FLAG() void LED_COLOMBIA_FLAG()
{ {
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
LED_SET_BRIGHTNESS(255); LED_SET_BRIGHTNESS(255);
LED_COLOR_WIPE(pixels.Color(255, 255, 0), 30); // Yellow LED_COLOR_WIPE(pixels.Color(255, 255, 0), 30); // Yellow
delay(250); delay(250);

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

View File

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

View File

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

View File

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Some files were not shown because too many files have changed in this diff Show More