DasenB / PicoStepper

A Library to drive stepper motors using the Raspberry Pi Pico (RP2040)
GNU General Public License v3.0
20 stars 4 forks source link

Problem when only executing a single step #6

Open DasenB opened 8 months ago

DasenB commented 8 months ago
          The issue seems to be related to the DMA transfer completing before the PIO has a chance to process the command when there's only one step. This might be due to the DMA and PIO running at different clock speeds, or it could be a timing issue related to how the DMA and PIO are synchronized.

Originally posted by @pedrorovi in https://github.com/DasenB/PicoStepper/issues/5#issuecomment-1952252028

DasenB commented 8 months ago

Currently there seems to be a problem that for very short actions the DMA seems to finish before the PIO is ready. To circumvent this a delay of 100µs has been added between the start of the PIO and the start of the DMA transfer. A better solution without an artificial delay would be nice.

src/picostepper/picostepper.c

    dma_channel_set_read_addr(psc.devices[device].dma_channel, &psc.devices[device].command, false);
    psc.devices[device].is_running = true;

     // Add a delay before starting the DMA transfer
    sleep_us(100);      //          <--  HERE

    // Start the DMA transfer
    dma_channel_start(psc.devices[device].dma_channel);
pedrorovi commented 8 months ago

I only used the picostepper_move_async and is added in the same moment, before the dma channel start. I can add it to picostepper_move_blocking, aswell.


   // Set read address for the dma (switching between two buffers has not been implemented) and start transmission
    dma_channel_set_read_addr(psc.devices[device].dma_channel, &psc.devices[device].command, false);
    psc.devices[device].is_running = true;

    // Add a delay before starting the DMA transfer
    // sleep_ms(1);
    sleep_us(50);

    // Start the DMA transfer
    dma_channel_start(psc.devices[device].dma_channel);

    dma_channel_wait_for_finish_blocking(psc.devices[device].dma_channel);
``
DasenB commented 8 months ago

It probably is a good idea to have a consistent behavior for both blocking and non blocking actions.

DasenB commented 8 months ago
if(steps < 10) {
 // Add a delay before starting the DMA transfer 
   sleep_us(100);
}

Do you think something like this might work to improve reactivity for larger steps counts? Or might it be possible that the first 10 steps are always missing but on step counts like 1000 it is just harder to notice?