Arduino Básico
// Projeto 7 – Lâmpada pulsante
int ledPin = 9;
float
sinVal;
int ledVal;
void
setup() {
pinMode(ledPin, OUTPUT);
}
void loop()
{
for (int x=0; x<180; x++) {
// converte graus
para radianos e, então, obtém o valor do seno
sinVal = (sin(x*(3.1416/180)));
ledVal = int(sinVal*255);
analogWrite(ledPin, ledVal);
delay(25);
}
}
Primeiramente, você define as
variáveis para o pino do LED, um foat (tipo de dado de ponto futuante) para o
valor da onda senoidal, e ledVal, que armazena o valor inteiro a ser enviado
para o pino digital PWM . Neste projeto, você está criando uma onda senoidal e
fazendo com que o brilho do LED acompanhe essa onda. É isso que faz com que a
luz pulse, em vez de simplesmente acender com brilho
máximo e apagar novamente. Você utiliza a função sin(), uma função matemática,
para calcular o seno de um ângulo. Você
tem de dar à função o grau em radianos. Assim , temos um loop for que vai de 0 a 179; não devemos passar
desse limite, pois isso resultaria em valores negativos, e o valor do brilho
pode estar apenas entre 0 e 255.
A função sin() requer que o
ângulo esteja em radianos, e não em graus. Assim , a equação x*(3.1416/180) converterá
o grau do ângulo para radianos. Depois, você transfere o resultado para ledVal,
multiplicando-o por 255 para obter seu valor. O resultado da função sin() será um número
entre -1 e 1, que poderá ser multiplicado por 255 para obter o brilho máximo.
Você converte (cast) o valor de tipo ponto futuante de sinVal para um inteiro,
utilizando int() na instrução a seguir:
ledVal = int(sinVal*255);
Então, você envia esse valor
para o pino digital PWM 15, utilizando a instrução:
analogWrite(ledPin, ledVal);
Na conversão, ou
casting, você converte o valor de ponto
futuante para um inteiro (efetivamente eliminando o que havia após o ponto
decimal). Mas como você pode enviar um valor analógico para um pino digital? Dê
uma olhada em seu
Arduino. Se
analisar os pinos digitais,
você verá que seis deles (3, 5, 6, 9, 10 e 11) têm PWM escrito ao lado. Esses
pinos são diferentes dos pinos digitais, pois são capazes de enviar um sinal
PWM.
PWM signifca Pulse Width
Modulation, ou Modulação por Largura de Pulso (MLP), e representa uma técnica
para obter resultados analógicos por meios digitais. Nesses pinos, o Arduino
envia uma onda quadrada, ligando e desligando o pino muito rapidamente. O
padrão de ligado/desligado pode simular uma voltagem variando entre 0 V e 5 V.
Isso é feito alterando a quantidade de tempo em que a saída permanece alta
(ligada) e baixa (desligada). A duração do tempo em que ela permanece ligada é
conhecida como a largura do pulso.
Por exemplo, se você quisesse enviar o valor 0 para o pino digital PWM utilizando analogWrite(), o período ON (ligado) seria zero, ou teria o que chamamos de um ciclo de trabalho (duty cycle1
) de 0%. Se você quisesse
enviar um valor de 63 (25% dos 255 máximos), o pino estaria ON em 25% do tempo
e OFF em 75% do tempo. O valor de 191 teria um ciclo de trabalho de 75%;
enquanto um valor de 255 teria um ciclo de trabalho de 100%. Os pulsos ocorrem
a uma velocidade de aproximadamente 500 Hz, ou 2 milissegundos, cada.
Assim, em seu sketch, o LED
está acendendo e apagando muito rapidamente. Se o ciclo de trabalho fosse de
50% (um valor de 127), o LED pulsaria, acendendo e apagando, a 500 Hz, e
exibiria metade de seu brilho máximo. Isso é basicamente uma ilusão que você pode utilizar em seu
proveito, permitindo que os pinos digitais emitam um valor analógico simulado
para seus LEDs.
pino 15, PB1 = Arduino 9
==========================================================
O mesmo exercício feito no Astudio4 com o GCC-AVR
Soft desenvolvido no Astudio4
com GCC.
#include <avr/io.h>
#include <avr/delay.h>
#include <math.h>
#include <avr/interrupt.h>
#include <avr/iom8.h>
//#include <avr/signal.h>
#define F_CPU 16000000L /
// Prototype
void iniPWM (void);
int ledVal;
float sinVal;
int i;
int main(void){
DDRB =
1<<PB1; // OC1A pin out
iniPWM();
while(1){
for
(int x=0; x<180; x++) {
// converte graus para radianos e, então, obtém o
valor do seno
sinVal =
(sin(x*(3.1416/180)));
ledVal = (sinVal*255);
OCR1A
= ledVal; // analogWrite(ledPin,
ledVal);
_delay_ms(100);
}
}
}
void iniPWM(void){
// non inverted
PWM, mode 5
TCCR1A =
(1<<WGM10)|(1<<COM1A1);
// no prescaling,
using system clock, mode 5
TCCR1B = (1<<CS10)|(1<<WGM12);
}
====================================
A saída foi tirado de um filtro conforme desenho a seguir.
Veja a forma de onda no osciloscópio