Created
January 14, 2020 12:58
-
-
Save BalzGuenat/8efb67c6ea04ecf2b0f5be1860527910 to your computer and use it in GitHub Desktop.
Potentiometer scanning snippet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// #include "analog.h" | |
#include "stdio.h" | |
#include "stdlib.h" | |
#include "stdint.h" | |
#include "stdbool.h" | |
// dz+s | 98*s | s+dz | |
// 100s+2dz = 1024 | |
// dz = 12 | |
// s = 10 | |
// #s = (1024 - 2dz) / s | |
// s = (1024 - 2dz) / #s | |
// dz = (1024-#s*s) / 2 | |
#define POT_STEPS 100 | |
#define DEADZONE 12 | |
#define HYST 1 | |
#define POT_PIN_HIGH 0 | |
#define POT_PIN_READ 1 | |
#define POT_BOTTOM_KEY 0 | |
#define POT_TOP_KEY 1 | |
#define POT_DOWN_KEY 2 | |
#define POT_UP_KEY 3 | |
#define ANALOG_MAX 1023 | |
// MOCKING | |
uint16_t pin_value; | |
void setPinInputHigh(uint16_t pin) {} | |
uint16_t analogReadPin(uint16_t pin) { | |
return pin_value; | |
} | |
void send_key(uint16_t key) { | |
printf("%d", key); | |
} | |
int16_t min(int16_t a, int16_t b) { | |
return a < b ? a : b; | |
} | |
int16_t max(int16_t a, int16_t b) { | |
return a > b ? a : b; | |
} | |
// LOGIC | |
const uint16_t step_size = ((ANALOG_MAX + 1) - 2 * DEADZONE) / POT_STEPS; | |
const uint16_t low_dz = step_size + DEADZONE; | |
const uint16_t high_dz = ANALOG_MAX - (step_size + DEADZONE); | |
uint16_t last = 0; | |
uint16_t into_range(uint16_t val) { | |
// move value into range between deadzones | |
// new val ranges [0, ANALOG_MAX-2*DEADZONE] | |
val = min(val, ANALOG_MAX - DEADZONE); | |
return max(0, val - DEADZONE); | |
} | |
void matrix_init(void) { | |
setPinInputHigh(POT_PIN_HIGH); | |
last = analogReadPin(POT_PIN_READ); | |
printf("step_size=%d\tlow_dz=%d\thigh_dz=%d\n", step_size, low_dz, high_dz); | |
printf("init done, last=%d\n", last); | |
} | |
void scan_pot(void) { | |
uint16_t cur = analogReadPin(POT_PIN_READ); | |
int16_t d = cur - last; | |
printf("cur=%d\tlast=%d\n", cur, last); | |
if (abs(d) <= HYST || (last < low_dz && cur < low_dz) || (last > high_dz && cur > high_dz)) { | |
// change is zero, within hysteresis or within deadzone | |
printf("no change\n"); | |
return; | |
} | |
uint16_t cur1 = into_range(cur); | |
printf("ranged cur = %d\n", into_range(cur)); | |
// calculate step positions | |
uint16_t cur_step = cur1 / step_size; | |
printf("ranged last = %d\n", into_range(last)); | |
uint16_t last_step = into_range(last) / step_size; | |
int16_t ds = cur_step - last_step; | |
printf("cur_step=%d\tlast_step=%d\tds=%d\n", cur_step, last_step, ds); | |
if (ds == 0) { | |
return; | |
} | |
uint16_t steps; | |
bool max; | |
uint16_t step_key; | |
uint16_t max_key; | |
if (ds > 0) { | |
steps = ds; | |
max = cur_step == POT_STEPS - 1; | |
step_key = POT_UP_KEY; | |
max_key = POT_TOP_KEY; | |
} else { | |
steps = -ds; | |
max = cur_step == 0; | |
step_key = POT_DOWN_KEY; | |
max_key = POT_BOTTOM_KEY; | |
} | |
for (int i = 0; i < steps-1; ++i) | |
{ | |
send_key(step_key); | |
} | |
if (max) { | |
send_key(max_key); | |
} else { | |
send_key(step_key); | |
} | |
printf("\n"); | |
last = cur; | |
} | |
int main(void) { | |
printf("gonna do things...\n"); | |
pin_value = 0; | |
matrix_init(); | |
scan_pot(); | |
pin_value = 100; | |
scan_pot(); | |
pin_value = 200; | |
scan_pot(); | |
pin_value = 200; | |
scan_pot(); | |
pin_value = 201; | |
scan_pot(); | |
pin_value = 202; | |
scan_pot(); | |
pin_value = 203; | |
scan_pot(); | |
pin_value = 1023; | |
scan_pot(); | |
pin_value = 0; | |
scan_pot(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment