1

I'm using a PWM port and outputting a freq. Is it possible to pulse the PWM port using software to simulate a pulse gate. For example, I'd like to output a freq of 111hz, but would like to gate that freq at .5-7hz. Is this possible to do all in software without external hardware. I'm using a Teensy board which is similar to an Arduino, but has 3 independent PWM ports. Any ideas on whether this possible?

5
  • PWM is not for outputting different frequencies, but for outputting a square wave of a fixed frequency with different duty cycles. And it's not clear, what do you mean by "gate that freq at .5-7hz" What exactly you are trying to achieve?
    – chrisl
    Commented Aug 5, 2018 at 15:49
  • You could use one timer for the 111Hz and another timer with interrupt. In the interrupt turn the other timer on and off. It is even possible to use the tone() for 111Hz and millis() in the loop() to create that .5 to 7Hz. Can you explain what this is for? Is it a modulated 111Hz? How accurate should it be?
    – Jot
    Commented Aug 5, 2018 at 15:55
  • Yes, I understand fully what the PWM port does and how it works and have been using it for years =) What I’m trying to achieve is how to change the shape of the freq by adding a controllable gate on the PWM port in software. I can do this by outputting the PWM freq into a collector of an 2N3904 transistor and drive the base of the transistor w/ another PWM acting has the gate freq and the emitter will have the newly shaped freq which seems to work, but would like to do it all in software using a timer on the PWM port. Is this possible?
    – Wildview
    Commented Aug 5, 2018 at 16:05
  • btw, this is for a brain tuner circuit I'm building. The brain is stimulated at freqs of 111Hz and 1110HZ, but pulsing the freq slightly w/ a controllable gate will alter the shape to create different types of stimulation modes. This is what I'm trying to achieve using the freq gate on the PWM port. The accuracy should be as close as possible. Once the wave form is created, it will be put through another circuit that includes a transformer to create the final output signal. If I can do the gating in software that would be really cool =) Tnx for your help.
    – Wildview
    Commented Aug 5, 2018 at 16:16
  • Jot 23, do you know of any good code examples using a timer interrupt on a PWM port to achieve what I'm looking for? Currently, I have 2 PWM ports 1 at running at 111Hz and 1 running at 1110Hz and both need a controllable gate of 5. to 7Hz applied to it. If the timer interrupt would be fast enough to work, that would be neat since I'd like to do this all in software if possible. In theory it should work. The Teensy v3.2 is a fast processor.
    – Wildview
    Commented Aug 5, 2018 at 16:27

1 Answer 1

1

If you can configure the PWM to run at 111 Hz (I don't know how this is done on the Teensy), then “gating” it is as simple as turning the PWM on and off at the desired frequency:

uint32_t half_period;  // half the gating period in microseconds

void set_gate_frequency(float freq_in_hz)
{
    half_period = (1e6 / 2) / freq_in_hz;
}

void loop()
{
    static uint32_t last_toggle = 0;
    static bool pwm_is_on = false;
    if (micros() - last_toggle >= half_period) {
        if (pwm_is_on) {
            digitalWrite(PWM_PIN, LOW);
            pwm_is_on = false;
        } else {
            analogWrite(PWM_PIN, 128);  // PWM with 50% duty cycle
            pwm_is_on = true;
        }
        last_toggle += half_period;
    }
}
4
  • Thank you, I will try that. I assume this is possible to put into a timer interrupt routine as well, is that correct? So I can separate it from the loop function. For reference on a Teensy this is how you would configure a PWM port to output a frequency. analogWriteResolution(8); // 187500Hz resolution analogWriteFrequency(pwmPin,FreqHz); analogWrite(pwmPin,dutyCycle);
    – Wildview
    Commented Aug 5, 2018 at 18:30
  • @Wildview: Yes, you could use an interrupt. However, for such low frequencies, you don't need to. Doing this in loop() should work just as well, and you can add whatever else you want to the same loop(). That is, it will work well unless you do something wrong like using delay()... Commented Aug 5, 2018 at 18:52
  • Thanks. I noticed in looking at the waveform running your example. There is no change to the frequency even w/ a gate freq of 50hz. It appears the digitalWrite is not working correctly to set the pin low. If I changed the digitalWrite to this analogWrite(PWM_PIN_PIN, 0) it looks like it's pulsing now. I have a 1K pull up on that port a well. Does the analogWrite(PWM_PIN_PIN, 0) have the same effect as the digitalWrite would?
    – Wildview
    Commented Aug 5, 2018 at 19:12
  • On the AVR core, digitalWrite() turns off any ongoing PWM. Maybe it doesn't do that on the Teensy, I don't know. analogWrite(PWM_PIN, 0) should do the same. If it works for you, keep it. Commented Aug 5, 2018 at 19:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.