RoboDurden / Hoverboard-Firmware-Hack-Gen2.x

with different defines_2-x.h for different board layouts :-) Compiles with Keil version 6
GNU General Public License v3.0
73 stars 24 forks source link

ESP32 UARTBUS receive can stuck #48

Closed JochenKr closed 6 months ago

JochenKr commented 6 months ago

UARTBUS receiving got stuck after a couple of seconds. It seems that if the receive Frame is broken something happens with the RX Buffer and bReceived keeps false.

adding some dummy reading before leaving the Receive function in hoverserial.h helps for me. https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/blob/dc33f4a9f4aa4dc72c37ff651b76a660d4e681c8/Arduino%20Examples/TestSpeed/hoverserial.h#L261C4-L261C4

while(oSerial.available() > 0) { char t = oSerial.read(); }

looks now like below, before the change, it would have stop reading in the example below at 23:36:29.148: 23:36:28.962 -> millis: 161 iSlave: 2 iOdom: 1 iSpeed: 0.00 iAmp: 0.40 iVolt: 26.81 23:36:29.148 -> CD AB :-) 23:36:29.148 -> millis: 161 iSlave: 1 iOdom: 2 iSpeed: 0.00 iAmp: 0.20 iVolt: 26.68 23:36:29.319 -> CD AB14 != 65D9 :-( 23:36:29.475 -> 02 00 00 00 97 38 CD AB :-) 23:36:29.475 -> millis: 321 iSlave: 2 iOdom: 1 iSpeed: 0.00 iAmp: 0.40 iVolt: 26.81 23:36:29.645 -> CD AB :-)

RoboDurden commented 6 months ago

Emptying the buffer to me looks like a workaround and not the the proper solution to a possible bug. Maybe my receive function skips a byte and therefore only succeeds every second incoming message. The skipped byte might slowly fill the buffer until no more messages can be received..

As i still live outdoors, it would be nice if you could investigate further.

You could add a global counter variable to RemoteUartBus.c and increment it on every Answer call. There overwrite the iOdom value with the count++ And look at the Arduino log if every count gets received or if only every second message gets received.

You could also log a serial.available() to see if the buffer ever increases..

Roland and :-)

RoboDurden commented 6 months ago

to be more prescise in remoteUartBus.c:


uint32_t iAnswerMaster = 0;

void AnswerMaster(void)
{

    // Ask for steer input
    SerialHover2Server oData;
    oData.cStart = START_FRAME;
    oData.iSlave = SLAVE_ID;
    oData.iVolt = (uint16_t)    (batteryVoltage * 100);
    oData.iAmp = (int16_t)  (currentDC * 100);
    oData.iSpeed = (int16_t) (realSpeed * 100);
    oData.iOdom = (int32_t) iOdom;
    oData.iOdom = iAnswerMaster++;
JochenKr commented 6 months ago

I added the iAnswerMaster++; debug only to my Slave 1. This is the log. Most of the time it is counting up by one. But sometimes, in the moment when the freeze would happen, it is counting up more. 6 in the log below. But I also see like 11 or 15.

12:31:06.030 -> millis: 161 iSlave: 1 iOdom: 70 iSpeed: 0.00 iAmp: 0.00 iVolt: 24.48 12:31:06.154 -> CD AB :-) 12:31:06.154 -> millis: 161 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.40 iVolt: 24.58 12:31:06.341 -> CD AB :-) 12:31:06.341 -> millis: 161 iSlave: 1 iOdom: 71 iSpeed: 0.00 iAmp: 0.00 iVolt: 24.48 12:31:06.483 -> CD AB0 != 73E7 :-( 12:31:06.654 -> 4C 00 00 00 6A E3 CD AB :-) 12:31:06.654 -> millis: 321 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.20 iVolt: 24.60 12:31:06.824 -> CD AB :-) 12:31:06.824 -> millis: 161 iSlave: 1 iOdom: 77 iSpeed: 0.00 iAmp: 0.20 iVolt: 24.50 12:31:06.996 -> CD AB :-) 12:31:06.996 -> millis: 161 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.20 iVolt: 24.60 12:31:07.135 -> CD AB :-) 12:31:07.135 -> millis: 161 iSlave: 1 iOdom: 78 iSpeed: 0.00 iAmp: 0.00 iVolt: 24.50

RoboDurden commented 6 months ago

Does this only happen with 2 boards ? Then maybe the two Answers still happen to overlap. When they mix then of course the CRC will fail .

Maybe I have some time on New Year's to look deeper into my code.

But I fear I need more debugging Infos..

JochenKr commented 6 months ago

I quickly checked with disconnected Slave 2. I kept the arduino program constant, which means that it is still trying to talk to both Slaves.

Now the issue disappeared and iAnswerMaster++ is counting up nicely.

RoboDurden commented 6 months ago

So the CRC failure is caused by an overlap. Yet the SerialHover2Server message is only 12 byte long = 120 / 19200 = 0,00625 = 6.25 milliseconds. You initiate an Answer every 100 ms ? Then I still have to figure out why the buffer is not emptied while searching for the next non mixed answer.

Do you use software serial ?

JochenKr commented 6 months ago

I'm basicly running the Testspeed example on a ESP32. From my understanding it is using HW Serial, doesn't it?

I already played around with the timings. originally I used 10ms delay between the two HoverSend requests and then 150ms delay until the loop starts again. On the scope I saw that this causes that Slave 1 is responding while the Master is sending data to Slave 2. PXL_20231230_103622074

So I increased the 10ms to 20ms and 100ms, but this didn't make a change. Maybe it is hard to trigger, but I tried to do some single shots with the scope to see if there is Frame which looks strange (maybe showing answer of both at the same moment), but I wasn't able to catch this.

RoboDurden commented 6 months ago

?? and then 150ms delay until the loop starts again.

The loop should not contain a delay(150) but the Receive () function should be called as often as possible. Only send to hover should happen every 100 ms. Every 10 ms should better be done with 115200 baud .

I keep 19200 baud as default because software serial in Arduino nano can only handle 19200 baud.

JochenKr commented 6 months ago

That makes sense. Let me check what I've mixed up here. Due to whatever reason I have added a delay(150) to the end of the loop. Just recognized that this is not in your example. The funny thing is, if I remove that line again, I do not get any output to my Serial Monitor. Let me tidy up and resynchronize to your example first.

RoboDurden commented 6 months ago

I have optimized the TestSpeed.ino a bit: https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/blob/b0c85653ac8b966cc9573198da1a0e1c14df65da/Arduino%20Examples/TestSpeed/TestSpeed.ino#L73

JochenKr commented 6 months ago

Tested and working perfectly! thx.

11:51:57.543 -> millis: 51 iSpeed: -66 iSlave: 1 iOdom: 2335 iSpeed: 0.00 iAmp: 1.00 iVolt: 29.23 11:51:57.574 -> millis: 51 iSpeed: -57 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.40 iVolt: 29.45 11:51:57.651 -> millis: 51 iSpeed: -48 iSlave: 1 iOdom: 2336 iSpeed: 0.00 iAmp: 0.00 iVolt: 29.23 11:51:57.698 -> millis: 51 iSpeed: -42 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.40 iVolt: 29.45 11:51:57.744 -> millis: 51 iSpeed: -33 iSlave: 1 iOdom: 2337 iSpeed: 0.00 iAmp: 0.20 iVolt: 29.23 11:51:57.789 -> millis: 51 iSpeed: -27 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.40 iVolt: 29.45 11:51:57.835 -> millis: 51 iSpeed: -18 iSlave: 1 iOdom: 2338 iSpeed: 0.00 iAmp: 0.00 iVolt: 29.23 11:51:57.867 -> millis: 51 iSpeed: -12 iSlave: 2 iOdom: 2 iSpeed: 0.00 iAmp: 0.40 iVolt: 29.45