Skip to content

Commit 960b42a

Browse files
authored
Fix Analog gauge glitches on FreeRTOS for xdrv_92_vid6608 driver (#24189)
* Fix Analog gauge glitches on FreeRTOS for xdrv_92_vid6608 driver Original version assumed position and command as thread safe, but it is not true. Wrong readings lead to random move back and forth. Patch was made and tested on real device. * Add mutex to protect vid6608 from update/command * Fix verious glitches * xdrv_92_vid6608: do not create mutex, if no drives found
1 parent 5d50622 commit 960b42a

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

tasmota/tasmota_xdrv_driver/xdrv_92_vid6608.ino

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,23 @@ enum GaugeInternalCommand {
108108
bool vid6608Present = false;
109109
float vid6608StepsFloat = VID6608_DEFAULT_MAX_STEPS;
110110
vid6608 *vid6608Drives[VID6608_MAX_DRIVES];
111+
#ifdef VID6608_RTOS
112+
/**
113+
* @brief Mutex for RTOS precision timing
114+
*
115+
* We have to use "real" trheads under FreeRTOS, as precision timing is required
116+
* for stepper motor driving. This mutex protects data access from multiple
117+
* threads simultaniously. Else it will lead to stepper motor glitches and random move.
118+
*
119+
*/
120+
SemaphoreHandle_t vid6608Mutex;
121+
// Macro for mutexs take/give
122+
#define VID6608_MUTEX_TAKE xSemaphoreTake(vid6608Mutex, portMAX_DELAY);
123+
#define VID6608_MUTEX_GIVE xSemaphoreGive(vid6608Mutex);
124+
#else
125+
#define VID6608_MUTEX_TAKE
126+
#define VID6608_MUTEX_GIVE
127+
#endif
111128

112129
/**
113130
* @brief Command Gauge
@@ -148,6 +165,7 @@ void CmndGaugeZero(void) {
148165
* @param payload command argument
149166
*/
150167
void CmndGaugeCommand(int32_t command, uint32_t index, int32_t payload) {
168+
VID6608_MUTEX_TAKE
151169
Response_P(PSTR("{\"" D_PRFX_GAUGE "\":{"));
152170
bool isFirstItem = true;
153171
for (uint8_t x = 0; x < VID6608_MAX_DRIVES; x++) {
@@ -179,6 +197,7 @@ void CmndGaugeCommand(int32_t command, uint32_t index, int32_t payload) {
179197
}
180198
}
181199
ResponseAppend_P(PSTR("}}"));
200+
VID6608_MUTEX_GIVE
182201
}
183202

184203
/**
@@ -188,6 +207,7 @@ void CmndGaugeCommand(int32_t command, uint32_t index, int32_t payload) {
188207
void VID6608StatusJson() {
189208
ResponseAppend_P(PSTR("\"" D_PRFX_GAUGE "\":{"));
190209
bool isFirstItem = true;
210+
VID6608_MUTEX_TAKE
191211
for (uint8_t x = 0; x < VID6608_MAX_DRIVES; x++) {
192212
vid6608 *driver = vid6608Drives[x];
193213
if (driver) {
@@ -198,6 +218,7 @@ void VID6608StatusJson() {
198218
isFirstItem = false;
199219
}
200220
}
221+
VID6608_MUTEX_GIVE
201222
ResponseJsonEnd();
202223
}
203224

@@ -208,12 +229,14 @@ void VID6608StatusJson() {
208229
*/
209230
void VID6608StatusWeb() {
210231
WSContentSend_PD(HTTP_TABLE100);
232+
VID6608_MUTEX_TAKE
211233
for (uint8_t x = 0; x < VID6608_MAX_DRIVES; x++) {
212234
vid6608 *driver = vid6608Drives[x];
213235
if (driver) {
214236
WSContentSend_PD(PSTR("<tr><th>Gauge %d</th><td>%d</td></tr>"), (int32_t)(x+1), (int32_t)driver->getPosition());
215237
}
216238
}
239+
VID6608_MUTEX_GIVE
217240
WSContentSend_PD(PSTR("</table>"));
218241
}
219242
#endif
@@ -227,6 +250,7 @@ void VID6608StatusWeb() {
227250
void VID6608XvTask(void *) {
228251
while(true) {
229252
bool needToMove = false;
253+
VID6608_MUTEX_TAKE
230254
for (uint8_t x = 0; x < VID6608_MAX_DRIVES; x++) {
231255
vid6608 *driver = vid6608Drives[x];
232256
if (driver) {
@@ -236,6 +260,7 @@ void VID6608XvTask(void *) {
236260
}
237261
}
238262
}
263+
VID6608_MUTEX_GIVE
239264
/*
240265
If we dont need to move any -> go sleep.
241266
This will delay next move begin up to 500ms, but freeds up CPU a lot.
@@ -274,6 +299,8 @@ void VID6608Init() {
274299
return;
275300
}
276301
#ifdef VID6608_RTOS
302+
// Create mutex for RTOS thread safety
303+
vid6608Mutex = xSemaphoreCreateMutex();
277304
// Start background RTOS thread -> required for precision timing
278305
xTaskCreate(
279306
VID6608XvTask, /* Function to implement the task */

0 commit comments

Comments
 (0)