improved UX with the control buttons, added README.md

master
Ondřej Hruška 8 years ago
parent fd7a1ccc9b
commit de584277fe
  1. 39
      README.md
  2. 29
      User/user_main.c

@ -0,0 +1,39 @@
# STM32F107 Audio Visualiser
Simple audio visualiser with a dot matrix LED display.
## Functions
- Using the central joystick button, select render mode.
- Arrows left, right adjust brightness.
- Arrows up, down adjust sensitivity.
Modes include:
- waveform display with simple triggering
- FFT display
- Spindle FFT display (mirror effect)
## Target hardware
Developed for the "STEVAL-PCC012V1" evaluation board with STM32F107, paired with a "TS4657 Audio card" daughter board.
The skeleton of the project is generated using *STM32CubeMX*, with some minor modifications. The majority of the visualiser code is localed in `User\user_main.c`. The other files in `User/` are helper functions and modules. It's a CLion project, using CMake.
The project uses USART1 for debug messages (`PB6` - Tx, `PB7` - Rx). The display is controlled by multiple daisy-chained MAX2719 drivers (available on ebay as modules). The first driver is interfaced over SPI1 (`PA5` - SCK, `PA7` - MOSI, `PE6` - CS)
There is a 5-direction joystick connected to `PE10`, `PE11`, `PE12`, `PE13`, `PE14`.
The Audio daughter board carries a ST472IQT microphone pre-amt with an electret microphone.
For details, see documents *UM0896* and *UM0722*.
## Porting
The project will work without bigger changes on any STM32Fx, you just have to adjust the pin mapping and update the linker script and defines. That can be done with some attention using *STM32CubeMX*.
Note that some settings that can't be adjusted in CubeMX directly are changed in this project. Use git diff to see what changed after you re-generate the initialization files, and revert those changes. They are marked by comments.
## TODO
- Save preferences to Flash

@ -40,7 +40,8 @@ uint32_t audio_samples[SAMPLE_COUNT * 2]; // 2x size needed for complex FFT
float *audio_samples_f = (float *) audio_samples; float *audio_samples_f = (float *) audio_samples;
// counter for auto repeat // counter for auto repeat
ms_time_t btn_press_cnt = 0; ms_time_t updn_press_timer = 0;
ms_time_t ltrt_press_timer = 0;
/** Dot matrix display instance */ /** Dot matrix display instance */
DotMatrix_Cfg *disp; DotMatrix_Cfg *disp;
@ -49,8 +50,8 @@ DotMatrix_Cfg *disp;
volatile bool capture_pending = false; volatile bool capture_pending = false;
/** scale & brightness config fields. Initial values. */ /** scale & brightness config fields. Initial values. */
float y_scale = 3; float y_scale = 5;
uint8_t brightness = 4; uint8_t brightness = 3;
/** active rendering mode (visualisation preset) */ /** active rendering mode (visualisation preset) */
enum { enum {
@ -137,7 +138,7 @@ void spread_samples_for_fft()
{ {
for (int i = SAMPLE_COUNT - 1; i >= 0; i--) { for (int i = SAMPLE_COUNT - 1; i >= 0; i--) {
audio_samples_f[i * 2 + 1] = 0; // imaginary audio_samples_f[i * 2 + 1] = 0; // imaginary
audio_samples_f[i * 2] = audio_samples_f[i] * win_hamming_512[i]; // real audio_samples_f[i * 2] = audio_samples_f[i]; // * win_hamming_512[i]; // real
} }
} }
@ -247,7 +248,7 @@ static void gamepad_button_cb(uint32_t btn, bool press)
case BTN_UP: case BTN_UP:
up_pressed = press; up_pressed = press;
if (press) { if (press) {
btn_press_cnt = 0; updn_press_timer = 0;
y_scale += 0.5f; y_scale += 0.5f;
} }
break; break;
@ -255,7 +256,7 @@ static void gamepad_button_cb(uint32_t btn, bool press)
case BTN_DOWN: case BTN_DOWN:
down_pressed = press; down_pressed = press;
if (press) { if (press) {
btn_press_cnt = 0; updn_press_timer = 0;
if (y_scale > 0.55) y_scale -= 0.5f; if (y_scale > 0.55) y_scale -= 0.5f;
} }
break; break;
@ -263,7 +264,7 @@ static void gamepad_button_cb(uint32_t btn, bool press)
case BTN_LEFT: case BTN_LEFT:
left_pressed = press; left_pressed = press;
if (press) { if (press) {
btn_press_cnt = 0; ltrt_press_timer = 0;
if (brightness > 0) brightness--; if (brightness > 0) brightness--;
} }
break; break;
@ -271,7 +272,7 @@ static void gamepad_button_cb(uint32_t btn, bool press)
case BTN_RIGHT: case BTN_RIGHT:
right_pressed = press; right_pressed = press;
if (press) { if (press) {
btn_press_cnt = 0; ltrt_press_timer = 0;
if (brightness < 15) brightness++; if (brightness < 15) brightness++;
} }
break; break;
@ -372,7 +373,7 @@ void user_main()
// hold-to-repeat // hold-to-repeat
// This is not the correct way to do it, but good enough // This is not the correct way to do it, but good enough
if (ms_loop_elapsed(&btn_press_cnt, 100)) { if (ms_loop_elapsed(&updn_press_timer, 100)) {
if (up_pressed) { if (up_pressed) {
y_scale += 0.5; y_scale += 0.5;
} }
@ -383,6 +384,12 @@ void user_main()
} }
} }
if (up_pressed || down_pressed) {
dbg("scale = %.1f", y_scale);
}
}
if (ms_loop_elapsed(&ltrt_press_timer, 250)) {
if (left_pressed) { if (left_pressed) {
if (brightness > 0) { if (brightness > 0) {
brightness--; brightness--;
@ -395,10 +402,6 @@ void user_main()
} }
} }
if (up_pressed || down_pressed) {
dbg("scale = %.1f", y_scale);
}
if (left_pressed || right_pressed) { if (left_pressed || right_pressed) {
dmtx_intensity(disp, brightness); dmtx_intensity(disp, brightness);
} }

Loading…
Cancel
Save