commit 8cab458c235bd3bfd9ac426bc6f4410868868691 Author: Geens Date: Sun Mar 24 16:25:56 2024 +0100 No meters diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2597191 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/extensions.json +.vscode/ipch +.vscode/launch.json +.vscode/settings.json diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..7fd9f48 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,13 @@ +[env:nano_33_iot] +platform = atmelsam +board = nano_33_iot +framework = arduino +build_flags="-DconfigTICK_RATE_HZ ((TickType_t)2000)" + +lib_deps = + briscoetech/FreeRTOS_SAMD21@^2 + arduino-libraries/WiFiNINA@^1 + hideakitai/ArduinoOSC@^0.4 + tedtoal/wiring_analog_SAMD_TT@^1 + makuna/NeoPixelBus@^2 + ruiseixasm/Versatile_RotaryEncoder@^1 \ No newline at end of file diff --git a/src/analog_read.cpp b/src/analog_read.cpp new file mode 100644 index 0000000..500d649 --- /dev/null +++ b/src/analog_read.cpp @@ -0,0 +1,48 @@ +#include "analog_read.h" + +#include +#include +#include +#include + +#include "mapping.h" +#include "priority.h" +#include "util.h" + +void analog_read_task(void *pvParameters); + +TaskHandle_t analog_read_task_handle; +SemaphoreHandle_t analog_read_mutex; +AnalogReadData analog_read_data; + +void setup_analog_read() { + analogReadResolution_SAMD_TT(12); + analogReference_SAMD_TT(AR_DEFAULT); + + xTaskCreate(analog_read_task, "analog_read_task", 256, NULL, ANALOG_READ_PRIORITY, &analog_read_task_handle); + + analog_read_mutex = xSemaphoreCreateMutex(); +} + +void analog_read_task(void *pvParameters) { + for(;;) { + xSemaphoreTake(analog_read_mutex, portMAX_DELAY); + analog_read_data.preamp += 0.1 * ((float) analogRead_SAMD_TT(PREAMP_PIN) - analog_read_data.preamp); + analog_read_data.buzz += 0.1 * ((float) analogRead_SAMD_TT(BUZZ_PIN) - analog_read_data.buzz); + analog_read_data.punch += 0.1 * ((float) analogRead_SAMD_TT(PUNCH_PIN) - analog_read_data.punch); + analog_read_data.crunch += 0.1 * ((float) analogRead_SAMD_TT(CRUNCH_PIN) - analog_read_data.crunch); + analog_read_data.drive += 0.1 * ((float) analogRead_SAMD_TT(DRIVE_PIN) - analog_read_data.drive); + analog_read_data.level += 0.1 * ((float) analogRead_SAMD_TT(LEVEL_PIN) - analog_read_data.level); + analog_read_data.low += 0.1 * ((float) analogRead_SAMD_TT(LOW_PIN) - analog_read_data.low); + analog_read_data.high += 0.1 * ((float) analogRead_SAMD_TT(HIGH_PIN) - analog_read_data.high); + xSemaphoreGive(analog_read_mutex); + delay_ms(30); + } +} + +AnalogReadData get_analog_read_data() { + xSemaphoreTake(analog_read_mutex, portMAX_DELAY); + AnalogReadData copy = analog_read_data; + xSemaphoreGive(analog_read_mutex); + return copy; +} \ No newline at end of file diff --git a/src/analog_read.h b/src/analog_read.h new file mode 100644 index 0000000..9bf8290 --- /dev/null +++ b/src/analog_read.h @@ -0,0 +1,16 @@ +#pragma once + +typedef struct { + float preamp; + float buzz; + float punch; + float crunch; + float drive; + float level; + float low; + float high; +} AnalogReadData; + +void setup_analog_read(); + +AnalogReadData get_analog_read_data(); \ No newline at end of file diff --git a/src/color.h b/src/color.h new file mode 100644 index 0000000..458d32b --- /dev/null +++ b/src/color.h @@ -0,0 +1,22 @@ +#pragma once + +#define COLOR_OFF RgbColor(0, 0, 0) + +#define COLOR_RED RgbColor(50, 0, 0) +#define COLOR_GREEN RgbColor(0, 50, 0) +#define COLOR_BLUE RgbColor(0, 0, 50) + +#define COLOR_CYAN RgbColor(0, 25, 25) +#define COLOR_MAGENTA RgbColor(25, 0, 25) +#define COLOR_YELLOW RgbColor(25, 25, 0) + +#define COLOR_SPINNER_FOREGROUND COLOR_BLUE +#define COLOR_SPINNER_BACKGROUND COLOR_OFF + +#define COLOR_MAIN_MENU_GAIN COLOR_CYAN +#define COLOR_MAIN_MENU_FADER COLOR_MAGENTA +#define COLOR_MAIN_MENU_MASTER COLOR_YELLOW + +#define COLOR_METER_PRE_FADER COLOR_RED +#define COLOR_METER_POST_FADER COLOR_GREEN +#define COLOR_METER_MASTER COLOR_BLUE \ No newline at end of file diff --git a/src/connect.cpp b/src/connect.cpp new file mode 100644 index 0000000..44e4638 --- /dev/null +++ b/src/connect.cpp @@ -0,0 +1,62 @@ +#include "connect.h" + +#include +#include +#include + +#include "main.h" +#include "network.h" +#include "priority.h" +#include "util.h" + +void check_connection_task(void *pvParameters); +void connect_task(void *pvParameters); + +TaskHandle_t check_connection_task_handle; +TaskHandle_t connect_task_handle; + +SemaphoreHandle_t connect_semaphore; + +wl_status_t wifi_status = WL_IDLE_STATUS; + + +void setup_connect() { + xTaskCreate(check_connection_task, "check_connection_task", 64, NULL, CHECK_CONNECT_PRIORITY, &check_connection_task_handle); + xTaskCreate(connect_task, "connect_task", 128, NULL, CONNECT_PRIORITY, &connect_task_handle); + + connect_semaphore = xSemaphoreCreateBinary(); +} + +void check_connection_task(void *pvParameters) { + for(;;) { + if (wifi_status != WL_CONNECTED) { + xSemaphoreGive(connect_semaphore); + delay_ms(15000); + } else { + delay_ms(5000); + } + } +} + +void connect_task(void *pvParameters) { + for(;;) { + xSemaphoreTake(connect_semaphore, portMAX_DELAY); + connection_lost(); + Serial.println("Connecting"); + wifi_status = (wl_status_t) WiFi.begin(WIFI_SSID, WIFI_PASS); + for (int i = 0; i < 10; i++) { + delay_ms(1000); + wifi_status = (wl_status_t) WiFi.status(); + if (wifi_status == WL_CONNECTED) { + connection_established(); + Serial.print("Connected with ip "); + Serial.println(WiFi.localIP()); + break; + } + } + } +} + +bool connected() { + return wifi_status == WL_CONNECTED; +} \ No newline at end of file diff --git a/src/connect.h b/src/connect.h new file mode 100644 index 0000000..9fc64d2 --- /dev/null +++ b/src/connect.h @@ -0,0 +1,5 @@ +#pragma once + +void setup_connect(); + +bool connected(); \ No newline at end of file diff --git a/src/digital_read.cpp b/src/digital_read.cpp new file mode 100644 index 0000000..822db8a --- /dev/null +++ b/src/digital_read.cpp @@ -0,0 +1,35 @@ +#include "digital_read.h" + +#include + +#include "mapping.h" +#include "priority.h" +#include "util.h" + +void digital_read_task(void *pvParameters); + +TaskHandle_t digital_read_task_handle; +SemaphoreHandle_t digital_read_mutex; +DigitalReadData digital_read_data; + +void setup_digital_read() { + xTaskCreate(digital_read_task, "digital_read_task", 256, NULL, DIGITAL_READ_PRIORITY, &digital_read_task_handle); + + digital_read_mutex = xSemaphoreCreateMutex(); +} + +void digital_read_task(void *pvParameters) { + for (;;) { + xSemaphoreTake(digital_read_mutex, portMAX_DELAY); + digital_read_data.cabinet = digitalRead(CABINET_PIN); + xSemaphoreGive(digital_read_mutex); + delay_ms(100); + } +} + +DigitalReadData get_digital_read_data() { + xSemaphoreTake(digital_read_mutex, portMAX_DELAY); + DigitalReadData copy = digital_read_data; + xSemaphoreGive(digital_read_mutex); + return copy; +} \ No newline at end of file diff --git a/src/digital_read.h b/src/digital_read.h new file mode 100644 index 0000000..871f03c --- /dev/null +++ b/src/digital_read.h @@ -0,0 +1,9 @@ +#pragma once + +typedef struct { + bool cabinet; +} DigitalReadData; + +void setup_digital_read(); + +DigitalReadData get_digital_read_data(); \ No newline at end of file diff --git a/src/encoder.cpp b/src/encoder.cpp new file mode 100644 index 0000000..f863af4 --- /dev/null +++ b/src/encoder.cpp @@ -0,0 +1,50 @@ +#include "encoder.h" + +#include +#include +#include + +#include "main.h" +#include "mapping.h" +#include "priority.h" +#include "spinner.h" +#include "util.h" + +void handle_press(); +void handle_rotate(int8_t rotation); +void encoder_task(void *pvParameters); + +TaskHandle_t encoder_task_handle; + +Versatile_RotaryEncoder *encoder; + +void setup_encoder() { + encoder = new Versatile_RotaryEncoder(ENCODER_PIN_CLK, ENCODER_PIN_DT, ENCODER_PIN_SW); + encoder->setHandlePress(handle_press); + encoder->setHandleRotate(handle_rotate); + + xTaskCreate(encoder_task, "encoder_task", 64, NULL, ENCODER_PRIORITY, &encoder_task_handle); +} + +void encoder_task(void *pvParameters) { + for(;;) { + encoder->ReadEncoder(); + delay_ms(10); + } +} + +void handle_press() { + Serial.println("Pressed"); + next_main_menu_item(); +} + +void handle_rotate(int8_t rotation) { + Serial.println("Rotated"); + rotation = -rotation; + if (rotation > 0) { + next_meter(); + } else if (rotation < 0) { + previous_meter(); + } + update_fader(rotation); +} \ No newline at end of file diff --git a/src/encoder.h b/src/encoder.h new file mode 100644 index 0000000..c28f5fc --- /dev/null +++ b/src/encoder.h @@ -0,0 +1,3 @@ +#pragma once + +void setup_encoder(); \ No newline at end of file diff --git a/src/led.cpp b/src/led.cpp new file mode 100644 index 0000000..8d0ea30 --- /dev/null +++ b/src/led.cpp @@ -0,0 +1,64 @@ +#include "led.h" + +#include + +#include "color.h" +#include "main.h" + +SemaphoreHandle_t led_mutex; + +NeoPixelBus strip(LED_BAR_COUNT + 1, LED_PIN); + +void setup_led() { + pinMode(LED_PIN, OUTPUT); + strip.Begin(); + led_mutex = xSemaphoreCreateMutex(); +} + +void set_state_led() { + RgbColor color; + switch (current_state()) { + case State::Connecting: + color = COLOR_OFF; + break; + case State::MainMenu: + switch (current_main_menu_item()) { + case MainMenuItem::Gain: + color = COLOR_MAIN_MENU_GAIN; + break; + case MainMenuItem::Fader: + color = COLOR_MAIN_MENU_FADER; + break; + case MainMenuItem::Master: + color = COLOR_MAIN_MENU_MASTER; + break; + case MainMenuItem::Meter: + switch (current_meter()) { + case Meter::PreFader: + color = COLOR_METER_PRE_FADER; + break; + case Meter::PostFader: + color = COLOR_METER_POST_FADER; + break; + case Meter::Master: + color = COLOR_METER_MASTER; + break; + } + break; + } + break; + }; + xSemaphoreTake(led_mutex, portMAX_DELAY); + strip.SetPixelColor(LED_BAR_COUNT, color); + strip.Show(); + xSemaphoreGive(led_mutex); +} + +void set_bar_leds(RgbColor bar[LED_BAR_COUNT]) { + xSemaphoreTake(led_mutex, portMAX_DELAY); + for (size_t i = 0; i < LED_BAR_COUNT; i++) { + strip.SetPixelColor(i, bar[i]); + } + strip.Show(); + xSemaphoreGive(led_mutex); +} \ No newline at end of file diff --git a/src/led.h b/src/led.h new file mode 100644 index 0000000..acabbb4 --- /dev/null +++ b/src/led.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +#include "mapping.h" + +void setup_led(); + +void set_state_led(); +void set_bar_leds(RgbColor bar[LED_BAR_COUNT]); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fe6f7f1 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,158 @@ +#include +#include +#include + +#include "analog_read.h" +#include "connect.h" +#include "color.h" +#include "digital_read.h" +#include "encoder.h" +#include "led.h" +#include "main.h" +#include "mapping.h" +#include "network.h" +#include "publish.h" +#include "spinner.h" +#include "util.h" + +SemaphoreHandle_t state_mutex; +State state = State::Connecting; +MainMenuItem main_menu = MainMenuItem::Meter; +Meter meter = Meter::Master; + + +void setup() { + Serial.begin(9600); + + setup_analog_read(); + setup_connect(); + setup_digital_read(); + setup_encoder(); + setup_led(); + setup_publish(); + setup_spinner(); + + state_mutex = xSemaphoreCreateMutex(); + + OscWiFi.publish(XAIR_IP, XAIR_PORT, "/xinfo")->setFrameRate(0.1); + OscWiFi.subscribe(LOCAL_PORT, "/*", print_osc_message); + + vTaskStartScheduler(); + Serial.println("Start scheduler failed"); +} + +void loop() { + for(;;) {} +} + +void connection_established() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + state = State::MainMenu; + stop_spinner(); + set_state_led(); + xSemaphoreGiveRecursive(state_mutex); +} + +void connection_lost() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + state = State::Connecting; + start_spinner(); + set_state_led(); + xSemaphoreGiveRecursive(state_mutex); +} + +State current_state() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + State current_state = state; + xSemaphoreGiveRecursive(state_mutex); + return current_state; +} + +void next_main_menu_item() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + if (State::Connecting == current_state()) { + xSemaphoreGiveRecursive(state_mutex); + return; + } + switch (main_menu) { + case MainMenuItem::Gain: + main_menu = MainMenuItem::Fader; + break; + case MainMenuItem::Fader: + main_menu = MainMenuItem::Master; + break; + case MainMenuItem::Master: + main_menu = MainMenuItem::Meter; + break; + case MainMenuItem::Meter: + main_menu = MainMenuItem::Gain; + break; + } + xSemaphoreGiveRecursive(state_mutex); + set_state_led(); +} + +MainMenuItem current_main_menu_item() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + MainMenuItem current_main_menu = main_menu; + xSemaphoreGiveRecursive(state_mutex); + return current_main_menu; +} + +void previous_meter() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + if (State::Connecting == current_state()) { + xSemaphoreGiveRecursive(state_mutex); + return; + } + if (MainMenuItem::Meter != current_main_menu_item()) { + xSemaphoreGiveRecursive(state_mutex); + return; + } + switch (meter) { + case Meter::PreFader: + break; + case Meter::PostFader: + meter = Meter::PreFader; + break; + case Meter::Master: + meter = Meter::PostFader; + break; + } + xSemaphoreGiveRecursive(state_mutex); + set_state_led(); +} + +void next_meter() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + if (State::Connecting == current_state()) { + xSemaphoreGiveRecursive(state_mutex); + return; + } + if (MainMenuItem::Meter != current_main_menu_item()) { + xSemaphoreGiveRecursive(state_mutex); + return; + } + switch (meter) { + case Meter::PreFader: + meter = Meter::PostFader; + break; + case Meter::PostFader: + meter = Meter::Master; + break; + case Meter::Master: + break; + } + xSemaphoreGiveRecursive(state_mutex); + set_state_led(); +} + +Meter current_meter() { + xSemaphoreTakeRecursive(state_mutex, portMAX_DELAY); + Meter current_meter = meter; + xSemaphoreGiveRecursive(state_mutex); + return current_meter; +} + +void update_fader(uint8_t value) { +} \ No newline at end of file diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..54977de --- /dev/null +++ b/src/main.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +enum class State { + Connecting, + MainMenu +}; + +enum class MainMenuItem { + Gain, + Fader, + Master, + Meter +}; + +enum class Meter { + PreFader, + PostFader, + Master, +}; + +void connection_established(); +void connection_lost(); +State current_state(); + +void next_main_menu_item(); +MainMenuItem current_main_menu_item(); + +void previous_meter(); +void next_meter(); +Meter current_meter(); + +void update_fader(uint8_t value); \ No newline at end of file diff --git a/src/mapping.h b/src/mapping.h new file mode 100644 index 0000000..9bd75a4 --- /dev/null +++ b/src/mapping.h @@ -0,0 +1,30 @@ +#pragma once + +#define ENCODER_PIN_CLK 8 +#define ENCODER_PIN_DT 9 +#define ENCODER_PIN_SW 10 + +#define CABINET_PIN 7 + +#define PREAMP_PIN A0 +#define BUZZ_PIN A1 +#define PUNCH_PIN A2 +#define CRUNCH_PIN A3 +#define DRIVE_PIN 5 +#define LEVEL_PIN 4 +#define LOW_PIN A6 +#define HIGH_PIN A7 + +#define LED_PIN 12 +#define LED_BAR_COUNT 10 + +#define CABINET_PAR "/fx/1/par/09" + +#define PREAMP_PAR "/fx/1/par/01" +#define BUZZ_PAR "/fx/1/par/02" +#define PUNCH_PAR "/fx/1/par/03" +#define CRUNCH_PAR "/fx/1/par/04" +#define DRIVE_PAR "/fx/1/par/05" +#define LEVEL_PAR "/fx/1/par/06" +#define LOW_PAR "/fx/1/par/07" +#define HIGH_PAR "/fx/1/par/08" \ No newline at end of file diff --git a/src/network.h b/src/network.h new file mode 100644 index 0000000..3f78937 --- /dev/null +++ b/src/network.h @@ -0,0 +1,9 @@ +#pragma once + +#define WIFI_SSID "telenet-D6A9117" +#define WIFI_PASS "gewoonzonderhoofdletters" + +#define XAIR_IP "192.168.0.4" +#define XAIR_PORT 10024 + +#define LOCAL_PORT 12345 diff --git a/src/priority.h b/src/priority.h new file mode 100644 index 0000000..b35bc70 --- /dev/null +++ b/src/priority.h @@ -0,0 +1,14 @@ +#pragma once + +#define CHECK_CONNECT_PRIORITY 1 +#define SPINNER_PRIORITY 1 + +#define ANALOG_READ_PRIORITY 2 +#define DIGITAL_READ_PRIORITY 2 + +#define PUBLISH_PRIORITY 3 + +#define OSC_UPDATE_PRIORITY 4 + +#define ENCODER_PRIORITY 5 +#define CONNECT_PRIORITY 5 \ No newline at end of file diff --git a/src/publish.cpp b/src/publish.cpp new file mode 100644 index 0000000..2d73697 --- /dev/null +++ b/src/publish.cpp @@ -0,0 +1,68 @@ +#include "publish.h" + +#include +#include + +#include "analog_read.h" +#include "digital_read.h" +#include "mapping.h" +#include "network.h" +#include "priority.h" +#include "util.h" + +void publish_task(void *pvParameters); +void osc_update_task(void *pvParameters); + +TaskHandle_t publish_task_handle; +TaskHandle_t osc_update_task_handle; + +SemaphoreHandle_t osc_mutex; + +void setup_publish() { + xTaskCreate(publish_task, "publish_task", 256, NULL, PUBLISH_PRIORITY, &publish_task_handle); + xTaskCreate(osc_update_task, "osc_update_task", 256, NULL, OSC_UPDATE_PRIORITY, &osc_update_task_handle); + + osc_mutex = xSemaphoreCreateMutex(); + + OscWiFi.getClient().localPort(LOCAL_PORT); +} + +void publish_task(void *pvParameters) { + for(;;) { + delay_ms(100); + + DigitalReadData digital_read_data = get_digital_read_data(); + int cabinet_int = digital_read_data.cabinet ? 0 : 1; + + AnalogReadData analog_read_data = get_analog_read_data(); + float preamp_scaled = analog_read_data.preamp / 4095.f; + float buzz_scaled = analog_read_data.buzz / 4095.f; + float punch_scaled = analog_read_data.punch / 4095.f; + float crunch_scaled = analog_read_data.crunch / 4095.f; + float drive_scaled = analog_read_data.drive / 4095.f; + float level_scaled = analog_read_data.level / 4095.f; + float low_scaled = analog_read_data.low / 4095.f; + float high_scaled = analog_read_data.high / 4095.f; + + xSemaphoreTake(osc_mutex, portMAX_DELAY); + OscWiFi.publish(XAIR_IP, XAIR_PORT, CABINET_PAR, cabinet_int); + OscWiFi.publish(XAIR_IP, XAIR_PORT, PREAMP_PAR, preamp_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, BUZZ_PAR, buzz_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, PUNCH_PAR, punch_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, CRUNCH_PAR, crunch_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, DRIVE_PAR, drive_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, LEVEL_PAR, level_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, LOW_PAR, low_scaled); + OscWiFi.publish(XAIR_IP, XAIR_PORT, HIGH_PAR, high_scaled); + xSemaphoreGive(osc_mutex); + } +} + +void osc_update_task(void *pvParameters) { + for(;;) { + xSemaphoreTake(osc_mutex, portMAX_DELAY); + OscWiFi.update(); + xSemaphoreGive(osc_mutex); + delay_ms(10); + } +} \ No newline at end of file diff --git a/src/publish.h b/src/publish.h new file mode 100644 index 0000000..3a2d570 --- /dev/null +++ b/src/publish.h @@ -0,0 +1,3 @@ +#pragma once + +void setup_publish(); \ No newline at end of file diff --git a/src/spinner.cpp b/src/spinner.cpp new file mode 100644 index 0000000..3c117b0 --- /dev/null +++ b/src/spinner.cpp @@ -0,0 +1,72 @@ +#include "spinner.h" + +#include + +#include "color.h" +#include "led.h" +#include "priority.h" +#include "mapping.h" +#include "util.h" + +void spinner_task(void *pvParameters); + +TaskHandle_t spinner_task_handle; +SemaphoreHandle_t spinner_semaphore; + +void setup_spinner() { + xTaskCreate(spinner_task, "spinner_task", 64, NULL, SPINNER_PRIORITY, &spinner_task_handle); + spinner_semaphore = xSemaphoreCreateBinary(); + start_spinner(); +} + +void start_spinner() { + if(!is_spinner_running()) + xSemaphoreGive(spinner_semaphore); +} + +void stop_spinner() { + xSemaphoreTake(spinner_semaphore, portMAX_DELAY); + RgbColor leds[LED_BAR_COUNT]; + for(size_t led = 0; led < LED_BAR_COUNT; led++) { + leds[led] = RgbColor(0, 0, 0); + } + set_bar_leds(leds); +} + +bool is_spinner_running() { + return uxSemaphoreGetCount(spinner_semaphore); +} + +void spinner_task(void *pvParameters) { + bool going_up = true; + size_t i = 0; + for(;;) { + RgbColor leds[LED_BAR_COUNT]; + for(size_t led = 0; led < LED_BAR_COUNT; led++) { + if(led == i) { + leds[led] = COLOR_SPINNER_FOREGROUND; + } else { + leds[led] = COLOR_SPINNER_BACKGROUND; + } + } + set_bar_leds(leds); + if(going_up) { + i++; + if(i == LED_BAR_COUNT - 1) { + going_up = false; + } + } else { + i--; + if(i == 0) { + going_up = true; + } + } + delay_ms(200); + if(!is_spinner_running()) { + i = 0; + going_up = true; + xSemaphoreTake(spinner_semaphore, portMAX_DELAY); + xSemaphoreGive(spinner_semaphore); + } + } +} \ No newline at end of file diff --git a/src/spinner.h b/src/spinner.h new file mode 100644 index 0000000..68bf92b --- /dev/null +++ b/src/spinner.h @@ -0,0 +1,7 @@ +#pragma once + +void setup_spinner(); + +void start_spinner(); +void stop_spinner(); +bool is_spinner_running(); \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..174f7cc --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,33 @@ +#include "util.h" + +void delay_ms(TickType_t ms) { + vTaskDelay(ms / portTICK_PERIOD_MS); +} + +void print_osc_message(OscMessage& m) { + Serial.println(m.address()); + Serial.println(m.typeTags()); + for (size_t i = 0; i < m.size(); i++) { + if (m.isBool(i)) { + Serial.println(m.getArgAsBool(i)); + } else if (m.isInt32((i))) { + Serial.println(m.getArgAsInt32(i)); + } else if (m.isInt64((i))) { + Serial.println(m.getArgAsInt64(i)); + } else if (m.isFloat((i))) { + Serial.println(m.getArgAsFloat(i)); + } else if (m.isDouble((i))) { + Serial.println(m.getArgAsDouble(i)); + } else if (m.isStr((i))) { + Serial.println(m.getArgAsString(i)); + } else if (m.isBlob((i))) { + for (auto c: m.getArgAsBlob(i)) { + Serial.print(c, HEX); + Serial.print(" "); + } + Serial.println(""); + } else { + Serial.println("unknown"); + } + } +} \ No newline at end of file diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..7d3a4c2 --- /dev/null +++ b/src/util.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +void delay_ms(TickType_t ms); + +void print_osc_message(OscMessage& m); \ No newline at end of file