gin66 / FastAccelStepper

A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3 and Atmel SAM Due
MIT License
286 stars 67 forks source link

getQueueLength() ? #112

Closed jhr1972 closed 2 years ago

jhr1972 commented 2 years ago

Hi and many many thanks for the great work you are sharing with the community. Do you envision any function returning the current fill grade of the command queue ? In particular, I do only want to add a command if the queue is either empty or has just one single more task do. I currently see no easy way of checking this. The function isQueueEmpty() is not generic enough.

Thank you, Jhr1972

gin66 commented 2 years ago

Sure. The latest commit add these functions, which should fulfill your needs:

  // functions to get the fill level of the queue
  //
  // To retrieve the forward planning time in the queue ticksInQueue()
  // can be used. It sums up all ticks () of the not yet processed commands.
  // For pauses, the summed up value is entry.ticks.
  // For steps, the summed up value is entry.steps*entry.ticks
  uint32_t ticksInQueue();

  // This function can be used to check, if the commands in the queue
  // will last for <min_ticks> ticks. This is again without the
  // currently processed commands.
  bool hasTicksInQueue(uint32_t min_ticks);

  // This function allows to check the number of commands in the queue.
  // This is including the currently processed command.
  uint8_t commandsInQueue();

The first two only needed to be exposed. The last one is new.

gin66 commented 2 years ago

funny commandsInQueue() has too an existing implementation. So I used that instead:

  // This function allows to check the number of commands in the queue.
  // This is including the currently processed command.
  uint8_t queueEntries();
jhr1972 commented 2 years ago

WOW. That was quick! Will pull and try tomorrow. Thank you

jhr1972 commented 2 years ago

Seems there are some issues with queueEntries(). Pls compare the following snipplets:

         Serial.print("qes premove: ");
         qes = stepper->queueEntries();
         Serial.print (qes);
         stepper->move(-moveIntervall); 
         stepper->move(-moveIntervall); 
         stepper->move(-moveIntervall); 
         delay(20);
         Serial.print(" qes postmove: ");
         qes = stepper->queueEntries();
         Serial.println (qes);

This will result in the following printout: qes premove: 0 qes postmove: 10 However, I would have expected qes premove: 0 qes postmove: 3

If I remove the delay(20) then I get qes premove: 0 qes postmove: 0

I would have thought that every moveTo() statement is one record in the queue that piles up. Is this a bug in the function or to I misunderstand the concept of queues in this context ? Thank you!

gin66 commented 2 years ago

The stepper->move() are not blocking. So this sequence will actually boil down to stepper->move(-3*moveIntervall)

One moveTo are either:

Any step rate lower than 250 Hz will require pauses between steps. In addition a move() will implement acceleration/deceleration, which results in several queue entries.

How many queue-entries have been created after a complete move, you cannot see, because the max number of reported commands will be 31.

I would expect after delay(20) you will have qes premove: 0 qes postmove: 0 and not immediately after the move().