Serial Receiving from Arduino to Raspberry Pi with PySerial stops after a while

30,247

Solution 1

I had the same problem and was breaking my head for a good time, try this

Run

ps -ef | grep tty

If the output looks anything like

root      2522     1  0 06:08 ?        00:00:00 /sbin/getty -L ttyAMA0 115200 vt100

Then you need to disable getty from trying to send data to that port

In order to use the Raspberry Pi’s serial port, we need to disable getty (the program that displays login screen) by find this line in file /etc/inittab

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

And comment it out by adding # in front of it

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100)

To prevents the Raspberry Pi from sending out data to the serial ports when it boots, go to file /boot/cmdline.txt and find the line and remove it

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

Reboot the Raspberry Pi

Credit where credit is due: http://blog.oscarliang.net/raspberry-pi-and-arduino-connected-serial-gpio/ helped me figure out how to diable getty

Solution 2

I had to struggle with this when reading gps data in raspberry pi. The output would stop after about 10seconds and report

 device reports readiness to read but returned no data (device disconnected?)

The solutions given in almost all forums are for raspberry pi 2 with wheezy. I finally managed to get continuous gps streaming in my raspberry pi3 with jessie by doing the following:

  1. set enable_uart=1 and add dtoverlay=pi3-disable-bt in /boot/config.txt. then reboot
  2. I had to change my /boot/cmdline.txt to

    dwc_otg.lpm_enable=0 console=tty1 console=serial0,9600 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

    then reboot

  3. stop getty: sudo systemctl stop [email protected]

    to disable: sudo systemctl stop [email protected]

You need to be careful with the /boot/cmdline.txt. Any mistake in the file may make your raspberry pi to not boot. It is better keep a backup of the file before editing. Also set the baud rate properly. In my case, it was 9600. Hope this helps!

Solution 3

I used to get this a lot, and then a friend told me to prompt the arduino for data from python.

Description below


consider having the arduino only send data when prompted by your python program:

prompt.py

#!/usr/bin/python
import serial, time
ser = serial.Serial('/dev/ttyACM0',  115200, timeout = 0.1)

#if you only want to send data to arduino (i.e. a signal to move a servo)
def send( theinput ):
  ser.write( theinput )
  while True:
    try:
      time.sleep(0.01)
      break
    except:
      pass
  time.sleep(0.1)

#if you would like to tell the arduino that you would like to receive data from the arduino
def send_and_receive( theinput ):
  ser.write( theinput )
  while True:
    try:
      time.sleep(0.01)
      state = ser.readline()
      print state
      return state
    except:
      pass
  time.sleep(0.1)

f = open('dataFile.txt','a')

while 1 :
    arduino_sensor = send_and_receive('1')
    f.write(arduino_sensor)
    f.close()
    f = open('dataFile.txt','a')

prompt.ino

void setup () {   pinMode(13, OUTPUT);   Serial.begin(115200); } 
    void loop() {

  if (Serial.available())    {

     ch = Serial.read();

     if ( ch == '1' ) { 
       Serial.println(analogRead(A0)); // if '1' is received, then send back analog read A0
     } 
     else if (ch == '2') {    
       digitalWrite(13,HIGH); // if '2' is received, turn on the led attached to 13
     } 
     else if (ch == '3') {
       digitalWrite(13,LOW); // if '3' is received then turn off the led attached 13
     } else {
       delay(10);
     }
   }    
}

Also, I made a github repository that has some further examples for python-arduino communication:

https://github.com/gskielian/Arduino-DataLogging/blob/master/PySerial/README.md

Share:
30,247
mozcelikors
Author by

mozcelikors

Interested in product development & Linux customization with C/C++, Embedded Linux, Yocto Project, and Linux Kernel. Contributor to Eclipse Foundation and Yocto Project community.

Updated on July 06, 2020

Comments

  • mozcelikors
    mozcelikors almost 4 years

    I'm working on a project in which I have to receive some 25 character data at a time in order to process it in Raspberry Pi. Here is the example code that generates some data I want to receive from Arduino:

    char i =0;
    char  a =0;
    char b=0;
    
    
    void setup(){
    
     Serial.begin(9600);
     for(i=0;i<25;i++){
    
        Serial.print('l');}
        Serial.print('\n');
        delay(2000);
    }
    
    
    void loop(){
    
     for(i=0;i<25;i++){
         for(a=0;a<i;a++){
          if((a==9)||(a==19)||(a==24))
              Serial.print('l');
          else
              Serial.print('d');   
         }
         for(b=0;b<25-i;b++){
              Serial.print('l');
         }
    
    
         delay(2000);
      }
    }
    

    It sends a line like this 'llllddddllldddd...' This line is 25 characters length. Now, I want to receive this with Raspberry Pi. Here is the code I'm trying to work:

    ser = serial.Serial('/dev/AMA0',9600,timeout=1)
    ser.open()
    
    try:
       serial_data = ser.readline()
       print serial_data
    except serial.serialutil.SerialException:
       pass
    

    This code receives data very correctly for like 5 seconds, and then suddenly stops receiving.

    Moreover, when I try the following, I get no output, or Input/output errors.

    serial_data = ser.readline()
    print serial_data
    

    EDIT1: Okay, I commented the exception now. It gives the following error:

     raise SerialException('device reporst rediness to read but returned no data (device disconnected?)')
    serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)
    

    What is the correct way to receive a 25 character data from arduino into raspberry via PySerial? Any help will be greately appreciated.

  • mozcelikors
    mozcelikors over 10 years
    Actually I did use that before. Nothing changes on raspberry side. The odd thing is I receive data exactly as I want for 5 seconds. Then, data suddenly stops being received even though I made sure Arduino continues transmitting.
  • Farmer Joe
    Farmer Joe over 10 years
    @mozcelikors Maybe you could try upping your timeout to something larger than 2 since you delay your Arduino that long? It could also be worth adding a print statement or something to your except in your python code (just for debugging), maybe the serial eventually hits an exception. I had that issue with an Arduino project I did recently.
  • Farmer Joe
    Farmer Joe over 10 years
    @mozcelikors =( ... I'm intrigued...I'm going to get out my arduino once I get home.
  • mozcelikors
    mozcelikors over 10 years
    Okay, I commented the exception now. It gives the following error: raise SerialException('device reporst rediness to read but returned no data (device disconnected?)') serial.serialutil.SerialException: device reporst rediness to read but returned no data (device disconnected?)
  • Farmer Joe
    Farmer Joe over 10 years
    @mozcelikors Have you tried lowering the delay in your Arduino code?
  • Cerin
    Cerin over 6 years
    If you disable getty, and getty displays the login screen, then how are you going to login to the Pi?