[UPDATED, still need help] Pyserial not reading Arduino serial messages

Here’s my arduino sketch:

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println(getWeather());
delay(100);
}

int getWeather() {
  int temperature = 0;
  Serial.write('W');
  while(Serial.available() < 0);
  temperature = Serial.parseInt();
  Serial.write('S');
  delay(1000);
  return temperature;
}

The python script looks like this:

from bs4 import BeautifulSoup, NavigableString, Tag
from decimal import *
from struct import *
import urllib2
import serial
import time

def getTemperature():
  print 'Now getting the weather...'
  weather_page = urllib2.urlopen(url_weather).read()
  soup = BeautifulSoup(weather_page)
  
  temperature = str(soup.span.b).strip('</b>')
  temperature = str(int(Decimal(temperature)))
  Lena.write(temperature)
  time.slee(2)
  success = Lena.read()
  if success == 'S':
    print 'I sent '+ temperature
  else: print 'FAILURE'

def sunrise_and_set():
  weather_page = urllib2.urlopen(url_weather).read()
  soup = BeautifulSoup(weather_page)

  sunrise = str(soup.find_all('b')[22]).strip('</b>')
  sunset = str(soup.find_all('b')[23]).strip('</b>')
  #send over serial
  sunrise_hour = int(sunrise[slice(0,0)])
  sunrise_minutes = int(sunrise[slice(2,4)])

  sunset_hour = int(sunset[slice(0,1)])
  sunset_minutes = int(sunset[slice(2,4)])

  bytesss = pack('B', sunset_hour)
  print bytesss

  Lena.write(sunrise_hour)
  Lena.write('\n')
  Lena.write(sunrise_minute)
  

Lena = serial.Serial('/dev/tty.usbmodem1d11', 9600)
print('Now connected.')
url_weather = "http://m.wund.com/cgi-bin/findweather/getForecast?brand=mobile&query=94560"
  
while True:
  #wait for instructions from arduino aka Lena
  action = Lena.read(1)

  if action == 'W':
    print('I received ' + action)
    getTemperature()

  if action == 'H': 
    sunrise_and_set()

  else: print('I received nothing.')

When the two programs run, I get this output from Python:

Now connected.
I received nothing.
I received nothing.
I received nothing.
I received nothing.
I received nothing.
I received W
Now getting the weather…
I sent 50
I received nothing.
I received W
Now getting the weather…
I sent 50
I received nothing.
I received W
Now getting the weather…
I sent 50

Arduino however, outputs this:

50
W0
50
W0
50
W0W0S50
WS0
WS0
WS0
W

What’s wrong? Thanks in advance for your help.

What's wrong?

Both sides appear to be reading data. Neither side appears to be writing data.

PaulS:

What's wrong?

Both sides appear to be reading data. Neither side appears to be writing data.

Doesn't the Serial.write() method write data to the serial connection?

Also if you're wondering, getTemperature() Python side writes data back to the Arduino using ser.write(), but I know it's not executing since the message 'I received ' + action never appears in the terminal.

In addition to all of that, simply typing into the Serial Monitor for the Arduino does not garner a response from Python other than

I received nothing. I received nothing.

If none of these things is what you were referring to, then I don't understand. How do I get Arduino to write data, and Python to read it- and vice versa?

Doesn't the Serial.write() method write data to the serial connection?

Oops. Missed that. I also missed, I guess, some proof that the getWeather() function was ever called.

In addition to all of that, simply typing into the Serial Monitor for the Arduino does not garner a response from Python other than

On Windows, you can only have one application at a time listening to a serial port. If the Serial Monitor is open, Python would not be able to connect to it. If Python opened the serial port, the Serial Monitor would not be able to. Therefore, we've ruled out Windows as your operating system. Or, we've ruled out that Python is doing any error handling.

Comments?

PaulS:

Doesn’t the Serial.write() method write data to the serial connection?

Oops. Missed that. I also missed, I guess, some proof that the getWeather() function was ever called.

In addition to all of that, simply typing into the Serial Monitor for the Arduino does not garner a response from Python other than

On Windows, you can only have one application at a time listening to a serial port. If the Serial Monitor is open, Python would not be able to connect to it. If Python opened the serial port, the Serial Monitor would not be able to. Therefore, we’ve ruled out Windows as your operating system. Or, we’ve ruled out that Python is doing any error handling.

Comments?

I’m using a Mac. Also on occasion, the python program will quit with this error:

Traceback (most recent call last):
File “sun-and-weather.py”, line 51, in
action = Lena.read(1)
File “/Library/Python/2.7/site-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?)

I would start to strip the PYTHON script to be as minimal as possible to read the data.

You must understand that serial data takes time, and the only thing defined is the speed of the bits in a byte.

On the receiving sides (both sides!) you must collect the output, until a message is complete .

further this one is an error as available() never returns a negative number.

while(Serial.available() < 0);
try this

while(Serial.available() == 0);

robtillaart:
I would start to strip the PYTHON script to be as minimal as possible to read the data.

You must understand that serial data takes time, and the only thing defined is the speed of the bits in a byte.

On the receiving sides (both sides!) you must collect the output, until a message is complete .

further this one is an error as available() never returns a negative number.

while(Serial.available() < 0);
try this

while(Serial.available() == 0);

The python getTemperature() method now looks like this:

def getTemperature():
  print 'Now getting the weather...'
  weather_page = urllib2.urlopen(url_weather).read()
  soup = BeautifulSoup(weather_page)
  
  temperature = str(soup.span.b).strip('</b>')
  temperature = str(int(Decimal(temperature)))
  Lena.write(temperature)
  print 'I sent ' + temperature

I changed that line in the arduino function and removed the send ‘S’ part. It now looks like this:

int getWeather() {
  int temperature = 8;
  Serial.write('W');
  while(Serial.available() == 0);
  Serial.flush();
  temperature = Serial.parseInt();
  delay(1000);
  return temperature;
}

Arduino output:

9
9
9
949
9W

Python output:

Now connected.
I received W
Now getting the weather…
I sent 49
I received nothing.
I received nothing.
I received nothing.
I received nothing.
I received nothing.
I received W
Now getting the weather…
I sent 49
I received nothing.
I received nothing.
I received nothing.
I received nothing.
I received nothing.
I received W
Now getting the weather…
I sent 49
I received nothing.
I received nothing.
I received nothing.
I received W
Now getting the weather…
I sent 49
I received nothing.

Traceback (most recent call last):
File “sun-and-weather.py”, line 45, in
action = Lena.read(1)
File “/Library/Python/2.7/site-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?)

  Serial.flush();

What version of the IDE are you running? What do you think this does? (It probably doesn't do that!)

PaulS:   Serial.flush();

What version of the IDE are you running? What do you think this does? (It probably doesn't do that!)

1.5

I was under the impression that it would wait until the data in the serial buffer was finished being entered into the stream.

I was under the impression that it would wait until the data in the serial buffer was finished being entered into the stream.

It does. Why is that necessary?