Escolar Documentos
Profissional Documentos
Cultura Documentos
Objetivos
Conversão analógico-digital.
Datalogger simples.
Conversão digital-analógico PWM.
PWM controlado por potenciômetro e por teclado.
Orientações
Os alunos, em grupos de no máximo 3, deverão ter o material necessário para a execução da
prática de laboratório proposta, incluindo o datasheet dos CIs utilizados e o computador com a IDE
de programação. Após a montagem e as medições, os alunos deverão discutir as dúvidas com o
professor, comprovando os conceitos apresentados pelo professor ao longo da atividade.
Material de Apoio
A conversão analógica-digital (normalmente designada por A/D) consiste na geração de um valor
numérico discreto, composto por um conjunto de bits, capaz de representar (com uma resolução
aceitável) o valor analógico original. Os microcontroladores mais antigos não possuíam conversores
integrados, e utilizavam conversores externos. Mas todas as famílias mais modernas possuem
conversores com diversas portas, selecionáveis através de um multiplexador analógico.
Engenharia de Sistemas Microprocessados
Professor: Márcio Gil Faccin
Aula 14 - Laboratório 6
Uma importante informação sobre os conversores A/D é o número total de bits de resolução da
informação digital. No caso do Arduino, os conversores possuem 10 bits, podendo representar
valores entre 0 e 1023.
Numa estrutura normal de conversão A/D, alguns registradores devem ser configurados para
selecionar o canal a ser convertido e para definir alguns parâmetros da conversão, habilitando uma
função de interrupção para tratar o final da conversão (a conversão A/D não é uma operação
instantânea).
No Arduino, a operação através de registradores não é necessária, visto que a biblioteca oferece
uma função que faz todo o tratamento e que opera de forma bloqueante até que a conversão termine
(a função analogRead( pin )). O fato da função ser bloqueante pode causar perda de performance,
mas como o conversor é relativamente rápido, essa perda não é tão significativa.
Além da função de leitura, a biblioteca do Arduino também disponibiliza a função
analogReference ( ref ), que faz a configuração do sinal AREF de modo a garantir o fundo de escala
do conversor A/D (ou seja, a máxima tensão de entrada que irá corresponder ao valor digital 1023).
Por padrão, a tensão AREF está conectada na tensão interna de Vcc (5 volts). Mudanças na tensão de
referência devem ser feitas com cuidado para evitar que o pino de AREF entre em curto com outros
níveis de tensão. Além disso, as primeiras conversões após a mudança de referência podem
apresentar valores inconsistentes.
A única operação importante que não está disponível nas funções da biblioteca é o ajuste do
prescaler do conversor A/D, permitindo que a operação de conversão seja feita de forma mais rápida
em sinais estáveis. Por padrão, a biblioteca configura o prescaler em 1/128, setando os bits
ADPS[2:0] do registrador ADCSRA.
PWM
Figura 1 - Sinais PWM característicos e exemplo de cálculo da tensão média (créditos da figura:
http://www.mecaweb.com.br/eletronica/content/e_pwm)
O Arduino possui diversos modos de configuração do PWM, de acordo com a configuração dos
bits WGMnX, presente nos registradores TCCRnA e TCCRnB. Mas a biblioteca do Arduino se
encarrega de fazer a configuração básica de todos os Timers e de todos os registradores para que eles
operem no modo PWM de 8 bits com correção de fase, e com prescaler de 1/64, simplificando a
operação, conforme a figura abaixo.
Engenharia de Sistemas Microprocessados
Professor: Márcio Gil Faccin
Aula 14 - Laboratório 6
⚠
tempo usá-lo como fonte de interrupção, mas um modo irá afetar o
comportamento do outro. Além disso, é importante que as operações de
configuração do Timer não desconfigurem o modo de operação PWM; ou então
que esse modo seja reconfigurado manualmente quando necessário.
Exemplo
1. Faça um programa que leia dois canais de entrada analógica e envie os dados lidos para
a porta serial do PC.
void setup() {
Serial.begin(9600);
// Reduz o divisor de prescaler de 1/128 (7) para 1/64 (6) fazer a conversão mais rápida
ADCSRA = ADCSRA & (B11111000 | 6);
}
void loop() {
static int timestamp = 0;
int x, y;
int cur = millis();
Engenharia de Sistemas Microprocessados
Professor: Márcio Gil Faccin
Aula 14 - Laboratório 6
2. Faça um programa que armazene um conjunto de 720 leituras de dois canais analógicos,
com 8 bits de resolução, registrados com um intervalo de amostragem de 50ms. Utilize
a borda de descida de um pino de entrada digital para disparar o início das leituras e
encerre as leituras ao encher o conjunto de amostras. Utilize um pino de saída
(conectado em um LED) para sinalizar que o sistema está adquirindo dados e utilize
outro pino para sinalizar que existem dados adquiridos prontos para serem
transmitidos. Após o término da leitura, aguarde pelo recebimento de um comando ‘S’
na porta serial e transmita os dados armazenados separando os canais por vírgula e as
amostras pelo símbolo de nova linha. Enquanto não forem transmitidos os dados, ignore
novos sinais de entrada. Assim que os dados forem transmitidos, faça com que a
próxima borda de subida da entrada dispare um novo ciclo de digitalizações.
#define LED1 13
#define LED2 12
#define TRIGGER 3
#define SAMPLES 720
#define TS 50
byte amostras[2][SAMPLES];
void setup() {
Serial.begin(115200);
pinMode ( LED1, OUTPUT );
digitalWrite ( LED1, LOW );
pinMode ( LED2, OUTPUT );
digitalWrite ( LED2, LOW );
pinMode ( TRIGGER, INPUT_PULLUP );
// Reduz o divisor de prescaler de 1/128 (7) para 1/64 (6) fazer a conversão mais rápida
ADCSRA = ADCSRA & (B11111000 | 6);
}
amostras[1][n] = (byte)(analogRead(1)>>2);
}
void loop() {
static unsigned long timestamp = 0;
static int n_amostra = 0;
static bool ready = false;
int i;
char msg[20];
if ((n_amostra == 0) && ( digitalRead ( TRIGGER ) == LOW )) {
timestamp = millis();
captura (n_amostra);
n_amostra++;
digitalWrite ( LED1, HIGH );
}
else if ((n_amostra > 0)&&(n_amostra < SAMPLES)) {
unsigned long cur = millis();
if ((cur - timestamp) >= TS) {
timestamp = cur;
captura (n_amostra);
n_amostra++;
if (n_amostra == SAMPLES) {
digitalWrite ( LED1, LOW );
digitalWrite ( LED2, HIGH );
ready = true;
}
}
}
else if (n_amostra == SAMPLES) {
if (ready) {
if (Serial.read() == 'S') {
for (i = 0; i < SAMPLES; i++) {
sprintf ( msg, "%d,%d,%d", i, amostras[0][i], amostras[1][i]);
Serial.println(msg);
}
ready = false;
digitalWrite ( LED2, LOW );
}
}
else if ( digitalRead ( TRIGGER ) == HIGH ) {
n_amostra = 0;
}
}
}
Engenharia de Sistemas Microprocessados
Professor: Márcio Gil Faccin
Aula 14 - Laboratório 6
3. Faça um programa que configure um sinal de PWM com resolução de 10 bits a partir do
valor recebido pela interface serial.
// Para operar com 10 bits de resolução, a configuração deve ser feita no Timer 1
#define PWM_PIN 10
void setup() {
// Inicializa a comunicação serial
Serial.begin (115200);
// Configura o pino do PWM como saída
pinMode (PWM_PIN, OUTPUT);
// E configura o Timer para operar em PWM phase-correct com 10-bits de resolução:
TCCR1A = B00100011;
}
void loop() {
static int level = 0;
static int bytesReceived = 0;
// Recebe um comando pela interface serial para atualizar o PWM
if (Serial.available() > 0)
{
int x = Serial.read();
// Se o comando lido não é um valor numérico, encerra o valor anterior
if ((x < '0')||(x > '9'))
{
// Se estava recebendo um valor, seta o PWM
if (bytesReceived > 0)
{
analogWrite (PWM_PIN, level);
// Transmite o valor configurado para depuração
Serial.println (level);
// E prepara para receber o próximo comando
bytesReceived = 0;
level = 0;
}
}
else
{
// Se o valor recebido é numérico, atualiza o level
level = level*10 + x - '0';
bytesReceived ++;
}
}
}
Engenharia de Sistemas Microprocessados
Professor: Márcio Gil Faccin
Aula 14 - Laboratório 6
Exercícios Propostos
1. Faça um programa que leia um canal analógico, com leituras espaçadas de 100 ms,
enviando o valor lido para a porta serial. Conecte a entrada analógica no pino central de
um potenciômetro, cujos terminais externos estejam conectados, respectivamente, em
GND e Vcc e observe a tela de Plotter Serial do Arduino enquanto a posição do
potenciômetro varia do início ao fim do curso e depois retornando ao início. Mantendo
o potenciômetro fixo em uma posição qualquer, compare o valor lido pelo Arduino com
o valor real medido com o uso de um instrumento.
2. Altere o programa para identificar o valor mínimo e o valor máximo da leitura em cada
conjunto de 600 medidas, enviando estes valores pela interface serial. Monitore o
comportamento desses limites para configuração do ADPS nos valores 7 (default), 6, 5,
4, 3 e 2.
3. Altere o programa para acionar um pino de saída antes de iniciar a leitura e desligar esse
pino assim que a leitura for concluída. Monitore o comportamento desse tempo para
configuração do ADPS nos valores 7 (default), 6, 5, 4, 3 e 2.
4. Conecte um LED ao pino do PWM acionado pelo programa do exemplo 3 (com uma
resistência série entre 220Ω e 470Ω) e observe (através da análise do brilho e pelo sinal
no osciloscópio) qual o efeito de comandos com os valores 0, 127, 254, 255, 511, 512,
640 e 1023. Meça o período total do PWM, o duty cycle e a tensão média para cada um
dos valores configurados.
5. Repita as medições de período total, duty cycle e tensão média do exercício 1 para o
caso em que o comando de configuração do modo PWM (TCCR1A = B00100011;) seja
removido da função setup ( ).
6. Repita a medição de período total do PWM para um valor de 254 para o caso de, no final
da função setup ( ), inserirmos a reconfiguração do Prescaler do Timer 1 para 1/1 (TCCR1B
= B00000001;).
7. Repita a medição de período total do PWM para um valor de 254 para o caso de, no final
da função setup ( ), inserirmos a reconfiguração do Prescaler do Timer 1 para 1/1024
(TCCR1B = B00000101;).
8. Repita o exercício 1 alterando o pino do PWM para um pino controlado pelo Timer 2.
9. Faça um programa que leia uma entrada analógica a partir de um divisor resistivo com
um potenciômetro (gerando um nível de tensão variável entre 0 e 5V) e use o valor lido
para controlar o brilho de um LED, através da configuração de um PWM. Mantenha o
PWM no modo default (8 bits) e faça a conversão necessária do sinal lido da entrada
analógica para que a tensão máxima na entrada corresponda ao brilho máximo do LED.
Monitore, com a ajuda de um multiteste, a tensão média da entrada e da saída.