sexta-feira, 29 de julho de 2016

Ensaio do Software Arduino visto no Livro:
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