Getting a 20Hz square wave from PWM pin 11

Dear all.

I'm trying to get 50 pulse train of 20Hz with a Ton of 2.1ms from arduino pin 11. Is it possible?

According to a piece of code I found on the old forum this is what I get. Is this correct from you?

int pulseNumber = 50;          // Number of pulses in pulse train                
double frequency = 20;            //frequency in Hz                              
double dutyCycle = .042;          //duty cycle                                        
unsigned long milliseconds = 10;        //delay between pulse sets                        

int on;
int off;                    
double period;  

#define fastWrite(_pin_, _state_) ( _pin_ < 8 ? (_state_ ?  PORTD |= 1 << _pin_ : PORTD &= ~(1 << _pin_ )) : (_state_ ?  PORTB |= 1 << (_pin_ -8) : PORTB &= ~(1 << (_pin_ -8)  )))
// the macro sets or clears the appropriate bit in port D if the pin is less than 8 or port B if between 8 and 13


void setup() {
  pinMode(11, OUTPUT);          // set outPin pin as output
}

void loop() {
period = (1 / frequency) * 1000000;
on = dutyCycle * period;
off = period * (1-dutyCycle);

  // call Pulse function for n = pulseNumber
  for (int i=1; i<=pulseNumber; i++) {  
    Pulse(on, off);
  }
  
  delay(milliseconds);  // delay between pulse sets
}

void Pulse(int on, int off) {
  fastWrite(7, HIGH);       // set Pin high
  delayMicroseconds(on);      // waits "on" microseconds
  fastWrite(7, LOW);        // set pin low
  delayMicroseconds(off);      //wait "off" microseconds
}

Looks like it will work and will give results accurate to a few microseconds.

johnwasser:
Looks like it will work and will give results accurate to a few microseconds.

thank' s a lot for answering. As I read that the largest value that will produce an accurate delay is 16383: http://arduino.cc/hu/Reference/DelayMicroseconds

I have modified it a bit. Not too much, but I took tOff/4 and then in Pulse function I use four time delayMicroseconds each around 11975usec.

What do you think?

Thank's :slight_smile:

I think you would be much better off using timer 2, that controls pin 11 in PWM mode. The problem with what you have written is that anything else that your arduino code does is going to affect the time of your pulses. Also the time will jitter a bit because of background interrupts. So how important is the accuracy and what else does your system need to do?

Grumpy_Mike:
I think you would be much better off using timer 2, that controls pin 11 in PWM mode. The problem with what you have written is that anything else that your arduino code does is going to affect the time of your pulses. Also the time will jitter a bit because of background interrupts. So how important is the accuracy and what else does your system need to do?

Yes, I'm sorry. In the final sketch I'm going to use pin 11 not pin 7. Pin 7 is used from the sketch I've found on the old forum.

What I've to do is sending a 20Hz 50 pulse train with 2.1ms T-on to an hitec digital servo to move it. Then another 20Hz 50 pulse train with 0.9ms T-on to put it to start position.

After and before that I do other operations. Could you please be more specific? I'm not an expert in pwm programming and this is my first time at it.

Regards.

Have you tried the servo library to see if it causes the servo to do what you want it to?

servo.writeMicroseconds(2100);  
delay(2500);  // Allow time for 50 pulses

servo.writeMicroseconds(900);
delay(2500);  // Allow time for 50 pulses

Thank's a lot.

Not yet. Maybe I will give it a try. But what if I don't want to use the servo library?

Regards.

Then you are a fool, using the servo libary you just set the position and the pulses are generated automatically in the background. Without this sort of programming it will be impossible for you to do anything other than keep the servo in place.

Grumpy_Mike:
Then you are a fool, using the servo libary you just set the position and the pulses are generated automatically in the background. Without this sort of programming it will be impossible for you to do anything other than keep the servo in place.

Thank's a lot all. I will be using an Hitec servo that need a Ton of 2.1ms, T=20ms at 50Hz to go to end position (sorry for error, not 20Hz). And it need Ton 0.9msec to reach start position.

So could I write:

myservo.writeMicroseconds(2100);
delay(1000); // 50 pulse
myservo.writeMicroseconds(900);
delay(1000) //50 pulse

That's all? I will only need to reach start and end position for controlling a lever.

Yes you could.
But also look at the other servo commands, you can just call up a position for it to go to defined in degrees.

Grumpy_Mike:
Yes you could.
But also look at the other servo commands, you can just call up a position for it to go to defined in degrees.

Thank's a lot Mike and John. I only need to reach two positions. Seems pretty simple with servo library,