| ||
Shopping Cart Download Website |
Home | Products | Teensy | Blog | Forum |
You are here: Teensy Teensyduino PWM & Tone |
|
Pulsed Output: PWM & ToneTeensy can output pulses digital signals that are useful for many projects.Pulse Width ModulationPWM creates an output with analog-like properties, where you can control the intensity in fine steps, even though the signal is really a digital pin rapidly pulsing.
PWM is controlled with the analogWrite(pin, value) function. analogWrite(3, 50); analogWrite(5, 140);Here are the actual waveforms this code creates on pins 3 and 5:
The value is between 0 to 256, where the higher the value, the more time the signal remains high. Values 1 to 255 pulse the pin, referred to in perentage terms as "duty cycle". A value of 128 is 50% duty cycle. Vales 0 and 256 are meant to correspond to logic low and high. However, the PWM hardware may not be capable of truly 100% low or high. A very short pulse may occur between each PWM cycle where the pin is driven to begin a new cycle, and then very quickly changed because the setting attempts to keep the pin always low or always high. To avoid any small glitch pulses, the pin may taken out of PWM mode using pinMode() and then controlled by digitalWrite(). PWM for LED BrightnessPWM is useful for controlling the brightness of LEDs. In this photo, 3 of the LEDs are driven by different PWM signals.
These LEDs are actually blinking very rapidly. Because the blinking happens much faster than the human eye can perceive, and much faster than the camera's shutter time for this photo, the result looks like a LED that is partially illuminated. Most LEDs decrease in efficieny as you approach their maximum output. The human eye is less sensitive to differences between brightly lit objects. As you can see in the photo above, these 2 factors cause the LED with PWM value 120 to appear almost as bright as the right-most LED connected directly to the power. The PWM-driven LED really is using only 47% of the power. When creating animated LED fading, consider changing the PWM value in larger steps when the value is larger, to achieve a more natural-looking result. PWM for MotorsPulse Width Modulation for controlling DC motors. The Teensy pins can not directly power a motor, so a transistor is used.TODO: photo: teensy3, motor, transistor, etc
TODO: schematic diagram, NPN transistor, arrows showing charge and discharge currents TODO: talk about average current, charge and discharge paths and current ramps Filtering PWM for Analog OutputPWM waveforms can turned into analog signals with a low pass filter. The simplest filter uses only a resistor and capacitor, for a very simple and low cost way to obtain an analog signal.
Analog signals from PWM have caveats. If the power supply voltage changes or has noise, perhaps due to other devices that greatly vary in their power usage, the PWM high voltage varies, which in turn becomes a change to the filtered analog output. Choosing the filter involves a trade-off between response speed and removing the PWM frequency. The lower the filter's corner frequency, the more steady the output becomes, but the slower it changes when you use analogWrite(). A more sophisticated filter can offer faster response and cleaner output, but at the cost of more components and complexity. In the tests below, this code was used to create a PWM output which changes between 20% to 78% duty cycle. void loop() { analogWrite(9, 50); delay(250); analogWrite(9, 200); delay(250); }Using a 1K resistor and 10µF capacitor gives a filter which leaves a substantial amount of the PWM frequency, but the output responds quickly when the PWM value changes.
Increasing the capacitor to 47µF results in a much smoother output, but the response is 5 times slower. Even this output has some of the PWM frequency present, so an even slower response would be needed to reduce it further.
A more complex filter can give faster response and smoother output, but such filters usually require opamp chips and many parts. Another approach to smoother output is to increase the PWM frequency, so the filter can more easily remove it. PWM FrequencyThe PWM signals are created by hardware timers. PWM pins common to each timer always have the same frequency, so if you change one pin's PWM frequency, all other pins for the same timer change.
Teensy LC, 3.x, 4.x support the analogWriteFrequency(pin, frequency) function to easily configure the PWM. void setup() { analogWriteFrequency(4, 375000); // Teensy 3.0 pin 3 also changes to 375 kHz } The analogWriteFrequency function has a lower limit of a few Hz. See this conversation for code to reach extremely slow speeds. On all Teensy 3.x boards, the FrequencyTimer2 library may be used to obtain a different frequency (than the FTM0 timer) on pin 5 using the CMT timer. For Teensy 2.0 and Teensy++ 2.0, the TimerOne & TimerThree libraries can be used to control the PWM frequency.
PWM Resolution (Teensy LC, 3.0 - 3.6, 4.0, 4.1)Normally analogWrite(pin, value) is used with the value between 0 to 255, which corresponds to 8 bit resolution. Writing 256 forces the pin always high. Teensy LC &x:w, 3.x support an analogWriteResolution(bits) function, to reconfigure analogWrite.
void setup() { analogWriteResolution(12); // analogWrite value 0 to 4095, or 4096 for high } This function only configures the analogWrite value range, which is mapped to the hardware's capability. The actual resolution available depends on the PWM frequency, where slower frequencies have higher resolution. For example, if you set the PWM frequency to 375 kHz and the resolution to 10 bits, analogWrite will automatically map the 0-1023 values to the available 0-127 range. Your code can write values from 0 to 1023, but groups of 8 consecutive values will produce the same output. To configure both frequency and resolution for matching performance, use the values from this table:
Teensyduino 1.23 and later accept a floating point number with analogWriteFrequency(), so you can set precise low frequencies for optimized PWM resolution. On Teensy LC, the timers operate directly from the main clock generator, so the ideal frequency and PWM resolution do not scale with CPU clock speed, as on Teensy 3.0 - 3.6. On Teensy 3.6, pins 16 & 17 operate from a fixed 16 MHz clock. For these pins, the ideal frequency is one third of the ideal PWM frequency at 48 MHz. ToneThe tone() function is useful for simple audio. It outputs a square wave at the frequency you specify. There are generally 2 ways to use tone:
tone(pin, frequency); // Begin the tone delay(300); noTone(pin); // manually stop it tone(pin, frequency, 300); // Begin a tone which automatically stops Either way, the tone() function returns quickly and your code continues to run while the pin outputs the specified frequency. An example can be opened from File > Examples > 02.Digital > toneMelody. When playing a sequence of tones, sometimes it is easier to start and stop the tone. For other uses, especially output of a beep for user feedback, the automatic stop is very convenient. To connect a speaker, a 330 ohm resistor and 100 µF capacitor are recommended. The negative terminal of the capacitor connects to the speaker.
Teensy 2.0 has a known issue where tone() will not play if you call the tone() function repetitively at high speed, restarting the tone over and over before it can begin. A future version of Teensyduino will correct this issue. As a workaround, do not call tone() again while the previous tone is still playing. Tone uses a timer interrupt. If libraries that use interrupts create excessive interrupt latency, tone's pulsing can be delayed, creating an incorrect frequency. SoftwareSerial and OneWire are libraries known to potentially interfere with tone(). |