From 64e84ad5315331d23484c95a271c703089d9a530 Mon Sep 17 00:00:00 2001 From: Quinn Date: Tue, 20 Aug 2024 18:06:07 -0400 Subject: [PATCH 1/3] Small code refactor and began using freertos tasks --- include/COMMANDS.h | 13 +++ lib/GlobalPrint/GlobalPrint.h | 28 ++++++ lib/SerialMessage | 2 +- src/main.cpp | 156 ++++++++++++++++++++-------------- 4 files changed, 135 insertions(+), 64 deletions(-) create mode 100644 include/COMMANDS.h create mode 100644 lib/GlobalPrint/GlobalPrint.h diff --git a/include/COMMANDS.h b/include/COMMANDS.h new file mode 100644 index 0000000..36691e4 --- /dev/null +++ b/include/COMMANDS.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +/** + * @brief These are the serial commands that the board supports + */ +enum Commands : uint8_t{ + BoardState = 0, + PING = 1, + SetStackColors = 2, + GoToIdle = 3 +}; \ No newline at end of file diff --git a/lib/GlobalPrint/GlobalPrint.h b/lib/GlobalPrint/GlobalPrint.h new file mode 100644 index 0000000..9a7c650 --- /dev/null +++ b/lib/GlobalPrint/GlobalPrint.h @@ -0,0 +1,28 @@ +/** + * @file GlobalPrint.h + * @brief a method of printing serial data to all outgoing communication methods + */ + +#pragma once + +#include + +namespace GlobalPrint{ + static void Print(const char * s){ + Serial.print(s); + } + + static void Print(const String &s){ + GlobalPrint::Print(s.c_str()); + } + + static void Println(const char * s){ + GlobalPrint::Print(s); + GlobalPrint::Print("\n"); + } + + static void Println(const String &s){ + GlobalPrint::Println(s.c_str()); + } + +} \ No newline at end of file diff --git a/lib/SerialMessage b/lib/SerialMessage index 7cd4374..a0bb936 160000 --- a/lib/SerialMessage +++ b/lib/SerialMessage @@ -1 +1 @@ -Subproject commit 7cd43742b650840c3e1c6f7472f7cb2720bdf479 +Subproject commit a0bb93624d4887774d653d98c3e2a6be9ba70746 diff --git a/src/main.cpp b/src/main.cpp index 6635410..dd49238 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,35 +1,34 @@ // Other peoples libraries #include #include +#include + +// Static Defines +#include "PINOUT.h" +#include "BOARD-DEFINITIONS.h" +#include "COMMANDS.h" // project specific libraries #include "BluetoothSerial.h" #include "SerialMessage.h" #include "BoardLayout.h" -#include "BOARD-DEFINITIONS.h" #include "Color.h" #include "ColorManager.h" - -// -------------------------------------------------- -// ----------------- Types ---------------------- -// -------------------------------------------------- -enum Commands : uint8_t{ - BoardState = 0, - PING = 1, - SetStackColors = 2, - GoToIdle = 3 -}; +#include "GlobalPrint.h" // -------------------------------------------------- // ----------------- VARIABLES ---------------------- // -------------------------------------------------- +TaskHandle_t updateCommunicaitonTask; +TaskHandle_t updateBoardTask; + uint32_t boardStateTimer{0}; bool boardStateHasChanged{false}; uint32_t boardStateMaxUpdatePeriod{34}; // this is a little slower than 30fps // BluetoothSerial SerialBT; // BluetoothSerialMessage serialMessageBT(&SerialBT); -SerialMessage<500> serialMessage(&Serial); +SerialMessage<500, 10> serialMessage(&Serial); BoardLayout board(BOARD_WIDTH, BOARD_LENGTH, BOARD_HEIGHT, stacks); // Temporary thing until we can get bluetooth color management working on the quest @@ -38,6 +37,11 @@ ColorManager colorManager(&board); // -------------------------------------------------- // ----------------- FUNCTIONS ---------------------- // -------------------------------------------------- +/** + * @brief Send programming commands to the serial to bluetooth adapter so + * it is set up as expected for the VR headset + * @post the serial baud rate will be set to 9600 + */ void SetupBluetoothModule(){ Serial.begin(38400); Serial.print("AT+UART=9600,0,0\r\n"); // set baud rate to 9600 @@ -52,37 +56,33 @@ void SetupBluetoothModule(){ Serial.print("AT+ROLE=0\r\n"); // set to slave delay(100); - - // exit at mode and go into pairing mode Serial.print("AT+INIT\r\n"); Serial.begin(9600); delay(100); } + + void printBoardState(){ // create a buffer to hold the board state uint16_t boardState[BOARD_WIDTH * BOARD_LENGTH]; // read in the board state board.GetBoardState(boardState); - Serial.print("!0,"); - // SerialBT.print("!0,"); + GlobalPrint::Print("!0,"); for(int i = 0; i < (BOARD_WIDTH * BOARD_LENGTH); i++){ - Serial.print(boardState[i]); - // SerialBT.print(boardState[i]); + GlobalPrint::Print(String(boardState[i])); if(i == (BOARD_WIDTH * BOARD_LENGTH) - 1){ break; } - Serial.print(","); - // SerialBT.print(","); + GlobalPrint::Print(","); } - Serial.println(";"); - // SerialBT.println(";"); + GlobalPrint::Println(";"); } -void setStackColor(uint32_t * args, int argsLength){ +void SetStackColor(uint32_t * args, int argsLength){ uint32_t stackNum = args[1]; uint32_t numColors = (argsLength - 2) / 3; Color colors[numColors]; @@ -95,80 +95,110 @@ void setStackColor(uint32_t * args, int argsLength){ } board.SetStackColors(stackNum, colors); - - } -void parseData(uint32_t * args, int argsLength){ +void parseData(Message<500, 10> &message){ + int32_t * args{message.GetArgs()}; + uint32_t argsLength{message.GetArgsLength()}; uint32_t command = args[0]; switch(command){ case Commands::BoardState: printBoardState(); break; case Commands::PING: - Serial.print("!"); - // SerialBT.print("!"); - Serial.print(Commands::PING); - // SerialBT.print(Commands::PING); - Serial.println(";"); - // SerialBT.println(";"); + GlobalPrint::Println("!" + String(Commands::PING) + ";"); break; case Commands::SetStackColors: - Serial.println("!2;"); - // SerialBT.println("!2;"); + GlobalPrint::Println("!2;"); colorManager.Enable(false); - setStackColor(args, argsLength); + SetStackColor(reinterpret_cast(args), argsLength); break; case Commands::GoToIdle: - Serial.println("!3;"); - // SerialBT.println("!3;"); + GlobalPrint::Println("!3;"); colorManager.Enable(true); break; default: - Serial.println("INVALID COMMAND"); - // SerialBT.println("INVALID COMMAND"); + GlobalPrint::Println("INVALID COMMAND"); break; } + + // now that we have run the command we can clear the data for the next command. + serialMessage.ClearNewData(); } +// -------------------------------------------------- +// ----------------- FREERTOS TASKS ----------------- +// -------------------------------------------------- +void UpdateCommunication(void * params){ + Serial.println("Spawning UpdateCommunication task"); + for(;;){ + // DO serial processing + serialMessage.Update(); + if(serialMessage.IsNewData()){ + parseData(serialMessage); + } + // serialMessageBT.Update(); + // if(serialMessageBT.IsNewData()){ + // parseData(serialMessageBT.GetArgs(), serialMessageBT.GetArgsLength()); + // serialMessageBT.ClearNewData(); + // } + vTaskDelay(3); + } + Serial.println("UpdateCommunication task has ended unexpectedly!"); + +} + +void UpdateBoard(void * params){ + Serial.println("Spawning UpdateBoard task"); + for(;;){ + if(board.BoardStateHasChanged()){ + boardStateHasChanged = true; + } + + if(millis() - boardStateTimer > boardStateMaxUpdatePeriod && boardStateHasChanged){ + boardStateTimer = millis(); + printBoardState(); + boardStateHasChanged = false; + } + + colorManager.Update(); + + vTaskDelay(5); + } + Serial.println("UpdateBoard task has ended unexpectedly!"); +} + + // -------------------------------------------------- // ----------------- SETUP AND LOOP ----------------- // -------------------------------------------------- void setup() { + // delay a little bit to get the serial monitor a chance to capture the next log messages. delay(1000); + + Serial.begin(9600); + Serial.println("Beginning Setup"); + Serial.println("Configuring Bluetooth Adapter"); SetupBluetoothModule(); Serial.begin(9600); + + Serial.println("Configuring communication methods"); + serialMessage.Init(9600); // SerialBT.begin("blockPartyBT"); + xTaskCreate(UpdateCommunication, "UpdateCommunication", 10000, NULL, 0, &updateCommunicaitonTask); + + Serial.println("Beginning Board Initializaiton"); + xTaskCreate(UpdateBoard, "UpdateBoard", 10000, NULL, 0, &updateBoardTask); Color colors[] = {Color(255, 0, 0), Color(0, 0, 0), Color(0, 0, 0)}; board.SetStackColors(2, colors); - boardStateTimer = millis(); - + + Serial.println("Setup Complete"); } void loop() { - if(board.BoardStateHasChanged()){ - boardStateHasChanged = true; - } - - if(millis() - boardStateTimer > boardStateMaxUpdatePeriod && boardStateHasChanged){ - boardStateTimer = millis(); - printBoardState(); - boardStateHasChanged = false; - } - - // DO serial processing - serialMessage.Update(); - if(serialMessage.IsNewData()){ - parseData(serialMessage.GetArgs(), serialMessage.GetArgsLength()); - serialMessage.ClearNewData(); - } - // serialMessageBT.Update(); - // if(serialMessageBT.IsNewData()){ - // parseData(serialMessageBT.GetArgs(), serialMessageBT.GetArgsLength()); - // serialMessageBT.ClearNewData(); - // } - colorManager.Update(); + // delete the loop task because we don't use it + vTaskDelete(NULL); } \ No newline at end of file From bf852ffc81f82039133023069fe6827f7313cdc7 Mon Sep 17 00:00:00 2001 From: Quinn Date: Tue, 20 Aug 2024 18:12:00 -0400 Subject: [PATCH 2/3] Added note to readme about initializing submodules --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cf8eaa..10dc64f 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ When the physical user removes a block from the board, the corresponding digital When the VR user hovers over or picks up a digital cube, the corresponding physical cube changes color to show the physical user what the VR user is doing. ## Setup +### Repository Setup +When the repository is first cloned you will need to initialize all of its submodules. + +In the terminal type: `git submodule update --init --recursive` which will initalize all of the submodules. + ### Board Assemble #### Parts List - Foam core (scavenged) @@ -53,7 +58,7 @@ wiring diagram for the cube is in the `documentation` directory. - Arduino libraries ### Bluetooth Module -On v0.1 of the baord, a seperate bluetooth module (HC-05) is being used for bluetooth. This module needs to be programmed when first plugged in. To program the module, disconnect it from power and hold the "EN" button on the module. (The button should be the only button on the HC-05 module). While still holding down the button, reconnect the module to the ESP32 and press the ESP32's reset button. Wait 5 seconds while still holding down the "EN" button on the module, then release the button, power cycle the module, and you're done. +On v0.1 of the board, a seperate bluetooth module (HC-05) is being used for bluetooth. This module needs to be programmed when first plugged in. To program the module, disconnect it from power and hold the "EN" button on the module. (The button should be the only button on the HC-05 module). While still holding down the button, reconnect the module to the ESP32. Let go of the button and then press the ESP32's reset button. Wait 5 seconds while still holding down the "EN" button on the module, then release the button, power cycle the module, and you're done. ## Run - Power up the board and pair it with the headset over bluetooth. From 2d3b1392d05d0f6b608bb42af9a73def2418f5d3 Mon Sep 17 00:00:00 2001 From: Quinn Date: Tue, 20 Aug 2024 18:28:40 -0400 Subject: [PATCH 3/3] Added framework for users to edit the paltformio file for machine differences without uploading the changes to github. --- .gitignore | 4 +++- platformio.ini | 8 +++++--- template-platformio-local.ini | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 template-platformio-local.ini diff --git a/.gitignore b/.gitignore index e024bb0..5611e53 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ Schematics/Block-Party/Block-Party-Cube-Bottom-Board/production Schematics/Block-Party/Block-Party-Main-Board/Block-Party-Main-Board-backups/ Schematics/Block-Party/Block-Party-Cube-Bottom-Board/Block-Party-Bottom-Board-backups/ -Schematics/Block-Party/Block-Party-Cube-Top-Board/Block-Party-Cube-Top-Board-backups/ \ No newline at end of file +Schematics/Block-Party/Block-Party-Cube-Top-Board/Block-Party-Cube-Top-Board-backups/ + +platformio-local.ini \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index b69f1c3..2b70b1f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,6 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] default_envs = esp32s3_release ; this ensures that only this environment is built for anything but the debug build +extra_configs = platformio-local.ini [env] ; platform = espressif32 @@ -17,10 +18,9 @@ platform = https://github.com/platformio/platform-espressif32.git board = esp32-s3-devkitc-1 framework = arduino build_flags = -Iinclude -; lib_ldf_mode = chain+ monitor_speed = 9600 -monitor_filters = esp32_exception_decoder, colorize, send_on_enter +monitor_filters = colorize, send_on_enter upload_speed = 2000000 ;ESP32S3 USB-Serial Converter maximum 2000000bps lib_deps = adafruit/Adafruit NeoPixel@^1.12.0 @@ -35,4 +35,6 @@ build_type = debug debug_speed = 20000 ; debug_port = COM7 ; monitor_port = COM14 -build_flags = -O1 -Iinclude \ No newline at end of file +build_flags = + -D DEBUG = 1 + -I include \ No newline at end of file diff --git a/template-platformio-local.ini b/template-platformio-local.ini new file mode 100644 index 0000000..fbe896d --- /dev/null +++ b/template-platformio-local.ini @@ -0,0 +1,23 @@ +; This is a template that will allow you to add additional configuration +; options to the platformio.ini file without changing anything in git. +; options like upload/monitor ports are great things to put here +; because those will vary from computer to computer. +; To use this configuration, make a copy of this file and rename it to "platformio-local.ini" +; and then uncomment some of the following code or add your own options +; Feel free to modify the code as needed + +; this will add additional configuration options to esp32s3_release environment. +; This environment is the default for building/sending code to the baord +; so this should be the first thing you change/modify +; Uncomment the following code as needed: +; [env:esp32s3_release] +; monitor_port = COM10 +; upload_port = COM11 +; monitor_speed = 115200 + +; this is the debug configuration which you probably don't need +; unless you're doing some complicated firmware development. +; [env:esp32s3_debug] +; debug_port = COM7 +; monitor_port = COM14 +; upload_port = COM12 \ No newline at end of file