recept icon indicating copy to clipboard operation
recept copied to clipboard

Why not use an exponential moving average to make it even faster?

Open magdev95 opened this issue 5 years ago • 1 comments

First of all, thank you very much for providing this code free of charge!

In order to avoid a lot of overhead with OOP and also to avoid keeping a separate buffer, I suggest to simplify your code to use an exponential moving average, albeit the lower weighting of older samples. It is very easy to implement and runs faster than your current implementation.

Note: ALPHA_2K is the alpha value from Wikipedia chosen as a power of two in order to use bit-shifting instead of costly integer division.

#ifndef ALPHA_2K #define ALPHA_2K 1 #endif

static uint32_t ema_x; static uint32_t ema_y;

void filter(char* buf) {

const uint8_t type = (uint8_t)buf[8];
const uint16_t code = (
	(uint16_t)buf[10]      |
	(uint16_t)buf[11] << 8);
uint32_t value = (
	(uint32_t)buf[12]       |
	(uint32_t)buf[13] << 8  |
	(uint32_t)buf[14] << 16 |
	(uint32_t)buf[15] << 24);

if (type == 1 && ((code == 320 && value == 1) || (code == 321 && value == 1)))
    ema = value; // Reset EMA when pen/eraser is touching

if (type == 3 && code < 2) {
	if (code == 0) {
        ema_x += value;
        value = ema_x >> ALPHA_2K;
        ema_x -= value;
	} else if (code == 1) {
        ema_y += value;
        value = ema_y >> ALPHA_2K;
        ema_y -= value;
	}

	// copy value back to buffer
	buf[12] = (uint8_t)value;
	buf[13] = (uint8_t)(value >> 8);
	buf[14] = (uint8_t)(value >> 16);
	buf[15] = (uint8_t)(value >> 24);
}

}

magdev95 avatar Dec 22 '20 00:12 magdev95

Has anyone tried this in practice? I would be expecting noisier lines, but also much less lag compared to the standard moving average.

croci avatar Feb 05 '21 00:02 croci