I'm trying to communicate with my arduino from a python script that uses the serial port however it doesn't seem to work. When i try the same set of instructions from the python terminal it works like a breeze however when i save it to a .py file and run it, it doesn't. there seems to be some trouble with the serial communication part of it. here is the code
int Dpin4 = 5;
int Dval4 = 0;
int ledPin = 13;
int val = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
pinMode(Dpin4, INPUT);
}
void loop() {
Dval4 = digitalRead(Dpin4);
val = Serial.read();
if(val == '1')
{
if(Dval4 == LOW)
{
digitalWrite(ledPin, HIGH);
Serial.print(4);
}
else
{
Serial.print(0);
}
Serial.println();
}
}
What I am trying to do is read from a light sensor. An optical fiber channels light to a sensor. I read a HIGH or LOW from the digital inputs the sensors are wired to.
In the code above, I am only testing this for one sensor, namely Dval4 to the pin 5 (sorry for the poor naming convention).
Here is my python code:
import serial
ser = serial.Serial('COM4', 9600)
while True:
ser.write('1');
x = ser.readline()
The problem with the python code is that it just hangs at readline(). If I do a x = ser.readline() before the while loop, it works fine. The other interesting thing is when I do:
ser.write('1'); x=ser.readline(); print x
x will have nothing the first time (meaning it only gets the \r\n and when I repeat the command, it works fine (meaning it gets 4\r\n).
What is happening here? Is there some issue with the ser.write('1') call I am making and whether its getting to the Arduino board fast enough?
Hi mrtm3050,
I doubt I can help with the python script but perhaps I can help fix your arduino code.
The sketch you posted will not light the led and send serial data if one or more characters are available on the serial port. Is this really the functionality you want? I would guess you want the opposite – light the LED if a character is available on the serial port and the input pin is low.
I wonder if you are confused by the unintuitive use of the -1 return code to serial read.
My guess is that this is what you want:
void loop() {
if(Serial.available()) { // do the following if one or more characters are available
val = Serial.read(); // remove a character from the serial buffer
if( val == 'A'){
// here if the character 'A' was received
Dval4 = digitalRead(Dpin4);
if(Dval4 == LOW) {
digitalWrite(ledPin, HIGH);
Serial.println(4);
}
else {
Serial.println(0);
}
}
}
}
IMO, calling Serial.available() to see if data is available is much more expressive than testing the return value from Serial.read for -1. I have seen -1 used in this way in a few times recently and hope this friendly post will encourage you to use the more common and intuitive Serial.available() method;
Can anyone help with the python code? its a real wierdo problem. I tried the same script and code in ubuntu and it works fine. So, now i've narrowed it down to a windows thing.
Ok! I figured out the problem. Windows responds slowly to the scripts request and even before the serial open request is actually processed the complete script is executed and the control exits from the program. I tried introducing a time delay in the python script for 2 seconds - between the time the serial port is opened and its written to - this seems to work.
I haven't tried serial comm with an arduino yet, but I've run into that problem with python before on windows. I found that if I passed in the number of chars that were in the buffer, that it would work. For example...
import serial
s = serial.Serial(0)
s.write("A")
buff_size= s.inWaiting()
x = s.read(buff_size)
print x