getting cv in to work

This commit is contained in:
Dominic DiTaranto 2026-03-15 19:37:26 -04:00
parent 5e500086f0
commit ce15b6466b
6 changed files with 94 additions and 8 deletions

View file

@ -37,6 +37,7 @@ pico_generate_pio_header(clock ${CMAKE_CURRENT_LIST_DIR}/quadrature_encoder.pio)
# Pull in standard library and hardware abstraction
target_link_libraries(clock
pico_stdlib
hardware_adc
hardware_pwm
hardware_gpio
hardware_pio

View file

@ -21,6 +21,12 @@ static constexpr uint8_t OUT_8_PIN = 14;
static constexpr uint8_t IN_CLK_PIN = 16;
static constexpr uint8_t IN_RUN_PIN = 17;
static constexpr uint8_t IN_CV_1_ADC_PIN = 0;
static constexpr uint8_t IN_CV_2_ADC_PIN = 1;
extern volatile float cv_values[2];
extern const float conversion_factor;
static constexpr uint8_t SCREEN_SCL_PIN = 18;
static constexpr uint8_t SCREEN_SDA_PIN = 19;

View file

@ -134,12 +134,12 @@ void DisplayHandler::handleCursorOnOutputScreen(bool dir) {
}
}
if (matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx > 7) {
if (matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx > 9) {
matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx = 0;
}
if (matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx < 0) {
matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx = 7;
matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx = 9;
}
} else if (currentScreen == 10) { // CV1 DEST
@ -490,8 +490,13 @@ void DisplayHandler::renderOutPage() {
matrix.slots[outputs[currentOut]->slotIdx1].active ? "ON" : "OFF";
} else if (currentScreen == 9) { // CV1 Source Chan Screen
param_string = std::to_string(
matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx + 1);
uint8_t sourceIdx = matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx + 1;
if (sourceIdx <= 7) {
param_string = std::to_string(sourceIdx);
} else {
param_string = "Ext" + std::to_string(sourceIdx - 7);
}
} else if (currentScreen == 10) { // CV1 DEST Screen
param_string = modDestToString(
@ -512,8 +517,13 @@ void DisplayHandler::renderOutPage() {
matrix.slots[outputs[currentOut]->slotIdx2].active ? "ON" : "OFF";
} else if (currentScreen == 14) { // CV2 Source Chan Screen
param_string = std::to_string(
matrix.slots[outputs[currentOut]->slotIdx2].sourceIdx + 1);
uint8_t sourceIdx = matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx + 1;
if (sourceIdx <= 7) {
param_string = std::to_string(sourceIdx);
} else {
param_string = "Ext" + std::to_string(sourceIdx - 7);
}
} else if (currentScreen == 15) { // CV2 DEST Screen
param_string = modDestToString(

View file

@ -381,7 +381,8 @@ void Gate::update() {
if (finalLevel > 1.0f) finalLevel = 1.0f;
if (finalLevel < 0.0f) finalLevel = 0.0f;
writeAnalog((uint16_t)(outVal * 1023.0f * finalLevel));}
writeAnalog((uint16_t)(outVal * 1023.0f * finalLevel));
}
void Gate::writeAnalog(uint16_t val) { pwm_set_gpio_level(pin, val); }

View file

@ -23,7 +23,15 @@ void ModMatrix::process(Gate **gates, uint8_t gateCount) {
if (slots[i].active == 0)
continue;
float srcVal = gates[slots[i].sourceIdx]->lastOutVal;
float srcVal = 0.0f;
if (slots[i].sourceIdx < 8) {
srcVal = gates[slots[i].sourceIdx]->lastOutVal;
} else if (slots[i].sourceIdx == 8) {
srcVal = cv_values[0];
} else if (slots[i].sourceIdx == 9) {
srcVal = cv_values[1];
}
float amt = (float)slots[i].amount;
float normalizedAmt = amt / 100.0f;

View file

@ -10,6 +10,7 @@
#include <math.h>
#include <pico/types.h>
#include <stdio.h>
#include <string>
#include "DisplayHandler.h"
#include "EncoderHandler.h"
@ -17,6 +18,7 @@
#include "Mod.h"
#include "Settings.h"
#include "globals.h"
#include "hardware/adc.h"
#include "hardware/pwm.h"
// Time based operations
@ -47,6 +49,9 @@ Gate out8(OUT_8_PIN, 7, 14, 15);
static Gate *outputs[] = {&out1, &out2, &out3, &out4,
&out5, &out6, &out7, &out8};
volatile float cv_values[2] = {0.0f, 0.0f};
const float conversion_factor = 1.0f / (1 << 12);
// Initialize Handlers
static DisplayHandler display_handler(outputs);
static EncoderHandler encoder_handler(&display_handler);
@ -208,6 +213,60 @@ void setup_ins() {
gpio_set_irq_enabled(IN_CLK_PIN, GPIO_IRQ_EDGE_RISE, true);
// SETUP CV INS
adc_init();
adc_gpio_init(26);
adc_gpio_init(27);
}
// Helper to scale your current range to 0.0 - 1.0
float fmap(float x, float in_min, float in_max) {
float result = (x - in_min) / (in_max - in_min);
// Constraints to keep it between 0.0 and 1.0
if (result < 0.0f)
return 0.0f;
if (result > 1.0f)
return 1.0f;
return result;
}
void update_cv() {
static uint64_t last_adc_read = 0;
uint64_t now = to_us_since_boot(get_absolute_time());
if (now - last_adc_read < 2000)
return; // 2ms is plenty fast
last_adc_read = now;
// Calibration (Adjust these based on your earlier -0.19 to 0.15 range)
const float raw_min = -0.19f;
const float raw_max = 0.15f;
const float offset_zero = 0.404f; // Your calibrated offset
for (int i = 0; i < 2; i++) {
adc_select_input(i);
// CROSSTALK FIX: Dummy read to clear the ADC capacitor
adc_read();
busy_wait_us(10); // Tiny pause to settle
// Actual read
float raw_val = (float)adc_read() * (1.0f / 4095.0f);
float centered = offset_zero - raw_val;
// SCALING & FLIPPING:
// By using (max - centered), we flip the inversion.
float scaled = (centered - raw_min) / (raw_max - raw_min);
// Optional: If it's STILL upside down, use this instead:
// float scaled = 1.0f - ((centered - raw_min) / (raw_max - raw_min));
// Constrain 0.0 to 1.0
if (scaled < 0.01f)
scaled = 0.0f;
if (scaled > 1.0f)
scaled = 1.0f;
cv_values[i] = scaled;
}
}
int main() {
@ -251,6 +310,7 @@ int main() {
}
while (true) {
update_cv();
encoder_handler.update();
if (PLAY) {