380 lines
12 KiB
C++
380 lines
12 KiB
C++
/* ===============================================
|
|
* - THIS IS TAKEONE BOARD -
|
|
* ===============================================
|
|
* MPU9250 Address : 0X69 (ADDRESS)
|
|
* OLED 128x64 Address : 0X3C (ADDRESS)
|
|
* -----------------------------------------------
|
|
* Description : PIN GPIO#
|
|
* -----------------------------------------------
|
|
* NEOPIXEL LED STRIP : A0/GPIO 26
|
|
* PIEZO SENSOR : A2/GPIO 34 - ANALOG ONLY INPUT
|
|
* RANDOM SEED : A3/GPIO 39 - ANALOG ONLY INPUT
|
|
* BUTTONS : TLB (35), BLB (15), CB (33), BRB (27), TRB(12)
|
|
* I2C PIN : SDA 21, SCL 22 (DIGITAL)
|
|
* SPI PIN : CS 5, SCK 18, MISO 19, MOSI 23 (DIGITAL)
|
|
* BOOST CONTROL PIN : 14 (DIGITAL) OUTPUT ON PADS (TP1 +5V, TP2 GND)
|
|
* LED PIN : 13 (DIGITAL)
|
|
* BATTERY MONITOR PIN : 35 (ANALOG)
|
|
* -----------------------------------------------
|
|
* BUTTONS PINOUTS : PIN GPIO
|
|
* -----------------------------------------------
|
|
* TOP LEFT BUTTON : 15 - SWITCH PREVIOUS MENU / CHANGE PARAMETER
|
|
* TOP RIGHT BUTTON : 12 - SWITCH NEXT MENU / CHANGE PARAMETER
|
|
* BOTTOM LEFT BUTTON : 32 - POWER INC & BACK & INC PARAMETER
|
|
* BOTTOM RIGHT BUTTON : 27 - POWER DEC & SAVE & DEC PARAMETER
|
|
* CENTER BUTTON : 33 - POWER ON & SELECT
|
|
*/
|
|
|
|
// Include Library
|
|
#include <FS.h>
|
|
#include <SD.h>
|
|
#include <SPI.h>
|
|
#include <Wire.h>
|
|
#include <Button.h>
|
|
#include <ArduinoJson.h>
|
|
#include <BluetoothSerial.h>
|
|
#include <Adafruit_NeoPixel.h>
|
|
|
|
//----------------------------------------------------------------
|
|
// Communication Models
|
|
//----------------------------------------------------------------
|
|
|
|
// Serial Port As Terminal
|
|
#define terminal Serial
|
|
|
|
// Clearing Terminal Remainning
|
|
#define flush_terminal while(terminal.available()) { terminal.read(); }
|
|
|
|
// Bluetooth Object
|
|
BluetoothSerial bluetooth;
|
|
|
|
// Bluetooth Connection Status
|
|
bool bluetooth_conn = false;
|
|
|
|
// Clearing Bluetooth Remainning
|
|
#define flush_bluetooth while(bluetooth.available()) { bluetooth.read(); }
|
|
|
|
// Fixed JSON Strings
|
|
#define POWERUP "{\"status\":\"POWER UP\"}"
|
|
#define UNDERSTOOD "{\"status\":\"OK\"}"
|
|
#define JSON_ERROR "{\"status\":\"ERROR JSON\"}"
|
|
#define TARGET_MET "{\"status\":\"TARGET MEET\"}"
|
|
#define GAME_OVER "{\"status\":\"GAME OVER\"}"
|
|
#define TIME_OVER "{\"status\":\"TIME OVER\"}"
|
|
#define UNKNOWN_GAME "{\"status\":\"UNKNOWN GAME\"}"
|
|
|
|
// GAME NAMES
|
|
#define GM_COUNTER "{\"gm\":\"COUNTER\"}"
|
|
#define GM_TATTACK "{\"gm\":\"TIME ATTACK\"}"
|
|
#define GM_REACTION "{\"gm\":\"REACTION\"}"
|
|
#define GM_DECISION "{\"gm\":\"DECISION\"}"
|
|
#define GM_STAMINA "{\"gm\":\"STAMINA\"}"
|
|
|
|
// COMMAND LIST
|
|
#define CM_START "{\"cm\":\"START\"}"
|
|
#define CM_RESET "{\"cm\":\"RESET\"}"
|
|
#define CM_STOP "{\"cm\":\"STOP\"}"
|
|
#define CM_EXIT "{\"cm\":\"EXIT\"}"
|
|
|
|
// JSON CAPACITY
|
|
#define capacity 250
|
|
|
|
//----------------------------------------------------------------
|
|
// TAKEONE BOARD HARDWARE DEFINITIONS
|
|
//----------------------------------------------------------------
|
|
|
|
// On Board MPU9250 I2C Address
|
|
#define MPU_ADD 0x69
|
|
|
|
// Connected I2C OLED Address
|
|
#define OLED_ADD 0x3C
|
|
|
|
// Connected I2C LCD Address
|
|
#define LCD_ADD 0x2C
|
|
|
|
// Define Impact Sensor
|
|
#define PIEZO analogRead(34)
|
|
#define VOLTS mapf(PIEZO, 0, 4095, 0, 3.3)
|
|
|
|
// Panel Push Buttons Pin Assignment Sections
|
|
Button TLB(32); // Top Left Button
|
|
Button BLB(15); // Bottom Left Button
|
|
Button CB(33); // Center Button
|
|
Button BRB(27); // Bottom Right Button
|
|
Button TRB(12); // Top Right Button 33
|
|
|
|
// Panel Push Buttons Command Assignment
|
|
#define PrvMenu TLB.pressed()
|
|
#define NxtMenu TRB.pressed()
|
|
#define SelMenu CB.pressed()
|
|
#define IncBtn BLB.pressed()
|
|
#define DecBtn BRB.pressed()
|
|
|
|
// NEO Pixel Strip Section
|
|
#define NEOPIXEL 26 // Define Pin Number
|
|
#define NUMPIXELS 22 // Define Number Of LED's
|
|
|
|
// Battery Level Monitoring
|
|
#define BATTERY (float)(((analogRead(35) * (3.3 / 4096)) * 2) + 0.31)
|
|
#define CHARGE mapf(BATTERY, 3.27, 4.31, 0, 100)
|
|
|
|
// Power Latch Holder Pin
|
|
#define POWER_PIN 14
|
|
#define POWER_SETUP pinMode(POWER_PIN, OUTPUT)
|
|
#define POWER_ON digitalWrite(POWER_PIN, HIGH)
|
|
#define POWER_OFF digitalWrite(POWER_PIN, LOW)
|
|
|
|
// Battery To 5V Level Booster Setup & Control
|
|
#define BOOST_PIN 14
|
|
#define BOOST_SETUP pinMode(BOOST_PIN, OUTPUT)
|
|
#define BOOST_ON digitalWrite(BOOST_PIN, HIGH)
|
|
#define BOOST_OFF digitalWrite(BOOST_PIN, LOW)
|
|
|
|
// On Board LED Setup & Control
|
|
#define LED_PIN 13
|
|
#define LED_SETUP pinMode(LED_PIN, OUTPUT)
|
|
#define LED_ON digitalWrite(LED_PIN, HIGH)
|
|
#define LED_OFF digitalWrite(LED_PIN, LOW)
|
|
|
|
// For Timming
|
|
unsigned long timetick = 0;
|
|
unsigned long prevtick = 0;
|
|
|
|
/* Display Change Flag Explaination
|
|
* This flag is used to prevent continous writing to the oled display
|
|
* once a change has happened we drive the display_changed to false this will tell
|
|
* the micro controller that a need to write new data is needed, after writing the new data to display
|
|
* then we drive the display_changed to true that means the nessary changes has been written
|
|
*/
|
|
|
|
bool display_changed = false;
|
|
uint8_t menu_count = 0;
|
|
|
|
//--------------------------------------------------------------------
|
|
// Bluetooth Connection Status Call Back
|
|
//--------------------------------------------------------------------
|
|
|
|
void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
|
|
{
|
|
if(event == ESP_SPP_SRV_OPEN_EVT){
|
|
//Serial.println("Client Connected");
|
|
bluetooth_conn = true;
|
|
}
|
|
|
|
if(event == ESP_SPP_CLOSE_EVT ){
|
|
//Serial.println("Client disconnected");
|
|
bluetooth_conn = false;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CHIP MAIN SETUP
|
|
//--------------------------------------------------------------------
|
|
|
|
void setup()
|
|
{
|
|
// Starting Serial Communications
|
|
terminal.begin(115200); // Starting Main USB UART Communication Interface
|
|
terminal.println(); // New Line Seperator 1
|
|
terminal.println(); // New Line Seperator 2
|
|
|
|
// Starting The Bluetooth Module
|
|
if(!bluetooth.begin("KICKER")) {
|
|
terminal.println("An error occurred initializing Bluetooth");
|
|
} else {
|
|
terminal.println("Bluetooth initialized");
|
|
}
|
|
|
|
// Checking The Connection Status
|
|
bluetooth.register_callback(callback);
|
|
|
|
// Pin Assignments
|
|
BOOST_SETUP; // Boost Converter Pin Setup
|
|
LED_SETUP; // OnBoard LED Pin Setup
|
|
|
|
// Turn Off The Pins
|
|
BOOST_OFF; // Turn Off The Booster
|
|
LED_OFF; // Turn Off The LED
|
|
|
|
// The Five Panel Buttons
|
|
TLB.begin(); // Setup The Top Left Panel Button
|
|
BLB.begin(); // Setup The Bottom Left Panel Button
|
|
BRB.begin(); // Setup The Bottom Right Panel Button
|
|
TRB.begin(); // Setup The Top Right Panel Button
|
|
CB.begin(); // Setup The Center Panel Button
|
|
|
|
// I2C Section
|
|
Wire.begin(); // Starting I2C Communication Interface
|
|
scanI2C(); // Starting I2C Communicatable Devices Detection
|
|
oled_init(); // Starting OLED Display I2C Communications
|
|
kicker_logo(); // Display Kicker Main Logo Display
|
|
|
|
// Starting SDCARD Interface
|
|
sdcard_init(); // Starting SDCARD Reader Communication Protocol
|
|
|
|
// Neo Pixel Section
|
|
neo_init(); // Starting Neo Pixel
|
|
neo_color(0, 0, 0); // Clear All LED's
|
|
delay(10); // Delay 10 Milli Seconds
|
|
neo_color(255, 0, 0); // Display RED LED Strip
|
|
delay(1000); // Delay 1 Second
|
|
neo_color(0, 255, 0); // Display GREEN LED Strip
|
|
delay(1000); // Delay 1 Second
|
|
neo_color(0, 0, 255); // Display BLUE LED Strip
|
|
delay(1000); // Delay 1 Second
|
|
neo_turnoff(); // Power Off Neo Pixels & Their Power
|
|
|
|
// THE PROGRAM STATE = MENU
|
|
display_changed = false; // Allow Display Change
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CHIP MAIN PROGRAM
|
|
//--------------------------------------------------------------------
|
|
|
|
void loop()
|
|
{
|
|
// Checking The Bluetooth Connection
|
|
bluetooth.register_callback(callback);
|
|
|
|
// Condition The Preiority Is For The Bluetooth
|
|
if(bluetooth_conn == true)
|
|
{
|
|
// Wait For Game JSON String
|
|
read_game_json();
|
|
}
|
|
|
|
// Condition To Stand Alone Mode - Manual Mode
|
|
else
|
|
{
|
|
// Previous Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
if(TLB.pressed()) {
|
|
if(menu_count == 0) {
|
|
menu_count = 4;
|
|
} else {
|
|
menu_count--;
|
|
}
|
|
display_changed = false;
|
|
}
|
|
|
|
// Next Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
if(TRB.pressed()) {
|
|
if(menu_count == 4) {
|
|
menu_count = 0;
|
|
} else {
|
|
menu_count++;
|
|
}
|
|
display_changed = false;
|
|
}
|
|
|
|
// Select A Game ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
if(CB.pressed()) {
|
|
select_game();
|
|
}
|
|
|
|
// Increase Power ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
if(BLB.pressed()) {
|
|
|
|
}
|
|
|
|
// Decrease Power ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
if(BRB.pressed()) {
|
|
|
|
}
|
|
|
|
// Display Target Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
switch_menu();
|
|
}
|
|
|
|
}
|
|
|
|
//======================================================
|
|
// Read Game JSON String Command From Mobile
|
|
//======================================================
|
|
|
|
void read_game_json()
|
|
{
|
|
// Reading From Bluetooth
|
|
if(bluetooth.available())
|
|
{
|
|
// Reading Message From Bluetooth
|
|
String msg = bluetooth.readStringUntil('\n');
|
|
|
|
// Clearing The Receive Buffer
|
|
flush_bluetooth;
|
|
|
|
// Clean The Message
|
|
msg.trim();
|
|
|
|
// Display On Sertial
|
|
terminal.println(msg);
|
|
|
|
// Parsing Objects Message Objects
|
|
DynamicJsonDocument root(capacity);
|
|
|
|
// Deserialize the JSON document
|
|
DeserializationError error = deserializeJson(root, msg);
|
|
|
|
// If The System Understood The Message Clearly
|
|
if(!error)
|
|
{
|
|
// Sending Status Message
|
|
terminal.println(UNDERSTOOD);
|
|
bluetooth.println(UNDERSTOOD);
|
|
|
|
// Reading Game Name & Settings
|
|
String game = root["gm"];
|
|
String settings = root["set"];
|
|
|
|
// Clearing JSON Document Buffer
|
|
root.clear();
|
|
|
|
// Entering To Game Selector
|
|
game_selector(game, settings);
|
|
}
|
|
else
|
|
{
|
|
// Display On Serial
|
|
terminal.println(JSON_ERROR);
|
|
}
|
|
|
|
// Bluetooth Serial RXD Flush
|
|
flush_bluetooth;
|
|
}
|
|
}
|
|
|
|
//======================================================
|
|
// Game Selector Function
|
|
//======================================================
|
|
|
|
void game_selector(String game, String settings)
|
|
{
|
|
// Kick Counter Game
|
|
if(game == "ct") {
|
|
terminal.println(GM_COUNTER);
|
|
//game_counter(settings);
|
|
return;
|
|
}
|
|
|
|
// Time Attack Game
|
|
else if(game == "ta") {
|
|
terminal.println(GM_TATTACK);
|
|
//game_timeAttack(settings);
|
|
return;
|
|
}
|
|
|
|
// Time Attack Game
|
|
else if(game == "ra") {
|
|
terminal.println(GM_REACTION);
|
|
//game_reaction(settings);
|
|
return;
|
|
}
|
|
|
|
// Unknown Game
|
|
else {
|
|
terminal.println(UNKNOWN_GAME);
|
|
bluetooth.println(UNKNOWN_GAME);
|
|
return;
|
|
}
|
|
}
|