4 Commits

Author SHA1 Message Date
686f76b0fd merged fastled into main 2025-05-28 00:48:38 +02:00
499d5f2c63 ui and edge leds working with pwmaudio and sdio 2025-05-28 00:43:05 +02:00
c9b6220449 switch to fastled because of too few pios 2025-05-28 00:31:00 +02:00
235603d47a readme updated 2025-05-27 19:45:00 +02:00
2 changed files with 67 additions and 56 deletions

View File

@ -9,6 +9,27 @@
- the board will go into bootloader mode and appear as USB thumb drive - the board will go into bootloader mode and appear as USB thumb drive
6. Copy the `soundcube-firmware.ino.uf2` file to the thumb drive and wait for the board to restart 6. Copy the `soundcube-firmware.ino.uf2` file to the thumb drive and wait for the board to restart
## config.txt
Json formatted config file. For now only edge led color working.
```
{
"edge": {
"color":{
"r":50,
"g":0,
"b":0
}
}
}
```
## click.wav (not played correctly)
Put a file called `click.wav` (not longer than a few seconds) in the root of the SD card and it will play when you press a button.
## Code something yourself ## Code something yourself
1. Download [Arduino IDE](https://www.arduino.cc/en/software/) 1. Download [Arduino IDE](https://www.arduino.cc/en/software/)

View File

@ -3,7 +3,7 @@
#include <TCA9555.h> #include <TCA9555.h>
#include <AS5600.h> #include <AS5600.h>
#include <Adafruit_NeoPixel.h> #include <FastLED.h>
#include <PWMAudio.h> #include <PWMAudio.h>
#include <I2S.h> #include <I2S.h>
#include <SPI.h> #include <SPI.h>
@ -22,8 +22,8 @@ PWMAudio ui_snd(8);
enum BUTTON {CVINL, CVINR, INL, INR, OUTR, OUTL, CVOUTR, CVOUTL, RIGHT, LEFT, SELECT, DEBUG1, DEBUG2, DEBUG3}; enum BUTTON {CVINL, CVINR, INL, INR, OUTR, OUTL, CVOUTR, CVOUTL, RIGHT, LEFT, SELECT, DEBUG1, DEBUG2, DEBUG3};
Adafruit_NeoPixel edge_pixels(11, 4, NEO_GRB + NEO_KHZ800); CRGB ui_leds[74];
Adafruit_NeoPixel ui_pixels(74, 5, NEO_GRB + NEO_KHZ800); CRGB edge_leds[11];
volatile bool flag = false; volatile bool flag = false;
volatile bool click = false; volatile bool click = false;
@ -72,7 +72,7 @@ void pwm_audio_callback() {
click = false; click = false;
} }
} else { } else {
digitalWriteFast(7, LOW); digitalWrite(7, LOW);
ui_snd.write(0); ui_snd.write(0);
counter = 0; counter = 0;
} }
@ -85,9 +85,10 @@ void tca_irq() {
void setup() { void setup() {
Serial.begin(); Serial.begin();
while (!Serial) { delay(2000);
;
} FastLED.addLeds<NEOPIXEL, 4>(edge_leds, 11);
FastLED.addLeds<NEOPIXEL, 5>(ui_leds, 74);
pinMode(21, INPUT_PULLUP); pinMode(21, INPUT_PULLUP);
sd_card_detected = !digitalRead(21); sd_card_detected = !digitalRead(21);
@ -102,13 +103,14 @@ void setup() {
if(sdInitialized && SD.exists("/click.wav")) { if(sdInitialized && SD.exists("/click.wav")) {
File click = SD.open("/click.wav"); File click = SD.open("/click.wav");
int click_bytes = 0; int click_bytes = 0;
int32_t maxv = 0; int16_t maxv = 0;
while (click.available() || click_bytes == UI_SAMPLERATE-1) { while (click.available() || click_bytes == UI_SAMPLERATE-1) {
int32_t sample = click.read() * 64; int16_t sample = click.read() * 32;
if(abs(sample) > maxv) maxv = sample; if(abs(sample) > maxv) maxv = sample;
beep[click_bytes] = sample; beep[click_bytes] = sample;
click_bytes++; click_bytes++;
} }
click.close();
beep_length = click_bytes; beep_length = click_bytes;
Serial.print("Read "); Serial.print("Read ");
@ -152,10 +154,11 @@ void setup() {
ui_snd.begin(UI_SAMPLERATE); ui_snd.begin(UI_SAMPLERATE);
digitalWrite(7, LOW); digitalWrite(7, LOW);
edge_pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
ui_pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
digitalWrite(6, HIGH);
delay(50);
digitalWrite(6, LOW);
// i2s.setDOUT(14); // i2s.setDOUT(14);
// i2s.setDIN(15); // i2s.setDIN(15);
// i2s.setBCLK(16); // // i2s.setBCLK(16); //
@ -172,6 +175,7 @@ void setup() {
// i2s.write16(l, r); // i2s.write16(l, r);
// } // }
} }
int active = 0; int active = 0;
int active_led_ring = 0; int active_led_ring = 0;
@ -179,91 +183,77 @@ uint32_t lastTime = 0;
int32_t position = 0; int32_t position = 0;
void loop() { 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(); position = ENC.getCumulativePosition();
// if (millis() - lastTime >= 100) sd_card_detected = !digitalRead(21);
// { if(sd_card_detected) edge_leds[8] = CRGB(0,25,0);
// lastTime = millis(); if(!sd_card_detected) edge_leds[8] = CRGB(25,0,0);
// Serial.print(ENC.getCumulativePosition());
// Serial.print("\t");
// Serial.println(ENC.getRevolutions());
// }
// EDGE LEDs
for (int i = 0; i < 8; i++) {
edge_leds[i] = CRGB(config.edge_color_r, config.edge_color_g, config.edge_color_b);
}
// LED Ring leeren // LED Ring leeren
for (int i = 0; i < 48; i++) { for (int i = 0; i < 48; i++) {
ui_pixels.setPixelColor(i + 3, edge_pixels.Color(0, 0, 0)); ui_leds[i + 3] = CRGB(0, 0, 0);
} }
// flag = true when a button is pushed // flag = true when a button is pushed
if (flag) { if (flag) {
int val = TCA.read16(); int val = TCA.read16();
Serial.println(val, BIN);
for(int i = 0; i < 16; i++){ for(int i = 0; i < 16; i++){
buttons[i] = ~(val >> i) & 0x01; buttons[i] = ~(val >> i) & 0x01;
Serial.print(buttons[i]);
Serial.print(" ");
} }
Serial.println();
// Make vibration
flag = false;
if (HAPTIC) { if (HAPTIC) {
digitalWrite(6, HIGH); digitalWrite(6, HIGH);
} delay(50);
// Make beep
if (AURAL) {
digitalWriteFast(7, HIGH);
click = true;
}
// Make vibration
if(HAPTIC){
if(!AURAL) delay(50);
digitalWrite(6, LOW); digitalWrite(6, LOW);
} }
// Make beep
if (AURAL) {
digitalWrite(7, HIGH);
click = true;
}
// Flash led ring // Flash led ring
for (int i = 0; i < 48; i++) { for (int i = 0; i < 48; i++) {
ui_pixels.setPixelColor(i + 3, edge_pixels.Color(0, 15, 0)); ui_leds[i + 3] = CRGB(0, 15, 0);
} }
// Switch through LED matrix // Switch through LED matrix
if(buttons[RIGHT]) active++; if(buttons[RIGHT]) active++;
if(buttons[LEFT]) active--; if(buttons[LEFT]) active--;
if(active == 13) active = 0; if(active == 13) active = 0;
if(active == -1) active = 12; if(active == -1) active = 12;
}
flag = false;
// EDGE LEDs
for (int i = 0; i < 8; i++) {
edge_pixels.setPixelColor(i, edge_pixels.Color(config.edge_color_r, config.edge_color_g, config.edge_color_b));
} }
// Rotary button LEDs // Rotary button LEDs
ui_pixels.setPixelColor(0, edge_pixels.Color(0, 0, 15)); ui_leds[0] = CRGB(0, 0, 15);
ui_pixels.setPixelColor(1, edge_pixels.Color(0, 0, 15)); ui_leds[1] = CRGB(0, 0, 15);
ui_pixels.setPixelColor(2, edge_pixels.Color(0, 0, 15)); ui_leds[2] = CRGB(0, 0, 15);
// empty LED matrix // empty LED matrix
for (int i = 0; i < 13; i++) { for (int i = 0; i < 13; i++) {
ui_pixels.setPixelColor(i + 3 + 48 + 4, edge_pixels.Color(0, 0, 0)); ui_leds[i + 3 + 48 + 4] = CRGB(0, 0, 0);
} }
// set active LED matrix LED // set active LED matrix LED
ui_pixels.setPixelColor(active + 3 + 48 + 4, edge_pixels.Color(255, 255, 255)); ui_leds[active + 3 + 48 + 4] = CRGB(255, 255, 255);
if(position < 0) position += 4096; if(position < 0) position += 4096;
active_led_ring = (position / 32) % 48; active_led_ring = (position / 32) % 48;
// set active LED ring LED // set active LED ring LED
ui_pixels.setPixelColor(active_led_ring + 3, edge_pixels.Color(255, 255, 255)); ui_leds[active_led_ring + 3] = CRGB(255, 255, 255);
edge_pixels.show(); FastLED.show();
ui_pixels.show();
delay(1); // wait 1ms delay(1); // wait 1ms
} }