4 ms·
Embedded developer here, using 8-bit microcontrollers, so all our calculations are done in fixed-point/integers. Here's a chunk of real code that converts resu
by photojosh 9y ago
Embedded developer here, using 8-bit microcontrollers, so all our calculations are done in fixed-point/integers.
Here's a chunk of real code that converts results from the analog-digital converter to appropriate units. A lot of precalculated constants and things like using shifts instead of division as much as possible.
// - motor current from ACS723 (2.5V is 0A, +/- 400mV/A)
ADC_SET_MUX(motor_current_in_adc);
ADC_START();
while (ADC_RUNNING()) {}
uint8_t result_current = ADCH;
// result(val) * 5V/256(val) * 1000mA/0.4V => result*48.828 = current in ma
// e.g. 5A -> 4.5V out = 230, less 2.5V (128) = 102
// 102 * 48.828125 = 4980 mA
// for max precision, max multiplier = 32678/128 = 255,
// use (value * (48.828 << 2)) >> 2. -> 195
// value_ma = (result_adc * 195) >> 2
current_ma = (((int16_t)(result_current) -127) * 195) >> 2;
// - motor output speed feedback signal (filtered PWM, 16% (1/6.1) of actual value, so 5V in == 30.5V)
ADC_SET_MUX(motor_speed_fb_adc);
ADC_START();
while (ADC_RUNNING()) {}
uint8_t result_speed = ADCH;
// result(val) * 6.1 = actual speed setting
// result / 256 * 6100 = actual in mV
int16_t speed_mv = (uint16_t) result_speed * 119;
#if DEBUG
// calculate target speed mv
uint16_t output_speed_mv = ((uint16_t) motor_current_speed * 195) >> 2;
#endif
- makmanalp 9y agoThis is exactly what I was imagining! x>>2 rather than x/2. Brilliant, thanks.
- esmi 9y agoI've definitely read a ton of code like this. I often do it in simulation as well to help speed up calculations. Basically one is still doing floating point, but manually. i.e. You changed the unit (a.k.a. exponent a.k.a. window) such that the desired value can be accurately quantized by an unsigned int (a.k.a. mantissa a.k.a offset). The big caveat being one needs to be sure the calculation doesn't over/under flow the window, of course.