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

Extensive analogRead() Operations while Stepper is Running Lead to Erratic Movement #124

Closed MamboJambo42 closed 2 years ago

MamboJambo42 commented 2 years ago

I use this fantastic library to run three stepper motors in parallel. The micro-controller I use is an ESP32 Wrover-B, the stepper drivers are TMC2209, and the motors are of standard Nema 11 Bipolar 1.8deg type. I apply 256x microstepping and the steppers rotate about 13000 steps (~90°) in approx. 1 s in one direction and then in the other.

In my setup, I have a MCP3008 ADC and I'd basically want to read several analog signals at every step of the three steppers to obtain the information "analog sensor value x while stepper n was at position p".

Conceptually, my code works as follows:

steppers[0]->moveTo(pos0);
steppers[1]->moveTo(pos1);
steppers[2]->moveTo(pos2);

while (steppers[0]->isRunning() || steppers[1]->isRunning() || steppers[2]->isRunning())
{
    // stepper loop
    for (int i = 0; i < 3; i++)
    {
        // sensor loop
        int nSensors = 4;
        for (int f = 0; f < nSensors ;  f ++) {

            // read analog signal
            int val = analogRead(pin);
            int stepperPos = steppers[i]->getCurrentPosition();

            // store data
            // ...

        }  
    }     
} 

(I actually don't call analogRead() but use the Adafruit_MCP3008 library, but I don't think that's crucial.) Judging from the README, this seems to be a bad idea in general, since long interrupts should be kept at a minimum for a smooth stepper movement, right?

In my case, every analog read takes about 15 us. My setup works great with nSensors = 2. However, when I increase it to nSensors = 4, the movement of the steppers becomes erratic, that is, sometimes they move smoothly, and sometimes they make a lot of unhealthy noise and seem to skip steps or even freeze.

I'm rather a newbie in stepper motors and micro-controllers, so my basic question is: Is there any way to get around the problem of making extensive analog reads while the steppers are running? Since the ESP32 is a dual-core, could it be possible to run the steppers on one core and do the analog read on the other core? Is there another conceptual approach I'm overlooking?

Or do you think I have a bug in my code or electronics and what I'm experiencing should not happen at all? Again - with the little knowledge I have - I think it is not surprising that I'm running into problems and I don't expect an issue with the FastAccelStepper library but with my setup.

gin66 commented 2 years ago

Thanks for the feedback and extensive problem description. Before I dig into the analogRead() topic on esp32, could you please firstly run two tests and check for the result ?

  1. In order to ensure, that FastAccelStepper alone is OK:
    while (steppers[0]->isRunning() || steppers[1]->isRunning() || steppers[2]->isRunning())
    {
    // stepper loop
    for (int i = 0; i < 3; i++)
    {
        // sensor loop
        int nSensors = 4;
        for (int f = 0; f < nSensors ;  f ++) {
            int stepperPos = steppers[i]->getCurrentPosition();
        }  
    }     
    } 
  2. If first test is OK, perhaps the reason is related to the storage:

    while (steppers[0]->isRunning() || steppers[1]->isRunning() || steppers[2]->isRunning())
    {
    // stepper loop
    for (int i = 0; i < 3; i++)
    {
        // sensor loop
        int nSensors = 4;
        for (int f = 0; f < nSensors ;  f ++) {
    
            // fake analog signal read
            int val = f;
            int stepperPos = steppers[i]->getCurrentPosition();
    
            // store data
            // ...
    
        }  
    }     
    } 
MamboJambo42 commented 2 years ago

Thanks for your quick reply! I ran both the suggested tests and the steppers moved perfectly smooth. In the innermost loop, I actually call readADC of the Adafruit_MCP3008 lib twice since I have two ADCs connected. I looked a bit closer into the wiring of the ADCs and their SPI interface and found out that I wired them wrong (they have to share 3 of the 4 SPI pins). After I fixed this mistake, the steppers move smoothly again! I have no idea why it had an influence on the steppers, but who knows ...

I'm so impressed with your library, as I can run crazy commands while the stepper is operating. That's amazing!

Thank you for pointing me in the right direction, and sorry for the fuss!

gin66 commented 2 years ago

good to hear, that you have fixed the problem. Nice, that you like FastAccelStepper