I would like some input please from experienced makers as I try and decide a good structure for code separation and command and control structures between a Raspberry Pi3B+ with sense hat and Arduino Mega.
The story so far. I have constructed a little house ‘robot’ using Arduino. It has many sensors attached including, Ultrasonic ranging module, servo motor to rotate the ultrasonics, IR control, L298N Motor controller, ESP8266 WiFi, MAG3110 compass, and a few more odds and sods.
Deep down this started as an ‘obstacle avoidance’ toy and it still has that functionality and I think therein lies the root of the issue. Last year, in a fit of ‘mid-life flashback’, I souped up the wheels and gearboxes so it now moves at a decent speed. Alas, far faster than its little brain can keep up with, so now it runs into walls before it ‘sees them’. Well I could go back to the old wheels OR I could get a bigger brain, no better still an additional brain!
So how to decide which functions to allocate to the ‘higher’ brain and which to the ‘lizard’ brain. The first choice is to drop the WiFi and Compass from the Arduino and replace with Sense Hat equivalents which seem to be more stable. The Wifi is an easy choice as it is used for command and control and I think that function should go to the ‘higher’ brain.
The compass on the other hand is used for turning eg ‘turn left 30 degrees’. So two choices: leave the command at ‘turn left 30 degrees’ in the lizard brain where it would presumably, somehow, report success or failure to achieve the command. OR make the command ‘Turn left’ and have the higher brain interpret the heading and when achieved issue another command ‘Stop wheels’.
I would like at least some primitive / self-preservation functions left lower down. Like if there is an obstacle (wall or boot) directly in front then stop – without asking permission – but report it (maybe use a real IO interrupt back to the RPi).
As for ‘How’ to achieve a command interface. From some time playing with this stuff I have an opinion that this time around I should build it from the ground up to be as asynchronous as possible (delay() and sleep() are the enemy). This is my first venture into Python and I see one is blessed with MANY choices along this front. I don’t think the use case matches the model needed for multiprocessing and so my first experiments are using threading and that seems OK. Eg it seems the gyro needs lots of calls to keep it accurate so its now in its own thread sampling 50 times/sec. But now I see asyncio may be an easier alternative.
There are several articles that suggest using the serial ports for communication between the halves. Again opting for asynchronous processing I am thinking of a queue on the Pi end to send commands and the same on the Arduino end to catch them and return the results. Do the serial ports work bi-directionally like this ?
Sorry for such a long story. Thoughts, suggestions, and ‘watch-out-for’ welcomed.