Most efficient code to generate pwm

I want to generate my own PWM signal because the analogWrite() function is slow to write to for some reason and I want to be able to write to it every loop so it starts to tank my loop frequency.
I've created this code and put it in a timer interrupt but I was wondering if there is a more efficient way to do this as it still slows my code down more than I would like.
Edit: I'm using a Nano

  //This runs at 50kHz
  byte pwm; //Changes the pulse width

  pwmFunc() {
    static byte pwmCount;
    pwmCount++;
    if (pwmCount < pwm or pwm == 255) {
      PORTB = B00000010;
    }
    else {
      PORTB = B00000000;
    }
  }

With some limits the Arduino has hardware PWM outputs, you can set them and forget them, no software overhead unless you need to change them. Look as some of the LED dimming applications for the Arduino they will give you the code etc on how to control the PWM. Same for motors.

I'm not sure I understand correctly. I'm trying to use this for motor rpm control. Set and forget doesn't seem right for that, unless I misunderstood.

Obvsly pwm is a global determine the duty cycle.

But that doesn’t matter. Seems like a counter/timer thing to me.

What board does this run on? I see you are getting 50kHz loop attention?

Do you have another free running loop counter it would be slightly cheaper (maybe) to borrow a byte from?

a7

No timer interrupt driven PWM will ever be faster than the timer PWM via compare register. I wrote some low level PWM code for the STM32F103. All I did, is set up the timer registers to enable PWM at the desired frequency, after that, a simple write to the compare register would set a PWM value immediately. So the PWM can be changed as fast as I can write a byte (but it's buffered by the timer, so in practice you can't change it more than once per cycle). I suggest that you could probably do the same thing with analogWrite(), once you call it, just find the right compare register and write directly to it.

It's cheesy but it works.

2 Likes

How much inertia does your motor have? At 50kHz, one PWM cycle lasts 20us. What kind of motor would be able to respond to speed changes at that rate? None that I have ever seen! That is why it can be set and forget.

Check this link: low frequency pwm possible?. It will do a better explanation then I can. Doing it this way your PWM frequency will not change each time your loot time does.

There is no motor in question.

@confusedpotato34 what is the PWM signal controlling?

a7

A motor driver which controls a hydraulic valve which controls a hydraulic motor

I'm already using the 50kHz timer for my code so im guessing its probably more efficient to just use it

I think I'm gonna look into this option

You are in control of your own designs. If you think a 50kHz interrupt is necessary for your motor control project, then use it. Some doubts about that have been voiced in this thread, and you didn't respond. To me, that indicates that you might not agree, or don't care. So go and try some different things, come back when you have actual code to show.

I don't think I need the 50kHz interrupt for PWM, but I do need it for other aspects of my code. (Using an LCD display and the code has to keep running even when the display is updating) I believe I could go down to a 20hz PWM output before the motor would jitter. I'm not sure what code you want me to show since none of my code is relevant to this discussion other than my actual PWM code.

Actually, you introduced the relevance in your first post, when you complained that your loop() time was too slow.

Also, you still have not really responded to any of the ideas in this thread.

Again, please go finish a complete working sketch, come back if you have any problems.

Also, you have no "actual PWM" code. You only have hypothetical PWM code.

Ok so my PWM sketch works, you can go put that on a board and it will run. I just want it to be more efficient. That's all I was asking. You mentioned compare registers and I'm looking into that. Thank you for telling me about that, That was very helpful. That's why I haven't responded to other concerns. They no longer apply because you have given me the help I needed.

It's on a Nano, sorry I should have given that info.

Then please run some tests that yield numerical benchmarks and post the results.

Yeah that's what I'm doing. Right now I'm reading up on compare registers so that I can test them

Confirm: 50,000 Hertz.

?

a7

Here is a good article on how to properly use PWM: Secrets of Arduino PWM