pole_mixing_RP2040 — Xiao Rp2040 simulation

An interactive Xiao Rp2040 circuit simulation you can run free in your browser on Velxio, by bwei.

Components

Sketch code

/*               */
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
#define OLED_ADDRESS  0x3C

// Hardware Pin Definitions for RP2040
#define PIN_CUTOFF    26 // ADC0 (Potentiometer 1)
#define PIN_RESONANCE 27 // ADC1 (Potentiometer 2)
#define PIN_ENCODER_A 2  // Quadrature Encoder A
#define PIN_ENCODER_B 3  // Quadrature Encoder B

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Filter Shape Classification
enum FilterShape {
    SHAPE_LOWPASS,
    SHAPE_HIGHPASS,
    SHAPE_BANDPASS,
    SHAPE_NOTCH,
    SHAPE_ALLPASS
};

struct FilterMode {
    const char* name;
    FilterShape shape;
    uint8_t poles; // 1 to 4 poles (determines slope steepness)
};

// Oberheim Matrix-12 / Xpander Inspired Response Types
const FilterMode FILTER_MODES[] = {
    {"1-Pole Lowpass",   SHAPE_LOWPASS,  1},
    {"2-Pole Lowpass",   SHAPE_LOWPASS,  2},
    {"3-Pole Lowpass",   SHAPE_LOWPASS,  3},
    {"4-Pole Lowpass",   SHAPE_LOWPASS,  4},
    {"1-Pole Highpass",  SHAPE_HIGHPASS, 1},
    {"2-Pole Highpass",  SHAPE_HIGHPASS, 2},
    {"3-Pole Highpass",  SHAPE_HIGHPASS, 3},
    {"4-Pole Highpass",  SHAPE_HIGHPASS, 4},
    {"2-Pole Bandpass",  SHAPE_BANDPASS, 2},
    {"4-Pole Bandpass",  SHAPE_BANDPASS, 4},
    {"2-Pole Notch",     SHAPE_NOTCH,    2},
    {"4-Pole Notch",     SHAPE_NOTCH,    4},
    {"3-Pole Phase",     SHAPE_ALLPASS,  3},
    {"4-Pole Allpass",   SHAPE_ALLPASS,  4}
};

const uint8_t TOTAL_MODES = sizeof(FILTER_MODES) / sizeof(FILTER_MODES[0]);
volatile uint8_t currentModeIndex = 0;

// Encoder Interrupt Service Routine
void readEncoder() {
    static uint8_t lastState = 0;
    uint8_t a = digitalRead(PIN_ENCODER_A);
    uint8_t b = digitalRead(PIN_ENCODER_B);
    uint8_t currentState = (a << 1) | b;
    
    if (currentState != lastState && currentState == 0b11) {
        if (lastState == 0b01) {
            currentModeIndex = (currentModeIndex + 1) % TOTAL_MODES;
        } else if (lastState == 0b10) {
            currentModeIndex = (currentModeIndex == 0) ? TOTAL_MODES - 1 : currentModeIndex - 1;
        }
    }
    lastState = currentState;
}

void setup() {
    
    Serial.begin(9600);
    analogReadResolution(12); // RP2040 12-bit ADC (0 - 4095)
    
    pinMode(PIN_ENCODER_A, INPUT_PULLUP);
    pinMode(PIN_ENCODER_B, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(PIN_ENCODER_A), readEncoder, CHANGE);

    Wire.setSDA(6);
    Wire.setSCL(7);
    Wire.begin();

    if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
            Serial.println(F("failed to start SSD1306 OLED"));
    while (1);
    }

    display.clearDisplay();
    display.setTextColor(SSD1306_WHITE);
    display.println("Setup over"); // set text
}

// Geometric approximation renderer for Minifreak-style filter UI
void renderFilterCurve(const FilterMode& mode, uint16_t cutoffAdc, uint16_t resAdc) {
    // Screen L

More projects by bwei