SerialTransfer not being accessed · Issue #105 · PowerBroker2/pySerialTransfer · GitHub
Skip to content

SerialTransfer not being accessed #105

Open

Description

@ericshear26

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.

import numpy as np
import pySerialTransfer
from pySerialTransfer import SerialTransfer
import struct

A = 50.0 # amplitude in mm
r = 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 seconds
base_step_angle = 0.031416 # base step angle of stepper motor in radians
gear_ratio = 26.85123967 # gear ratio of gearhead
microstepping = 8 # microsteps per step
interval = 100
deltat = 1/interval # time increment in seconds

numberOfSteps = 1/((base_step_angle/gear_ratio)/microstepping) # microsteps per radian
omega = 2.0*np.pi*f # in rad/s

t = np.linspace(0,T,interval)
z = A*np.sin(omega*t) # mathematical position of linear motion in mm
v = A*omega*np.cos(omega*t) # mathematical velocity of linear motion in mm/s
a = (-A*np.square(omega))*np.sin(omega*t) # mathematical acceleration of linear motion in mm/s^2
d = v*deltat + 0.5*a*np.square(deltat) # linear displacement in mm
delta_theta = d/r # angle that motor moves between z positions, in radians
steps = np.round(delta_theta*numberOfSteps) # number of steps to move between positions
int_steps = steps.astype(int)  # Convert data into integers

link = pySerialTransfer.SerialTransfer('/dev/cu.usbmodem83201', 115200)

while True:
    data = struct.pack('<' + 'i' * len(int_steps), *int_steps) # format data with struct
    size = struct.pack('<i', len(int_steps)) # send data size first
    link.send(size)
    link.send(data)

Thanks in advance.

Activity

  1. PowerBroker2 commented on Feb 9, 2025

    @PowerBroker2
    Owner

    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:

    import numpy as np
    from pySerialTransfer.pySerialTransfer import SerialTransfer
    import struct
  2. ericshear26 commented on Feb 9, 2025

    @ericshear26
    Author

    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'?"

  3. PowerBroker2 commented on Feb 9, 2025

    @PowerBroker2
    Owner

    Idk, it works for me:

    Image

    Did you ignore the warning and try running it anyway?

    Also, you will want to change your code to say this:

    link = SerialTransfer('/dev/cu.usbmodem83201', 115200)
  4. self-assigned this
    on Feb 9, 2025
  5. ericshear26 commented on Feb 10, 2025

    @ericshear26
    Author

    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.

  6. PowerBroker2 commented on Feb 10, 2025

    @PowerBroker2
    Owner

    Why are you packing the struct manually when the lib class can do that for you?

  7. ericshear26 commented on Feb 10, 2025

    @ericshear26
    Author

    You mean struct.pack? Pack is one of the classes in the struct module. I don't see a lib class in struct.

  8. PowerBroker2 commented on Feb 10, 2025

    @PowerBroker2
    Owner

    No, no - SerialTransfer can pack the transmit struct for you using tx_obj() and rx_obj()

  9. ericshear26 commented on Feb 10, 2025

    @ericshear26
    Author

    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.

  10. PowerBroker2 commented on Feb 10, 2025

    @PowerBroker2
    Owner

    Look at an example

  11. ericshear26 commented on Feb 10, 2025

    @ericshear26
    Author

    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?

  12. ericshear26 commented on Feb 10, 2025

    @ericshear26
    Author

    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.

  13. PowerBroker2 commented on Feb 11, 2025

    @PowerBroker2
    Owner

    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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions