5

I'm looking to use a raspberry pi to speak to multiple "arduino" ATMEGA328p ICs (through a logic-level converter). I figure I can do this reasonably well over the GPIO RX/TX and use qualifiers to let each chip know if the Pi is talking to it or not. However, there may be instances in which all the chips want to be chatty at the same time, and the intended implementation is somewhat time-critical (there is a PID involved). I can't have one chip set a pin high or low unless another pin on another chip has been set to it's appropriate state in the sequence.

As far as planning goes, should I be looking at using the other GPIO pins to communicate to each 328p? Is there an approach to doing this outside "bit-banging" on the other GPIO pins? As far as coding goes, I assume I could have a 328p serial.print something that indicates the change was indeed made, and have that transmission read by the pi to issue the next Rx in the sequence, but I also don't want to be caught with the Pi waiting on a relevant Tx from a chip. Could adding a RTC and having pin state changes tied into that somehow help me out (assuming the pi is running a python script)?

3
  • Hi. Did you manage to answer your question? Please mark an answer or kindly write your answer to provide more help to other users. Thanks - Hope to see you soon! :)
    – Piotr Kula
    Commented Dec 7, 2016 at 8:09
  • @ppumpkin, yes -- please read below. I did not mark any of the answers, as I went with serial from the Pi to an a 328p. I downvoted modbus, but don't have the rep to have that shown. Pi sends and receives data on serial, arduino talks to other arduinos via I2C
    – Mark Brown
    Commented Dec 11, 2016 at 7:00
  • Thanks for commenting. You can write that as your answer and accept it too. It may help others decide ahead of time. Thanks
    – Piotr Kula
    Commented Dec 11, 2016 at 9:28

3 Answers 3

4

Single master (Pi) multiple slaves (Arduinos) communication can easily be done with RS485 and MODBUS. There are many open source MODBUS protocol implementations for both Pi and Arduino. With 115200 bps and 2 slaves for example, you can exchange up to few hundred short messages per second.

1

Please allow me to suggest you use I2C for this. Use the Wire.h library on the Arduino and A4 for SDA and A5 for SCL. Plus GND. When you invoke the Wire.begin(x); command be sure to give your Arduino a unique address, x, such as 0x20.

Raspi-config can enable I2C on the Pi, and you can use GPIO pins 3 and 5 for SDA and SCL.

Here is a basic tutorial: https://learn.sparkfun.com/tutorials/raspberry-pi-spi-and-i2c-tutorial

Once you apt-get install i2c-tools you can use i2cdetect -y 1 to see the Arduino's address when it is ready.

Another major advantage to using I2C is that it is easy to add a real-time clock (DS3231) or other I2C-enabled devices including more Arduinos..

More to the point of your question, here is more info on the Pi's pins if you want to connect to them directly: https://pinout.xyz/pinout/i2c

Cheers.


UPDATED: Removed my first comment regarding TX/RX and USB, based on the comments. I learned something through this experience, which is what I have wanted by participating in this Q&A. Thanks for your time to give thoughtful comments, @goldilocks.

9
  • I ended up wiring the Pi's serial lines to an arduino acting as master on an i2c bus. When the pi requests something, the master knows which slave to talk to.
    – Mark Brown
    Commented Oct 28, 2016 at 5:37
  • "On the Arduino the TX/RX pins are also connected to the USB connector. If you try to use them you will have trouble uploading programs from your PC." -> Really it's a hard problem to create, since you have to have the Arduino busy sending contingent upon nothing -- in which case (or if what it is contingent upon is too much to bother with removing) you should be able to do it with the reset button held down; you may also have to plug and unplug it while doing so. I use the UART pins for communication all the time and it's never been a serious issue.
    – goldilocks
    Commented Oct 28, 2016 at 6:21
  • I understand your point, @goldilocks. But my Arduinos are asynchronous, which is why I use I2C. There is no way to predict whether they might be trying to transmit. And I do very frequent software development, and the uploads are the only times I reset, so need to make sure USB is available at all times. Trying to use TX/RX would introduce unnecessary complications. UART pins are not available on the screw terminals in the socket, so I avoid that as if it doesn't exist. My way of upgrading software on the production system is to simply pull the old Nano and plug in the new one. No wires
    – SDsolar
    Commented Oct 31, 2016 at 4:44
  • @Mark_Brown, the new pgpio library finally (as of today, thanks to @joan) allows the Pi to work as a slave, so it is possible to send to it at a time of the Arduino's choosing. That way none of the Arduino's timing can be thrown off by a randomly-timed request from the Pi. I want my Arduinos left alone. They will decide when to send information. It is hard enough to program them to work properly without needing to worry about interrupts. Interrupting LCD writes make for weird displays. Interruptions when it is moving a solar panel can result in misalignment. Etc., etc.
    – SDsolar
    Commented Oct 31, 2016 at 4:48
  • 1
    O_O? You might want to check what the A in UART is for, lol. Handling arbitrary transmissions is par for the course in most forms of communication and largely about how your receiver is designed; UART is certainly much closer to normal socket based networking than I2C; in fact other than there usually being only one connection, it is identical. I wasn't referring to uploading via the pins, BTW, I always use the USB to flash and a have a little stack of nanos.
    – goldilocks
    Commented Oct 31, 2016 at 12:26
0

I ended up using the raspberry pi to speak to one "arduino" ATMEGA328p IC that acted as master on an I2C bus. The Pi sent commands to the 'arduino' which listened for and parsed incoming serial strings. Depending on the content of the strings, the arduino would either address another arduino on the I2C bus and give it instructions, or relay information back to the pi.

I used the standard Wire.h library for arduino, and the Pi4j java package in a netbeans project to get the pi talking to the "master" arduino.

3
  • Why didn't you use the Pi to do this directly? The Raspberry Pi also has an I2C peripheral with a lot of code behind it.
    – NomadMaker
    Commented Jul 14, 2018 at 21:02
  • The length of the run between the pi and all the 328p chips was at the upper end of bus capacitance acceptable for i2c. By positioning a chip closer to the chips it was commanding, I did not have this limitation. This post was from 2013, about a year and a half after the pi was released. The ecosystem was pretty much just Minecraft at the time.
    – Mark Brown
    Commented Jul 15, 2018 at 1:00
  • I saw answers from 2016 and didn't notice the question date. Yes, in 2013 the raspberry pi was a brand new toy. Now the support is much better. But for hard real time performance the Arduino (when carefully programmed) does better.
    – NomadMaker
    Commented Jul 15, 2018 at 1:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.