Initial commit of arduino software

This commit is contained in:
Victor Barberan 2025-07-13 21:42:21 +02:00
parent a377243efd
commit dc1efea80e
3 changed files with 301 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
arduino/dj/build

298
arduino/dj/dj.ino Normal file
View file

@ -0,0 +1,298 @@
#include <FastLED.h>
class Mux {
private:
uint8_t _pins[4];
uint8_t _enablePin = 255;
uint8_t _channel = 0;
uint8_t _comm;
public:
Mux(uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3, uint8_t comm) {
_pins[0] = s0;
_pins[1] = s1;
_pins[2] = s2;
_pins[3] = s3;
_comm = comm;
for (uint8_t i=0; i<4; i++) {
pinMode(_pins[i], OUTPUT);
digitalWrite(_pins[i], LOW);
}
pinMode(_comm, INPUT);
_channel = 0;
}
bool setChannel(uint8_t channel) {
if (channel > 15) return false;
uint8_t _new = channel;
if (_new != _channel) {
uint8_t _changed = _new ^ _channel;
uint8_t mask = 0x08;
uint8_t i = 3;
while (mask) {
// only write changed pins.
if (mask & _changed) digitalWrite(_pins[i], (mask & _new));
i--;
mask >>= 1;
}
_channel = _new;
}
return true;
}
bool digitalR(uint8_t chann) {
setChannel(chann);
return digitalRead(_comm);
}
int analogR(uint8_t chann) {
setChannel(chann);
return analogRead(_comm);
}
};
class Button {
private:
uint8_t _chann;
Mux * _mux;
bool _state;
bool _debounceState;
uint32_t _lastDebounce = 0;
uint16_t _debounceDelay;
public:
const char* name;
Button(const char * newName ,uint8_t chann, Mux * mux, uint16_t debounceDelay=10) {
_chann = chann;
_mux = mux;
_debounceDelay = debounceDelay;
name = newName;
}
bool stateChanged() {
bool tmpState = !_mux->digitalR(_chann);
if (tmpState != _debounceState) _lastDebounce = millis();
if (millis() - _lastDebounce > _debounceDelay) {
if (tmpState != _state) {
_state = tmpState;
return true;
}
}
_debounceState = tmpState;
return false;
}
// Returns true if something has changed
bool update() {
if (stateChanged()) {
Serial.print(name);
Serial.print(": ");
if (_state == true) Serial.println("pressed");
else Serial.println("Released");
return true;
}
return false;
}
// Eventos
// - state (down or up)
// - press (up-down)
// - release (down-up)
// - single click (press-release en menos de n millis)
// - double click (single-single en menos de n millis)
// - triple click (single-single-single en menos de n millis)
//
};
class Pot {
private:
uint8_t _chann;
Mux * _mux;
int _prevValue;
uint8_t _diff; // A change bigger than this indicates that the pot has moved
public:
const char* name;
int value;
Pot(const char * newName ,uint8_t chann, Mux * mux, uint8_t diff=5) {
_chann = chann;
_mux = mux;
_diff = diff;
name = newName;
}
bool valueChanged() {
value = _mux->analogR(_chann);
if (abs(value - _prevValue) > _diff) {
_prevValue = value;
return true;
}
return false;
}
// Returns true if something has changed
bool update() {
if (valueChanged()) {
Serial.print(name);
Serial.print(": ");
Serial.println(value);
return true;
}
return false;
}
// TODO
// Un rolling average que suvice un poco los movimientos
};
Mux mux_A(26, 25, 27, 32, 33); // (s0, s1, s2, s3, comm)
// 6, 7, 8, 9, 10, 15 -> NC
Mux mux_B(16, 17, 18, 19, 34); // (s0, s1, s2, s3, comm)
// 3 -> ANO_ENC_A
// 4 -> ANO_ENC_B
Button ACenter("A Center", 5, &mux_B); // SW1
Button ADown("A Down", 6, &mux_B); // SW2
Button ARight("A Right", 7, &mux_B); // SW3
Button AUp("A Up", 8, &mux_B); // SW4
Button ALeft("A Left", 9, &mux_B); // SW5
Pot MLevel("M Level", 0, &mux_A);
Pot LLevel("L Level", 1, &mux_A); // Slide
Pot LHigh("L High", 2, &mux_A);
Pot LMiddle("L Middle", 3, &mux_A);
Pot LLow("L Low", 4, &mux_A);
Pot LFx("L FX", 5, &mux_A);
Pot RLevel("R Level", 14, &mux_B); // Slide
Pot RHigh("R High", 13, &mux_B);
Pot RMiddle("R Middle", 12, &mux_B);
Pot RLow("R Low", 11, &mux_B);
Pot RFx("R FX", 10, &mux_B);
Pot * pots[11];
Button LPlay("L Play", 12, &mux_A);
Button LCue("L Cue", 11, &mux_A);
Button LSync("L Sync", 13, &mux_A);
Button LPhones("L Phones", 14, &mux_A);
Button RPlay("R Play", 0, &mux_B);
Button RCue("R Cue", 15, &mux_B); // BUG: Al mover el slider (channel 14) se mete ruido al boton (pareciera ser un problema de hardware)
Button RSync("R Sync", 1, &mux_B);
Button RPhones("R Phones", 2, &mux_B);
Button * botones[8];
const int BATT_CHG_SIGNAL_PIN = 14;
const int BATT_VOLT_PIN = 35;
// 5% steps
float battTable[] = {
4.2, // 100
4.15, // 95
4.11, // 90
4.08, // 85
4.02, // 80
3.98, // 75
3.95, // 70
3.91, // 65
3.87, // 60
3.85, // 55
3.84, // 50
3.82, // 45
3.80, // 40 (Storage recomended)
3.79, // 35
3.77, // 30
3.75, // 25
3.73, // 20
3.71, // 15 (Sane limit)
3.69 // 10 (Danger limit)
};
uint8_t battLevel() {
// Vin = Vout * ((R1 + R2) / R2)
// ((R1 + R2) / R2) = (1,200,000 / 200,000) = 6
int Vout = analogRead(BATT_VOLT_PIN);
float Vin = Vout * 6.0;
uint8_t percent = 100;
for (uint8_t l=0; l<19; l++) {
if (Vin >= battTable[l]) return percent;
percent -= 5;
}
return 0;
// TODO
// Interpolar los porcentajes
}
bool battIsCharging() {
return !digitalRead(BATT_CHG_SIGNAL_PIN);
}
#define NUM_LEDS 17
CRGB leds[NUM_LEDS];
uint32_t ledChanged = 0;
uint8_t ledIndex = 0;
void refreshLeds() {
if (millis() - ledChanged < 500) return;
ledChanged = millis();
if (ledIndex == NUM_LEDS) ledIndex = 0;
fill_solid(&(leds[0]), NUM_LEDS, CRGB::Black);
leds[ledIndex] = CRGB::Red;
FastLED.show();
ledIndex++;
}
void setup() {
FastLED.addLeds<NEOPIXEL, 13>(leds, NUM_LEDS);
pinMode(BATT_VOLT_PIN, INPUT);
pinMode(BATT_CHG_SIGNAL_PIN, INPUT);
Serial.begin(115200);
botones[0] = &LPlay;
botones[1] = &LCue;
botones[2] = &LSync;
botones[3] = &LPhones;
botones[4] = &RPlay;
botones[5] = &RCue;
botones[6] = &RSync;
botones[7] = &RPhones;
pots[0] = &MLevel;
pots[1] = &LLevel; // Slide
pots[2] = &LHigh;
pots[3] = &LMiddle;
pots[4] = &LLow;
pots[5] = &LFx;
pots[6] = &RLevel; // Slide
pots[7] = &RHigh;
pots[8] = &RMiddle;
pots[9] = &RLow;
pots[10] = &RFx;
}
void loop() {
for (uint8_t i=0; i<8; i++) {
botones[i]->update();
}
for (uint8_t i=0; i<11; i++) {
pots[i]->update();
}
refreshLeds();
}

2
arduino/dj/sketch.yaml Normal file
View file

@ -0,0 +1,2 @@
default_port: /dev/ttyUSB0
default_fqbn: arduino:esp32