From a16ac73d9bc3fa511ed8cb538a5a91e4bdeb37a4 Mon Sep 17 00:00:00 2001 From: Sebastian Kujas Date: Tue, 27 May 2025 19:40:13 +0200 Subject: [PATCH] SD card working, simple config for edge led color added --- soundcube-firmware/soundcube-firmware.ino | 99 +++++++++++++++++++---- 1 file changed, 84 insertions(+), 15 deletions(-) diff --git a/soundcube-firmware/soundcube-firmware.ino b/soundcube-firmware/soundcube-firmware.ino index 41331c5..7d89681 100644 --- a/soundcube-firmware/soundcube-firmware.ino +++ b/soundcube-firmware/soundcube-firmware.ino @@ -1,8 +1,13 @@ +#include +#include + #include #include #include #include #include +#include +#include #define HAPTIC 1 #define AURAL 1 @@ -17,8 +22,8 @@ PWMAudio ui_snd(8); enum BUTTON {CVINL, CVINR, INL, INR, OUTR, OUTL, CVOUTR, CVOUTL, RIGHT, LEFT, SELECT, DEBUG1, DEBUG2, DEBUG3}; -Adafruit_NeoPixel edge_pixels(8, 4, NEO_GRB + NEO_KHZ800); -Adafruit_NeoPixel ui_pixels(72, 5, NEO_GRB + NEO_KHZ800); +Adafruit_NeoPixel edge_pixels(11, 4, NEO_GRB + NEO_KHZ800); +Adafruit_NeoPixel ui_pixels(74, 5, NEO_GRB + NEO_KHZ800); volatile bool flag = false; volatile bool click = false; @@ -29,16 +34,48 @@ int counter = 0; bool buttons[16] = {false}; int16_t beep[UI_SAMPLERATE]; +uint16_t beep_length = 0; + +bool sd_card_detected = false; + +struct Config { + int edge_color_r = 0; + int edge_color_g = 0; + int edge_color_b = 50; +}; + +Config config; + +void loadConfiguration(Config& config) { + File file = SD.open("/config.txt"); + JsonDocument doc; + + DeserializationError error = deserializeJson(doc, file); + if(error) Serial.println(F("Failed to read file, using default configuration")); + + config.edge_color_r = doc["edge"]["color"]["r"] | 0; + config.edge_color_g = doc["edge"]["color"]["g"] | 0; + config.edge_color_b = doc["edge"]["color"]["b"] | 50; + + //strlcpy(config.hostname, doc["hostname"] | "example.com", sizeof(config.hostname)); + + file.close(); +} void pwm_audio_callback() { while (ui_snd.availableForWrite()) { if(click) { ui_snd.write(beep[counter]); + counter++; + if(counter == beep_length) { + counter = 0; + click = false; + } } else { + digitalWriteFast(7, LOW); ui_snd.write(0); + counter = 0; } - counter++; - if(counter == UI_SAMPLERATE) counter = 0; } } @@ -47,14 +84,45 @@ void tca_irq() { } void setup() { - - for(int i = 0; i < UI_SAMPLERATE; i++){ - float sine_pos = (2.0f * M_PI * 8000.0f * (float)i) / (float)UI_SAMPLERATE; - beep[i] = (int16_t)(sin(sine_pos) * 8000.0f); + Serial.begin(); + while (!Serial) { + ; } - Serial.begin(); - delay(2000); + pinMode(21, INPUT_PULLUP); + sd_card_detected = !digitalRead(21); + delay(500); + + bool sdInitialized = SD.begin(22, 23, 24); + delay(100); + if(!sdInitialized) sdInitialized = SD.begin(22, 23, 24); // hack to prevent SD card from not initializing after soft reset + + if(sdInitialized) loadConfiguration(config); + + if(sdInitialized && SD.exists("/click.wav")) { + File click = SD.open("/click.wav"); + int click_bytes = 0; + int32_t maxv = 0; + while (click.available() || click_bytes == UI_SAMPLERATE-1) { + int32_t sample = click.read() * 64; + if(abs(sample) > maxv) maxv = sample; + beep[click_bytes] = sample; + click_bytes++; + } + + beep_length = click_bytes; + Serial.print("Read "); + Serial.print(beep_length); + Serial.print(" bytes from click.wav into beep array. maxV was "); + Serial.println(maxv); + } else { + for(int i = 0; i < UI_SAMPLERATE; i++){ + float sine_pos = (2.0f * M_PI * 8000.0f * (float)i) / (float)UI_SAMPLERATE; + beep[i] = (int16_t)(sin(sine_pos) * 8000.0f); + } + Serial.println("Synthesized 8kHz sine into beep array."); + beep_length = UI_SAMPLERATE; + } Serial.println("INIT WIRE"); Wire1.setSDA(2); @@ -114,6 +182,10 @@ void loop() { edge_pixels.clear(); // Set all pixel colors to 'off' ui_pixels.clear(); // Set all pixel colors to 'off' + sd_card_detected = !digitalRead(21); + if(sd_card_detected) edge_pixels.setPixelColor(8, edge_pixels.Color(0,25,0)); + if(!sd_card_detected) edge_pixels.setPixelColor(8, edge_pixels.Color(25,0,0)); + position = ENC.getCumulativePosition(); // if (millis() - lastTime >= 100) @@ -147,11 +219,8 @@ void loop() { } // Make beep if (AURAL) { - digitalWrite(7, HIGH); + digitalWriteFast(7, HIGH); click = true; - delay(50); - click = false; - digitalWrite(7, LOW); } // Make vibration if(HAPTIC){ @@ -171,7 +240,7 @@ void loop() { // EDGE LEDs for (int i = 0; i < 8; i++) { - edge_pixels.setPixelColor(i, edge_pixels.Color(15, 15, 15)); + edge_pixels.setPixelColor(i, edge_pixels.Color(config.edge_color_r, config.edge_color_g, config.edge_color_b)); } // Rotary button LEDs