Você está na página 1de 59

PWM

Prof. Ilton L Barbacena 2012.2

PWM
Modulao de Largura de pulso, ou PWM, uma tcnica para obter sinais analgicos utilizando sinais digitais. Um conversor Digital-Analgico barato; O controle digital usado para criar uma onda retangular, formado por um sinal alternado entre ligado e desligado. Este padro on-off pode simular tenses analgicas entre 5 Volts e 0 volts, alterando a poro de tempo que o sinal esteja alto em comparao com o tempo em que o sinal esteja baixo. A durao do "tempo" chamado de largura de impulso. Para obter diferentes valores analgicos, muda-se a largura de pulso. Se repetir este padro on-off com rapidez suficiente, com um LED por exemplo, o resultado obter o controle da luminosidade do LED; Esta durao do tempo ou perodo o inverso da frequncia de PWM.

2/59

PWM
A tcnica de PWM consiste em manipularmos a razo cclica de um sinal, o duty cycle, afim de transportar informao ou controlar a potncia de algum outro circuito. Com isso, teremos um sinal digital que oscila entre 0v e 5v com determinada frequncia (o Arduino trabalha com um padro prximo a 500Hz). O duty cycle a razo do tempo em que o sinal permanece em 5v sobre o tempo total de oscilao, como est ilustrado abaixo:

3/59

PWM Pulse Width Modulation

Com PWM pode-se obter uma tenso analgica a partir de um sinal digital (DAC), com utilizao de filtros na sada;

4 /59

PWM
A tenso mdia ser:

Onde: V(t) = Vpulsos <=tp V(t) = 0 <= T

para para

0<= t tp < t

A tenso mdia diretamente proporcional ao duty cycle ou ciclo ativo.


5 /59

PWM
Para se obter um conversor digital analgico a partir de um pino digital, basta implementar um sinal PWM e adicionar em sua sada um filtro passa baixa com frequncia de corte menor que a prpria frequncia do PWM.
Supor um filtro RC, onde fcorte = 1 / (2*pi*R*C); Neste caso, deve-se adotar sempre o seguinte:

Quando no necessria obter uma tenso mdia contnua, a implementao do filtro descartada; No caso de resistores de aquecimento ou motores DC o filtro dispensvel, uma vez que estes componentes j atuam como filtros, desde que a frequncia do PWM no seja muito baixa.
6 /59

PWM - DAC

7 /59

PWM com filtro RC

Etapas:

1 Escolhe p/ gerar pulsos 3 duty = 10%

2- Tenso de pico (5V) 4 freq. Do PWM


8 /59

PWM com filtro RC

Duty = 10%
Veja alguns exemplos em: http://ww1.microchip.com/downloads/en/AppNotes/00655a.pdf http://aquaticus.info/pwm-sine-wave http://www.wpi.edu/Pubs/E-project/Available/E-project-042711190851/unrestricted/PWM_Techniques_final.pdf

Duty = 70%

9 /59

PWM com filtro RC

Filtro RC com 2 polos

Sinal de entrada pwm de 19kHz e duty de 70%

Veja o resultado da simulao com um sinal PWM aplicado em utilizando um filtro RC com 2 estgios, para gerao de um sinal senoidal.
10 /59

PWM com filtro LC

Filtro LC com 2 polos

Sinal de entrada pwm de 19kHz e duty de 80%

Veja o resultado da simulao com um sinal PWM aplicado em utilizando um filtro LC com 2 estgios, para gerao de um sinal senoidal. Em no havendo necessidade de obter tenso mdia contnua, utilizase o PWM sem filtros (aquecimento e acionamento de motores), desde que a frequncia do PWM no seja muito baixa. 11 /59

PWM gerado com 555


Controle de Velocidade de motor DC (PWM)
IFPB - Maio - 2012 Componentes fora da PCI:
- Chave reversora (H-H dupla) - Fonte de alimentao - Potencimetro - Motor DC (12V)

Prof Ilton Barbacena

BAT1
12V

M1

R1
1k X1 8

+88.8

Volts

R3
1k

Q1
BD136

rpm

D2
1N4148

D3
1N4148

VCC

Q DC

3 7

C3
100n

X2

SW1
SW -DPDT HH duplo

RV1
42%

CV

U1
555 GND 6

47k

D1
1N4148

TR

TH

x1

A B C

C2
0.1u

X2

C1
0.01u

RV1 Controla a velocidade (PWM) SW1 Controla o sentido de rotao

Nota:

Usar conectores KRE para ligaes da PCI aos componentes fora da PCI (chassis)

12/59

PWM trivial com Arduino


void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); delayMicroseconds(100); // aproximadamente 10% duty cycle @ 1KHz digitalWrite(13, LOW); delayMicroseconds(1000 - 100); }

Esta tcnica tem a vantagem de que se pode usar qualquer pino de sada digital. Alm disso, tem-se o controle completo do ciclo de trabalho e da frequncia. Uma grande desvantagem que quaisquer interrupes ir afetar o tempo, o que pode causar instabilidade considervel a menos que voc se desabilite todas as interrupes. Nesta fonte de PWM difcil determinar as constantes apropriadas para um ciclo de trabalho particular e frequncia, a menos que voc queira contar os ciclos cuidadosamente, enquanto observa no osciloscpio.
13/59

PWM trivial com filtro no Arduino

Implementao do exemplo anterior

14/59

PWM com uso de analogWrite() no Arduino


#define ledPin 5 #define analogPin A3 // Pinos de pwm: 3, 5, 6, 9, 10, e 11 // Leitura de potenciometro, tensao analogica void loop() { val = analogRead(analogPin); // Le ADC: 0 ... 1023 val1= val/4; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); while(!Serial) {}; Serial.println("IFPB - Prof. Ilton"); Serial.println("PWM com analogWrite()"); Serial.println("Plataforma Arduino "); Serial.println("Jan / 2013"); Serial.println(" "); delay(4000); } // sada do PWM // mximo 255 int val = 0, val1=0, val2=1;

if (val != val2) // se houver mudancas { analogWrite(ledPin, val1); // gerar PWM em ledPin Serial.print("ADC = "); Serial.print(val, DEC); Serial.print(" duty = "); Serial.print(100*val1/256, DEC); Serial.println("% "); } val2 = val; } // val varia de 0 a 1023 // val1 varia de 0 a 255

PWM no arduno fcil de utilizar, com a funo: analogWrite(pin, dutyCycle), onde dutyCycle is um valor de 0 a 255, e o pin uma das sadas analgicas (pinos 3, 5, 6, 9, 10, ou 11). A funo analogWrite fornece uma interface simples, mas no fornece qualquer controle sobre frequncia. (Note-se que, apesar do nome da funo, a sada um sinal digital, muitas vezes referenciada como uma onda quadrada.) Provavelmente 59% dos leitores pode parar aqui, e usar apenas analogWrite para PWM, mas h outras opes que oferecem mais flexibilidade.
15/59

PWM com uso de analogWrite() no Arduino

Implementao do exemplo anterior

16/59

PWM com uso de registradores no Arduno


O microcontrolador ATMEGA328, do arduno UNO, possui 3 temporizadores que podem controlar at 6 sadas PWM diretamente, obtendo-se mais controle, do que a funo analogWrite() proporciona. A tabela abaixo resume os timers existentes na linha arduno:
timer
timer0 timer0 timer1 timer1 timer2 timer2 timer3 timer3 timer3 timer4 timer4 timer4 timer5 timer5 timer5

bits
8 8 16 16 8 8 16 16 16 16 16 16 16 16 16

Canal
A B A B A B A B C A B C A B C

Pino no UNO (CI)


6(12) 5(11) 9 (15) 10(16) 11 (17) 3(5) -

Pino no MEGA
13 4 11 12 10 9 5 2 3 6 7 8 44 45 46 17/59

No reset, o bootloader do Arduno configura os timers para uso em PWM pela funo analogWrite (); Os timers so configurados para o modo phasecorrect 8-bit e com o relgio preescaleado por 64. No entanto, o timer0 configurado para o modo fast PWM, para uso das funes millis() / micros().

PWM com uso de registradores no Arduno

Timer output
OC0A OC0B OC1A OC1B OC2A OC2B

Arduino output
6 5 9 10 11 3

Chip pin
12 11 15 16 17 5

Pin name
PD6 PD5 PB1 PB2 PB3 PD3 18/59

Pinos do ATMEGA328 em vermelho relacionados a PWM

PWM com uso de registradores no Arduno


Timers no arduino:
Timer0 Timer0 um temporizador de 8 bits. Na plataforma arduino o timer0 est sendo utilizado para as funes de tempo, como delay(), Millis() e micros(). Se houver alterao nos registradores do uC do arduno, relativo a timer0, isso pode influenciar nas funes de temporizador. Ento, voc deve saber o que est fazendo. Timer1 Timer1 um temporizador de 16 bits. Na plataforma Arduno, a biblioteca Servo usa timer1 do Arduno Uno e timer5 no Arduno Mega. Timer2 Timer2 um temporizador de 8 bits como timer0. A funo Tone() usa timer2. Timer3, Timer4, Timer5: Temporizador 3,4,5 esto disponveis apenas em placas Arduino Mega. Estes temporizadores so todos os temporizadores de 16 bits.
19/59

PWM com uso de registradores no Arduno


O controlador do arduino UNO o AVR Atmel ATmega168 ou ATmega328. Estes uCs so compatveis pino a pino e apenas diferem no tamanho da memria interna. Ambos tm 3 temporizadores, chamado timer0, timer1 e timer2. O Timer0 e timer2 so temporizador de 8 bits, e o timer1 um temporizador de 16 bits. Um timer um bloco de hardware embutido no controlador do arruno e em outros uC. como um relgio, e pode ser utilizado para medir eventos de tempos. A diferena mais importante entre temporizador de 8 bits e 16 bits a resoluo do temporizador: 8bits significa 256 valores e 16bit significa 65536 valores para maior resoluo. O temporizador programado por alguns registradores especiais. Podese configurar o prescaler para o timer, o modo de operao, e muitas outras coisas.

20/59

PWM com uso de registradores no Arduno


Os temporizadores tambm podem gerar interrupes no overflow (final de contagem) como tambm, comparar valores de registradores, quando usados em CCR (capture e Compare); O controlador para a srie arduino Mega o AVR Atmel ATmega1280 ou o ATmega2560. Este semelhante ao ATmega328 do UNO diferenciando-se apenas no tamanho da memria. Estes controladores tm 6 temporizadores. O timer0, timer1 e timer2 so idnticos aos do ATmega168/328. O timer3, timer4 e timer5 so todos os temporizadores de 16 bits, semelhante ao timer1. Todos os temporizadores depende do relgio do sistema. Normalmente, o relgio do sistema 16MHz, mas para o Arduino Pro, 3,3 V, 8MHz. Portanto, deve-se ter cuidado ao escrever funes utilizando os timers. O hardware do temporizador pode ser configurado usando alguns registradores especiais da CPU. No firmware do arduno todos os temporizadores foram configurados para uma frequncia de 1kHz e interrupes so geralmente habilitadas.
21/59

PWM com uso de registradores no Arduno


Prescaler nos Timers:
Cada um dos temporizadores tem um contador que incrementado a cada instante do relgio do timer; A contagem interrompe quando o contador chegar a um valor final (especificado para a comparao); Uma vez que um contador atingiu este valor mximo, o contador zerado; Ao escolher o valor mximo para a comparao pode-se controlar a freqncia de interrupes do timer. O primeiro parmetro a ser considerado a velocidade com que o temporizador incrementa o contador. Como o clock do Arduino de 16MHz, esta a maior velocidade que os temporizadores podem incrementar seus contadores. Em 16MHz cada tique-taque do contador representa 1/16, 000.000 de um segundo =~ 63ns: Para uma contagem de 0 a 9 => T = 10/16000000s (tempo p/ fazer a contagem) Para uma contagem de 0 a 99 => T = 100/16000000s; Para uma contagem de 0 a 255 => T = 256/16000000s =~ 16uS / mx para timer0 e timer2; Para uma contagem de 0 a 65535 => T = 65536/16000000 = ~ 4 ms / mximo para timer1 (16bits); Prescaler => Aumenta o tempo de contagem. Todos os timers pode selecionar o prescaler de 1, 8, 64, 256 e 1024;

Ftimer (Hz) = (Fclock ) / prescaler Valor_registrador = (16 MHz) / (prescaler * tempo) ) 1 Exemplo: tempo=1s / prescaler = 1024 => valor_do registrador = 15624 => (apenas o timer1)
22/59

Timers no Arduino
Diagrama de blocos dos TImers
O bit flag TOVn setado de acordo com o modo de operao em WGMn2:0, podendo ser usado para gerar uma interrupo.

Modos de Operao: Os bits WGM (Waveform Generation Mode) controlam os vrios modos de funcionamento dos timers.

count Incrementa e decrement TCNTn por 1; direction Seleciona incremento ou decremento; clear limpa TCNTn; clkTn clock do timer top indica que TCNTn atingiu valor mximo; bottom indica que TCNTn atingiu valor mnimo (0)

23/42

Timers no Arduino
Waveform Generation Mode bits (WGM) Timer0 (8 bits)

Modos:
Normal PWM - Phase Correct PWM Fast CTC Desligado

24/42

Timers no Arduino
Waveform Generation Mode bits (WGM) Timer1 (16 bits)

Modos: Normal PWM fase Correta PWM fase Correta 8bits PWM fase Correta 9bits PWM fase Correta 10bits PWM fase e frequncia Correta PWM Fast PWM Fast, 8 bits PWM Fast, 9 bits PWM Fast, 10 bits CTC Desligado

25/42

Timers no Arduino
Waveform Generation Mode bits (WGM) Timer2 (8 bits)

Modos: Normal PWM Phase Correct Fast PWM CTC

26/42

Timers no Arduino
Timer/Counter Prescaler Timer1

27/42

Timers no Arduino
Timer/Counter Prescaler Timer2

28/42

Timers no Arduino
8-bit Timer/Counter2 with PWM and Asynchronous Operation

O ATMEGA328 tem 3 timers e 6 sadas PWM; O Arduino usa o Timer0, 8bits, internamente para as funes millis() e delay(); Portanto, mudando os registradores deste timer, pode afetar o uso destas funes; A biblioteca de PWM usa estas funes internamente: Timer0 => Pinos de sada: PD6 (6) e PD5(5) Timer1 => Pinos de sada: PB1(9) e PB2(10) Timer2 => Pinos de sada: PB3(11) e PD3(3)
)elcyc_ytud ,nip(etirWgolana

29/42

Timers no Arduino
Cada temporizador tem 2 registradores para comparar os valores de contagem com o valor limite ou programado (0xFF ou OCRnA), e controlar a largura PWM; Quando o registrador de contagem chega no valor programado, a CPU avisada atravs de um bit flag, que pode causar uma interrupo, se previamente programada. O Temporizador/Contador pode ser sincronizado internamente, atravs do prescaler (AS2=0, default), ou de forma assncrona com clock nos pinos TOSC (TOSC1 e TOSC2 / AS2=1, neste caso). A operao assncrona (externa/Tn) controlada pelo Estado Assynchronous Register (RAEE).

30/42

Timers no Arduino
Cada um dos timers tem um contador que incrementado ou decrementado a cada pulso de clock; A interrupo do timer ocorre quando o contador atingir 0xFF ou chegar a um valor especificado previamente no registrador de comparao do timer (OCR2A Output Compare Register A ou OCR2B Output Compare Register B); Neste momento o valor do contador zerado e inicia novamente a nova contagem; A frequncia PWM gerada pode ser controlado de 2 modos: (b) frequncia de PWM, usando o prescaler; (b) limite superior do contador (0xFF ou OCRnA); Ao escolher o valor para a comparao, junto com o valor da frequncia de clock (usando o prescaler), que sincroniza o incremento no contador, pode-se controlar a frequncia de interrupes do timer, quando habilitada, bem como, a gerao do PWM.
31/42

Timers no Arduino
Timer1 - Output Unit (16 bits)
O contador de 16-bit formado por dois registradores de 8-bit: TCNT1H e TCNT1L. O Registro TCNT1H s pode ser acessada indiretamente pela CPU; Quando a CPU precisa acessar TCNT1H I, usa o registro temporrio (TEMP). O registo temporrio atualizado com o valor TCNT1H quando o TCNT1L lido, e TCNT1H com o valor do registrador temporrio, quando escreve em TCNT1L. Isso permite a CPU a ler ou escrever todo o valor de 16 bits dentro um ciclo de clock atravs do barramento de dados de 8 bits. Dependendo do modo de operao utilizado, o contador limpo, incrementado ou decrementado a cada relgio temporizador (clkT1). O sinal clkT1 pode ser gerada a partir de uma fonte de relgio externo ou interno, selecionado pelos bits Relgio Select (CS12: 0). Quando no h fonte de clock selecionado (CS12: 0 = 0) e o cronmetro parado. No entanto, o valor TCNT1 pode ser acessada pela CPU, independentemente de clkT1 est presente ou no.
32/42

Timers no Arduino
Timer2 - Output Compare Unit (8 bits)

O comparador de 8 bits que compara continuamente TCNT2 com a sada do Registrador (OCR2A ou OCR2B). Sempre que TCNT2 for igual a OCR2A ou OCR2B, o comparador seta o flag correspondente (OCF2A ou OCF2B) para avisar o timer e reiniciar a contagem; Se a interrupo correspondente estiver ativada, acionada a rotina de atendimento a interrupo, onde o flag automaticamente limpo; Como alternativa, o flag pode ser limpo por software, escrevendo 1 diretamente no registrador correspondente; O PWM gerado utiliza o flag para gerar uma sada OC2A ou OC2B, de acordo com o modo de funcionamento definido por WGM22:0 e COM2x1:0.

Pinos de sada: 3 (OC2B) e 11 (OC2A)


33/42

Timers no Arduino
Modos de operao do Timer2 (8 bits)
Modo Normal
O timer conta normalmente at o MAX, 0xFF, quando reinicia a contagem, setando flag de interrupo (TOP = MAX); No gera PWM automtico, podendo ser gerado na rotina de interrupo; O timer conta normalmente at atingir o limite o TOP de contagem:OCR2A ou OCR2B, quando reinicia a contagem, setando flag de interrupo; No gera PWM automtico, podendo ser gerado na rotina de interrupo; Um modo de gerao automtica de PWM nos pinos 11 e/ou 3, onde ocorre o incremento do MIN ao TOP (neste caso, MIN=0); Um modo de gerao automtica de PWM nos pinos 3 e/ou 11, onde o contador incrementa de MIN at o TOP e, em seguida, decrementa at o valor mnimo (0). Melhor opo para acionamento de certas cargas, como motores.

Modo Clear Timer on Compare Match (CTC)

Modo: Fast PWM Modo: Phase Corrected PWM


Modo: Phase and Frequency Corrected PWM


Diferencia-se do anterior apenas no momento em que o registrador OCRnx atualizado com o novo buffer. Como o nome sugere, a vantagem do Phase and Frequency correct PWM ser mais apropriado para alterar a frequncia do PWM, por estar os sinais PWM em fase. Para qualquer um dos modos, existem 3 bits no registrador TCCR2B, que alteram o prescaler ou o relgio do contador. Valores do prescaler: 1, 8, 32, 64, 128, 256 e 1024.

34/42

Timers no Arduino

Fast PWM no Timer2


O timer conta at OCR2x, e nesse momento atualiza o pino OC2x (se o liga ou desliga depende da configurao dos bits COM1x0 e COM1x1). Depois continua a contar at TOP, e nesse momento volta ao BOTTOM e atualiza o pino OC2x, alterando o seu estado;

Pino OC2A duty de 66,66%

Pino OC2B duty de 33,66%

35/42

Timers no Arduino

Phase Corrected PWM no Timer2


O timer conta at OCR2x, e nesse momento atualiza o pino OC2x (se o liga ou desliga depende da configurao dos bits COM1x0 e COM1x1). Depois decrementa at chegar ao BOTTOM (0). Ao passar por OCR2x atualiza o pino OC2x, alterando o seu estado;

36/42

Timers no Arduino
Timer2 Modos de Operao Fast PWM Mode (WGM22:0 = 3 ou 7)
Usado para gerar frequencias maiores para o PWM; No modo de PWM rpido, o contador incrementado at que o valor do contador atingir ao valor TOP, a o contador ento limpo no ciclo seguinte do relgio temporizador. O valor TCNT2 e o diagrama de temporizao esto ilustrads na figura a seguir; O diagrama inclui sadas PWM no invertida e invertida; As pequenas marcas vistas na linha horizontal na TCNT2 representam a comparao entre OCR2x e TCNT2; No modo de PWM rpido, a unidade de comparao permite a gerao de formas de onda PWM no pino OC2x; Definindo os bits COM2x1:0 para 2 ser produzido um PWM no invertida e uma sada PWM invertido; Definindo a COM2x1:0 para 3, TOP definido como 0xFF quando WGM2:0 = 3, e quando MGM2:0 = 7 em OCR2A ; O valor OC2x real s ser visvel no pino da porta se a direo de dados para o pino da porta for definido como sada. A forma de onda PWM gerada ajustando-se o Registrador OC2x equando entre OCR2x for igual a TCNT2; A frequncia de sada de PWM pode ser calculada pela seguinte equao:
N = prescaler = (1, 8, 32, 64, 128, 256, ou 1024)
37/42

Timers no Arduino
Timer2 Modos de Operao Fast PWM Mode (WGM22:0 = 3 ou 7)
O flag de estouro do timer, TOV2, setado a cada estouro de contagem (TOP). Se a interrupo estiver ativada, a rotina de tratamento de interrupo pode ser utilizada para atualizar o valor de comparao, permitindo gerar o PWM no pino OC2x; Definindo os bits COM2x1:0 = 2 ir produzir um PWM no invertido, e uma sada PWM invertido pode ser gerado, definindo a COM2x1:0 = 3; O TOP definido como 0xFF, quando WGM2:0 = 3, e quando em OCR2A, MGM2: 0 = 7; O valor OC2x somente estar visvel no pino da porta se a direo de dados para o pino da porta estiver definida como sada. A forma de onda PWM gerada no registrador OC2x (1 ou 0), durante a comparao entre OCR2x e TCNT2, e na transio lgica de durante os pulsos de alto para baixo;; A frequncia de PWM da sada pode ser calculada pela seguinte equao:

Neste modo o timer conta de 0 a 255. A sada liga quando o timer 0, e desliga quando o valor do timer corresponder ao valor do registrador OCR2A. Quanto maior o valor da sada de comparao, maior o ciclo de servio (duty). Os valores extremos para o Registrador OCR2A representam casos especiais ao gerar um PWM de sada neste modo. Se o OCR2A = BOTTOM, a sada ser um pico estreito para cada ciclo de clock (MAX+1). Se OCR2A=MAX+1, resultar numa sada constante, alto ou baixo, dependendo da polaridade da sada definido nos bits COM2A1: 0.

N = prescale =

(1, 8, 32, 64, 128, 256, ou 1024)

Duty = (OCR2A *N * 256 / clk I/O)

38/42

Timers no Arduino
Timer2 Modos de Operao Clear Timer on Compare (WGM22:0 = 2) Match (CTC) Mode

Neste modo, o registrador OCR2A usado para configurar a resoluo do timer; No modo CTC o contador zerado quando o timer atingir o valor do contador (TCNT2) for igual ao valor no registrador OCR2A; O OCR2A define o topo da contagem, portanto, a resoluo do timer; Este modo permite maior controle na comparao e no frequncia do sinal de sada; Este modo simplifica a operao com evento externo;

1. Para gerar uma de forma de onda na sada no CTC modo, a sada OC2A pode ser definido para alternar o nvel lgico em cada partida comparao definindo a comparar bits de modo de sada para alternar o modo de (COM2A1: 0 = 1). 2. A frequncia da forma de onda definido pela seguinte equao:

N = prescaler ={1, 8, 32, 64, 128, 256, ou 1024}


39/42

Timers no Arduino
Timer2 Modos de Operao Phase-Correct PWM (WGM22:0 = 1 ou 5)
Neste modo, o timer conta de 0 a 255 e, em seguida, de volta para 0. Este modo baseia-se numa operao de dupla inclinao;

O TOP definido como 0xFF quando WGM2:0 = 3, e quando em OCR2A, MGM2:0 = 7; A sada da comparao (OC2x) zerada enquanto o timer estiver com valores acima do TOP de comparao e setado para valores abaixo, execeto na primeiro ciclo, que inicia setada; A operao de inclinao dupla tem menor freqncia de operao que a de inclinao nica. No entanto, devido caracterstica simtrica dos modos de dupla inclinao PWM, estes modos so preferidos para aplicaes de controle do motores; Neste modo o timer incrementado at o TOP e, ento, muda a direo de contagem. O valor de TCNT2 ser igual ao TOP uma vez no ciclo do timer; O flag TOV2 setado toda vez que o timer igualar ao valor BOTTOM (mais baixo); Neste modo gerado um sinal PWM no pino OC2x, fazendo-se COM2x1:0=2, produz o PWM invertido; Um PWM invertido pode ser gerado fazendo-se COM2x1:0=3; O TOP definido como 0xFF quando WGM2:0 = 3, e em OCR2A, MGM2:0 = 7;
40/42

Timers no Arduino
Timer2 Modos de Operao Phase-Correct PWM (WGM22:0 = 1 ou 5)

O valor OC2x somente ficar visvel no pino da porta se a direo de dados para o pino da porta for definida como sada; A frequncia de PWM na sada pode ser calculada pela seguinte equao:
N = prescale ={1, 8, 32, 64, 128, 256, ou 1024}
41/42

Timers no Arduino
Registradores para TIMER2:
TCCR2A Timer/Counter Control Register A TCCR2B Timer/Counter Control Register B TCNT2 Timer/Counter Register OCR2A Output Compare Register A OCR2B Output Compare Register B

42/42

Timers no Arduino
Registradores para TIMER2:
TIMSK2 Timer/Counter2 Interrupt Mask Register

TIFR2 Timer/Counter2 Interrupt Flag Register ASSR Asynchronous Status Register

GTCCRGeneral Timer/Counter
Control Register

43/42

Timers no Arduino
Detalhes dos registradores para TIMER2: TCCR2A

44/42

Timers no Arduino
Detalhes dos registradores para TIMER2:
TCCR2A Timer/Counter Control Register A TCCR2B Timer/Counter Control Register B Bit 7 de TCCR2B FOC2A: Force Output Compare A Ativo somente quando WGM configurar modo de no PWM / no gera interrupo / Sempre lido como 0; Bit 6 de TCCR2B FOC2B: Force Output Compare A Ativo somente quando WGM configurar modo de no PWM / no gera interrupo / Sempre lido como 0; TCNT2 Timer/Counter Register Contador do timer2 de 8 bits / Usado para comparar valores com o registrador OCR2x; OCR2A Output Compare Register A Registrador 8 bits com valor para comparar com TCNT2. O resultado pode gerar interrupo e gerar sinal no pino OC2A; OCR2B Output Compare Register B Registrador 8 bits com valor para comparar com TCNT2. O resultado pode gerar interrupo e gerar sinal no pino OC2B; TIMSK2 Timer/Counter2 Interrupt Mask Register
Bit 2 OCIE2B: Timer/Counter2 Output Compare Match B Interrupt Enable Se 1, habilita interrupo quando TCNT2 = OCR2B levando o flag OCF2B= 1, em TIFR2, e desviando o programa p/ atender a interrupo; Bit 1 OCIE2A: Timer/Counter2 Output Compare Match A Interrupt Enable Se 1, habilita interrupo quando TCNT2 = OCR2A levando o flag OCF2A= 1, em TIFR2, e desviando o programa p/ atender a interrupo; Bit 0 TOIE2: Timer/Counter2 Overflow Interrupt Enable Se 1, habilita interrupo quando ocorrer overflow no timer2 levando o flag TOV2=1, em TIFR2, e desviando o programa p/ atender a interrupo; Bit 2 OCF2B: Output Compare Flag 2 B Se 1, indica houve uma interrupo decorrente de quando TCNT2 = OCR2B; Bit 1 OCF2A: Output Compare Flag 2 A Se 1, indica houve uma interrupo decorrente de quando TCNT2 = OCR2A; Bit 0 TOV2: Timer/Counter2 Overflow Flag Se 1, indica que houve uma interrupo decorrente do estouro de timer2;

TIFR2 Timer/Counter2 Interrupt Flag Register


45/42

Timers no Arduino
Detalhes dos registradores para TIMER2:

ASSR Asynchronous Status Register


Bit 7 Reserved Bit 6 EXCLK: Enable External Clock Input Se 1, clock assncrono (externo) selecionado para um clock de 32 KHz no pino TOSC1; Bit 5 AS2: Asynchronous Timer/Counter2 Se 0, indica clock interno clkI/O e se 1, clock externo em TOSC1 ; Bit 4 TCN2UB: Timer/Counter2 Update Busy Se 0, indica que TCNT2 est pronto para atualizao; Bit 3 OCR2AUB: Output Compare Register2 Update Busy Se 0, indica que OCR2A est pronto para atualizao; Bit 2 OCR2BUB: Output Compare Register2 Update Busy Se 0, indica que OCR2B est pronto para atualizao; Bit 1 TCR2AUB: Timer/Counter Control Register2 Update Busy Se 0, indica que TCCR2A est pronto para atualizao; Bit 0 TCR2BUB: Timer/Counter Control Register2 Update Busy Se 0, indica que TCCR2B est pronto para atualizao;

Os mecanismos para a leitura TCNT2, OCR2A, OCR2B, TCCR2A e TCCR2B so diferentes. Ao ler TCNT2, o valor atual lido. Ao ler OCR2A, OCR2B, CCR2A e TCCR2B o valor no registrador lido. GTCCR General Timer/Counter Control Register
Bit 1 PSRASY: Prescaler Reset Timer/Counter2 Se 1, o prescaler resetado. No pode ser zerado por hardware, se TSM=1.

46/42

PWM com uso de registradores no Arduno


#define TOGGLE_PIN 13 #define pot A3 int ler=0, ler1=2, ler3; void setup() { // Setup Timer2 overflow to fire every 8ms (125Hz) // period [sec] = (1 / f_clock [sec]) * prescale * (255-count) // (1/16000000) * 1024 * (255-130) = .008 sec Serial.begin(9600); while(!Serial) {}; TCCR2B = 0x00; TCNT2 = 130; TIFR2 = 0x00; TIMSK2 = 0x01; TCCR2A = 0x00; TCCR2B = 0x07; // Disable Timer2 while we set it up ler1=ler; // Reset Timer Count (255-130) = execute ev 125-th T/C clock // Timer2 INT Flag Reg: Clear Timer Overflow Flag // Timer2 INT Reg: Timer2 Overflow Interrupt Enable // Timer2 Control Reg A: Wave Gen Mode normal // Timer2 Control Reg B: Timer Prescaler set to 1024 if (ler != ler1) { Serial.print("ler = "); Serial.print(ler, DEC); Serial.print(" ler3 = "); Serial.println(ler3, DEC); } void loop(){ ler = analogRead(pot); // ler potenciometro ler3 = map(ler, 0, 1023, 0, 255);

} ISR(TIMER2_OVF_vect) { static unsigned int led_state = 0; // LED state led_state = !led_state; // toggles the LED state

Serial.println("IFPB - Prof. Ilton"); Serial.println("PWM com Timer2 Normal"); Serial.println("Plataforma Arduino "); Serial.println("Jan / 2013"); Serial.println(" "); delay(2000); } };

digitalWrite(TOGGLE_PIN, led_state); //TCNT2 = 130; // 8mS TCNT2 = ler3; TIFR2 = 0x00; // timer2 int flag reg: clear overflow flag

Neste exemplo temos o uso do estouro de timer2, para gerar um pwm de duty de 50%

47/59

PWM com uso de registradores no Arduno


PWM normal com uso de registradores do timer2

Gerao do PWM descrito no exemplo anterior, onde observa-se que mesmo mudando o valor do estouro de contagem, o duty fica em 50%
48/59

PWM com uso de registradores no Arduno


Exemplo: Fast PWM em timer2
#define pwm1 3 // OC2B #define pwm2 11 // OC2A #define pot A3 int ler=0, ler1=2, ler3; void setup() { // Setup Timer2 overflow to fire every 8ms (125Hz) // period [sec] = (1 / f_clock [sec]) * prescale * (255-count) // (1/16000000) * 1024 * (255-130) = .008 sec Serial.begin(9600); while(!Serial) {}; pinMode(pwm1, OUTPUT); pinMode(pwm2, OUTPUT); pinMode(pot, INPUT); TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(COM2B0) |_BV(WGM22) | _BV(WGM21)| _BV(WGM20); // COM2A=10 => Fast pwm no pino OC2A (no invertido) // COM2B=11 => Fast pwm no pino OC2B (invertido) // WGM=7 => Fast PWM com MAX em OCR2A TCCR2B = _BV(CS22); // CS22=1 => prescaler 64 para timer2 OCR2A = 180; OCR2B = 50; Serial.println("IFPB - Prof. Ilton"); Serial.println("PWM Fast - timer2"); Serial.println("Plataforma Arduino "); Serial.println("Jan / 2013"); Serial.println(" "); delay(2000); } } void loop() { ler = analogRead(pot); // ler potenciometro ler3 = map(ler, 0, 1023, 0, 255); OCR2A = ler3; OCR2B = 256-ler3; if (ler != ler1) // mostra mudancas { Serial.print("ler3 = "); Serial.print(ler3, DEC); Serial.print(" ORR2A = "); Serial.print(ler3, DEC); Serial.print(" OCR2B = "); Serial.println(256-ler3, DEC); } ler1=ler; delay(100);

49/59

PWM com uso de registradores no Arduno

Gerao do PWM descrito no exemplo anterior, com o duty varivel


50/59

PWM com uso de registradores no Arduno


Driver para Motor DC ou servo: L293D

Controla 2 motores DC de forma independente; Para cada motor possvel controlar o sentido de rotao e a velocidade com um sinal de PWM; Limitado a at 1,2 A / 12V por motor DC.

Fonte: http://www.societyofrobots.com/member_tutorials/node/164
51/59

PWM com uso de registradores no Arduno


Driver para Motor DC: SN754410

http://www.sparkfun.com/datasheets/IC/SN754410.pdf

52/59

PWM com uso de registradores no Arduno


Funcionamento dos drivers L293D ou SN754410

Caractersticas: Controlam at 2 motores DC ou servos Para cada motor: (a) controle de sentido de rotao; (b) Controle de velocidade; (c ) Alimentao independente;
53/59

PWM com uso de registradores no Arduno


Funcionamento dos drivers L293D ou SN754410
#define pwm1 3 // OC2B #define pwm2 11 // OC2A #define pot A3 // controla velocidade (PWM) #define led1 4 // pino do led que sinaliza qdo botao acionado #define in1 A0 // controla sentido rotao do motor int ler=0, ler1=2, ler3; boolean inv1=0, inv=0, ss=0; void setup() { Serial.begin(9600); while(!Serial) {}; pinMode(pwm1, OUTPUT); pinMode(pwm2, OUTPUT); pinMode(pot, INPUT); pinMode(led1, OUTPUT); // pisca led qdo muda o sentido pinMode(in1, OUTPUT); // muda o sentido de rotacao attachInterrupt(0, muda_sentido, RISING); // interrupo no botao TCCR2A = _BV(COM2A1)| _BV(COM2B1) | _BV(COM2B0) | _BV(WGM22) | _BV(WGM21)| _BV(WGM20); // COM2A=10 => Fast pwm no pino OC2A (no invertido) // COM2B=11 => Fast pwm no pino OC2B (invertido) // WGM=7 => Fast PWM com MAX em OCR2A TCCR2B = _BV(CS22); // CS22=1 => prescaler 64 para timer2 OCR2A = 180; OCR2B = 50; Serial.println("IFPB - Prof. Ilton"); Serial.println("PWM Fast - L293D"); Serial.println("Plataforma Arduino "); Serial.println("Jan / 2013"); Serial.println(" "); ss=1; delay(500); } // setup void loop(){ ler = analogRead(pot); // ler potenciometro ler3 = map(ler, 0, 1023, 0, 255); OCR2B = ler3; OCR2A = 256-ler3; if (ler != ler1) { Serial.print("ler3 = "); Serial.print(ler3, DEC); Serial.print(" INV= "); if (inv) Serial.println(" 1"); else Serial.println(" 0"); } ler1=ler; delay(100); } // loop void muda_sentido() { inv1 = ~inv1; inv = ~inv; // liga motor digitalWrite(led1, inv1); // inverte led digitalWrite(in1, inv); // inverte sentido if (ss) { Serial.print(" INV= "); if (inv) Serial.println(" 1"); else Serial.println(" 0"); } }

//

54/59

Uso do driver L293 p/ motor DC


Usando o driver L293D (O CI L293DD possui 4 drivers):

Para controlar os motores, utiliza-se os pinos 2 e 7 para motor 1 e os pinos 10 e 15 para motor 2. Os pinos de ligao aos motores so os pinos 3 e 6 para um dos motores e 11 e 14 para o outro. Os aterramentos so os pinos 4 e 13 e 5 e 12 para os motores 1 e 2; Os pinos 1 e 9 habilitam os canais; para utilizar 1 motor sinalize 1 ou 9. Para utilizar 2 motores, sinalize ambos. Para tal, basta liga-los 5v; O pino 16 a alimentao do circuito lgico, onde que deve ser conectada a 5v; O pino 8 a entrada de energia para alimentao dos motores. Essa entrada suporta at 36v, ou seja, podemos tranquilamente alimentar 2 motores de impressora; 55/59

Uso do driver L293 p/ motor DC


Usando o driver L293D:

Ligando e mudando o sentido de rotao do motor DC com L293D 56/59

Uso do driver L293 p/ motor DC


const int L293_ENA2 = 8; // D8 const int L293_INP3 = 9; // D9 const int L293_INP4 = 10; // D10 #define led1 4 // pino do led que sinaliza qdo botao acionado int inv=0, ss=0; boolean inv1=0; void setup() { Serial.begin(9600); while(!Serial) {}; pinMode (L293_ENA2, OUTPUT); pinMode (L293_INP3, OUTPUT); pinMode (L293_INP4, OUTPUT); pinMode (led1, OUTPUT); attachInterrupt(0, muda_sentido, RISING); digitalWrite (L293_ENA2, LOW); digitalWrite (L293_INP3, LOW); digitalWrite (L293_INP4, LOW); Serial.println("IFPB - Prof. Ilton"); Serial.println("L293D sem PWM"); Serial.println("Plataforma Arduino "); Serial.println("Jan / 2013 - inv=1"); Serial.println(" "); ss=1; digitalWrite (L293_ENA2, HIGH); digitalWrite (L293_ENA2, LOW); digitalWrite (L293_INP4, HIGH); digitalWrite (L293_INP3, LOW); digitalWrite (L293_ENA2, HIGH); delay(1000); } void loop () { } } void muda_sentido() { inv1 = ~inv1; digitalWrite(led1, inv1); // inverte led

switch(inv) { case 0: // esquerda digitalWrite (L293_ENA2, LOW); digitalWrite (L293_INP4, LOW); digitalWrite (L293_INP3, HIGH); digitalWrite (L293_ENA2, HIGH); break; case 1: // direita digitalWrite (L293_ENA2, LOW); digitalWrite (L293_INP4, HIGH); digitalWrite (L293_INP3, LOW); digitalWrite (L293_ENA2, HIGH); break; case 2: // parado digitalWrite (L293_ENA2, LOW); digitalWrite (L293_INP3, LOW); digitalWrite (L293_INP4, LOW); digitalWrite (L293_ENA2, LOW); break; } if (ss) { Serial.print(" INV= "); Serial.println(inv, DEC); } inv++; if (inv >= 3) inv=0;

57/59

PWM no ARDUINO
Fontes de Consulta:
http://arduino.cc/en/Tutorial/PWM http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM http://www.eletronica.org/arq_apostilas/apostila_pwm.pdf http://jaktek.com/wp-content/uploads/2011/12/HC-SR04.pdf http://www.instructables.com/id/Easy-ultrasonic-4-pin-sensor-monitoring-hc-sr04/ http://playground.arduino.cc/Main/PWMallPins http://www.fiz-ix.com/2012/01/how-to-configure-arduino-timer-2-registers-to-drive-an-ultrasonic-transducerwith-a-square-wave/ http://blipbox.org/blog/2011/05/23/arduino-squarewave-generation/ https://sites.google.com/site/qeewiki/books/avr-guide/pwm-on-the-atmega328 http://lusorobotica.com/index.php?topic=2838.120 http://www.mythic-beasts.com/~markt/ATmega-timers.html http://www.societyofrobots.com/member_tutorials/book/export/html/228 http://electronics.stackexchange.com/questions/26363/how-do-i-create-a-timer-interrupt-with-arduino http://bluepichu.wordpress.com/2012/07/16/fast-pwm-with-arduino-fast/ http://www.cursodearduino.com.br/apostila/apostila-rev4.pdf http://www.societyofrobots.com/member_tutorials/node/159 http://labdegaragem.com/profiles/blogs/tutorial-motor-de-passo-parte-3-circuitos-de-acionamento http://itp.nyu.edu/physcomp/Labs/DCMotorControl http://web.ics.purdue.edu/~fwinkler/616/sn754410_Arduino.pdf http://www.tigoe.net/pcomp/code/circuits/motors/stepper-motors/
58/59

Obrigado
iltonlb@gmail.com