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