-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbalance_board.cpp
162 lines (143 loc) · 3.98 KB
/
balance_board.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <service/balance_board.h>
#include <service/prefs.h>
#include <os_config.h>
#if HAS(BALANCE_BOARD_INTEGRATION)
#include <Wiimote.h>
static char LOG_TAG[] = "BBRD";
EXT_RAM_ATTR Wiimote wiimote;
static balance_board_state_t sts;
static int kilos = 0;
static int offset = 0;
static bool initialized = false;
static FauxSensor *kiloSensor;
static TimerSensor *startledSensor;
static TaskHandle_t hTask;
static uint16_t hRemote = 0;
static TickType_t lastUpdate = 0;
static TickType_t lastBlink = 0;
static bool lastLed = false;
static bool forceLed = false;
static bool button = false;
// Low-pass filter parameters
static const float alpha = 0.1f; // Smoothing factor (0.0 - 1.0)
static int filteredKilos = 0; // Filtered weight value
static int avgKilos = 0;
void balance_board_zero()
{
offset = kilos;
prefs_set_int(PREFS_KEY_BALANCE_BOARD_OFFSET, offset);
}
void wiimote_callback(wiimote_event_type_t event_type, uint16_t handle, uint8_t *data, size_t len)
{
if (event_type == WIIMOTE_EVENT_DATA)
{
if (len > 11 && data[1] == 0x34)
{
TickType_t now = xTaskGetTickCount();
float weight[4];
wiimote.get_balance_weight(data, weight);
float measurement = weight[BALANCE_POSITION_TOP_LEFT] + weight[BALANCE_POSITION_TOP_RIGHT] + weight[BALANCE_POSITION_BOTTOM_LEFT] + weight[BALANCE_POSITION_BOTTOM_RIGHT];
int current = (int)(trunc(measurement * 100.0));
// Apply low-pass filter
filteredKilos = (int)(alpha * current + (1.0f - alpha) * filteredKilos);
avgKilos += filteredKilos;
avgKilos /= 2;
if (now - lastUpdate >= pdMS_TO_TICKS(100))
{
if (abs(avgKilos - kilos) >= 2000)
{
startledSensor->trigger();
}
kilos = avgKilos;
kiloSensor->value = (kilos - offset);
ESP_LOGV(LOG_TAG, "Balance board value: %f kg", kilos);
lastUpdate = now;
}
button = (data[3] & 0x08) != 0;
if (button)
{
startledSensor->trigger();
}
if(!forceLed) {
if(now - lastBlink >= pdMS_TO_TICKS((lastLed ? 125 : 120000))) {
lastLed = !lastLed;
wiimote.set_led(handle, lastLed ? 1 : 0);
lastBlink = now;
}
}
}
}
else if (event_type == WIIMOTE_EVENT_INITIALIZE)
{
ESP_LOGI(LOG_TAG, "WIIMOTE_EVENT_INITIALIZE\n");
if (sts != BB_CONNECTED)
balance_board_scan(true);
}
else if (event_type == WIIMOTE_EVENT_SCAN_START)
{
ESP_LOGI(LOG_TAG, "WIIMOTE_EVENT_SCAN_START");
sts = BB_SCANNING;
}
else if (event_type == WIIMOTE_EVENT_SCAN_STOP)
{
ESP_LOGI(LOG_TAG, "WIIMOTE_EVENT_SCAN_STOP");
if (sts != BB_CONNECTED)
sts = BB_IDLE;
}
else if (event_type == WIIMOTE_EVENT_CONNECT)
{
ESP_LOGI(LOG_TAG, "WIIMOTE_EVENT_CONNECT");
sts = BB_CONNECTED;
hRemote = handle;
}
else if (event_type == WIIMOTE_EVENT_DISCONNECT)
{
ESP_LOGI(LOG_TAG, " event_type=WIIMOTE_EVENT_DISCONNECT\n");
sts = BB_IDLE;
}
}
void bb_task(void *)
{
while (1)
{
wiimote.handle();
vTaskDelay(pdMS_TO_TICKS(10));
}
}
void balance_board_start(SensorPool *sensors)
{
if (initialized)
return;
wiimote.init(wiimote_callback);
sts = BB_IDLE;
offset = prefs_get_int(PREFS_KEY_BALANCE_BOARD_OFFSET);
kiloSensor = new FauxSensor(0);
startledSensor = new TimerSensor(pdMS_TO_TICKS(500));
sensors->add(SENSOR_ID_BALANCE_BOARD_MILLIKILOS, kiloSensor, pdMS_TO_TICKS(250));
sensors->add(SENSOR_ID_BALANCE_BOARD_STARTLED, startledSensor, pdMS_TO_TICKS(250));
if (!xTaskCreate(
bb_task,
LOG_TAG,
8192,
nullptr,
pisosTASK_PRIORITY_BALANCEBOARD,
&hTask))
{
ESP_LOGE(LOG_TAG, "Task creation failed");
}
initialized = true;
}
void balance_board_scan(bool state)
{
wiimote.scan(state);
}
balance_board_state_t balance_board_state()
{
return sts;
}
void balance_board_led(bool ledSts) {
if(sts != BB_CONNECTED) return;
forceLed = ledSts;
wiimote.set_led(hRemote, ledSts ? 1 : 0);
}
#endif