Pages: [1]   Go Down
Author Topic: PWM at Low Frequencies (.12 Hz-10 Hz)  (Read 4494 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone!

I have been trying to use the Arduino Uno to create square pulses at the following frequencies, 10Hz, 5Hz, 1Hz, .5Hz, and .12Hz using PWM. I’ve been using Timer1 in CTC mode with a 1024 (1562Hz) prescaler.

The problem is that as I lower the frequency, the waveforms I see on the oscilloscope looks less and less like a square wave. 10Hz, 5Hz, and even 1Hz produces a square wave that produce square waves where the bottom and top of the waveform has a slope and is not flat. The .5Hz and .12Hz waveforms are unrecognizable and almost seem sporadic. I’ve tried different combinations of OCR values and prescalers in Timer1 but no I have seen no real improvement.

Are there any suggestions on how to produce a clean square waveform at these lower frequencies? This is being used as apart of a scientific instrument so it is important that the signal is clean and reliable.

The code is below:



Thanks so much for your help!!


Code:
int ledPin = 10; // sets pin 10 to output the same value at the ledPin output
int blinkPin = 9; // set pin 9 to output the same value as the output timer which is the blinkPin

void TimerOne_setPeriod(long OCRValue)

{
  TCCR1B = _BV(WGM12)|_BV(CS12)|_BV(CS10);   // CTC mode - 1024 prescale
                                             //  TCCR1B = _BV(WGM12)|_BV(CS12)|_BV(CS11)|_BV(CS10); is the entire command but since CS11=0 its left out
                                             //  manipulates prescale (one of the parameters we can manipulate**we want to use prescales that yeields high ORC values for more reliable signals
  TCCR1A = _BV(COM1A0);                      //  or use TCCR1A = 0x40;            // Toggle mode 0C1A  
                                             //  This is used to toggle on pin 11 ** pin 11 = 0 x 1 so COM(COM1A1) = 0 and is not in code
                                             //  **Determines pin behavor
  OCR1A = OCRValue;                          //  set the counter
}

void setup()
{
  pinMode(ledPin, OUTPUT);                   //  Makes ledPin is the output
  pinMode(blinkPin, OUTPUT);                  // turn on the timer ouput pin and it also the input;
  TimerOne_setPeriod(15625);                 // set up and start Timer1 to blink at the same rate as the blink sketch
                                            /* Insert the follwing values into the TimerOne_setPeriod() here for the following frequencies:
                                             .12 Hz: 65104.16667
                                             .5 Hz: 15625
                                             1 Hz: 7812.5
                                             5 Hz: 1562.5
                                             10 Hz: 781.25
                                             */
                                            
                                        
 }
                                          
                                            

void loop()
{
  digitalWrite(ledPin, LOW);                 // set the LED on
  delay(1000);                               // wait for a second
  digitalWrite(ledPin, HIGH);                // set the LED off
  delay(1000);                               // wait for a second
}

 
Moderator edit: [code] [/code] tags added.
« Last Edit: January 06, 2013, 04:07:08 am by Coding Badly » Logged

Montreal
Offline Offline
Faraday Member
**
Karma: 27
Posts: 2565
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
//  This is used to toggle on pin 11 ** pin 11 = 0 x 1 so COM(COM1A1) = 0 and is not in code
Timer1 PWM pins 9 and 10. Is there a reason not to use Tone library?
http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
Looks like it has same 1/8 Hz lower minimum freq. on 16-bit timer.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12744
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Are there any suggestions on how to produce a clean square waveform at these lower frequencies?

I have a sneaky suspicion that the problem has nothing to do with your code or the Uno.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17261
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Are there any suggestions on how to produce a clean square waveform at these lower frequencies?

I have a sneaky suspicion that the problem has nothing to do with your code or the Uno.


As I suspect all along, it is the work of the illuminati !

Lefty
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13482
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I have been trying to use the Arduino Uno to create square pulses at the following frequencies, 10Hz, 5Hz, 1Hz, .5Hz, and .12Hz using PWM.

As these frequencies are quite low, why not with using "blink without delay"

Code:
unsigned long duration = 100;  // in millis  -- 100, 200, 1000, 2000, 4000 == 10Hz, 5Hz, 1Hz, .5Hz, and .125Hz
unsigned long lastFlip=0;
int state = LOW;

void setup()
{
  pinMode(7, OUTPUT);
  digitalWrite(7, state);
  Serial.begin(115200);
}

void loop()
{
  unsigned long now = millis();
  if (now - lastFlip >= duration)
  {
    lastFlip = now;
    state = !state;
    digitalWrite(7, state);
  }
}

Or try my PulsePattern library - http://arduino.cc/forum/index.php/topic,139407.0.html - which is timer driven
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1328
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Are there any suggestions on how to produce a clean square waveform at these lower frequencies?

I have a sneaky suspicion that the problem has nothing to do with your code or the Uno.


 I wonder what would have the capacity to change a waveform... What in the world could perhaps induce resistance to voltage change....
Logged


0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3470
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You might try my code http://blog.blinkenlight.net/experiments/measurements/flexible-sweep/ here. It is completely tested down to 0.0001 Hz. If your issue persists with my code then your issue is caused by your circuit and not by the code.
Logged

Check out my experiments http://blog.blinkenlight.net

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17261
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Assuming you want a 50%/50% square wave output I would just load up the MStimer2 library and have it's ISR just flip the output pin each time it's called. So I would just set the timer to interrupt at the millisecond value that corresponds to one half the period time of the desired frequency you wish to use. To change the frequency just
stop the timer interrupt, issue a new set timer interrupt with the new time value then do another start timer interrupts. Simple and low overhead I would think?

http://www.pjrc.com/teensy/td_libs_MsTimer2.html

Lefty
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12744
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I wonder what would have the...

 smiley-lol
Logged

Denmark
Offline Offline
God Member
*****
Karma: 15
Posts: 654
Please don't send questions as PM!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I cannot see why a lower frequency would alter the logic level on the output - try looking at the probe on the scope, it sounds like it's set to AC coupling!!

// Per.
Logged

Pages: [1]   Go Up
Jump to: