This commit is contained in:
ghassan committed 2020-05-25 04:56:48 +03:00
1 parent 6b0cd678c1
commit ecbffd73dd
37 files changed
+74 -2002

No files matched your search

-262
View File
@@ -1,262 +0,0 @@
//======================================================
// LIBRARIES
//======================================================
// Library Include
#include <ArduinoJson.h>
#include <TimeTrigger.h>
#include <Adafruit_NeoPixel.h>
//======================================================
// HARDWARE SETUP & SELECTION
//======================================================
// Arduino Uno Or Nano Was The Hardware
#ifdef ARDUINO_AVR_UNO || ARDUINO_AVR_NANO
//------------------------------------------------------
// Library Nessesary
#ifdef __AVR__
#include <avr/power.h>
#endif
/* ARDUINO NANO DOESNOT HAVE A SECOND NATIVE
SERIAL PORT SO WE USE SOFTWARE SERIAL LIBRARY */
#include <SoftwareSerial.h>
// 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
SoftwareSerial Bluetooth(10, 11); // Pin 10 RX, Pin 11 TX
#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 2 // 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 A4 // RANDOM NUMBER GENERATOR SOURCE
//------------------------------------------------------
// ESP32 TAKEONE BOARD
#elif ESP32
//------------------------------------------------------
/* ===============================================
* - THIS IS TAKEONE 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
* 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)
*/
/* ESP32 HAVE A NATIVE BLUETOOTH MODULE
SO WE USE BLUETOOTH SERIAL LIBRARY */
#include <BluetoothSerial.h>
// 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(); }
// JSON Object & Memory
#define CAPACITY 100
DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer
// LED Strip
#define LED_STRIP 33 // 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 39 // IMPACT SENSOR
#define RANDOM_SOURCE 34 // RANDOM NUMBER GENERATOR SOURCE
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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 */
// Boost Converter
#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)
// 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)
// Function To Make Sure The Pin Is ON
void LED_BOOST_CHK() {
if(BOOST_STU == LOW) {
BOOST_ON;
delay(1);
}
}
// 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;
}
#endif
//======================================================
// PREDEFINED JSON STRINGS MESSAGES
//======================================================
// FIXED MESSAGES
#define POWERUP "{\"status\":\"POWER UP\"}"
#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\"}"
//======================================================
// READING IMPACT POWER FROM ANALOG PINS
//======================================================
// READING THE IMPACT
int readImpact()
{
int value = analogRead(SENSOR_PIN);
return value;
}
//======================================================
// MAIN HARDWARE SETUP
//======================================================
void setup()
{
// Communications
Terminal.begin(9600);
// Make Sure Of The Core
#ifdef ESP32
Bluetooth.begin("KICKER"); // Bluetooth device name
BOOST_SETUP; // Boost Pin Setup
BOOST_OFF; // Turn It Off
#else
Bluetooth.begin(9600); // Bluetooth HC-05 / HC-06
#endif
// I/O
pixels.begin(); // Neo Pixel
LED_CLEAR(); // Turn Off All LED
// The Random Number Source
randomSeed(analogRead(RANDOM_SOURCE));
// POWER UP MESSGAE
dualcomm(POWERUP);
// DISPLAY COMPANY COUNTRY FLAG
LED_BAHRAIN_FLAG(); // Bahrain Flag
LED_COLOMBIA_FLAG(); // Colombia Flag
// DisJSON Rainbow
LED_CLEAR();
}
//======================================================
// MAIN PROGRAM LOOP
//======================================================
void loop()
{
// Reading From Bluetooth
if(isBluetooth)
{
// Reading Message From Bluetooth
String msg = Bluetooth.readStringUntil('\n');
flushBluetooth;
msg.trim();
// Display On Serial Monitor For Debuging
terminal(msg);
// 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
game_selector(game, settings);
}
else
{
terminal(JSON_ERROR);
}
Bluetooth.flush();
}
}
//======================================================
// END OF PROGRAM
//======================================================
-29
View File
@@ -1,29 +0,0 @@
//======================================================
// TERMINAL WINDOW - NATIVE USB
//======================================================
void terminal(String msg)
{
msg += "\n";
Terminal.print(msg);
}
//======================================================
// BLUETOOTH WINDOW - NATIVE/VERTUAL USB
//======================================================
void bluetooth(String msg)
{
msg += "\n";
Bluetooth.print(msg);
}
//======================================================
// BLUETOOTH WINDOW - NATIVE/VERTUAL USB
//======================================================
void dualcomm(String msg)
{
terminal(msg);
bluetooth(msg);
}
-178
View File
@@ -1,178 +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 = 0;
bool limitEnable = 0;
// Play The Game
game_counter(limit, limitEnable);
}
//======================================================
// 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);
}
//======================================================
// 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();
//-------------------------
// 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 = 0;
startStamp = millis();
timeStamp = startStamp;
LED_SIGNAL_RESET();
}
}
// If Limits Are Enabled And Meet
if(limitEnable == true && counter == limit)
{
// END GAME
dualcomm(GAME_OVER);
// Celebration
LED_SIGNAL_CELEBRATION();
// RESET
return;
}
// Read Impact
if(readImpact() > VTH)
{
counter++;
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;
}
-266
View File
@@ -1,266 +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 = 0;
uint8_t maxDelay = 0;
uint8_t trials = 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
// If The Menu Number 3 -> We Set The Number Of Trials
// Call the Game Play
play_reaction(minDelay, maxDelay, trials);
}
//======================================================
// 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);
}
//======================================================
// Play The Game
//======================================================
void play_reaction(uint8_t minDelay, uint8_t maxDelay, uint16_t trials)
{
// PUBLIC VARIABLES
uint16_t temp = trials;
// 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();
//-------------------------
// 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 = readImpact();
// 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();
trials = temp;
break;
}
}
}
// Stop Timer
stopTime = millis();
// Stop Light
LED_SET_COLOR(255, 0, 0, 255);
// Calculating Response Time
response = stopTime - startTime - 1;
// Create Json JSON
String msg = reaction_JSON_json(i+1, power, response, sdelay);
// 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();
// 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);
}
-37
View File
@@ -1,37 +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 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;
}
}
-233
View File
@@ -1,233 +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 = 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
// If The Menu Number 3 -> We Set The Number Of Trials
// Call the Game Play
game_timeAttack(time, timer, limit, limitEnable);
}
//======================================================
// 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
uint16_t time = JSON["tm"]; // Time Window To JSON
uint16_t timer = time;
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, timer, limit, limitEnable);
}
//======================================================
// Play Time Atack Game
//======================================================
void game_timeAttack(uint16_t time, uint16_t timer, uint16_t limit, bool limitEnable)
{
// Building Timers 1000mSec -> 1Sec
TimeTrigger sec_tick(1000);
// Kick Counter
uint16_t counter = 0;
// Start LED Signal
LED_SIGNAL_START();
//-------------------------
// PREPARE FOR GAME START
//-------------------------
// Send Initial DisJSON
dualcomm(timeAttack_JSON_json(timer, counter, 0, 0));
// 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();
dualcomm(timeAttack_JSON_json(timer, counter, lastStamp, timeStamp));
LED_SIGNAL_RESET();
}
}
// Every Kick ---------------------------->>>
if(readImpact() > VTH)
{
counter++;
dualcomm(timeAttack_JSON_json(timer, counter, lastStamp, timeStamp));
lastStamp = timeStamp;
delay(100);
}
// 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)
{
// END GAME
dualcomm(GAME_OVER);
// Celebrate
LED_SIGNAL_CELEBRATION();
// Return
return;
}
}
// Send End Game Signal To Smart Phone
dualcomm(GAME_OVER);
// 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;
}
-345
View File
@@ -1,345 +0,0 @@
#define BETWEEN_FADE 15
#define FADE_RATE 15
#define BLINK_RATE 250
//------------------------------------------------------
// Clearing The LED Strip
//------------------------------------------------------
void LED_CLEAR()
{
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Clear The Strip Color
pixels.clear();
// Make Sure Of The Core
#ifdef ESP32
delay(1);
#endif
// Show On LED Strip
LED_SHOW();
// Make Sure Of The Core
#ifdef ESP32
BOOST_OFF;
#endif
}
//------------------------------------------------------
// DISPLAY ON STRIP
//------------------------------------------------------
void LED_SHOW()
{
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Pass It To The LED Strip
pixels.show();
}
//------------------------------------------------------
// Set LED Brightness
//------------------------------------------------------
void LED_SET_BRIGHTNESS(uint8_t Value)
{
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Set The Brightness
pixels.setBrightness(Value);
}
//------------------------------------------------------
// Set LED Color
//------------------------------------------------------
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
LED_SET_BRIGHTNESS(Intensity);
// Loop
for(int i=0; i<NUM_PIXELS; i++) {
pixels.setPixelColor(i, pixels.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 Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Work Loop
for(uint16_t i=0; i<NUM_PIXELS; i++)
{
pixels.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 Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// 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< pixels.numPixels(); i++)
{
pixels.setPixelColor(i, LED_COLOR_WHEEL(((i * 256 / pixels.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 Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Wheel Sequance
WHEELPos = 255 - WHEELPos;
if(WHEELPos < 85)
{
return pixels.Color(255 - WHEELPos * 3, 0, WHEELPos * 3);
}
if(WHEELPos < 170)
{
WHEELPos -= 85;
return pixels.Color(0, WHEELPos * 3, 255 - WHEELPos * 3);
}
WHEELPos -= 170;
return pixels.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 Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Loop For Fade
for(int i=0; i<=255; i++)
{
pixels.setBrightness(i);
for(int j=0; j<NUM_PIXELS; j++)
{
pixels.setPixelColor(j, pixels.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 Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
// Loop For Fade Out
for(int i=255; i>=0; i--)
{
pixels.setBrightness(i);
for(int j=0; j<NUM_PIXELS; j++)
{
pixels.setPixelColor(j, pixels.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 Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
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()
{
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
LED_SET_BRIGHTNESS(255);
LED_COLOR_WIPE(pixels.Color(255, 255, 255), 30); // White
delay(250);
LED_COLOR_WIPE(pixels.Color(255, 0, 0), 30); // Red
delay(250);
LED_FADEOUT(255, 0, 0);
}
//------------------------------------------------------
// DISPLAY COLOMBIA FLAG
//------------------------------------------------------
void LED_COLOMBIA_FLAG()
{
// Make Sure Of The Core
#ifdef ESP32
LED_BOOST_CHK();
#endif
LED_SET_BRIGHTNESS(255);
LED_COLOR_WIPE(pixels.Color(255, 255, 0), 30); // Yellow
delay(250);
LED_COLOR_WIPE(pixels.Color(0, 0, 255), 30); // Blue
delay(250);
LED_COLOR_WIPE(pixels.Color(255, 0, 0), 30); // Red
delay(250);
LED_FADEOUT(255, 0, 0);
}
-40
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);
}
-22
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();
}
}
}
-264
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;
}
}
}
-346
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;
}
}
}
-70
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;
}
-316
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;
}
}
}
-382
View File
@@ -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 <Wire.h>
#include <EEPROM.h>
#include <Button.h>
#include <TimeTrigger.h>
#include <ArduinoJson.h>
#include <BluetoothSerial.h>
#include <Adafruit_NeoPixel.h>
//======================================================
// OVER THE AIR PROGRAMMING
//======================================================
// #include <WiFi.h>
// #include <ESPmDNS.h>
// #include <WiFiUdp.h>
// #include <ArduinoOTA.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
//------------------------------------------------------
#ifdef __AVR__
#include <avr/power.h> // 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;
}
}
}
-247
View File
@@ -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<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)
{
// 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)
{
// 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)
{
// 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)
{
// 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)
{
// 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)
{
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()
{
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()
{
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);
}
-272
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;
}
}
-53
View File
@@ -1,53 +0,0 @@
//====================================================================
// GENERAL FUNCTION SECTION
//====================================================================
// 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");
}
//--------------------------------------------------------------------
// Float Number Mapping Function
//--------------------------------------------------------------------
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;
}
-41
View File
@@ -1,41 +0,0 @@
//====================================================================
// COUNTER GAME PROGRAM PAGE
//====================================================================
// GAME COUNTER - MENU
//--------------------------------------------------------------------
void game_counter_menu()
{
menu_display("COUNTER");
}
//--------------------------------------------------------------------
// GAME COUNTER - SETTINGS DISPLAY
//--------------------------------------------------------------------
void game_counter_settings()
{
}
//--------------------------------------------------------------------
// GAME COUNTER - GAME PLAY
//--------------------------------------------------------------------
void game_counter_play()
{
oled_clear();
drawTextCenter(128/2, 0, 2, "KICKS");
//drawTextCenter(128/2, 20, 3, String(count));
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
oled_show();
}
//--------------------------------------------------------------------
// GAME COUNTER - GAME FINAL RESULT
//--------------------------------------------------------------------
void game_counter_results()
{
}
-41
View File
@@ -1,41 +0,0 @@
//====================================================================
// DECISION GAME PROGRAM PAGE
//====================================================================
// GAME DECISION - MENU
//--------------------------------------------------------------------
void game_decision_menu()
{
menu_display("DECISION");
}
//--------------------------------------------------------------------
// GAME DECISION - SETTINGS DISPLAY
//--------------------------------------------------------------------
void game_decision_settings()
{
}
//--------------------------------------------------------------------
// GAME DECISION - GAME PLAY
//--------------------------------------------------------------------
void game_decision_play()
{
oled_clear();
drawTextCenter(128/2, 0, 2, "KICKS");
//drawTextCenter(128/2, 20, 3, String(count));
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
oled_show();
}
//--------------------------------------------------------------------
// GAME DECISION - GAME FINAL RESULT
//--------------------------------------------------------------------
void game_decision_results()
{
}
-42
View File
@@ -1,42 +0,0 @@
//====================================================================
// FOUCSE GAME PROGRAM PAGE
//====================================================================
// GAME FOUCSE - MENU
//--------------------------------------------------------------------
void game_foucse_menu()
{
menu_display("FOCUSE");
}
//--------------------------------------------------------------------
// GAME FOUCSE - SETTINGS DISPLAY
//--------------------------------------------------------------------
void game_foucse_settings()
{
}
//--------------------------------------------------------------------
// GAME FOUCSE - GAME PLAY
//--------------------------------------------------------------------
void game_foucse_play()
{
oled_clear();
drawTextCenter(128/2, 0, 2, "KICKS");
//drawTextCenter(128/2, 20, 3, String(count));
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
oled_show();
}
//--------------------------------------------------------------------
// GAME FOUCSE - GAME FINAL RESULT
//--------------------------------------------------------------------
void game_foucse_results()
{
}
-42
View File
@@ -1,42 +0,0 @@
//====================================================================
// REACTION GAME PROGRAM PAGE
//====================================================================
// GAME REACTION - MENU
//--------------------------------------------------------------------
void game_reaction_menu()
{
menu_display("REACTION");
}
//--------------------------------------------------------------------
// GAME REACTION - SETTINGS DISPLAY
//--------------------------------------------------------------------
void game_reaction_settings()
{
}
//--------------------------------------------------------------------
// GAME REACTION - GAME PLAY
//--------------------------------------------------------------------
void game_reaction_play()
{
oled_clear();
drawTextCenter(128/2, 0, 2, "KICKS");
//drawTextCenter(128/2, 20, 3, String(count));
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
oled_show();
}
//--------------------------------------------------------------------
// GAME REACTION - GAME FINAL RESULT
//--------------------------------------------------------------------
void game_reaction_results()
{
}
-41
View File
@@ -1,41 +0,0 @@
//====================================================================
// STAMINA GAME PROGRAM PAGE
//====================================================================
// GAME STAMINA - MENU
//--------------------------------------------------------------------
void game_stamina_menu()
{
menu_display("STAMINA");
}
//--------------------------------------------------------------------
// GAME STAMINA - SETTINGS DISPLAY
//--------------------------------------------------------------------
void game_stamina_settings()
{
}
//--------------------------------------------------------------------
// GAME STAMINA - GAME PLAY
//--------------------------------------------------------------------
void game_stamina_play()
{
oled_clear();
drawTextCenter(128/2, 0, 2, "KICKS");
//drawTextCenter(128/2, 20, 3, String(count));
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
oled_show();
}
//--------------------------------------------------------------------
// GAME STAMINA - GAME FINAL RESULT
//--------------------------------------------------------------------
void game_stamina_results()
{
}
-41
View File
@@ -1,41 +0,0 @@
//====================================================================
// TIMEATTACK GAME PROGRAM PAGE
//====================================================================
// GAME TIMEATTACK - MENU
//--------------------------------------------------------------------
void game_timeattack_menu()
{
menu_display("TIMEATTACK");
}
//--------------------------------------------------------------------
// GAME TIMEATTACK - SETTINGS DISPLAY
//--------------------------------------------------------------------
void game_timeattack_settings()
{
}
//--------------------------------------------------------------------
// GAME TIMEATTACK - GAME PLAY
//--------------------------------------------------------------------
void game_timeattack_play()
{
oled_clear();
drawTextCenter(128/2, 0, 2, "KICKS");
//drawTextCenter(128/2, 20, 3, String(count));
drawTextCenter(128/2, 50, 1, "<< EXIT >>");
oled_show();
}
//--------------------------------------------------------------------
// GAME TIMEATTACK - GAME FINAL RESULT
//--------------------------------------------------------------------
void game_timeattack_results()
{
}
-58
View File
@@ -1,58 +0,0 @@
//====================================================================
// COUNTER GAME PROGRAM PAGE
//====================================================================
// DISPLAY MENU TITLE FUNCTION
//--------------------------------------------------------------------
void menu_display(String Title)
{
// Starting The First Code
oled_clear();
drawTextCenter(128/2, 5, 1, "MODE " + String(menu_count + 1));
drawTextCenter(128/2, 22, 2, " - " + Title + " - ");
drawTextCenter(128/2, 43, 1, "<< SELECT >>");
oled_show();
display_changed = true;
}
//--------------------------------------------------------------------
// SWITCH GAME MENUS
//--------------------------------------------------------------------
void switch_menu()
{
if(menu_count == 0 && display_changed == false) {
game_counter_menu();
} else if(menu_count == 1 && display_changed == false) {
game_timeattack_menu();
} else if(menu_count == 2 && display_changed == false) {
game_reaction_menu();
} else if(menu_count == 3 && display_changed == false) {
game_decision_menu();
} else if(menu_count == 4 && display_changed == false) {
game_stamina_menu();
} else if(menu_count == 5 && display_changed == false) {
game_foucse_menu();
}
}
//--------------------------------------------------------------------
// SELECT A GAME
//--------------------------------------------------------------------
void select_game()
{
if(menu_count == 0 && CB.pressed()) {
} else if(menu_count == 1 && CB.pressed()) {
} else if(menu_count == 2 && CB.pressed()) {
} else if(menu_count == 3 && CB.pressed()) {
} else if(menu_count == 4 && CB.pressed()) {
} else if(menu_count == 5 && CB.pressed()) {
}
}
-61
View File
@@ -1,61 +0,0 @@
//====================================================================
// ADAFRUITE NEO PIXEL
//====================================================================
// INCLUDE LIBRARY
//--------------------------------------------------------------------
// Neo Pixel Library
#include <Adafruit_NeoPixel.h>
// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL, NEO_GRB + NEO_KHZ800);
//--------------------------------------------------------------------
// INITIALIZE LED STRIP OBJECT (REQUIRED)
//--------------------------------------------------------------------
void neo_init() {
BOOST_ON;
delay(5);
pixels.begin();
pixels.clear();
pixels.show();
delay(5);
BOOST_OFF;
}
//--------------------------------------------------------------------
// TURNON LED STRIP - FOR WELCOME
//--------------------------------------------------------------------
void neo_welcome() {
}
//--------------------------------------------------------------------
// TURNON LED STRIP WITH COLOR
//--------------------------------------------------------------------
void neo_color(uint8_t R, uint8_t G, uint8_t B) {
BOOST_ON;
delay(1);
pixels.clear();
for(int i=0; i<NUMPIXELS; i++)
{
pixels.setPixelColor(i, pixels.Color(R, G, B));
}
pixels.setBrightness(50);
delay(2);
pixels.show();
}
//--------------------------------------------------------------------
// TURNOFF LED STRIP
//--------------------------------------------------------------------
void neo_turnoff() {
pixels.clear();
pixels.show();
BOOST_OFF;
}
-175
View File
@@ -1,175 +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 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) + "%");
}
//--------------------------------------------------------------------
// OLED CLEAR DISPLAY
//--------------------------------------------------------------------
void oled_clear() {
display.clear();
}
//--------------------------------------------------------------------
// 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 BATTERY LEVEL
//--------------------------------------------------------------------
void battery_level_display() {
// Counting Time
timetick = millis();
// Taking Action Based On Time Count
if(timetick - prevtick >= 5000)
{
prevtick = timetick;
String BV = String(BATTERY,2);
String BC = String(CHARGE, 0);
oled_clear();
drawTextFlowDemo("Battery Level : " + BV + " V Charge Level : " + BC + "%");
drawProgressBarDemo(BC.toInt());
oled_show();
}
}
-240
View File
@@ -1,240 +0,0 @@
//====================================================================
// SDCARD READER FUNCTIONS
//====================================================================
// LIST DIRECTORIES
//--------------------------------------------------------------------
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.println(file.name());
if(levels){
listDir(fs, file.name(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
//--------------------------------------------------------------------
// CREATE DIRECTORY
//--------------------------------------------------------------------
void createDir(fs::FS &fs, const char * path){
Serial.printf("Creating Dir: %s\n", path);
if(fs.mkdir(path)){
Serial.println("Dir created");
} else {
Serial.println("mkdir failed");
}
}
//--------------------------------------------------------------------
// REMOVE DIRECTORIES
//--------------------------------------------------------------------
void removeDir(fs::FS &fs, const char * path){
Serial.printf("Removing Dir: %s\n", path);
if(fs.rmdir(path)){
Serial.println("Dir removed");
} else {
Serial.println("rmdir failed");
}
}
//--------------------------------------------------------------------
// READ FILE
//--------------------------------------------------------------------
void readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if(!file){
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while(file.available()){
Serial.write(file.read());
}
file.close();
}
//--------------------------------------------------------------------
// WRITE TO A FILE / CREATE A NEW FILE
//--------------------------------------------------------------------
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
//--------------------------------------------------------------------
// WRITE TO THE BOTTOM OF A FILE / CONTINUE WRITING
//--------------------------------------------------------------------
void appendFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
//--------------------------------------------------------------------
// RENAME A FILE / CHNAGE THE NAME OF A FILE
//--------------------------------------------------------------------
void renameFile(fs::FS &fs, const char * path1, const char * path2){
Serial.printf("Renaming file %s to %s\n", path1, path2);
if (fs.rename(path1, path2)) {
Serial.println("File renamed");
} else {
Serial.println("Rename failed");
}
}
//--------------------------------------------------------------------
// DELETE A FILE
//--------------------------------------------------------------------
void deleteFile(fs::FS &fs, const char * path){
Serial.printf("Deleting file: %s\n", path);
if(fs.remove(path)){
Serial.println("File deleted");
} else {
Serial.println("Delete failed");
}
}
//--------------------------------------------------------------------
// SDCARD TEST ROUTINE
//--------------------------------------------------------------------
void testFileIO(fs::FS &fs, const char * path){
File file = fs.open(path);
static uint8_t buf[512];
size_t len = 0;
uint32_t start = millis();
uint32_t end = start;
if(file){
len = file.size();
size_t flen = len;
start = millis();
while(len){
size_t toRead = len;
if(toRead > 512){
toRead = 512;
}
file.read(buf, toRead);
len -= toRead;
}
end = millis() - start;
Serial.printf("%u bytes read for %u ms\n", flen, end);
file.close();
} else {
Serial.println("Failed to open file for reading");
}
file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
size_t i;
start = millis();
for(i=0; i<2048; i++){
file.write(buf, 512);
}
end = millis() - start;
Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
file.close();
}
//--------------------------------------------------------------------
// STARTING SDCARD READER
//--------------------------------------------------------------------
void sdcard_init(){
if(!SD.begin()){
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if(cardType == CARD_MMC){
Serial.println("MMC");
} else if(cardType == CARD_SD){
Serial.println("SDSC");
} else if(cardType == CARD_SDHC){
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
//listDir(SD, "/", 0);
//createDir(SD, "/mydir");
//listDir(SD, "/", 0);
//removeDir(SD, "/mydir");
//listDir(SD, "/", 2);
writeFile(SD, "/battery.txt", "Battery Monitoring");
//appendFile(SD, "/hello.txt", "World!\n");
//readFile(SD, "/hello.txt");
//deleteFile(SD, "/foo.txt");
//renameFile(SD, "/hello.txt", "/foo.txt");
//readFile(SD, "/foo.txt");
//testFileIO(SD, "/test.txt");
//Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
//Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}
-380
View File
@@ -1,380 +0,0 @@
/* ===============================================
* - THIS IS TAKEONE 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
* 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)
* 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
*/
// Include Library
#include <FS.h>
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <Button.h>
#include <ArduinoJson.h>
#include <BluetoothSerial.h>
#include <Adafruit_NeoPixel.h>
//----------------------------------------------------------------
// Communication Models
//----------------------------------------------------------------
// Serial Port As Terminal
#define terminal Serial
// Clearing Terminal Remainning
#define flush_terminal while(terminal.available()) { terminal.read(); }
// Bluetooth Object
BluetoothSerial bluetooth;
// Bluetooth Connection Status
bool bluetooth_conn = false;
// Clearing Bluetooth Remainning
#define flush_bluetooth while(bluetooth.available()) { bluetooth.read(); }
// Fixed JSON Strings
#define POWERUP "{\"status\":\"POWER UP\"}"
#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\"}"
// JSON CAPACITY
#define capacity 250
//----------------------------------------------------------------
// TAKEONE BOARD HARDWARE DEFINITIONS
//----------------------------------------------------------------
// On Board MPU9250 I2C Address
#define MPU_ADD 0x69
// Connected I2C OLED Address
#define OLED_ADD 0x3C
// Connected I2C LCD Address
#define LCD_ADD 0x2C
// Define Impact Sensor
#define PIEZO analogRead(34)
#define VOLTS mapf(PIEZO, 0, 4095, 0, 3.3)
// Panel Push Buttons Pin Assignment Sections
Button TLB(32); // Top Left Button
Button BLB(15); // Bottom Left Button
Button CB(33); // Center Button
Button BRB(27); // Bottom Right Button
Button TRB(12); // Top Right Button 33
// Panel Push Buttons Command Assignment
#define PrvMenu TLB.pressed()
#define NxtMenu TRB.pressed()
#define SelMenu CB.pressed()
#define IncBtn BLB.pressed()
#define DecBtn BRB.pressed()
// NEO Pixel Strip Section
#define NEOPIXEL 26 // Define Pin Number
#define NUMPIXELS 22 // Define Number Of LED's
// Battery Level Monitoring
#define BATTERY (float)(((analogRead(35) * (3.3 / 4096)) * 2) + 0.31)
#define CHARGE mapf(BATTERY, 3.27, 4.31, 0, 100)
// Power Latch Holder Pin
#define POWER_PIN 14
#define POWER_SETUP pinMode(POWER_PIN, OUTPUT)
#define POWER_ON digitalWrite(POWER_PIN, HIGH)
#define POWER_OFF digitalWrite(POWER_PIN, LOW)
// Battery To 5V Level Booster Setup & Control
#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)
// On Board LED Setup & Control
#define LED_PIN 13
#define LED_SETUP pinMode(LED_PIN, OUTPUT)
#define LED_ON digitalWrite(LED_PIN, HIGH)
#define LED_OFF digitalWrite(LED_PIN, LOW)
// For Timming
unsigned long timetick = 0;
unsigned long prevtick = 0;
/* Display Change Flag Explaination
* This flag is used to prevent continous writing to the oled display
* once a change has happened we drive the display_changed to false this will tell
* the micro controller that a need to write new data is needed, after writing the new data to display
* then we drive the display_changed to true that means the nessary changes has been written
*/
bool display_changed = false;
uint8_t menu_count = 0;
//--------------------------------------------------------------------
// Bluetooth Connection Status Call Back
//--------------------------------------------------------------------
void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
if(event == ESP_SPP_SRV_OPEN_EVT){
//Serial.println("Client Connected");
bluetooth_conn = true;
}
if(event == ESP_SPP_CLOSE_EVT ){
//Serial.println("Client disconnected");
bluetooth_conn = false;
}
}
//--------------------------------------------------------------------
// CHIP MAIN SETUP
//--------------------------------------------------------------------
void setup()
{
// Starting Serial Communications
terminal.begin(115200); // Starting Main USB UART Communication Interface
terminal.println(); // New Line Seperator 1
terminal.println(); // New Line Seperator 2
// Starting The Bluetooth Module
if(!bluetooth.begin("KICKER")) {
terminal.println("An error occurred initializing Bluetooth");
} else {
terminal.println("Bluetooth initialized");
}
// Checking The Connection Status
bluetooth.register_callback(callback);
// Pin Assignments
BOOST_SETUP; // Boost Converter Pin Setup
LED_SETUP; // OnBoard LED Pin Setup
// Turn Off The Pins
BOOST_OFF; // Turn Off The Booster
LED_OFF; // Turn Off The LED
// The Five Panel Buttons
TLB.begin(); // Setup The Top Left Panel Button
BLB.begin(); // Setup The Bottom Left Panel Button
BRB.begin(); // Setup The Bottom Right Panel Button
TRB.begin(); // Setup The Top Right Panel Button
CB.begin(); // Setup The Center Panel Button
// I2C Section
Wire.begin(); // Starting I2C Communication Interface
scanI2C(); // Starting I2C Communicatable Devices Detection
oled_init(); // Starting OLED Display I2C Communications
kicker_logo(); // Display Kicker Main Logo Display
// Starting SDCARD Interface
sdcard_init(); // Starting SDCARD Reader Communication Protocol
// Neo Pixel Section
neo_init(); // Starting Neo Pixel
neo_color(0, 0, 0); // Clear All LED's
delay(10); // Delay 10 Milli Seconds
neo_color(255, 0, 0); // Display RED LED Strip
delay(1000); // Delay 1 Second
neo_color(0, 255, 0); // Display GREEN LED Strip
delay(1000); // Delay 1 Second
neo_color(0, 0, 255); // Display BLUE LED Strip
delay(1000); // Delay 1 Second
neo_turnoff(); // Power Off Neo Pixels & Their Power
// THE PROGRAM STATE = MENU
display_changed = false; // Allow Display Change
}
//--------------------------------------------------------------------
// CHIP MAIN PROGRAM
//--------------------------------------------------------------------
void loop()
{
// Checking The Bluetooth Connection
bluetooth.register_callback(callback);
// Condition The Preiority Is For The Bluetooth
if(bluetooth_conn == true)
{
// Wait For Game JSON String
read_game_json();
}
// Condition To Stand Alone Mode - Manual Mode
else
{
// Previous Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(TLB.pressed()) {
if(menu_count == 0) {
menu_count = 4;
} else {
menu_count--;
}
display_changed = false;
}
// Next Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(TRB.pressed()) {
if(menu_count == 4) {
menu_count = 0;
} else {
menu_count++;
}
display_changed = false;
}
// Select A Game ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(CB.pressed()) {
select_game();
}
// Increase Power ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(BLB.pressed()) {
}
// Decrease Power ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(BRB.pressed()) {
}
// Display Target Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~
switch_menu();
}
}
//======================================================
// Read Game JSON String Command From Mobile
//======================================================
void read_game_json()
{
// Reading From Bluetooth
if(bluetooth.available())
{
// Reading Message From Bluetooth
String msg = bluetooth.readStringUntil('\n');
// Clearing The Receive Buffer
flush_bluetooth;
// Clean The Message
msg.trim();
// Display On Sertial
terminal.println(msg);
// Parsing Objects Message Objects
DynamicJsonDocument root(capacity);
// Deserialize the JSON document
DeserializationError error = deserializeJson(root, msg);
// If The System Understood The Message Clearly
if(!error)
{
// Sending Status Message
terminal.println(UNDERSTOOD);
bluetooth.println(UNDERSTOOD);
// Reading Game Name & Settings
String game = root["gm"];
String settings = root["set"];
// Clearing JSON Document Buffer
root.clear();
// Entering To Game Selector
game_selector(game, settings);
}
else
{
// Display On Serial
terminal.println(JSON_ERROR);
}
// Bluetooth Serial RXD Flush
flush_bluetooth;
}
}
//======================================================
// Game Selector Function
//======================================================
void game_selector(String game, String settings)
{
// Kick Counter Game
if(game == "ct") {
terminal.println(GM_COUNTER);
//game_counter(settings);
return;
}
// Time Attack Game
else if(game == "ta") {
terminal.println(GM_TATTACK);
//game_timeAttack(settings);
return;
}
// Time Attack Game
else if(game == "ra") {
terminal.println(GM_REACTION);
//game_reaction(settings);
return;
}
// Unknown Game
else {
terminal.println(UNKNOWN_GAME);
bluetooth.println(UNKNOWN_GAME);
return;
}
}