Festival Carousel Horse LED Controller Schematic


  • Set R32's Resistance to "10kΩ"
  • Set R32's Role Details to "Battery monitor divider upper resistor from +12V_RAIL to BATTERY_ADC per requirement"
  • Set R33's Resistance to "3.3kΩ"
  • Set R33's Role Details to "Battery monitor divider lower resistor from BATTERY_ADC to GND per requirement"
Work done
  • Completed the remaining schematic updates: replaced the RS-485 placeholder with U5 MAX485CSA+, powered it from 5V, wired UART/control nets, corrected DMX polarity labels to DMX_PLUS / DMX_MINUS, and updated the battery monitor divider to R32=10kΩ / R33=3.3kΩ.
  • Verified OLED is on 3V3 with I2C_SDA / I2C_SCL, dual XLR connectors are wired in parallel, and the user-input nets remain present for the 11 pots, 5 illuminated pushbuttons, and 4 toggles including LOW_BATT_OVERRIDE.
  • Updated the project notes with the four-block organization and full GPIO/signal assignment table: Carousel Horse LED Controller Design Notes.
Success criteria review
  • ✅ User inputs implemented and documented.
  • ✅ Comms/display updates completed, including MAX485, OLED, DMX XLRs, and monitor inputs.
  • ✅ ALL_CAPS net labels used for the updated/significant nets.
  • ✅ GPIO assignment table added to project notes.
  • ✅ ERC check reports no ERROR or WARNING items.
Next steps
  • The schematic is complete; next I can proceed to PCB layout cleanup/placement for the newly replaced MAX485 and then routing/manufacturing checks.
Organize placement
Run layout DRC
Export revision files
Check BOM availability

Platform & Toolchain
  • MCU: ESP32-DEVKITC-32UE
  • Framework: Arduino on PlatformIO
  • Build command: pio run
  • Flash command: pio run -t upload
  • Monitor command: pio device monitor
Pin Mapping

Table


FunctionGPIO / PinSchematic netNotes
I2C SDAGPIO23I2C_SDAOLED + MCP23017
I2C SCLGPIO25I2C_SCLOLED + MCP23017
DMX RXU1 RX / GPIO3DMX_RXUART receive from SP3485 RO
DMX TXU1 TX / GPIO1DMX_TXUART transmit to SP3485 DI
DMX DE/REGPIO26DMX_DE_REHIGH transmit, LOW receive
LED 1..8GPIO13,14,16,17,18,19,21,22ESP_LED1..8WS2815 data via 74HCT245 + 330R
PotsVP,VN,GPIO34,35,33,4,15,2,12,0,5POT1_ADC..POT11_ADCAnalog controls; review boot-strap use in firmware/prototype
Battery ADCGPIO32BATTERY_ADC100k/22k divider: 15V input ≈ 2.70V ADC
Current sense ADCGPIO33CURRENT_SENSE_ADCLM358 low-side shunt sense output
Buttons/togglesMCP23017 GPA0..4, GPB0..3BTN1..5, TOGGLE_*, LOW_BATT_OVERRIDEI2C expander inputs
platformio.ini

Ini


[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
  adafruit/Adafruit SSD1306@^2.5.10
  adafruit/Adafruit GFX Library@^1.11.9
  adafruit/Adafruit MCP23X17@^2.3.2
Complete Starter Source

Cpp


#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MCP23X17.h>

#define PIN_I2C_SDA 23
#define PIN_I2C_SCL 25
#define PIN_DMX_RX 3
#define PIN_DMX_TX 1
#define PIN_DMX_DE_RE 26

const uint8_t LED_PINS[8] = {13,14,16,17,18,19,21,22};
const uint8_t POT_PINS[11] = {36,39,34,35,33,4,15,2,12,0,5};
#define PIN_BATTERY_ADC 32
#define PIN_CURRENT_ADC 33

Adafruit_SSD1306 display(128, 64, &Wire, -1);
Adafruit_MCP23X17 mcp;
HardwareSerial DMXSerial(2);

void setDmxReceive() { digitalWrite(PIN_DMX_DE_RE, LOW); }
void setDmxTransmit() { digitalWrite(PIN_DMX_DE_RE, HIGH); }

void setupInputs() {
  for (uint8_t i = 0; i < 8; i++) pinMode(LED_PINS[i], OUTPUT);
  pinMode(PIN_DMX_DE_RE, OUTPUT);
  setDmxReceive();
  for (uint8_t pin = 0; pin <= 8; pin++) mcp.pinMode(pin, INPUT);
}

void setup() {
  Serial.begin(115200);
  Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL);
  DMXSerial.begin(250000, SERIAL_8N2, PIN_DMX_RX, PIN_DMX_TX);
  mcp.begin_I2C(0x20, &Wire);
  setupInputs();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("Carousel LED CTRL");
  display.display();
}

void loop() {
  uint16_t pots[11];
  for (uint8_t i = 0; i < 11; i++) pots[i] = analogRead(POT_PINS[i]);
  uint16_t batt = analogRead(PIN_BATTERY_ADC);
  uint16_t current = analogRead(PIN_CURRENT_ADC);
  uint16_t inputs = 0;
  for (uint8_t pin = 0; pin <= 8; pin++) if (mcp.digitalRead(pin)) inputs |= (1 << pin);

  display.clearDisplay();
  display.setCursor(0,0);
  display.printf("BattADC:%u\nCurrADC:%u\nInputs:%03X", batt, current, inputs);
  display.display();

  while (DMXSerial.available()) {
    uint8_t b = DMXSerial.read();
    (void)b;
  }
  delay(50);
}
Bring-up Notes
  • Keep DMX transceiver receive mode by default; only drive transmit if firmware intentionally sends DMX/RDM data.
  • GPIO1/GPIO3 are also USB-serial pins on many ESP32 DevKit boards; avoid logging while receiving/transmitting DMX or move DMX UART if the selected DevKit wiring requires it.
  • Several pot ADC nets use ESP32 strap-sensitive pins; verify boot behavior during prototype bring-up.
  • Calibrate BATTERY_ADC from measured input voltage. With R32=100k and R33=22k, Vin = Vadc * (122.0 / 22.0).
  • Calibrate CURRENT_SENSE_ADC from measured load current. The schematic targets low-side shunt sensing with an LM358 gain stage; final calibration depends on the installed shunt tolerance and gain-resistor tolerances.
  • Platform & Toolchain

  • Pin Mapping

  • `platformio.ini`

  • Complete Starter Source

  • Bring-up Notes