Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MrJefter/sdvx-controller/llms.txt

Use this file to discover all available pages before exploring further.

This page collects the most common problems encountered when building or using the SDVX Controller and explains how to diagnose and fix each one. Issues are grouped by symptom. If your problem is not listed here, cross-reference the GPIO Pinout and HID Report pages for low-level signal details.
The host operating system sees no new HID device after plugging in the controller.Checklist:
  1. Use a data-capable USB-C cable. Charge-only cables omit the D+ / D− data lines. Swap to a cable that is rated for data transfer and try again.
  2. Verify that firmware is actually running. If the BlackPill is showing the factory blink pattern (LED flashing rapidly), the STM32 bootloader is running but no application firmware has been flashed yet. Flash the firmware using DFU or an ST-Link first.
  3. Check Device Manager (Windows) or lsusb (Linux/macOS). Look for an entry with the USB Vendor ID and Product ID assigned to the project. An entry with a yellow warning triangle indicates a driver problem; a missing entry means the MCU is not enumerating at all.
  4. Reseat the BlackPill in its socket. Oxidised pins on a DIP socket can cause intermittent contact.
  5. Try a different USB port. Some front-panel USB ports provide less power or have marginal signal integrity. Use a rear-panel port directly on the motherboard if possible.
One or more buttons show no state change in a HID viewer even when physically pressed.Checklist:
  1. Verify active-low wiring. Each button must connect the GPIO pin to GND when pressed. Connecting to 3.3 V instead will fight the internal PULLUP and the firmware will always read the pin as released.
  2. Do not add an external pull-down. The firmware configures GPIO_PULLUP in software (GPIO_InitStruct.Pull = GPIO_PULLUP). An external pull-down resistor on the same pin will create a voltage divider and prevent the pin from switching cleanly.
  3. Measure with a multimeter. With no button pressed, the pin should read approximately 3.3 V relative to GND. When the button is held down, it should read < 0.1 V. Any other reading indicates a wiring problem.
  4. Check EXTI assignments. Confirm that the GPIO pin matches the IRQ listed in main.h. BT-A (PA5) and FX-R (PA9) share the EXTI9_5_IRQn handler — if both stop working simultaneously, investigate that shared handler.
  5. Debounce lockout. The 3 ms software lockout (DEBOUNCE_LOCKOUT_MS = 3) is designed to reject contact bounce, not normal presses. If a button works intermittently, the lockout is not the cause — look for a mechanical or wiring fault instead.
The VOL-L or VOL-R axis does not move in a HID viewer, moves in the wrong direction, or jumps unpredictably.Checklist:
  1. Verify channel wiring. VOL-L channel A must be on PA6 (TIM3_CH1) and channel B on PA7 (TIM3_CH2). VOL-R channel A must be on PB6 (TIM4_CH1) and channel B on PB7 (TIM4_CH2). Swapping the timer pins between the two encoders will cause one or both to fail completely.
  2. Check encoder power supply. The LPD3806 encoder requires +5 V on its supply line. A missing or under-voltage supply will prevent the encoder from outputting any signal.
  3. Reverse direction by swapping A and B. If the axis moves in the opposite direction from the physical knob rotation, exchange the A and B wires at the connector. There is no software direction inversion in the firmware.
  4. Increase the IC filter for noisy encoders. Both timers are initialised with IC1Filter = 5 and IC2Filter = 5 (in MX_TIM3_Init() / MX_TIM4_Init()). Increasing this value (maximum 15) rejects shorter glitches at the cost of slightly reduced maximum speed.
  5. Reduce the smoothing alpha for less jitter. ENCODER_SMOOTHING_ALPHA = 0.15f in main.c controls how aggressively the EMA filter tracks the raw encoder value. Lowering it (e.g. to 0.05f) produces a slower but smoother axis response.
The X or Y axis value in a HID viewer creeps upward or downward even when the knob is stationary.This is expected behaviour when the encoder is physically still but vibration or electrical noise is producing occasional counts. The firmware does not implement a software deadzone — the EMA accumulates every delta, however small.If the drift is significant (more than a few counts per second), investigate mechanical or electrical noise sources: loose encoder mounting, long unshielded cable runs, or missing decoupling capacitors near the encoder supply. Increasing the IC filter value (see above) will also help.
The LED strip shows no light at all, or only the first few LEDs in the chain illuminate.Checklist:
  1. Verify the data line. The WS2812B data-in pin must be connected to PB0. The data line must also share a GND reference with the BlackPill.
  2. Check LED strip power. WS2812B LEDs require 5 V on the strip’s power rail. The BlackPill’s 3.3 V output is insufficient. Measure the 5 V rail with a multimeter under load.
  3. Verify the LED count. WS2812B_NUMBER_OF_LEDS is set to 12 in ws2812b.h. If you have a different number of LEDs in your strip, the DMA buffer will be the wrong length and some LEDs will display garbage or not light at all.
  4. Check strip orientation. WS2812B strips have a data-flow direction printed on them (arrows or a “DIN → DOUT” label). Connecting the BlackPill to the DOUT end instead of DIN will produce no output.
  5. A damaged LED blocks the rest. WS2812B LEDs are daisy-chained; each LED regenerates the signal before passing it on. If one LED is damaged, every LED downstream will receive no data. Bypass the suspect LED to confirm.
Never power a long WS2812B strip directly from the BlackPill’s 5 V pin. Use a dedicated 5 V power supply capable of providing sufficient current for all 12 LEDs (approximately 720 mA worst case at full white).
Holding the START button for 5 seconds does not trigger a reboot into the USB DFU bootloader.The firmware DFU entry path (GoToBootloader()) drives PA15 HIGH and then calls NVIC_SystemReset(). For this to select DFU mode on reset, BOOT0 must be seen as HIGH by the MCU at the start of the boot sequence. This requires the 150 nF ceramic capacitor modification described in the project README — a capacitor placed so that PA15 driving HIGH charges the BOOT0 pin before the reset pulse ends.Without the capacitor modification, the BOOT0 pin is not driven in time and the MCU simply boots the application firmware again.Alternative — physical BOOT0 button:
  1. Hold the BOOT0 button on the BlackPill board.
  2. While holding BOOT0, press and release the NRST (reset) button.
  3. Release BOOT0. The MCU will enumerate as a DFU device.
You can then flash new firmware using dfu-util (Linux/macOS) or STM32CubeProgrammer (Windows).
The project fails to compile or linker errors appear after importing the source.Checklist:
  1. Import as “Existing Project”, not “New Project”. In STM32CubeIDE go to File → Import → General → Existing Projects into Workspace and browse to the firmware/HID_SDVX_NEW4/ folder. Creating a new project and copying files in will not preserve the correct build configuration.
  2. Do not regenerate CubeMX code. If you open the .ioc file and click “Generate Code”, STM32CubeMX will overwrite the /* USER CODE BEGIN *//* USER CODE END */ sections unless they are strictly within the protected blocks. The custom button, encoder, and LED logic lives in those blocks — regenerating without care may erase it.
  3. Target device must be STM32F401CEx. The linker script, flash size, and peripheral addresses are specific to this part. Selecting a different MCU in the project settings will cause build or runtime failures.

Build docs developers (and LLMs) love