0

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)
  • This page discusses some of the issues with trying to use a Linux device for "real-time" tasks and the associated problems. https://www.raspberrypi.org/forums/viewtopic.php?t=62820 – William Jun 28 '21 at 22:03
  • Typically you would want a microcontroller device (without a heavy Linux OS) doing the real-time tasks (i.e. motor steps) and just use the raspberry-pi to tell the microcontroller where to move to. I understand this is probably not your goal, but that's the reason it's typically done that way. – William Jun 28 '21 at 22:04

1 Answers1

0

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.

jmklam
  • 135
  • 6
  • Is it possible to seperate a cpu core which only stands in for the hardware control? Somethink like Beckhoff does with their TwinCat PLC system. – Jarne De Clercq Jun 29 '21 at 11:44
  • Reserving cpu cores for processes is known as [processor affinity](https://en.wikipedia.org/wiki/Processor_affinity). [This answer](https://stackoverflow.com/a/51127149/7543727) shows one way to pin a process to a core in Python, and [here's another](https://stackoverflow.com/a/9079117/7543727) for Linux. However, you'll still run into timing issues since Python is an interpreted language and speed is not typically its strong suit. – jmklam Jun 29 '21 at 16:26