20Hz Square Wave on the Uno

I am working on a project for school and I need to generate a 20Hz square wave in which I can adjust the duty cycle based on an input. I have tried using the Timer1 library, as I chose pin 9 as my output. I could really use a point in the right direction. If you need any additional information, I can supply it.

Read the processors data sheet that will put you in the right direction. However how accurate does the 20Hz need to be? You can not get accurate frequencies using the raw division ratios . You might need to generate an interrupt driven system where you cha he the timer on each half cycle to get full duty cycle control.

I am trying to drive a treadmill motor and it is quite particular about the signal that it receives in order to run and it only seems to like anything that is in the 20Hz range. Not 19, not 21. Just 20. So it needs to be pretty accurate.

#include "TimerOne.h"

void setup()
{
  
  pinMode(10, OUTPUT);
  Timer1.initialize(50000);     // initialize timer1, and set a 1/2 second period
  Timer1.stop();
  Timer1.restart();
  Timer1.pwm(9, 512);                // setup pwm on pin 9, 50% duty cycle
}

void loop()
{
  // your program here.
  digitalWrite(10, HIGH);
}

This is what my current code looks like. I just modified the example that came with the Timer1 library, and was hoping it would just be that simple, but it is turning out to not be so.

Uggro:
I need to generate a 20Hz square wave in which I can adjust the duty cycle based on an input.

Twenty hertz? Use blink-without-delay with an interval of 50000 microseconds. The duty cycle is a percent of 50000. micros has a granularity of 4 microseconds which gives you 12500 steps. You will have about 100 microseconds of jitter (0.2%) from the timer 0 interrupt service routine and other overhead.

Uggro:
... need to generate a 20Hz square wave in which I can adjust the duty cycle...
... tried using the Timer1 library ...

I think that the TimerOne library will support a very nice 20Hz square wave, with a variable duty cycle, and a resolution of one part in 1024.

If you need any additional information, I can supply it.

Please supply it.

  • Did you use the TimerOne library accessible from this page: Arduino Playground - Timer1 ? If not, you'll want to include a link that points to the library you used.
  • What did you try? Post code, please, using code tags.
  • What did you expect it to do?
  • What did it do?

Using blink without delay you can achieve 20.0008 +/- 0.0004 Hz, maybe 20.00008 +/- 0.00004Hz.
Easy for a user to change the duty cycle that way too.
Review my posts from yesterday or the day before, I'm not gonna type it out again tonight.

Using the Original Poster's code as posted, I got an excellent 20Hz signal from pin 9. I don't know what didn't work.

TimerOne uses the Phase and Frequency Correct mode, in which the centers of the output pulses are separated by the signal period. It's possible that the treadmill motor is so sensitive that it doesn't like that signal, and would prefer to see the rising edges of the signals separated by the signal period. That would be sensitive indeed, for a gizmo like this.

What went wrong using this code?

CrossRoads:
Review my posts from yesterday ...

I think it's this one: Not able to generate continous pulse using delay in microseconds and in millisec - #3 by CrossRoads - Programming Questions - Arduino Forum. That technique allows for a constant leading-edge-to-leading-edge period.

So, apparently the problem was that I was using bad cables and they were adding extra noise to my signal. Decided to swap out the cables and it works exactly as it should have. Thank you very much for your responses.