I am trying to make a universal steppermotor driver for a raspberry pi (raspberry pi OS) in Python. When the dirivermodule (physical device connected to the steppermotor) recives a pulse, the stepper rotates one step (with microstepping 1600 steps per revolution). The pulse is controlled by the RPI.GPIO module). To control the speed i use the builtin 'time' module to set a delay between pulses. Here is my problem: the speed is not accurate, and high speeds are not possible. I dont thing it has anything to do with an overflow. My guess is that I reached the limits of the time module, can anyone confirm this? Here is the code I used:
def run(self, speed: float, rotations: float, direction: Direction = Direction.CLOCKWISE) -> None:
"""
Start stepper motor signal.
:param speed: Motor speed in RPM.
:param rotations: Amount of rotations motor turns.
:param direction: Set the direction of the motor ('CW' or 'CCW'), default='CW'.
:return: None
"""
steps: int = int(self.spr * rotations)
delay: float = 60/(self.spr*speed)
if delay <= 0:
raise ValueError('Speed cannot be zero or lower.')
elif delay < 0.0001:
raise ValueError(f'Maximum speed in this setup is: {60/(self.spr * 0.0001)} RPM.')
if not isinstance(direction, Stepper.Direction):
raise TypeError('direction must be an instance of Direction')
GPIO.output(self.dir, direction.value)
for _ in range(steps):
GPIO.output(self.pul, GPIO.HIGH)
sleep(delay / 2)
GPIO.output(self.pul, GPIO.LOW)
sleep(delay / 2)
Like others have said, motor control is typically managed by microcontrollers since they can guarantee precise timing. Operating systems like Linux, on the other hand, cannot provide the same timing consistency since it is managing all parts of the OS (networking, drivers, etc.).
So instead of a Raspberry Pi sending commands to energize the stepper motor coils in succession, you could have something like:
[Pi] --Tx/Rx--> [Arduino] --GPIO--> [Stepper Motor]
However, if you really need to control hardware on the OS level, you can look into libraries like pigpio, which offloads the processing to a daemon instead of accessing the hardware on the application level.