4

I am having an Arduino Nano sending "48" or "49" via a serial connection to a Pi. I'd like to use this input, but for some reason the connection always cuts out after a few seconds with the following error message.

Traceback (most recent call last):
File "ser.py", line 7, in <module>
response = serialport.read()
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 460, in read
raise SerialException('device reports readiness to read but returned no  data (device disconnected?)')
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)

What is happening here?

Edit1: Solved this part by editing /boot/cmdline.txt and deleting the line

console=ttyAMA0,115200

This is the relevant part of the Python code I run:

def update_image(self):    
    serialport = serial.Serial("/dev/ttyAMA0", 9600, timeout=25)
    response = serialport.readlines()
    if response == 48:
        self.panel1.configure(image=self.image2)
        print "green"
        self.display = self.image2
    else:
        self.panel1.configure(image=self.image1)
        print "red"
        self.display = self.image1
    self.root.after(500, self.update_image)

This is the code on the Arduino, it is receiving serial information from another Arduino and passing it along to the Pi:

#include <SoftwareSerial.h>
SoftwareSerial Rasp(6, 7);
void setup() {
  Rasp.begin(9600);
  Serial.begin(9600);
  pinMode(10, OUTPUT);
 }

void loop() {

  if (Serial.available() > 0) 
  {
    int ser = Serial.read();
    Serial.println(ser);
    Rasp.println(ser);
      if (ser == 49)
        {
           digitalWrite(10, HIGH);
        }
      else
        {
          digitalWrite(10, LOW);
        }
  }
}

I am trying to have the Python code switch between displaying 2 images depending on the serial input.

Edit1: Still having problems with this part. Can't get the images to change based on the serial input.

Edit2: Used SlySven's supposed code. This is all i have right now:

#!/usr/bin/python

# use a Tkinter label as a panel/frame with a background image
# note that Tkinter only reads gif and ppm images
# use the Python Image Library (PIL) for other image formats
# free from [url]http://www.pythonware.com/products/pil/index.htm[/url]
# give Tkinter a namespace to avoid conflicts with PIL
# (they both have a class named Image)

import Tkinter as tk
import PIL
from PIL import Image, ImageTk
from ttk import Frame, Button, Style
import time
import serial

class Example():
    def __init__(self):
        self.root = tk.Tk()
        self.root.title('My Pictures')

        # pick an image file you have .bmp  .jpg  .gif.  .png
        # load the file and covert it to a Tkinter image object
        imageFile = "red.jpg"
        self.image1 = ImageTk.PhotoImage(Image.open(imageFile))
        self.image2 = ImageTk.PhotoImage(Image.open("green.jpg"))

        # get the image size
        w = self.image1.width()
        h = self.image1.height()

        # position coordinates of root 'upper left corner'
        x = 0
        y = 0

        # make the root window the size of the image
        self.root.geometry("%dx%d+%d+%d" % (w, h, x, y))

        # root has no image argument, so use a label as a panel
        self.panel1 = tk.Label(self.root, image=self.image1)
        self.display = self.image1
        self.panel1.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
        print "Initialized"
        self.root.after(500, self.update_image)
        self.root.mainloop()

    def update_image(self):
        serialport = serial.Serial("/dev/ttyAMA0", 9600)
        response = int(serialPort.readlines())
        print response
        if response == "0":
            self.panel1.configure(image=self.image2)
            print "green"
            self.display = self.image2
        else response == "1":
            self.panel1.configure(image=self.image1)
            print "red"
            self.display = self.image1
        self.root.after(500, self.update_image)

def main():
        app = Example()

if __name__ == '__main__':
        main()

Now I sadly encounter this problem and can't figure out what's wrong:

  File "try4.py", line 55
  else response == "1":
            ^
  SyntaxError: invalid syntax

I had to scrap the part with the part with the error message SlySven wrote up, because that was giving my weird problems with a syntax error in the following line which is:

self.root.after(500, self.update_image)
  • 1
    I can't really follow what you have done, but response = serialport.readlines() is not going to return a character (if this is what you expect). You really need to learn some debugging technique; write small snippets of code to test what is happening in stages. This is not a Pi question. – Milliways Dec 16 '15 at 22:42
  • 1
    I suspect that ` else response == "1":` should be: ` elif response == "1":` – user3629249 Dec 17 '15 at 16:43
  • What @user3629249 said! Use elif test-expression: or else : (NO test-expression) - you've tried to mash the two together and that won't work. Also, as per @Milliways comment, neither of us think response = serialport.readlines() is going to return a single character - which is why I suggested the else : in my code sample to tell you exactly what you are getting if it doesn't meet either of the expected cases (which is always a good debugging technique, IMHO!) However think of this as experience, by the time you get it working you will know more about readlines() than before. 8-) – SlySven Jan 7 '16 at 16:58
2

Do you have an /etc/inittab file - which is pretty much mandatory for the old sysV init (not sure whether systemd, which is the default now on Raspian "Jessie" but not previous versions "Wheezy" and before, preserves and tries to replicate its functions) - if so you should check that there is not a line containing something with the port in, like:

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

This is so that you can login via a serial connection, but will interfere with what you want. Disable it by editing the file as root or via sudo and put a comment character # at the start of that line.

As for the second part, when you say you are sending 48,or 49 I take it you mean that you intend to send a single ASCII character '0' {ASCII code 48 decimal} or '1' {ASCII code 49} but there is also a Line-Feed('\n') or Carriage-Return/Line-Feed pair ("\r\n") at the end of the data being sent by the Arduino in the Rasp.println(ser) call. The way that serial port data is handled can be "line-buffered" which means that things are not sent out or processed when read in until an End-of-Line state is detected so this is not a bad thing. However your Pi code uses

response = serialport.readlines()

and assumes that the result will be EXACTLY 48 to use one result and anything else will be the other. However I'm new enough to Python to not be sure that response is what a C coder would call a integer, I think you want to covert the output to a number:

response = int(serialPort.readlines())

Better still, keep it as a "string" and test for BOTH cases - and report a problem if it is something else, also you might need to trim off CR or LF :

    response = serialport.readlines()
    if response == "0":
        self.panel1.configure(image=self.image2)
        print "green"
        self.display = self.image2
    elif response == "1":
        self.panel1.configure(image=self.image1)
        print "red"
        self.display = self.image1
    else:
        print(str.format("Error, bad response: \"{}\"",response)

I am sure this will show something is not as you expect -probably that you need to use str.strip(). 8-P

  • Thanks a ton for the suggestions. Cant seem to find any file like you are reffering to in the first part of your post. the only folder I have is /etc/init, which contains all sort of files, so I think I'm good in that regard. Implemented some of your suggestions but am still getting some errors. Thanks alot for the help! – zwafro Dec 16 '15 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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