Go Down

Topic: Arduino and Python - Problems with Delay/Sleep (Read 316 times) previous topic - next topic

BrainFreeze

Hello,

I am using a Arduino Mega with Python and PyFirmata. Right now, I want to control a stepper Motor using a Pololu TB67S279 driver. I can control it and set the stepper a defined amount of steps. No complications so far.

The problem I have is with the delay between each step pulse to the stepper. I know, that Pythons time.sleep() is dependend on the platform it is running on. In my case, this is Win10 and I can't get a delay shorter than 10 milliseconds (time.sleep(0.01)). Therefore, the stepper is moving quite slowly.

My example code is:

Code: [Select]

// Code to turn the stepper one round clockwise slowly, then 2 rounds counterclockwise fast

import pyfirmata
import time

port = 'COM3'
board = pyfirmata.ArduinoMega(port)
time.sleep(3.0)
it = pyfirmata.util.Iterator(board)
it.start()

direction = board.get_pin('d:8:o')
clk = board.get_pin('d:10:o')

steps_per_round = 200

while True:
    direction.write(1)
    for i in range(0,steps_per_round):
        clk.write(1)
        time.sleep(0.02)
        clk.write(0)
        time.sleep(0.02)
   
    time.sleep(1)
    direction.write(0)
    for i in range(0,2*steps_per_round):
        clk.write(1)
        time.sleep(0.01)        // <-- minimum sleep time, I can succesfully use!!!
        clk.write(0)
        time.sleep(0.01)

    time.sleep(1)
   

board.exit()



If I write the same thing in Arduino, it can go much faster:

Code: [Select]

// Define Constants

// Connections to Driver
const int dirPin = 8;
const int stepPin = 10;

// Motor steps per revolution
const int STEPS_PER_REV = 200;

void setup() {

  // Setup pins as output
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

void loop() {
  // Set motor direction clockwise
  digitalWrite(dirPin, HIGH);

  // Spin motor one direction slowly
  for(int x = 0; x < STEPS_PER_REV; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(2000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(2000);
  }

  // Pause for one second
  delay(1000);

  // Set motor direction counter clockwise
  digitalWrite(dirPin, LOW);

  // Spin motor two rotations quickly
  for(int x = 0; x < (STEPS_PER_REV * 2); x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1000);          // usable without problems and much faster than in Python
    digitalWrite(stepPin, LOW);
    delayMicroseconds(1000);
  }

  // Pause for one second
  delay(1000);

}




Now my question is: is there ANY way, to make the stepper go faster using Python? Is there a Python library, function, code or anything I could use? Can I modify the StandardFirmata protocol or the pyFirmata library to get shorter delays? Any help would be really appreciated!

I really need to use Python instead of directly using the Arduino IDE, because my stepper has to run in sync with other measurement devices that I control via GPIB and, you guessed it, Python.

Robin2

Now my question is: is there ANY way, to make the stepper go faster using Python?
You should not be trying to do the step timing with Python. Leave that job to the Arduino.

Your Python program could send a message to the Arduino something like <375, 5000> meaning move 375 steps with 5000 microsecs between each step.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

Also this Python - Arduino demo may be of interest.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

BrainFreeze

Thank you very much! I had seen both tutorials before, but somehow got stuck on using pyFirmata. I changed my whole code based on your examples and am now able to move my stepper by telling him <direction, steps, delay> and parsing this data.

I still have one problem I could not figure out by myself until now. I want to use the stepper for a measurement system, where I move the stepper, measure (via GPIB), move the stepper, measure and so on. But I can't get the timing right. Instead of stepping and pausing (to do the measuring) consecutively, my stepper goes on without interruption, although my python code is basically:

Code: [Select]

runStepper(steps_forward)  # sends <direction,steps,delay> to Arduino

performMeasurement()  # get measurement data


time.sleep() doesn't work here, because this stops the python script from doing stuff if I'm not mistaken. And including a delay() in my .ino file doesn't seem to be a good solution either.

Do you have any idea how to fix this or just a hint, how I could try it?

Robin2

Do you have any idea how to fix this or just a hint, how I could try it?
Not without more information - perhaps the Arduino program.

I wonder if the Arduino needs to send a message to the PC to tell it when a move has completed?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

Not without more information - perhaps the Arduino program.

I wonder if the Arduino needs to send a message to the PC to tell it when a move has completed?

...R
That would make sense else one would be making a measurement even though the move has not completed.


.

BrainFreeze

Not without more information - perhaps the Arduino program.

I wonder if the Arduino needs to send a message to the PC to tell it when a move has completed?

That would make sense else one would be making a measurement even though the move has not completed.
Yes, that was exactly it! Implemented that function and everything is working now!

Thank you very much, you have helped me a lot!


Go Up