From 5322661aa9223e5e01be04440a42f4ffc501bf50 Mon Sep 17 00:00:00 2001 From: saveSandraThanme Date: Sun, 27 Apr 2025 18:19:57 -0700 Subject: [PATCH] Added mager +workers structure --- CMakeLists.txt | 10 ++-- main/CMakeLists.txt | 2 +- main/global.c | 12 ++++ main/global.h | 22 +++++++ main/hello_world_main.c | 58 ++++++++++++------ main/metronome.c | 103 ++++++++++++++++++++++++++++++++ main/metronome.h | 28 +++++++++ main/timer_task.h | 27 --------- main/uart_echo.c | 128 ---------------------------------------- 9 files changed, 211 insertions(+), 179 deletions(-) create mode 100644 main/global.c create mode 100644 main/global.h create mode 100644 main/metronome.c create mode 100644 main/metronome.h delete mode 100644 main/timer_task.h delete mode 100644 main/uart_echo.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 6911567..d2d24a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ -# The following lines of boilerplate have to be in your project's -# CMakeLists in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.16) + # The following lines of boilerplate have to be in your project's + # CMakeLists in this exact order for cmake to work correctly + cmake_minimum_required(VERSION 3.16) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(Glove_Game) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) + project(Glove_Game) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index ba058ef..aab7195 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "uart_echo.c" "hello_world_main.c" +idf_component_register(SRCS "metronome.c" "global.c" "hello_world_main.c" PRIV_REQUIRES spi_flash INCLUDE_DIRS "") diff --git a/main/global.c b/main/global.c new file mode 100644 index 0000000..8af429b --- /dev/null +++ b/main/global.c @@ -0,0 +1,12 @@ +#include "global.h" +int work_ready = 0; +int workers_done = 0; + +int current_input = 0; +int correct_input = 0; + +bool start = 0; +bool should_terminate = 0; +bool running = 0; + +Scoreboard scoreboard = {0, 0}; diff --git a/main/global.h b/main/global.h new file mode 100644 index 0000000..65b9ee7 --- /dev/null +++ b/main/global.h @@ -0,0 +1,22 @@ +// global.h +#ifndef GLOBAL_H +#define GLOBAL_H + +#include + +// Declare variables +extern bool start; +extern bool running; +extern bool should_terminate; + +extern int current_input; +extern int correct_input; + +typedef struct { + int hit; + int miss; +} Scoreboard; + +extern Scoreboard scoreboard; + +#endif // GLOBAL_H \ No newline at end of file diff --git a/main/hello_world_main.c b/main/hello_world_main.c index 9e3e0df..b395786 100644 --- a/main/hello_world_main.c +++ b/main/hello_world_main.c @@ -12,35 +12,42 @@ #include "esp_chip_info.h" #include "esp_flash.h" #include "esp_system.h" - -#include "timer_task.h" +#include #include "esp_log.h" -#include "uart_echo.c" + +#include "metronome.h" //definitions #define MAIN_DELAY_MS 5000 //variables static const char *TAG_MAIN = "Main"; +pthread_t worker_tid; +pthread_t manager_tid; +void start_game(int bpm); void app_main(void) { - printf("Hello world!\n"); - ESP_LOGI(TAG_MAIN,"About to Setup the Task"); - setup_the_timertask(); - ESP_LOGI(TAG_MAIN,"task setup starting the main loop"); - for(;;){ - ESP_LOGI(TAG_MAIN,"Going to snooze for a bit"); - vTaskDelay(MAIN_DELAY_MS / portTICK_PERIOD_MS); - } - gpio_reset_pin(13); - /* Set the GPIO as a push/pull output */ - gpio_set_direction(13, GPIO_MODE_OUTPUT); - blink_led(); - xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, 10, NULL); - xTaskCreate(blink_task, "blink_LED", 1024, NULL, 5, &myTaskHandle); - vTaskSuspend(myTaskHandle); + start_game(1000000); + + + // printf("Hello world!\n"); + // ESP_LOGI(TAG_MAIN,"About to Setup the Task"); + // setup_the_timertask(); + // ESP_LOGI(TAG_MAIN,"task setup starting the main loop"); + // for(;;){ + // ESP_LOGI(TAG_MAIN,"Going to snooze for a bit"); + // vTaskDelay(MAIN_DELAY_MS / portTICK_PERIOD_MS); + + // } + // gpio_reset_pin(13); + // /* Set the GPIO as a push/pull output */ + // gpio_set_direction(13, GPIO_MODE_OUTPUT); + // blink_led(); + // xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, 10, NULL); + // xTaskCreate(blink_task, "blink_LED", 1024, NULL, 5, &myTaskHandle); + // vTaskSuspend(myTaskHandle); /* Print chip information esp_chip_info_t chip_info; @@ -75,3 +82,18 @@ void app_main(void) fflush(stdout); esp_restart();*/ } + + +void start_game(int bpm) { + MetronomeArgs m_args; + m_args.bpm = bpm; + m_args.metronome = create_metronome(); + + pthread_create(&worker_tid, NULL, metronome_worker, (void*)&m_args); + pthread_create(&manager_tid, NULL, manager_thread, NULL); + + pthread_join(manager_tid, NULL); + pthread_join(worker_tid, NULL); + + ESP_LOGI("App", "All threads finished."); +} diff --git a/main/metronome.c b/main/metronome.c new file mode 100644 index 0000000..92fdfa8 --- /dev/null +++ b/main/metronome.c @@ -0,0 +1,103 @@ +#include "metronome.h" +#include "global.h" +#include "esp_log.h" +#include "esp_sleep.h" +#include "sdkconfig.h" + + +static const char* TAG = "Metronome"; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +// Private function +static void metronome_callback(void* arg); + +esp_timer_handle_t create_metronome(void) { + const esp_timer_create_args_t periodic_timer_args = { + .callback = &metronome_callback, + .name = "metronome" + }; + + esp_timer_handle_t metronome; + ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &metronome)); + return metronome; +} + +void* metronome_worker(void* args) { + MetronomeArgs* m_args = (MetronomeArgs*)args; + + // Wait for manager to signal to start + pthread_mutex_lock(&mutex); + while (!start && !should_terminate) { + pthread_cond_wait(&cond, &mutex); + } + + if (start) { + ESP_ERROR_CHECK(esp_timer_start_periodic(m_args->metronome, m_args->bpm)); + } + pthread_mutex_unlock(&mutex); + + // handles the metronone callbacks + while (1) { + pthread_mutex_lock(&mutex); + + if (should_terminate) { + pthread_mutex_unlock(&mutex); + break; + } + + pthread_mutex_unlock(&mutex); + + vTaskDelay(pdMS_TO_TICKS(10)); + } + + ESP_ERROR_CHECK(esp_timer_stop(m_args->metronome)); + ESP_ERROR_CHECK(esp_timer_delete(m_args->metronome)); + ESP_LOGI(TAG, "Worker exited cleanly"); + + return NULL; +} + +//callback function, put espnow send true/false at end +static void metronome_callback(void* arg) { + if (correct_input == 0){ + //hahhshshdshdshdvsd + + } + else if (current_input == correct_input) { + scoreboard.hit++; + } else { + scoreboard.miss++; + // Vibrate code here + } + + + ESP_LOGI(TAG, "Status of input: %d", current_input == correct_input); //prints to serial 1 if match 0 if not +} + +void* manager_thread(void* arg) { + ESP_LOGI(TAG, "Manager thread started"); + + vTaskDelay(pdMS_TO_TICKS(1000)); // 1 second + + pthread_mutex_lock(&mutex); + start = true; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + ESP_LOGI(TAG, "Sent start signal to metronome"); + + vTaskDelay(pdMS_TO_TICKS(5000)); // 5 seconds + + pthread_mutex_lock(&mutex); + should_terminate = true; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + ESP_LOGI(TAG, "Sent terminate signal to metronome"); + + return NULL; +} + + diff --git a/main/metronome.h b/main/metronome.h new file mode 100644 index 0000000..21b420b --- /dev/null +++ b/main/metronome.h @@ -0,0 +1,28 @@ +#ifndef METRONOME_H +#define METRONOME_H + +#include +#include "esp_timer.h" +#include +#include // for sleep() +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include + +// External variables (mutex/cond) +extern pthread_mutex_t mutex; +extern pthread_cond_t cond; + +// Struct to pass worker arguments +typedef struct { + uint64_t bpm; // timer period in microseconds + esp_timer_handle_t metronome; // timer handle +} MetronomeArgs; + + +// Functions you can call +esp_timer_handle_t create_metronome(void); +void* metronome_worker(void* bpm_ptr); +void* manager_thread(void* arg); + +#endif // METRONOME_H diff --git a/main/timer_task.h b/main/timer_task.h deleted file mode 100644 index 08d16df..0000000 --- a/main/timer_task.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "esp_log.h" - -#define TASK_STACK_SIZE 2048 -#define TASK_DELAY_MS 500 -//declarations -//public - -void setup_the_timertask(void); - - -//private -static const char *TAG_TASK = "Task"; -static void the_actual_task(void); - -//function definitions -void setup_the_timertask(void){ - ESP_LOGI(TAG_TASK,"setting up the task"); -} -static void the_actual_task(void){ - // - ; -} \ No newline at end of file diff --git a/main/uart_echo.c b/main/uart_echo.c deleted file mode 100644 index d8bd4ca..0000000 --- a/main/uart_echo.c +++ /dev/null @@ -1,128 +0,0 @@ -/* UART Echo Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include "string.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "driver/uart.h" -#include "driver/gpio.h" -#include "sdkconfig.h" -#include "esp_log.h" - -/** - * This is an example which echos any data it receives on configured UART back to the sender, - * with hardware flow control turned off. It does not use UART driver event queue. - * - * - Port: configured UART - * - Receive (Rx) buffer: on - * - Transmit (Tx) buffer: off - * - Flow control: off - * - Event queue: off - * - Pin assignment: see defines below (See Kconfig) - */ - -#define ECHO_TEST_TXD (CONFIG_EXAMPLE_UART_TXD) -#define ECHO_TEST_RXD (CONFIG_EXAMPLE_UART_RXD) -#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE) -#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE) - -#define ECHO_UART_PORT_NUM (CONFIG_EXAMPLE_UART_PORT_NUM) -#define ECHO_UART_BAUD_RATE (CONFIG_EXAMPLE_UART_BAUD_RATE) -#define ECHO_TASK_STACK_SIZE (CONFIG_EXAMPLE_TASK_STACK_SIZE) - -#define DEFAULT_PERIOD 10 - -static uint8_t s_led_state = 1; - -static uint32_t flash_period = DEFAULT_PERIOD; -static uint32_t flash_period_dec = DEFAULT_PERIOD/10; - - -TaskHandle_t myTaskHandle = NULL; - -#define BUF_SIZE (1024) - -static void blink_led(void) -{ - /* Set the GPIO level according to the state (LOW or HIGH)*/ - gpio_set_level(13, s_led_state); -} - -static void blink_task(void *arg) -{ - while(1) - { - s_led_state = !s_led_state; - blink_led(); - vTaskDelay(flash_period/ portTICK_PERIOD_MS); - } - -} - -static void echo_task(void *arg) -{ - /* Configure parameters of an UART driver, - * communication pins and install the driver */ - uart_config_t uart_config = { - .baud_rate = ECHO_UART_BAUD_RATE, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .source_clk = UART_SCLK_DEFAULT, - }; - int intr_alloc_flags = 0; - -#if CONFIG_UART_ISR_IN_IRAM - intr_alloc_flags = ESP_INTR_FLAG_IRAM; -#endif - - ESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags)); - ESP_ERROR_CHECK(uart_param_config(ECHO_UART_PORT_NUM, &uart_config)); - ESP_ERROR_CHECK(uart_set_pin(ECHO_UART_PORT_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS)); - - // Configure a temporary buffer for the incoming data - uint8_t *data = (uint8_t *) malloc(BUF_SIZE); - - uart_write_bytes(ECHO_UART_PORT_NUM, "Commands", strlen("Commands")); - while (1) - { - // Read data from the UART - int len = uart_read_bytes(ECHO_UART_PORT_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS); - // Write data back to the UART - uart_write_bytes(ECHO_UART_PORT_NUM, (const char *) data, len); - if (len) - { - data[len] = '\0'; - switch(data[0]) - { - case 'I': - s_led_state = 1; - blink_led(); - uart_write_bytes(ECHO_UART_PORT_NUM, "ESP32", strlen("ESP32")); - break; - case 'T': - flash_period -= flash_period_dec; - if(flash_period <= flash_period_dec) flash_period = flash_period_dec; - break; - case 'A': - vTaskResume(myTaskHandle); - break; - case 'B': - vTaskSuspend(myTaskHandle); - break; - case 'R': - flash_period = DEFAULT_PERIOD; - break; - default: - break; - } - } - } -}