As I write this I'm realizing that this is a python question but I'm going to post it here just in case anyone has used the PySerial library with the AccelStepper Arduino library.
[b]This code works fine. [/b]I am able to open the serial monitor from the Arduino IDE and
enter in a comma separated pair of steps (i.e. 1000,1000) and both motors rotate.
My issue is with the implementation of the PySerial Python package. My code is as
follows:
import serial
ser = serial.Serial(port='COM3', baudrate=9600)
ser.write(b'1000,1000)
I have confirmed that my port is COM3 and my baudrate is 9600. I have tried various
different techniques to get the values to write to serial (such as assigning a variable
a value and passing the .write() that variable) but nothing is working. In fact most of
the time my code runs without an error message but the motors don't move.
My end goal is to open a 2000x2 csv file with 2000 pairs of steps and then loop through
that file passing the steps over serial. If anyone can give me any insight or point me
in the direction of resources that would be great.
Thanks so much!
On the rpi have you tried a serial loopback test? Examples abound on the internet.
Also, the Python code I use to send serial is a bit more extensive then what you are using. Unfortunately the code I am using is on my RPi which is running headless at the moment.
Idahowalker:
On the rpi have you tried a serial loopback test? Examples abound on the internet.
Also, the Python code I use to send serial is a bit more extensive then what you are using. Unfortunately the code I am using is on my RPi which is running headless at the moment.
I'm actually not using a raspberry pi, just running my file in the command prompt. I'll look into a serial loopback test though, thank you!
import serial
ser = serial.Serial(port='COM3', baudrate=9600)
ser.write(b'1000,1000)
You do not give the serial port time to open and reset the Aduino.
Here is some simple python code which should emulate the serial monitor for input. I'm not certain it will get you any closer to your goal of reading out file data pairs, but it will show you that pyserial and the arduino can communicate fine once you give the serial port time to open.
import serial
import time
ArduinoSerial = serial.Serial('COM3',9600, timeout = 2) #timeout for response on readline()
time.sleep(2) #allow time for serial port to open
while True:
print("enter pitchangle,yawangle comma separated pair")
var = input()# get input from user
print ("you entered", var )# print the input for confirmation
ArduinoSerial.write(var.encode())#send to Arduino
#read echo back from arduino to verify receipt of message
data = ArduinoSerial.readline()[:-2] #the last bit gets rid of the new-line char
if data:
print("received message back from Arduino")
print (data.decode())
Your code has blocking input with .parseInt() and you would do well to study the not blocking methods presented in Robin2's Serial Input Basics.
The python code can also be written for non blocking serial input back from the Arduino if needed, but it sound like you mainly want to push data out.
My end goal is to open a 2000x2 csv file with 2000 pairs of steps and then loop through
that file passing the steps over serial. If anyone can give me any insight or point me
in the direction of resources that would be great.
EDIT: It is fairly straightforward to have python read a csv file line by line and you can send each reading to the Arduino. The csv file needs to be in the same folder as the python program which will send it. How do you want to time the sending?
I am working on a Arduino to Arduino/PC Serial connection tutorial at the moment.
I have Arduino code for SoftwareSerial and HardwareSerial for multiple board types and example python sketches that send data / receive data / prompt for user input and send that
Will be a few days before it is published so drop me a PM with your email if you want to try it out
Also note that the Rpi works at 3.3v, the Arduino at 5v . If you’ve not done so , You need to level shift any connections between the two ( eg: the RX pin of the Arduino will see the 3.3v signal ok , use a potential divider on the Arduino Tx pin)
I'm not sure how an RPi fits into this discussion. As far as I know the OP wants to set stepper target counts with 3000 pairs of integers from a csv file generated and held on a PC and sent to a UNO over USB.
cattledog:
You do not give the serial port time to open and reset the Aduino.
Here is some simple python code which should emulate the serial monitor for input. I'm not certain it will get you any closer to your goal of reading out file data pairs, but it will show you that pyserial and the arduino can communicate fine once you give the serial port time to open.
import serial
import time
ArduinoSerial = serial.Serial('COM3',9600, timeout = 2) #timeout for response on readline()
time.sleep(2) #allow time for serial port to open
while True:
print("enter pitchangle,yawangle comma separated pair")
var = input()# get input from user
print ("you entered", var )# print the input for confirmation
ArduinoSerial.write(var.encode())#send to Arduino #read echo back from arduino to verify receipt of message
data = ArduinoSerial.readline()[:-2] #the last bit gets rid of the new-line char
if data:
print("received message back from Arduino")
print (data.decode())
Your code has blocking input with .parseInt() and you would do well to study the not blocking methods presented in Robin2's [Serial Input Basics.](https://forum.arduino.cc/index.php?topic=396450.0)
The python code can also be written for non blocking serial input back from the Arduino if needed, but it sound like you mainly want to push data out.
EDIT: It is fairly straightforward to have python read a csv file line by line and you can send each reading to the Arduino. The csv file needs to be in the same folder as the python program which will send it. How do you want to time the sending?
Hey thank you so much, adding the delay worked! Unfortunately my arduino code is written in such a way that it will only send the last "pair" of steps to the drivers and only 1 rotation is made. Is this a result of using parseInt()? And if so the link you posted didn't provide a clear replacement for parseInt(). Thanks again!
For some non-blocking Serial read solutions see my Arduino Software Solutions
Once you have read in the 'line' of text, the solutions at the end of that webpage cover converting the text to an int.
You will send data pairs with start and end markers like <45,90> and use atoi() to convert the text numbers to integers.
Unfortunately my arduino code is written in such a way that it will only send the last "pair" of steps to the drivers and only 1 rotation is made.
I'm unclear about what you need on the Arduino side to drive the stepper as you want, but a good way to test things out independent of python is to use a 2D integer array of your stepper target values, and iterate through it based on a millis() timer.
This will eliminate the complications of reading text pairs and converting to integers with atoi.
Just pretend you had all your integer pairs stored on the Arduino and figure out how to drive the stepper.
Check out my complete code solution to sending a CSV file from Python to Arduino.
One useful part of the the solution is that the python side is blocked from sending more lines until the Arduino side has processed the last line and is ready to continue.
You can greatly simplify all of this by using a proven set of compatible Arduino and Python libraries: SerialTransfer.h and pySerialTransfer. These libraries automatically packetize and parse your serial data, so you don't have to worry about that portion of the project.
SerialTransfer.h is installable via the Arduino IDE, pySerialTransfer is pip-installable, and both come with many examples