update
This commit is contained in:
1 parent
6b0cd678c1
commit
ecbffd73dd
37 files changed
+74
-2002
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,8 +10,8 @@
|
||||
//======================================================
|
||||
// HARDWARE SETUP & SELECTION
|
||||
//======================================================
|
||||
// Arduino Uno Or Nano Was The Hardware
|
||||
#ifdef ARDUINO_AVR_UNO || ARDUINO_AVR_NANO
|
||||
// Arduino MEGA
|
||||
#ifdef ARDUINO_AVR_MEGA2560
|
||||
//------------------------------------------------------
|
||||
|
||||
// Library Nessesary
|
||||
@@ -19,7 +19,41 @@
|
||||
#include <avr/power.h>
|
||||
#endif
|
||||
|
||||
/* ARDUINO NANO DOESNOT HAVE A SECOND NATIVE
|
||||
// Serial Terminal
|
||||
#define Terminal Serial // SERIAL PORT USED AS TERMINAL WINDO FOR DEBUG
|
||||
#define isTerminal Terminal.available() // Terminal Serial Buffer Available
|
||||
#define flushTerminal while(isTerminal) { Terminal.read(); }
|
||||
|
||||
// Bluetooth Terminal
|
||||
#define Bluetooth Serial1 // We will Connect The HC-05 To Hardware Serial1 In Arduino Mega
|
||||
#define isBluetooth Bluetooth.available() // Bluetooth Serial Buffer Available
|
||||
#define flushBluetooth while(isBluetooth) { Bluetooth.read(); }
|
||||
|
||||
// JSON Object & Memory
|
||||
#define CAPACITY 100
|
||||
DynamicJsonDocument JSON(CAPACITY); // Building JSON Buffer
|
||||
|
||||
// LED Strip
|
||||
#define LED_STRIP 53 // LED STRIP PIN NUMBER
|
||||
#define NUM_PIXELS 14 // NUMBER OF LED'S IN NEO PIXEL STRIP
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, LED_STRIP, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
// Impact Detection
|
||||
#define VTH 14 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR
|
||||
#define SENSOR_PIN A0 // IMPACT SENSOR
|
||||
#define RANDOM_SOURCE A7 // RANDOM NUMBER GENERATOR SOURCE
|
||||
|
||||
//------------------------------------------------------
|
||||
// Arduino Uno / Nano
|
||||
#elif ARDUINO_AVR_UNO || ARDUINO_AVR_NANO
|
||||
//------------------------------------------------------
|
||||
|
||||
// Library Nessesary
|
||||
#ifdef __AVR__
|
||||
#include <avr/power.h>
|
||||
#endif
|
||||
|
||||
/* ARDUINO NANO DOESNOT HAVE A SECOND NATIVE
|
||||
SERIAL PORT SO WE USE SOFTWARE SERIAL LIBRARY */
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
@@ -67,7 +101,7 @@
|
||||
* SPI PIN : CS 5, SCK 18, MISO 19, MOSI 23 (DIGITAL)
|
||||
* BOOST CONTROL PIN : 14 (DIGITAL) OUTPUT ON PADS (TP1 +5V, TP2 GND)
|
||||
* LED PIN : 13 (DIGITAL)
|
||||
* BATTERY MONITOR PIN : 35 (ANALOG)
|
||||
* BATTERY MONITOR PIN : 35 (ANALOG)
|
||||
*/
|
||||
|
||||
/* ESP32 HAVE A NATIVE BLUETOOTH MODULE
|
||||
@@ -102,7 +136,7 @@
|
||||
#define VTH 14 // THRESHOLD VOLTAGE FOR ZERO POSITIONNING KICKING POWER SENSOR
|
||||
#define SENSOR_PIN 39 // IMPACT SENSOR
|
||||
#define RANDOM_SOURCE 34 // RANDOM NUMBER GENERATOR SOURCE
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Exclusive Features Of TAKEONE BOARD
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -110,7 +144,7 @@
|
||||
/* ESP32 TAKEONE Board has some unique hardware features
|
||||
* 1. Battery Voltage Level Monitoring Via Analog Pin 35
|
||||
* 2. Boost Converter In Case We Need 5V Supply From Li-Ion Battery
|
||||
* 3. I2C : Motion Sensor IMU/MPU9250 9 Degrees Of Fredom
|
||||
* 3. I2C : Motion Sensor IMU/MPU9250 9 Degrees Of Fredom
|
||||
* 4. SPI : SDCARD Reader */
|
||||
|
||||
// Boost Converter
|
||||
@@ -171,7 +205,7 @@
|
||||
//======================================================
|
||||
|
||||
// READING THE IMPACT
|
||||
int readImpact()
|
||||
int readImpact()
|
||||
{
|
||||
int value = analogRead(SENSOR_PIN);
|
||||
return value;
|
||||
@@ -181,7 +215,7 @@
|
||||
// MAIN HARDWARE SETUP
|
||||
//======================================================
|
||||
|
||||
void setup()
|
||||
void setup()
|
||||
{
|
||||
// Communications
|
||||
Terminal.begin(9600);
|
||||
@@ -217,10 +251,10 @@
|
||||
// MAIN PROGRAM LOOP
|
||||
//======================================================
|
||||
|
||||
void loop()
|
||||
void loop()
|
||||
{
|
||||
// Reading From Bluetooth
|
||||
if(isBluetooth)
|
||||
if(isBluetooth)
|
||||
{
|
||||
// Reading Message From Bluetooth
|
||||
String msg = Bluetooth.readStringUntil('\n');
|
||||
@@ -229,7 +263,7 @@
|
||||
|
||||
// Display On Serial Monitor For Debuging
|
||||
terminal(msg);
|
||||
|
||||
|
||||
// Deserialize the JSON document
|
||||
DeserializationError error = deserializeJson(JSON, msg);
|
||||
|
||||
@@ -245,7 +279,7 @@
|
||||
|
||||
// Clearing JSON Buffer
|
||||
JSON.clear();
|
||||
|
||||
|
||||
// Entering To Game Selector
|
||||
game_selector(game, settings);
|
||||
}
|
||||
@@ -2,17 +2,17 @@
|
||||
// TERMINAL WINDOW - NATIVE USB
|
||||
//======================================================
|
||||
|
||||
void terminal(String msg)
|
||||
void terminal(String msg)
|
||||
{
|
||||
msg += "\n";
|
||||
Terminal.print(msg);
|
||||
}
|
||||
|
||||
|
||||
//======================================================
|
||||
// BLUETOOTH WINDOW - NATIVE/VERTUAL USB
|
||||
//======================================================
|
||||
|
||||
void bluetooth(String msg)
|
||||
void bluetooth(String msg)
|
||||
{
|
||||
msg += "\n";
|
||||
Bluetooth.print(msg);
|
||||
@@ -22,7 +22,7 @@
|
||||
// BLUETOOTH WINDOW - NATIVE/VERTUAL USB
|
||||
//======================================================
|
||||
|
||||
void dualcomm(String msg)
|
||||
void dualcomm(String msg)
|
||||
{
|
||||
terminal(msg);
|
||||
bluetooth(msg);
|
||||
File renamed without changes.
File renamed without changes.
@@ -3,7 +3,7 @@
|
||||
//======================================================
|
||||
|
||||
/* game selector is the main function that tell the game groutine
|
||||
* which game to be JSONed and at what parameters
|
||||
* which game to be JSONed and at what parameters
|
||||
*/
|
||||
|
||||
void game_selector(String game, String settings)
|
||||
@@ -18,7 +18,7 @@
|
||||
// Time Attack Game
|
||||
else if(game == "ta") {
|
||||
terminal(GM_TATTACK);
|
||||
time_attack_bluetooth(settings);
|
||||
game_reaction_bluetooth(settings);
|
||||
return;
|
||||
}
|
||||
|
||||
+22
-24
@@ -2,17 +2,17 @@
|
||||
// TIME ATTACK GAME MAIN ROUTINE
|
||||
//======================================================
|
||||
|
||||
/* This Game Can Be Called From
|
||||
/* This Game Can Be Called From
|
||||
* Stand Alone Mode / Bluetooth Connection
|
||||
* The primary mode is the standalone but
|
||||
* if the bluetooth is connected it has the priority
|
||||
* so it will take over the control of the device
|
||||
*
|
||||
*
|
||||
* If you want to control the game via bluetooth
|
||||
* you need to call : time_attack_bluetooth(JSON String)
|
||||
* If you want to use the stand alone mode
|
||||
* you need to call : time_attack_standalone()
|
||||
*
|
||||
*
|
||||
* the game returns a float point number which is
|
||||
* in seconds. so the athlete know how long he takes to react
|
||||
*/
|
||||
@@ -24,11 +24,11 @@
|
||||
void time_attack_standalone()
|
||||
{
|
||||
// Variables
|
||||
uint16_t time = 0;
|
||||
uint16_t timer = 0;
|
||||
uint16_t limit = 0;
|
||||
uint16_t time = 0;
|
||||
uint16_t timer = 0;
|
||||
uint16_t limit = 0;
|
||||
bool limitEnable = 0;
|
||||
|
||||
|
||||
// Display Screen Menu And Button Actions
|
||||
// If The Menu Number 1 -> We Set The Value Of Min Delay
|
||||
// If The Menu Number 2 -> We Set The Value Of Max Delay
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
/* TIME ATTACK GAME SETTINGS PARAMETERS NOTE:
|
||||
* ------------------------------------------
|
||||
*
|
||||
*
|
||||
* FORMAT :
|
||||
* --------
|
||||
* {"tm": 10, "le": false, "lm": 10}
|
||||
@@ -52,22 +52,22 @@
|
||||
* tm : count down timer starting value
|
||||
* le : stands for limit enable, if is TRUE the game end if target value is meet
|
||||
* lm : targeted amount of kicks
|
||||
*
|
||||
*
|
||||
* THINGS THAT ENDS THE GAME :
|
||||
* ---------------------------
|
||||
* 1. BY COUNT DOWN "tm" REACH TO ZERO
|
||||
* 2. BY A COMMAND "FROM APP VIA BLUETOOTH"
|
||||
* 3. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE"
|
||||
*
|
||||
*
|
||||
* CALCULATING RESULTS :
|
||||
* ---------------------
|
||||
* Rapid Kick Speed = Number Of Kickes Made / Elasped Time In Sec
|
||||
* Delay Between Kicks = Time Of Current Kick - Time Of Last Kick
|
||||
*
|
||||
*
|
||||
* RETURNNING JSON FORMAT :
|
||||
* ------------------------
|
||||
* {"tm" : 82, "ct" : 10, "dl" : 1234, "st" : 585}
|
||||
*
|
||||
*
|
||||
* tm : timer count in Sec
|
||||
* ct : strike counter (number of kicks)
|
||||
* dl : delay between strikes
|
||||
@@ -75,7 +75,7 @@
|
||||
*/
|
||||
|
||||
void time_attack_bluetooth(String settings)
|
||||
{
|
||||
{
|
||||
// Deserialize the JSON document
|
||||
DeserializationError error = deserializeJson(JSON, settings); // the main JSON body container
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
// Play Time Atack Game
|
||||
//======================================================
|
||||
|
||||
void game_timeAttack(uint16_t time, uint16_t timer, uint16_t limit, bool limitEnable)
|
||||
void game_timeAttack(uint16_t time, uint16_t timer, uint16_t limit, bool limitEnable)
|
||||
{
|
||||
// Building Timers 1000mSec -> 1Sec
|
||||
TimeTrigger sec_tick(1000);
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
// staring Of time stamp
|
||||
unsigned long startStamp = millis();
|
||||
|
||||
|
||||
// store the time of the previous kick
|
||||
unsigned long lastStamp = 0;
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
String msg = Bluetooth.readStringUntil('\n');
|
||||
flushBluetooth;
|
||||
msg.trim();
|
||||
if(msg == CM_STOP)
|
||||
if(msg == CM_STOP)
|
||||
{
|
||||
dualcomm(GAME_OVER);
|
||||
// Grean Light In
|
||||
@@ -161,9 +161,8 @@
|
||||
LED_SIGNAL_RESET();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Every Kick ---------------------------->>>
|
||||
|
||||
if(readImpact() > VTH)
|
||||
{
|
||||
counter++;
|
||||
@@ -173,13 +172,12 @@
|
||||
}
|
||||
|
||||
// Every Second ---------------------------->>>
|
||||
|
||||
if(sec_tick.Trigger())
|
||||
{
|
||||
timer--;
|
||||
dualcomm(timeAttack_JSON_json(timer, counter, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
// If Limits Are Enabled And Meet
|
||||
if(limitEnable == true && counter == limit)
|
||||
{
|
||||
@@ -207,25 +205,25 @@
|
||||
//======================================================
|
||||
|
||||
String timeAttack_JSON_json(unsigned int RunningTime, unsigned int KickCount, unsigned int LastStamp, unsigned int TimeStamp)
|
||||
{
|
||||
{
|
||||
// Building The Buffer
|
||||
JSON["tm"] = RunningTime;
|
||||
JSON["ct"] = KickCount;
|
||||
|
||||
// Calculations
|
||||
if(TimeStamp > 0)
|
||||
if(TimeStamp > 0)
|
||||
{
|
||||
// Calculate Time Stamp In Seconds
|
||||
float st = TimeStamp;
|
||||
st /= 1000;
|
||||
JSON["st"] = String(st, 3).toFloat();
|
||||
|
||||
|
||||
// Calculate Strike Delay In Seconds
|
||||
float dl = TimeStamp - LastStamp;
|
||||
dl /= 1000;
|
||||
JSON["dl"] = String(dl, 3).toFloat();
|
||||
}
|
||||
|
||||
|
||||
String output;
|
||||
serializeJson(JSON, output);
|
||||
JSON.clear();
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -9,7 +9,6 @@
|
||||
* NEOPIXEL LED STRIP : A0/GPIO 26
|
||||
* PIEZO SENSOR : A2/GPIO 34 - ANALOG ONLY INPUT
|
||||
* RANDOM SEED : A3/GPIO 39 - ANALOG ONLY INPUT
|
||||
* https://www.aliexpress.com/item/32813561581.html?spm=a2g0s.9042311.0.0.48644c4dfH5L8o
|
||||
* BUTTONS : TLB (35), BLB (15), CB (33), BRB (27), TRB(12)
|
||||
* I2C PIN : SDA 21, SCL 22 (DIGITAL)
|
||||
* SPI PIN : CS 5, SCK 18, MISO 19, MOSI 23 (DIGITAL)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user