1
0
mirror of https://github.com/whowechina/iidx_pico.git synced 2025-02-15 10:22:31 +01:00

ADC auto adjust and analog deadzone

This commit is contained in:
whowechina 2023-04-16 22:06:43 +08:00
parent 1452418d40
commit c3796d6e42
5 changed files with 88 additions and 34 deletions

Binary file not shown.

View File

@ -23,8 +23,11 @@ static iidx_cfg_t default_cfg = {
.brightness = 5, .brightness = 5,
.reversed = false, .reversed = false,
}, },
.tt_sensor_analog = false, .tt_sensor = {
.tt_sensor_reversed = false, .analog = false,
.reversed = false,
.analog_deadzone = 0,
},
.effects = { .effects = {
.play_vol = 255, .play_vol = 255,
.filter = 128, .filter = 128,
@ -41,6 +44,10 @@ static void config_loaded()
iidx_cfg->tt_led.num = 24; iidx_cfg->tt_led.num = 24;
config_changed(); config_changed();
} }
if (iidx_cfg->tt_sensor.analog_deadzone > 2) {
iidx_cfg->tt_sensor.analog_deadzone = 0;
config_changed();
}
} }
void config_changed() void config_changed()

View File

@ -26,8 +26,11 @@ typedef struct __attribute ((packed)) {
uint8_t brightness; uint8_t brightness;
bool reversed; bool reversed;
} tt_led; } tt_led;
bool tt_sensor_analog; struct {
bool tt_sensor_reversed; bool analog;
bool reversed;
uint8_t analog_deadzone;
} tt_sensor;
struct { struct {
uint8_t play_vol; uint8_t play_vol;
uint8_t filter; uint8_t filter;

View File

@ -136,8 +136,6 @@ static struct {
bool adjust_led_start; bool adjust_led_start;
int16_t start_angle; int16_t start_angle;
uint8_t counter; uint8_t counter;
bool e4_press_valid;
uint64_t e4_timeout;
} tt_ctx; } tt_ctx;
void mode_tt_enter() void mode_tt_enter()
@ -153,15 +151,19 @@ static void mode_tt_key_change()
} else if (JUST_PRESSED(E_EFFECT)) { } else if (JUST_PRESSED(E_EFFECT)) {
tt_ctx.adjust_led_start = false; tt_ctx.adjust_led_start = false;
tt_ctx.start_angle = input.angle; tt_ctx.start_angle = input.angle;
} else if (JUST_PRESSED(E_4)) { } else if (JUST_PRESSED(E_VEFX)) {
tt_ctx.e4_press_valid = true;
tt_ctx.e4_timeout = setup_tick_ms + 3000;
}
if (JUST_RELEASED(E_VEFX)) {
iidx_cfg->tt_led.reversed = !iidx_cfg->tt_led.reversed; iidx_cfg->tt_led.reversed = !iidx_cfg->tt_led.reversed;
} else if (JUST_RELEASED(E_4) && tt_ctx.e4_press_valid) { } else if (JUST_PRESSED(E_4)) {
iidx_cfg->tt_sensor_reversed = !iidx_cfg->tt_sensor_reversed; if (iidx_cfg->tt_sensor.reversed) {
iidx_cfg->tt_sensor.analog = !iidx_cfg->tt_sensor.analog;
}
iidx_cfg->tt_sensor.reversed = !iidx_cfg->tt_sensor.reversed;
} else if (JUST_PRESSED(KEY_2)) {
iidx_cfg->tt_sensor.analog_deadzone = 0;
} else if (JUST_PRESSED(KEY_4)) {
iidx_cfg->tt_sensor.analog_deadzone = 1;
} else if (JUST_PRESSED(KEY_6)) {
iidx_cfg->tt_sensor.analog_deadzone = 2;
} }
check_exit(); check_exit();
@ -225,16 +227,16 @@ void mode_tt_loop()
uint32_t green = button_rgb32(0, 99, 0, false); uint32_t green = button_rgb32(0, 99, 0, false);
uint32_t cyan = button_rgb32(0, 99, 99, false); uint32_t cyan = button_rgb32(0, 99, 99, false);
uint32_t yellow = button_rgb32(99, 99, 0, false); uint32_t yellow = button_rgb32(99, 99, 0, false);
uint32_t silver = button_rgb32(60, 60, 60, false);
setup_led_button[LED_E_VEFX] = iidx_cfg->tt_led.reversed ? cyan : yellow; setup_led_button[LED_E_VEFX] = iidx_cfg->tt_led.reversed ? cyan : yellow;
setup_led_button[LED_E_4] = iidx_cfg->tt_sensor_analog ? setup_led_button[LED_E_4] = iidx_cfg->tt_sensor.analog ?
(iidx_cfg->tt_sensor_reversed ? red : green) : (iidx_cfg->tt_sensor.reversed ? red : green) :
(iidx_cfg->tt_sensor_reversed ? yellow : cyan); (iidx_cfg->tt_sensor.reversed ? yellow : cyan);
if (PRESSED_ANY(E_4) && tt_ctx.e4_press_valid && (setup_tick_ms > tt_ctx.e4_timeout)) { setup_led_button[LED_KEY_2] = iidx_cfg->tt_sensor.analog_deadzone == 0 ? silver : 0;
iidx_cfg->tt_sensor_analog = !iidx_cfg->tt_sensor_analog; setup_led_button[LED_KEY_4] = iidx_cfg->tt_sensor.analog_deadzone == 1 ? silver : 0;
tt_ctx.e4_press_valid = false; setup_led_button[LED_KEY_6] = iidx_cfg->tt_sensor.analog_deadzone == 2 ? silver : 0;
}
} }
static struct { static struct {
@ -289,10 +291,8 @@ bool setup_run(uint16_t keys, uint16_t angle)
printf("@ %3d %2x\n", input.rotate, input.angle); printf("@ %3d %2x\n", input.rotate, input.angle);
mode_defs[current_mode].rotate(); mode_defs[current_mode].rotate();
} }
if (input.just_pressed) { if (input.just_pressed) {
printf("+ %04x\n", input.just_pressed); printf("+ %04x\n", input.just_pressed);
printf("S:%u L:%u\n", iidx_cfg->tt_led.start, iidx_cfg->tt_led.num);
} }
if (input.just_released) { if (input.just_released) {
printf("- %04x\n", input.just_released); printf("- %04x\n", input.just_released);

View File

@ -42,14 +42,14 @@ static void init_analog()
static void follow_mode_change() static void follow_mode_change()
{ {
if (running_analog != iidx_cfg->tt_sensor_analog) { if (running_analog != iidx_cfg->tt_sensor.analog) {
turntable_init(); turntable_init();
} }
} }
void turntable_init() void turntable_init()
{ {
running_analog = iidx_cfg->tt_sensor_analog; running_analog = iidx_cfg->tt_sensor.analog;
if (running_analog) { if (running_analog) {
init_analog(); init_analog();
} else { } else {
@ -57,12 +57,44 @@ void turntable_init()
} }
} }
uint32_t max_adc = 3650; static uint32_t min_adc = 0; /* idealy [0..3740] */
static uint32_t max_adc = 3740;
static bool min_touched = false;
static bool max_touched = false;
static inline void adjust_max(uint32_t value) static inline void adjust_max(uint32_t value)
{ {
if (value > max_adc) { if (value > max_adc) {
max_adc += (value - max_adc + 1) / 2; max_adc += (value - max_adc + 1) / 2;
printf("Auto adc max: %4lu %4lu\n", min_adc, max_adc);
} }
max_touched = true;
}
static inline void adjust_min(uint32_t value)
{
if (value < min_adc) {
min_adc -= (min_adc - value + 1) / 2;
printf("Auto adc min: %4lu %4lu\n", min_adc, max_adc);
}
min_touched = true;
}
static void auto_adjust_adc()
{
if (!min_touched || !max_touched) {
return;
}
min_touched = false;
max_touched = false;
if (max_adc > 3540) {
max_adc--;
}
if (min_adc < 200) {
min_adc++;
}
printf("Auto adc adj: %4lu %4lu\n", min_adc, max_adc);
} }
static uint16_t read_average(uint16_t size) static uint16_t read_average(uint16_t size)
@ -75,10 +107,10 @@ static uint16_t read_average(uint16_t size)
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
uint32_t sample = adc_read(); uint32_t sample = adc_read();
if (sample > 3500) { if (sample > 3540) {
large_cnt++; large_cnt++;
large += sample; large += sample;
} else if (sample < 500) { } else if (sample < 200) {
small_cnt++; small_cnt++;
small += sample; small += sample;
} else { } else {
@ -86,10 +118,14 @@ static uint16_t read_average(uint16_t size)
} }
} }
if (large_cnt > 100) { if (large_cnt > 50) {
adjust_max(large / large_cnt); adjust_max(large / large_cnt);
} }
if (small_cnt > 50) {
adjust_min(small / small_cnt);
}
uint32_t all = large + small + medium; uint32_t all = large + small + medium;
if (large_cnt && small_cnt) { if (large_cnt && small_cnt) {
@ -101,15 +137,23 @@ static uint16_t read_average(uint16_t size)
static void update_analog() static void update_analog()
{ {
const uint16_t deadzone = 24;
static uint16_t sample = 0; static uint16_t sample = 0;
auto_adjust_adc();
uint16_t deadzone = (iidx_cfg->tt_sensor.analog_deadzone + 1) * 16;
int new_value = read_average(200); int new_value = read_average(200);
int delta = abs(new_value - sample); int delta = abs(new_value - sample);
if ((abs(delta) < deadzone) || (abs(delta) > 4096 - deadzone)) { if ((abs(delta) < deadzone) || (abs(delta) > 4096 - deadzone)) {
return; return;
} }
sample = new_value; sample = new_value;
angle = (sample * 4095) / max_adc; if (sample < min_adc) {
angle = 0;
return;
}
angle = (sample - min_adc) * 4095 / (max_adc - min_adc);
} }
static void update_i2c() static void update_i2c()
@ -136,5 +180,5 @@ void turntable_update()
uint16_t turntable_read() uint16_t turntable_read()
{ {
return iidx_cfg->tt_sensor_reversed ? 4095 - angle : angle; // 12bit return iidx_cfg->tt_sensor.reversed ? 4095 - angle : angle; // 12bit
} }