btsimonh / hoverboard-firmware-hack

New Hoverboard Firmware Hack. Now written from scratch and generally much better.
GNU General Public License v3.0
22 stars 4 forks source link

Use Interrupt based UART from sensor communication for serial protocol #3

Closed p-h-a-i-l closed 5 years ago

p-h-a-i-l commented 5 years ago

Separated the UART parts from the Sensor code and reused it to be used as input for the uart protocol instead of only software serial.

This is follow up to: https://github.com/btsimonh/hoverboard-firmware-hack/pull/2

My thoughts went like this: Too bad, that @btsimonh does have no motivation to implement Interrupt based UART for @EmerickH and myself. He should have lots of experience from the Sensor communication... Wait a minute... So I tried to pull out the interrupt based uart part from the code and feed it into the protocol parsing. It is working, but from time to time the board crashes. (as in wheels keep on turning but not even the On/Off buttons leads to a reaction. Stopping only possible by pulling the battery).

Can somebody review the changes I made?

btsimonh commented 5 years ago

:). Will take a look at the weekend.... still up to my eyes in 'real' work, and juggling wifey vs. hobby.... thankyou for the contribution :) not sure I will be able to test with real uart (means a lot of taking apart of the HB to get to the cabling, but you never know; I only have to get to one side.

btsimonh commented 5 years ago

ok, a visual check of the code; it's faultless, nice work. Will now go get my hoverboard and see if it still works for me with valid values for my application in config :). Ref the crash; I get something similar occasionally. I have connected it with excessive movements; maybe a brown-out. The HB then will not respond to anything for a few minutes - at first I was disconnecting the power, then it worked again, but subsequently found that just leaving it a while worked (less dissassembly!). I don't get this during 'normal' use.

btsimonh commented 5 years ago

I've pushed your branch plus some fixes to my repo. It's not perfect; even before merging, when I powered on the HB, the (software) serial was spewing junk; a reboot solved that once, but now it spews junk every restart. However, the hoverboard functionality works, so I recon your interrupt routines are fine. I'll see if I can solve the software serial issue.... no ideas at the moment.

EmerickH commented 5 years ago

Hello, I have also theses issues even with the original Niklas' firmware. I think this is normal because of the high rate of the serial (115200 bauds = 0,01 MB/s!) and all the interferences caused by electronic. I think we should implement a stronger serial protocol with redundancy, delimiter characters... to avoid this. We should also implement a max speed, max acceleration and heartbeat to secure everything. I'll maybe have some time next week to work a little bit on it.

btsimonh commented 5 years ago

ahah!! or should I say HaHa!! ... spent the last 3 hours chasing it spewing junk. Turns out it's responding to my test program which is sending test messages to it!!!!!

btsimonh commented 5 years ago

Merged and pushed :). @p-h-a-i-l : there are a few fixes in there, but nothing I would have considered a show stopper in terms of your application. I'm not sure that my crash and your crash are the same thing; mine only happens when it goes completely wild (e.g. bad pid values -> violent oscillation -> board dead for 5 minutes; suspect a thermal or current based fuse which recovers). I've not tested new 'priority' software serial with wheels running, as per your original report yet. @EmerickH - pls report on use of uart serial for control :). And think about what we want to do in the 'protocol'. At the moment it's really only a skeleton ready to be filled out with functions :). I still think we need to address 'slow' speed - i.e. speeds lower than can be handled with the hall sensor feedback & pid loop. This would basically be being able to power the coils at a specified angle (and constant 'power'), then moving the angle slowly.

btsimonh commented 5 years ago

ref config.h - I've just added a commit which adds a section at the TOP of config.h to select the 'control type'. It builds for all 4 types, but not actually tested the firmware. should be fine. Also made the pidcontrol branch the default branch for this repo.

p-h-a-i-l commented 5 years ago

thanks for taking care of some build warnings! I'm glad my code is useful. However I was hoping for you to find an easy explanation for my freezes :) The bad thing about them is, that the BLDC Interrupts are still functional. Therefore spinning wheels and me hitting stuff.

@EmerickH right now I'm using a galvanic isolation for my UART: https://www.analog.com/en/products/adum3211.htm. I hope that someday I'll be able to control it directly, but for now thats my hotfix to have somehow reliable connections. A bit annoying since I cannot power my ESP32 from the 15V suppy.

btsimonh commented 5 years ago

@p-h-a-i-l - how are you getting on with ESP32? I've put mine aside for a month waiting for esp-idf 3.2 - I find it incredibly unreliable, program size is huge, and memory exhaustion happens at the drop of a hat :(. I am trying to use Bluetooth LE, but I found even MQTT on it's own not fit for purpose. Rpizero with usb serial works a treat though! p.s. for freezes - @EmerickH 's regular handshake idea plus watchdog timer is probably a wise thing to add?

p-h-a-i-l commented 5 years ago

Well you are carrying around a lot of overhead, but since it also has lots of memory and multiple cores, I didn't care too much. I tried BTLE but everything I read was warnings - it's not ready yet. In order to fit both BLE and Wifi on there, I had to change the partition table. For now I'm using ESPnow to remote control my board.

p-h-a-i-l commented 5 years ago

watchdog timer is absolutely necessary 👍 What is meant by handshake?

btsimonh commented 5 years ago

sorry; heartbeat - sending messages regularly, and if one does not arrive, stopping after a timeout. So heartbeat would cover controller/communications failure, and watchdog firmware failure.

p-h-a-i-l commented 5 years ago

What do you think of a timer based interrupt function which decreases the set point (pwm/steer, speed) every time it is called? This way, if no new value arrives via uart, the hoverboard will gently stop. If there is only a hickup, you will not brake too hard.

Will you guys be at 35C3? I'd love to see some other moving objects :)

btsimonh commented 5 years ago

35C3: I wish :). too much to do in my 'real' job. ok, two options; killing pwm leads to no power to the wheels, which is a kind of graceful slowdown. Deliberately requesting a slowed PID controlled speed is probably not what you need in an emergency, since if you hit a wall already, the HB will still be trying (hard) to drive you forwards even though it's demand speed is reducing.... In terms of collision detection, some form of intelligent PID sense is probably needed. e.g. we can't just limit power, because maybe we WANT to go fast or hard. But we could add some expectation of maximum error in certain circumstances, and if that is exceeded, hit the emergency procedure. But the parameters around this will vary considerably according to application (load and desired performance). In my case, load is likely to be minimal, but in the case of a 'bobbycar', it's all about maximum acceleration. One thing which is not catered (i think?) for is 'reverse thrust' - currently when we ask for slower, it just reduces the power. But it may be that as the error increases (imagine going down a hill), that we need to instead reverse the power to deliberately retard motion? - this kind of leads to 'speed' control being 'position control' - if we just fed our desired position in, then the position PID loop would do this (until there is some nasty bug like integer overflow, then it goes wild, crashes, and throws you into the bushes!). Also, where my brain hurts here is - if the position error is getting larger all the time (because we just can't achieve the position we asked for), then when we come to want to stop, it does not stop for a further 15m of gathered error. So it's like 'every 100ms add 15cm to our current position'; i.e. NOT our overall calculated position - but then we lose steering accuracy by implementing 'slip' :(. sorry for random thoughts....

EmerickH commented 5 years ago

What do you think of a timer based interrupt function which decreases the set point (pwm/steer, speed) every time it is called? This way, if no new value arrives via uart, the hoverboard will gently stop. If there is only a hickup, you will not brake too hard.

I think decelerating very fast is not a problem in case of emergency, and it's better if it's going throug a wall

@btsimonh just "killing pwm leads" may be a solution but it can be also dangerous with speed in some applications

For the collision detection, I personnaly use car drive back sensors connected to the Raspberry Pi wich is controlling my board with serial and has control over a power relay to cut everything in case of emergency. For me a "I'm trying to move to position from more than X seconds but I cant = I stop" will be sufficient

But you're right there's a lot of fixes to do on PID control....

Will you guys be at 35C3? I'd love to see some other moving objects :) I'm from South-West France, so it's complicated... But I will try to send you some photos/videos of my robot

btsimonh commented 5 years ago

sorry guys; got another haha!!/LoL/Ahah! moment. Beware: on linux, TTY ports are NOT transparent. stty -F /dev/ttyUSB0 raw -echo solves most of my software serial issues.... (into node-red)

But I do think 'protocol' needs a formal continuity counter..... @p-h-a-i-l - I can't reproduce your reported software serial issues with motors running. just pushed some software serial changes;

p-h-a-i-l commented 5 years ago

the idea behind gradual deceleration vs. hard stop is to prevent unnecessary stops when the connection is only briefly disturbed.

@btsimonh my issues occur when using interrupt based uart and the protocol when driving around.

What kind of power relais are you using? switching 30+ Amps is not trivial for a mechanical switch, I'd probably go with a MOSFET instead of an mechanical switch

btsimonh commented 5 years ago

mine is direct connection to original battery (it is actually still the hoverboard; just with an Rpi, usb hub, stlink, usbserial packed inside :). When in sensor mode; I do get the occasional 'tick', like a missed message or incorrect angle, but not enough to cause any disturbance to the ride. (interrupt driven serial to sensor boards.....)

@both: please read/comment on https://github.com/btsimonh/hoverboard-firmware-hack/wiki/Protocol-Proposal also, I've enabled issues on the repo.... (idea - can't you use the original power switch connection for power control? just watch out, it carries 36v - blew up my first boards because of that!)

p-h-a-i-l commented 5 years ago

The original power switch achieves switch powers off via software - not good for emergencies :)

btsimonh commented 5 years ago

@both - added an issue for comments on the proposed protocol, and updated the proposed protocol page

p-h-a-i-l commented 5 years ago

Spend the last week now with trying to debug why my board would crash. Achievements: I can now debug the board with my stlink and learned a lot about Openocd and gdb.

In the end I stripped down everything and just put a minimal version of the protocol together with interrupt based uart on top of the origin branch: https://github.com/p-h-a-i-l/hoverboard-firmware-hack. No more crashes.. So I'll merge more and more parts back to see where it breaks.

I also added a timer based watchdog. (It was a bit annoying to crash into furniture at full speed all the time).

btsimonh commented 5 years ago

are you on the original STM based board, or the chinese copy cpu board (like me)? I've not used it in 'controlled' form for long periods, but mine never crashed in 'hoverboard' mode (would have more injuries to my daughter!).

p-h-a-i-l commented 5 years ago

I need to check which boards I had for testing. Probably GD board on my bench and ST board for driving around.