How do i serially communicate between them, just using the usb ports on the raspi and the rx, tx pins on the arduino? Are there any better ways to communicate between raspi and arduino?
2 Answers
You may be finding the UART(or USART) communication, which is what Arduino RT/TX pins and some of RPi GPIO pins used for. USB ports uses 5V and UART pins are for 3.3V, thus you may need additional 5V-3.3V interconvert circuit to use as your first describe. If you choose to use direct UART communication instead, you don't need such additional circuit.
I've tried it and succeeded to serial communicate between a RPi and an AVR ATMEGA chipset which is the same MCU chipset used in Arduino.
To use this, firstly, you need to use sudo raspi-config
to disable serial shell. It's because this service is running on those pins by default and we need to use the pin by ourselves. It's in the advanced settings.
Secondly, wire RX/TX pins of RPi with of arduino. The RX pin of RPi should be connected with TX pin of Arduino and vice versa (Think of the crossover cable in TCP). You can see that pin 8 is TX and pin 10 is RX from Official GPIO Guide. This goes the same in RPi2 too, FYI.
Lastly, choose or program a terminal program to use them. I chose the easiest one:Python3 with pySerial library. This'll let you do it like this.
from serial import Serial
from time import strftime, time, localtime, sleep
def write(s, t=None):
if t is None:
t = strftime('s%H:%M:%S', localtime(time() + 1)).encode('ascii')
else:
t = ('s%s' % t).encode('ascii')
s.write(t)
while int(time()%1*1000): pass # wait for ms to be 0
s.write(b'\r')
print(t)
if __name__ == '__main__':
from sys import argv
s = Serial('/dev/ttyAMA0')
for i in range(3):
write(s, None if len(argv)<2 else argv[1])
sleep(.1)
It's sending internet-synchronized RPi clock in command string format(for ex.s05:55:20
) to AVR on exact O'second clock to let it have real time system clock and repeat that 3 times to ensure it.
Here's my reading function for your comfortness. It requires the AVR have to send a message ended with a line break.
def read(s):
buf=rst=b''
while buf != b'\n':
buf = s.read()
rst += buf
rst = rst.rstrip()
return rst
Well, I strongly recommend you to wrap them up with a class inheriting Serial
for better code reusability.
Also, note that screen
or minicom
kind of terminal programs could be useful if you need to send manual remote control signals.
Finally, you may need a service to forget about running python script everytime you reboot your RPi.
I have my own very simple approach about this and it's used in this project.
https://github.com/chidea/pyGPIOclock/
install_service.sh
and raspberry_pi/gpio_clock
would be fitted for this.
Don't be confused.. This project is not using serial connected AVR but RPi GPIO itself to show the time.
-
3You shouldn't connect a 5V Arduino TX pin to a 3V3 Pi RX pin. In many respects it is simpler to use a USB Serial dongle at the Pi end connected to the Arduino's pins.– joanJan 6, 2016 at 21:26
-
thanks for replying and i do get the software part, but the i'm still confused over the hardware interfacing. How did you convert the voltage levels? If any modules were used? Jan 7, 2016 at 19:20
-
Sorry, I didn't know that the arduino uses 5V by default. There are numerous ways... The one I recommend most is just converting its default voltage to 3.3V by replacing its main regulator which makes it 100% compatible with RPi. Consider the other sensors or actuators you use with arduino and checkout instructions below. learn.adafruit.com/arduino-tips-tricks-and-techniques/… Other ways would be resistor divider or logic converter.– Ch.IdeaJan 9, 2016 at 15:19
It is easier to just use a regular USB cable. On the Pi it will likely show up as /dev/ttyUSB0