robomakery / pvc-powerchair

Open-source, low-cost, pediatric powerchair
Other
11 stars 6 forks source link

Software between joystick nano and main arduino #71

Closed badiozam closed 6 years ago

badiozam commented 6 years ago

Develop software for connecting an arduino nano to the joystick and having the nano communicate to an arduino uno for driving the motors.

badiozam commented 6 years ago

Hey guys, so I did some work on this and there are some considerations we have to make.

Consider first that we have our OLED screen currently being driven by the Arduino UNO via I2C. Now we can have the Nano connect to the joystick, translate joystick values into commands and then either:

1) have the UNO poll it on I2C before sending it off to the motor controller.

OR

2) send the commands to the UNO via Serial comms at 115200 bps (i.e. UNO listening).

With method 1 there are fewer cables (GND, Vin, SDA, SCL) but less bandwidth. I2C operates on the Arduino at 100kHz (it can be bumped up to 400kHz with some tweaking but only between like-speed devices which I don't think our OLED can do but I'm not sure). Now given that we transfer 1 bit per clock cycle we end up at 100kbps which is 15% slower than method 2. And we also have to consider that the Nano would have to share the bandwidth with the OLED on the I2C bus. It's certainly doable especially if we're not doing fancy graphics on the OLED and given that commands are typically only a few bytes long, but we should be cognizant of the limitation.

With method 2 there are a couple more cables (GND, Vin, SDA, SCL, RX, TX) but there's more bandwidth, and more importantly, dedicated bandwidth (i.e. no race conditions on the wire). However, we get hit with a double whamy in the maintainability aspect:

a) we'd have to disconnect the Nano from the UNO any time we want to upload sketches to either one since they both need their respective serial ports for upload/download and

b) we couldn't use the serial ports to output debug messages so we're basically blind unless we can use the OLED for debugging.

There is a another option and that is to use a beefier Arduino. I'd recommend the Arduino MEGA2560. AliExpress sells them for $9 if you're willing to wait 60 days or you can buy them on Amazon for $14 in 2 days. The Mega has a larger footprint than the UNO (I'll bring them all tomorrow so we can see), but it has 4 Serial ports and more RAM and way more pins. I think it should be able to handle an OLED, a joystick, a motor controller, and comms to a higher level board (i.e. autonomy) all in one sketch and on one board.

JamesNewton commented 6 years ago

Minor suggestions: If there are spare pins on the UNO, you can "bit bang" either I2C or UART. So you can have a second I2C bus (not shared with the display) or you can have an RX/TX that is seperate from the main one (no interference with bootloading or debug). Look for "Software Serial" or "Software I2C" (I think... Software Serial for sure). Here it is, I looked it up for you: https://www.arduino.cc/en/Reference/SoftwareSerial

The only downside is that they take up a bit more processor time (shouldn't be an issue) and they can't operate as fast. 57600 baud max for serial. But for a mechanical system on human time, like the joystick, 100K or even 57600 is total overkill. That is 5760 updates per second.

Another point: You don't need TX back from the Uno to the Nano. Data is only flowing one way, so the Uno only needs a RX pin. On the Uno, you can't use software serial RX on pin 13, but any other available pin will work.

badiozam commented 6 years ago

All valid points James.

I have used SoftwareSerial before and it sucked up too much of the processor's time for my purposes. Although, as you pointed out we could likely slow down the baud rate even lower than 57.6k max and not suffer any noticeable performance at this stage (in the future we may want to add more functionality to the UNO which might begin to encroach).

Also, a good suggestion on doing away with the TX back from Uno. No need for that wire that I can see.

Also just for a little more background: I think the reason we wanted to add a Nano next to the joystick rather than directly connecting the joystick to the UNO was to avoid having a lot of analog wires going all the way down to the base which may become noisy/lossy. This way, we interpret at the Nano level with short wires and then send commands digitally where we can do CRC checks (which would allow us to drop noisy/lossy packets).

I'm still leaning I2C with Uno or Mega with hardware UART, only because the Mega is cheap and we have the space for its footprint and we can get more bang for the buck for future proofing.

JamesNewton commented 6 years ago

Very (very) wise to get away from long analog runs in this application. Honestly, low speed serial is so reliable that CRC is probably not needed. The better choice is to add a low value resistor in series and a low value cap in parallel to take the edge off the digital transitions, and run a couple of ground wires along side. Ribbon cable (ground on every other pin) or shielded cable is wonderful. Very long runs, digital data with smooth state transitions, no problems for miles. Literally. Higher voltages needed if the wire is thin.

Yeah, even 9600 is 960 updates a second, so at that speed, the impact on the processor is minimal.

Having said all that, totally agree the Mega is cheap and having lots of IO is good. I don't agree that buying knockoffs is ethical, but I'm weird that way. I like seeing Massimo get a penny out of each sale. Just my opinion, no judgement. no, I'm totally judging you. no, just kidding. ,o)

badiozam commented 6 years ago

Just following up on our conference call discussion. Here's the USB host shield for the UNO that we can use for connecting game controllers instead of a custom joystick.

https://store.arduino.cc/usa/arduino-usb-host-shield

badiozam commented 6 years ago

Here's the Amazon link:

https://www.amazon.com/Arduino-org-A000004-Arduino-Host-Shield/dp/B00LUJYN5S/ref=sr_1_fkmr0_1?ie=UTF8&qid=1522299450&sr=8-1-fkmr0&keywords=MAX3421E+uno+shield