Interfacing issues with Python and Arduino

So at the moment I am running this sketch on my Arduino Duemilanove:

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

void pulse(int pin, int time)  {
  digitalWrite(pin, HIGH);
  delayMicroseconds(time);
  digitalWrite(pin, LOW);
}

void loop()  {
  while (!Serial.available())  {
  }
  int length;
  int points;
  length = Serial.parseInt();
  unsigned int array[length];
  int i;
  for (i = 0; i < length; i++)  {
    array[i] = Serial.parseInt();
  }
  points = Serial.parseInt();
  int data[points];
  int d;
  int c = 0;
  while (c < length)  {
    pulse(13, 1);
    delayMicroseconds(array[c]);
    c++;
  }
  pulse(5, 1);
  for (d = 0; d < points; d++)  {
    data[d] = analogRead(0);
  }
  int e = 0;
  while (e < points)  {
    String dataString = "";
    dataString += data[e];
    Serial.println(dataString);
    e++;
  }
}

In the serial monitor (at the appropriate baud rate that was set in the sketch) let's say that I give the arduino the following:

2[100,100]10

What it will do is read the first three numbers in accordingly, execute the pulsing, and give me back 10 points of data. So far everything works.

The tricky part that I'm having issues with is when I'm trying to use a Python script to control it. Right now I'm running this diagnostic version of the script:

import serial
import random
import time
import string
 
# Change timeout so we can quickly see what's wrong
arduino = serial.Serial(port='/dev/cu.usbserial-A600egLQ', baudrate=115200, timeout=0.1)
 
print "Connected:", arduino.isOpen()
 
testList = []
c = 0
while (c < 10):
    a = random.randint(50,150)
    testList.append(a)
    c+=1
 
# Length will be 9 always (c<10 determines how many items we have)
length = len(testList)
points = 20
writeString = str(length) + str(testList) + str(points)
 
print "Writing this string:", writeString
 
arduino.write(writeString)
time.sleep(0.5)
d = 0
dataList = []
while (d < points):
    readIn = arduino.readline()
    # Print the actual string we get - maybe we don't get \r\n at the end
    print repr(readIn)
    point = string.translate(readIn, None, deletions='\r\n')
    print point
    dataList.append(point)
    d+=1
 
arduino.close()
maximum = max(dataList)
print 'The Maximum point returned is:', maximum

Now what this should be doing is writing the same thing that I am giving it over the serial monitor. The thing is, when I run this module in IDLE I get this in return:

Connected: True
Writing this string: 10[53, 86, 110, 124, 66, 92, 64, 53, 111, 94]20
''

''

''

''

''

''

''

''

''

''

''

''

''

''

''

''

''

''

''

''

The Maximum point returned is:

So something in the Arduino itself is timing out and I cannot figure out for the life of me what it is. Does anyone have any suggestions on what I should do to fix these issues?

  while (e < points)  {
    String dataString = "";
    dataString += data[e];
    Serial.println(dataString);
    e++;
  }

There hardly seems any sense in using the += operator to append one value to a new String. There hardly seems to any reason to use the String class at all. Serial.print() KNOWS how to convert an int or float to a string.

A for loop is typically used when the number of iterations is known.

PaulS:

  while (e < points)  {

String dataString = "";
    dataString += data[e];
    Serial.println(dataString);
    e++;
  }



There hardly seems any sense in using the += operator to append one value to a new String. There hardly seems to any reason to use the String class at all. Serial.print() KNOWS how to convert an int or float to a string.

A for loop is typically used when the number of iterations is known.

So would doing this possibly fix the timeout issues, or am I just out of luck?

So would doing this possibly fix the timeout issues, or am I just out of luck?

I'm curious. How long would it have taken to make the changes and test?

When you open the serial port, the Arduino resets into the bootloader and hangs out there for a short while to see if the PC wants to flash a new program.

So, if you send data too soon after opening the serial port, your data will be seen by the bootloader, not your program, which is not running yet. This usually leads to symptoms like "Arduino doesn't see the command I sent to it", because the bootloader ignores what it can't understand and goes ahead and starts your program. Which sits there waiting for the command that has already come and gone.

See if it works a little better if you delay a short while on the python side after opening the serial port -- I use time.sleep(2).

-br

Ok, I finally got back to the Arduino project after a hectic time where I couldn't touch it again. As far as I know PaulS I guess that my programming with the Arduino is just an artifact leftover from programming software to interface with the Arduino, so my programmer's instinct tells me that when it comes to write() commands the process is "convert everything to strings" -> "write to port." So far, that doesn't seem to be the problem, but I suppose that if Arduino's write() command does the string conversion already I suppose some code is unnecessary from a programming budget perspective.

Thanks billroy by the way. I added a time.sleep(2) on the line after I define the serial object "arduino" and I readjusted the time.sleep() after the write() command to be a time.sleep(2) as well. So far, everything works now.