Stepper Motor Control with Closed Loop - Changing Frequency on the fly

Hello guys,
I have been posted on this forum some time ago. I am a mechatronic engineering student and I am starting a new project where I have to use a stepper motor with a pump module to dispense some liquid. For each stepper motor rotation, x mL of liquid are dispensed. Problem is that I want high accuracy on the volume dispensed. (i.e. 1%) Focus of the project is on the control, not on the stepper model. Moreover, pump module have mechanical tolerances among different parts and stepper can lose steps. So I want to compensate all those problems with the control.

I have succesfully programmed my arduino to give in output the STEP signal, managing the PWM register of Timer 2. This generates a precise frequency for my STEP signal. I have a sensor that close my loop and is telling me what is the actual flow rate. Goal is to integrate this information and continuously adjusting the frequency Timer 2 (I currently set it by OCR2A value) in order to adjust the flow rate towards the desired one.

Do you have any idea how I can dynamically change the OCR2A value at each step dynamically in my void loop? I want a kind of PID control. I read online that if you change the frequency on the fly while your pin is giving an output, it will affect the PWM. Each step you should stop the PWM, changing frequency and then restart the PWM. I am not sure about that. Do you guys have any recommendation or suggestion?

Thanks for whoever will take time to discuss!

You don't need PWM, CTC is sufficient and easier to control.

If your motor looses steps in microstepping mode then you should improve your hardware. Incrementing the step rate will decrease the motor force and thus can not help in overcoming an obstacle.

My frequency is high, around 30/35 kHz. That's why I am using that modality.

I am not actually microstepping. I am using my stepper in full step mode.

D10S:
My frequency is high, around 30/35 kHz. That's why I am using that modality.

I am not actually microstepping. I am using my stepper in full step mode.

How much liquid are you dispensing with a motor that is running at about 9,000 RPM? (30,000 / 200 * 60)

I suspect there is a mix-up somewhere.

...R

Robin2:
How much liquid are you dispensing with a motor that is running at about 9,000 RPM? (30,000 / 200 * 60)

I suspect there is a mix-up somewhere.

...R

That's because you are assuming that my motor does 1.8 degrees per pulse. My motor angle/step is much lower.
Moreover, I have a gear reduction.

D10S:
That's because you are assuming that my motor does 1.8 degrees per pulse. My motor angle/step is much lower.
Moreover, I have a gear reduction.[/color]

So why not put us out of our misery and provide all the details?

It's much easier to provide useful advice when we fully understand the project you are working on.

...R

Robin2:
So why not put us out of our misery and provide all the details?

It's much easier to provide useful advice when we fully understand the project you are working on.

...R

Robin sorry about that. I have tried to give all the info in my first statement. Since I am successfully providing a PWM by setting the timer register, I didn't give info on the motor. My problem is how to adjust the frequency on the fly. In a certain sense this is independent from the motor characteristics themselves

If you want a variable frequency you can use the TimerOne library.

If that does not help you should provide more information.

The PWM key is useless with stepper motors, and Timer 2 does not have a PWM register. That's the first item that you should clarify, as I already told in #1.

Of course you can set OCR2A as long as the new value is higher than the current TCNT2, check that by polling or using an interrupt.

DrDiettrich:
If you want a variable frequency you can use the TimerOne library.

If that does not help you should provide more information.

The PWM key is useless with stepper motors, and Timer 2 does not have a PWM register. That's the first item that you should clarify, as I already told in #1.

Of course you can set OCR2A as long as the new value is higher than the current TCNT2, check that by polling or using an interrupt.

I am actually using and Arduino Mega, so I have 5 timers available.
I don't quite get what you mean when you say that PWM is useless with stepper motor. Stepper Motors need an edge to count to make one step, if that edge is a pulse or the rising edge of a square wave it is kind of same. I am using a PWM done by configuring Timer 3 of Arduino Mega cause it gives me an accurate frequency. Am I wrong?
This is the code I am using for the generation of the square wave:

// set up Timer 3
int myEraserPulses = 7;             // this is 111 in binary and is used as an eraser
TCCR3B &= ~myEraserPulses;   // this operation (AND plus NOT),  set the three bits in TCCR3B to 0
TCCR3A = _BV(COM3A0)| _BV(WGM31) | _BV(WGM30); // fast PWM
TCCR3B = _BV(WGM33) | _BV(WGM32); // 16MHz/8=2MHz 
OCR3A =  36;          // 27 kHz
TCNT3 = 0;
TCCR3B |= _BV(CS31); //start timer

@D10S

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

ballscrewbob:
@D10S

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Sorry about that.

I see at least two problems with your code:

TCCR3B is initialized twice.

Which channel do you use for output, and where do you set its duty cycle?

DrDiettrich:
I see at least two problems with your code:

TCCR3B is initialized twice.

Which channel do you use for output, and where do you set its duty cycle?

I am using pin 5 as output that is based on Timer 3 for Arduino Mega.
With this code my duty cycle is 50%. You can double check copying and pasting the code to an Arduino Mega and checing the output of pin 5 with an oscilloscope.
Anyway duty cycle is not important for moving the stepper while the frequency is.

What I am trying to figure out is how to adjust the value inside OCR3A on the fly. According to my sensor reading that value should change based on the need of slowing down or speeding up the motor.
I assume that OCR3A change should be done within void loop but it hasn't to be a fixed increment/decrement while something proportional to the sensor reading

If you don't accept what I wrote in #7 then I cannot help you. See 17.9.3 Fast PWM Mode and Figure 17-7 on the effect of changing TOP.

DrDiettrich:
If you don’t accept what I wrote in #7 then I cannot help you. See 17.9.3 Fast PWM Mode and Figure 17-7 on the effect of changing TOP.

I am not saying I don’t accept. I just don’t understand what are you trying to say. That’s all…
I don’t get why there is an error in my code while I am successfully generating a square wave. Can you please clarify this aspect?

Your code does strange things, which seem to produce your intended output. We can end this discussion if everything happens to do what you want.

Whoever has been experienced my same doubt:
Changing values of OCRxA during the void loop let you change the frequency on the fly :wink: