I try to make a my Arduino microcontroller and my Mac talk together, and have created a functional serial connection. My computer is sending data to my Arduino, and my Arduino is sending a '1'
when it is ready to receive a new piece of data.
I have created an if-else
statement (Python script below), which is either sending a new line of data to the Arduino or waiting for the Arduino to be ready for receiving a new line of data.
The problem is that ser.read()
in the first part of the Python script always returns '1'
, which means that the script is sending the individual data lines faster than the Arduino connected stepper motors can possible react.
In the Arduino script you can see that I am sending the state-status in the first line of the serialEvent()
function, which in my world should let the Arduino finish its job, before a new "task" is coming. However, it is for some reason not working. Can anybody help me out here?
Python script
import os
import time
import serial
# Name of csv file with drawing coordinates
csvFile = "scaled_coordinates.csv"
# Create serial connection
ser = serial.Serial(port='/dev/tty.usbserial-A9005bDh', baudrate=9600)
wd = os.getcwd()
myFile = open(wd + "/coordinates/" + csvFile)
state = '1'
while True: # Exits when there is no more lines to read
if state == '0': # Wait for Arduino to be ready
state = ser.read()
elif state == '1': # Send one more line to Arduino
line = myFile.readline()
if not line:
break
print line
ser.write(line)
#time.sleep(1)
state = '0' # Wait for Arduino before reading next line
myFile.close
Arduino loop
function
void loop() {
serialEvent(); // Call the serial function
if (coord_complete) {
// Steps to move from currrent to new point
target1 = steps(x_current, y_current, x_new, y_new, 1);
target2 = steps(x_current, y_current, x_new, y_new, 2);
// Start moving
stepper1.move(target1);
stepper2.move(target2);
// Update current position
x_current = x_new;
y_current = y_new;
// Reset variables
x_complete = false;
y_complete = false;
coord_complete = false;
}
// Stay in while loop until steppermotors is done
while ((stepper1.distanceToGo() != 0) && (stepper2.distanceToGo() != 0)) {
stepper1.run();
stepper2.run();
}
}
Arduino serialEvent
function
void serialEvent() {
Serial.write('1'); // Tell Python that Arduino is ready for one more line
while (Serial.available() && coord_complete == false) {
char ch = Serial.read(); // Get new character
Serial.print(ch);
// If digit; add it to coord_string
if (isDigit(ch)) {
coord_string[index++] = ch;
// Else if ch is ","; then rename to x_new
} else if (ch == ',') {
coord_string[index++] = NULL; // Finish coord_string
x_new = atoi(coord_string); // Convert to integer
x_complete = true; // Change x_complete to true
index = 0; // Reset index
memset(coord_string, 0, sizeof(coord_string)); // Reset coord_string
// Else if ch is a new line; then rename as y_new
} else if (ch == ';') {
//Serial.write('0');
coord_string[index++] = NULL;
y_new = atoi(coord_string);
y_complete = true;
index = 0;
memset(coord_string, 0, sizeof(coord_string));
}
// Ends while-loop when true
coord_complete = x_complete * y_complete;
}
}
Edit
The current Python code looks like this:
import os
import time
import serial
# Name of csv file with drawing coordinates
csvGraphic = "Scaled_coordinates.csv"
# Create serial connection
ser = serial.Serial(port='/dev/tty.usbserial-A9005bDh', baudrate=9600)
wd = os.getcwd()
myFile = open(wd + "/graphics/" + csvGraphic)
state = '1'
while True: # Exits when there is no more lines to read
print "state", state
if state == '0': # Wait for Arduino to be ready
state = str(ser.read())
elif state == '1': # Send one more line to Arduino
line = myFile.readline()
if not line:
ser.close()
break
print line
ser.write(line)
state = '0' # Wait for Arduino before reading next line
ser.close()
myFile.close
The Python output is shown below. The code is executed in one go, without waiting for the Arduino. It seems like the line state = str(ser.read())
reads data which is in some kind of serial buffer. I guess the solution is to clear the buffer. I just don't know how.
state 1
239,275;
state 0
state 1
1100,275;
state 0
state 1
300,400;
state 0
state 1
200,400;
state 0
state 1
200,300;
state 0
state 1
[Finished in 0.1s]
ser = serial.Serial(port='/dev/tty.usbserial-A9005bDh', baudrate=9600)
. – Christoffer