You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, PowerBroker2. I am trying to figure out an issue with pySerialTransfer. I'm on an Apple Silicon Mac and installed the packages with pip3, and my Python was installed from python.org, if that helps.
My intention is to send an array of integers to an Arduino for it to run a stepper motor using that array. The array-generation part of the code works well.
The class SerialTransfer does not work when I run my code. It keeps returning the error message "ImportError: cannot import name 'SerialTransfer' from 'pySerialTransfer' (/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/pySerialTransfer/init.py)".
I looked at the pySerialTransfer.py text file and it does have a class called SerialTransfer so I don't understand what's going on here.
Here's my code.
importnumpyasnpimportpySerialTransferfrompySerialTransferimportSerialTransferimportstructA=50.0# amplitude in mmr=19.0# radius of gear in mm (divide pitch diameter by 2)f=0.1# frequency in Hz (between 0 and 1)T=1/f# period of one cycle in secondsbase_step_angle=0.031416# base step angle of stepper motor in radiansgear_ratio=26.85123967# gear ratio of gearheadmicrostepping=8# microsteps per stepinterval=100deltat=1/interval# time increment in secondsnumberOfSteps=1/((base_step_angle/gear_ratio)/microstepping) # microsteps per radianomega=2.0*np.pi*f# in rad/st=np.linspace(0,T,interval)
z=A*np.sin(omega*t) # mathematical position of linear motion in mmv=A*omega*np.cos(omega*t) # mathematical velocity of linear motion in mm/sa= (-A*np.square(omega))*np.sin(omega*t) # mathematical acceleration of linear motion in mm/s^2d=v*deltat+0.5*a*np.square(deltat) # linear displacement in mmdelta_theta=d/r# angle that motor moves between z positions, in radianssteps=np.round(delta_theta*numberOfSteps) # number of steps to move between positionsint_steps=steps.astype(int) # Convert data into integerslink=pySerialTransfer.SerialTransfer('/dev/cu.usbmodem83201', 115200)
whileTrue:
data=struct.pack('<'+'i'*len(int_steps), *int_steps) # format data with structsize=struct.pack('<i', len(int_steps)) # send data size firstlink.send(size)
link.send(data)
That worked. Thanks. Now I have more error messages saying "TypeError: '<' not supported between instances of 'bytes' and 'int'" and "message_len = constrain(message_len, 0, MAX_PACKET_SIZE)" but I think I can figure them out on my own.
where int_steps is the array of integers to be sent.
Now getting the error message "TypeError: SerialTransfer.tx_obj() missing 1 required positional argument: 'val'".
As I understand from the pySerialTransfer.py file, "int_steps" would be considered the "self". Val is defined as the value to be inserted into the TX buffer. I don't know what that is.
I just realized after looking at your example that I'm supposed to enter the first element of my array, then the second, then third, and so on. My array has 100 elements. Could I just loop them all through?
Also, the txdata.py example keeps returning a KeyboardInterrupt error when I run it. The Arduino side keeps outputting "avrdude: stk500_recv(): programmer is not responding" 10 times. I feel like there's not a connection at all.
This is my first Arduino project, and I'm doing a PhD in chemical engineering. I'm not an electrical or software engineer. So I would really appreciate your help.
The avrdude issue is because the USB port wasn't closed correctly by Python before trying to flash the Arduino. Closing all Python processes and resetting the Arduino should fix that. As for your other question, there's only one way to find out: most of robotics programming is running experimental code and simply seeing how the system responds and moving on from there. But the short answer is yes, you can do a loop to stuff the transmit buffer. Just be sure to keep in mind that there's a limited number of available bytes you can send in one packet...
Activity
PowerBroker2 commentedon Feb 9, 2025
Python's import system is a little tricky. I know for a fact the examples used to work 100% no problem, but I'm getting the same error now.
Try this instead:
ericshear26 commentedon Feb 9, 2025
Thanks for the quick reply.
I amended my code with this and now when I put the cursor over SerialTransfer the popup says '"SerialTransfer" is not accessed.'
And the new error message says: "AttributeError: module 'pySerialTransfer' has no attribute 'SerialTransfer'. Did you mean: 'pySerialTransfer'?"
PowerBroker2 commentedon Feb 9, 2025
Idk, it works for me:
Did you ignore the warning and try running it anyway?
Also, you will want to change your code to say this:
ericshear26 commentedon Feb 10, 2025
That worked. Thanks. Now I have more error messages saying "TypeError: '<' not supported between instances of 'bytes' and 'int'" and "message_len = constrain(message_len, 0, MAX_PACKET_SIZE)" but I think I can figure them out on my own.
PowerBroker2 commentedon Feb 10, 2025
Why are you packing the struct manually when the lib class can do that for you?
ericshear26 commentedon Feb 10, 2025
You mean struct.pack? Pack is one of the classes in the struct module. I don't see a lib class in struct.
PowerBroker2 commentedon Feb 10, 2025
No, no - SerialTransfer can pack the transmit struct for you using
tx_obj()andrx_obj()ericshear26 commentedon Feb 10, 2025
Tried that. My code is as follows:
data = SerialTransfer.tx_obj(int_steps)where int_steps is the array of integers to be sent.
Now getting the error message "TypeError: SerialTransfer.tx_obj() missing 1 required positional argument: 'val'".
As I understand from the pySerialTransfer.py file, "int_steps" would be considered the "self". Val is defined as the value to be inserted into the TX buffer. I don't know what that is.
PowerBroker2 commentedon Feb 10, 2025
Look at an example
ericshear26 commentedon Feb 10, 2025
I just realized after looking at your example that I'm supposed to enter the first element of my array, then the second, then third, and so on. My array has 100 elements. Could I just loop them all through?
ericshear26 commentedon Feb 10, 2025
Also, the txdata.py example keeps returning a KeyboardInterrupt error when I run it. The Arduino side keeps outputting "avrdude: stk500_recv(): programmer is not responding" 10 times. I feel like there's not a connection at all.
This is my first Arduino project, and I'm doing a PhD in chemical engineering. I'm not an electrical or software engineer. So I would really appreciate your help.
PowerBroker2 commentedon Feb 11, 2025
The avrdude issue is because the USB port wasn't closed correctly by Python before trying to flash the Arduino. Closing all Python processes and resetting the Arduino should fix that. As for your other question, there's only one way to find out: most of robotics programming is running experimental code and simply seeing how the system responds and moving on from there. But the short answer is yes, you can do a loop to stuff the transmit buffer. Just be sure to keep in mind that there's a limited number of available bytes you can send in one packet...