Files

  • Not Found
  • Invalid object requested. SHA must identify a commit or a tree.
Last update 12 months 3 days by Stephen Crane
Files
eagle
examples
images
sounds
.gitignore
PWM.md
README.md
TTS.cpp
TTS.h
english.h
keywords.txt
library.json
sound.cpp
sound.h
PWM.md

How PWM is used for TTS

We'll analyze the code for speech output on Arduino pin 9, on an ATMega328. This is hardware pin 15 (known here as OC1A).

A good introduction to PWM can be found ]]>here]]>. This ]]>guide]]> is also useful.

At it's most basic however, a PWM waveform is a square-wave with a varying duty-cycle. The duty-cycle is the ratio of time spent high to the total cycle time. The AVR's built-in timers are used to determine both the frequency and the duty-cycle.

Sound is initialised in soundOn():

```c++ TCCR1A = 0; ICR1 = PWM_TOP; TCCR1B = _BV(WGM13) | _BV(CS10); TCNT1 = 0; TCCR1A |= _BV(COM1A1);

In this mode, known as "PWM, Phase and Frequency corrected", Timer-1 counts up from 0 to PWM_TOP and then back down to 0 again.

The PWM frequency in this mode is given by the formula:

> freq = Clock / (2 x Prescaler x TOP)

Here Clock = 16e6, Prescaler = 1 (set by CS10 above) and TOP = 1200/2. This gives a fixed frequency of about 13kHz.

The PWM duty cycle is changed in sound():

```c++ if (duty != OCR1A) { TCNT1 = 0; OCR1A = duty; }

Here the OCR1A value is used to set the value at which Timer-1's counter causes the output on OC1A to flip: - while it's counting up from 0 (BOTTOM) to OCR1A, OC1A is high, - when it reaches OCR1A it sets OC1A low and counts to TOP (ICR1), - when it reaches TOP it starts counting down again, - when it reaches OCR1A again, it sets OC1A high and counts to BOTTOM (0).

Report a bug