Problems by using Timer to generate a PWM signal in arduino

At first im a beginner in programming especially in Arduino.

The goal of my project is to drive a motor with 2 PWM signals. One for driving forward and the other one to drive backwards. So im trying to generate these PWM Signals with some Timer functions of the DueTimer.h, because im using the Arduino Due.

The problem is at the beginning it generates the PWM Signal but after it starts running the commands of the loop() it only creates a constant voltage. I have tried many diffrent variations of the code and sometimes it works and after changing one little thing that doesnt change the idea of the code it wont work anymore.

I think either its the header-file or maybe the interrupt-methods. Is there any other header-file I could use? It neiher works without interrupt-methods.

Thanks in advance!

Here is my Code: (only one PWM Signal)

#include <DueTimer.h>

int hSide=5;
int lSide=6;

void setup() {
 pinMode(hSide, OUTPUT);
 pinMode(lSide, OUTPUT);
 //pinMode(4,OUTPUT);
 //digitalWrite(4,HIGH);
 Timer3.attachInterrupt(ISR3).setPeriod(500);
 Timer4.attachInterrupt(ISR4).setPeriod(500);
 Timer3.start();
}

// Testing duty cycle
void loop() {
  delay(2000);
  for (int i = 1; i <= 1000; i++) {
    noInterrupts();
    Timer3.setPeriod(i);
    Timer4.setPeriod(1000 - i); 
    interrupts();
  }
}

void ISR3(){
  // High side on (Port 2)
  digitalWrite (hSide,HIGH);
  //digitalWrite(lSide,LOW);
  Timer3.stop();
  Timer4.start();
}

void ISR4() {
  // Low side on (Port 2)
  digitalWrite (hSide,LOW);
  //digitalWrite(lSide,HIGH);
  Timer4.stop();
  Timer3.start();
}

PWM (Pulse Width Modulation) has two parameters, pulse period and pulse width.

The (relative) pulse width is what exerts motor control, or sets the average voltage.

Yes i know but im generating the pulse width with the proportion of the High and low time of the Pin. But still the code dont work. You have any idea why? Im struggeling with this problem a loong time now.

Not that I can see, and that library doesn't even offer a PWM control option. Are you trying to follow a tutorial, or just making this up as you go?

Why not use the built-in analogWrite() to generate PWM for motor control?

Thank you for your answer.

Okkay im trying to explain what my goal was.
I am using 2 Timers to generate a pwm signal.
It works for the first 2000 ms with a duty cycle of 50 %. The first Timer starts counting until 500 ms and then it stops counting and sets the Output on high.
Then the other Timer starts counting and after 500 ms it sets the output again to low.
But in the loop it wont work anymore because im changing the cycle duty every 2 seconds.
And yes you are right i confound the duty cycle with the pulse width. But the pulse width should be the input of the setperiod()-method of Timer 3.

To your Question:
No I know it dont offers a PWM control option but i am trying to implement the signal by myself to learn more. I actually dont know the analogWrite-method i will look it up.

Hi

Main problem of your code that the "for" cycle in your loop run much often then timers period, so the interrupts haven't chance to fire.
What is the purpose of this cycle? It is not needed for PWM generation.

PS I'm sure I already saw your code 2-3 days ago and wrote exactly the same comment... have you re-registered?

Oh yes you right i have to add a pause() in the loop. But thats not the main issue. It wont work neither without the for-loop. I have tried it with

void loop() {
  delay(2000);
  noInterrupts();
  Timer3.setPeriod(700);
  Timer4.setPeriod(300); 
  interrupts();
  delay(2000);
  noInterrupts();
  Timer3.setPeriod(300);
  Timer4.setPeriod(700); 
  interrupts();
  }
}

So you have any idea what the problem could be? On another platform someone said that the signals extinguishe themself but i dont understand why.
I have never got any response for my problem so i think you confound the code.
But thanks for your help

Try delete all from loop() and test.

Just empty loop

void loop()  {}

Then it works. But i have to change the duty cycle in my code so the loop needs to work.
What's really weird is that

void loop() {
  delay(2000);
  Timer3.setPeriod(700);
  Timer4.setPeriod(300); 
  delay(2000);
  noInterrupts();
  Timer3.setPeriod(300);
  Timer4.setPeriod(700); 
  interrupts();
  }
}

works.

I don't quite understand - does it work or not?

the code on post #8 dont work. The empty loop works. And the last code works but i deleted the noInterrupts() and snterrupts() method before the first change of the period.

I dont know this library well... try to stop the timer before changing it period. And remove noInrerrupts() and interrupts() at all.

1 Like

I am not sure if its possible but i can try it. Because i think that then the duty cycle wont be right anymore. The problem is I am home and my system is in the lab so i cant test it right now. But i will the next days.

That code is setting the period. There is a separate register (the compare register) for the duty cycle, on each timer. The library you are using does not appear to offer that option.

But i can see on an oscilloscope that the duty cycle is changing. But i think i wont get this code work so do you know any other library for an arduino due? My Goal is to control the motor with a remote control. So I need a PWM signal to drive forward and another one to drive backwards. And depending on the duty cycle , the speed of the motor should be regulated.

Then why have you not tried analogWrite()?

The direction of rotation is independent of the PWM speed control.

If you want help with a PROJECT, post the details of the PROJECT.

@jremington
no, OP specifies two periods in its code. Two periods, one for high level and other for low, are actually what is called PWM. The ratio of these periods gives us duty ratio

With two different timers.

One timer is all you need to generate a PWM signal, with constant period and variable duty cycle. As done by analogWrite().

I'm done here, so good luck with your project!

Yes, i know :slight_smile: I know that pwm on hardware timers is easier and more efficient.
But, as i see, OP do it for educational purposes

Thanks for your help I will try to use analogWrite(). I think i wont get this code work but it would be nice to know what I have done wrong.