Arduino e algumas ferramentas CAD

FI577 - Instrumentação eletrônica para a física

Leitura recomendada: www.arduino.cc e Google.

A plataforma arduino

  • Plataforma para desenvolvimento eletrônico
  • Microcontrolador: computador (processador + memória + armazenamento) + periféricos de comunicação e controle.
  • Pode obter sinais de sensores, bem como enviar sinais para controlar dispositivos. Parte ativa de um experimento
  • Circuito digital com possíveis aplicações analógicas
    • Atenção: O arduino e seus periféricos são adequados para trabalhar com tensões entre 0 e 5 V. Ao conectar circuitos analógicos, deve-se ter sempre ter cuidado para que o circuito analógico não exceda estas especificações!
  • Aqui, focaremos principalmente em alguns periféricos: GPIO, PWM/TIMER e ADC.

Periféricos úteis em eletrônica analógica

  • Estamos interessados em que tipo de grandezas físicas num circuito eletrônico?
    • Tensões, correntes e suas variações no tempo.
  • Algumas aplicações dos periféricos:
    • GPIO: pode ser usado para gerar uma tensão \(0\text{ V}\) ou \(+5\text{ V}\)
    • PWM/TIMER: pode ser usado para gerar sinais analógicos e/ou medir tempos com uma precisão razoável (<1 \(\mu\)s).
    • Conversor analógico digital (ADC): mede a tensão entre um dado terminal e o terra, e registra o valor numa variável.

Entrada e saída digital (Input Output - IO)

  • As portas Dx (Digital X) possuem a capacidade de aplicar tensões (0V ou 5V) via software.
    • Maior corrente por pino (entrando ou saindo): 40 mA
    • Máxima corrente total passando por todos os pinos do arduino: 200 mA
  • Arduino segue a lógica digital binária (Boole)

  • Também é possível ler tensões em Dx:
    • Se \(V_{Dx} < 0.3 V_{CC}\), então lê o valor \(0\). (\(V_{Dx}<1.5V\))
    • Se \(V_{Dx} > 0.7 V_{CC}\), então lê o valor \(1\). (\(V_{Dx}>3.5V\))
    • E se \(1.5\text{ V}<V_{Dx}<3.5\text{ V}\)?

Saída digital

  • Façamos o arduino dar um sinal de vida.
  • Abrir a Arduino IDE.
  • Abrir o exemplo em Arquivo\Exemplos\01. Basics\Blink
  • Compilar (\(\rightarrow\)) e observar…
  • Mais detalhes sobre exemplos incluídos podem ser acessados em www.arduino.cc/en/Tutorial/BuiltInExamples
Arduino IDE
Arduino IDE

Configurações iniciais

  • Configurações iniciais do sistema (void setup(){})

  • Cada vez que o microcontrolador inicializa ele precisa ser ‘informado’ sobre o que cada periférico deve realizar.
  • Neste caso, queremos apenas informar que o pino do led embutido LED_BUILTIN será usado como uma saída.
  • função pinMode(pin, type);, onde pin=LED_BUILTIN e type=OUTPUT
  • Nota: Funções em geral são chamadas como funcao(argumentos)
  • Nota: Ao final de cada linha de código em C, terminar com ;
  • Nota: Blocos de código começam com { e terminam com }

Exercícios

  • No código original, o LED pisca a 0.5 Hz. Modifiquem o código para que o LED pisque a uma taxa de 1 Hz.
  • Faça com que o led pisque apenas uma única vez.
  • Faça com que o led pisque apenas 3 vezes.

Leitura digital de tensão

  • Nos exemplos anteriores, o arduino controla um led. Este sinal sai do arduino.
  • Queremos também enviar sinais para controlar o arduino. O sinal entra no arduino.
  • Ex.: Um botão para controlar o volume de um som enviado a um auto-falante.
  • Inicialmente, vamos considerar apenas a entrada de sinais digitais.
  • Lembrando…
    • Se \(V_{Dx} < 0.3 V_{CC}\), então lê o valor \(0\). (\(V_{Dx}<1.5V\))
    • Se \(V_{Dx} > 0.7 V_{CC}\), então lê o valor \(1\). (\(V_{Dx}>3.5V\))

Circuito equivalente

  • Como representar um botão ideal em um circuito?
  • Circuitos aberto (Não há contato elétrico) e fechado (Há contato elétrico).
  • Como converter a informação de que o contato elétrico foi realizado ou não em uma tensão?
  • 2 estados representáveis por uma resistência efetiva:
    • Aberto (\(R=\infty\)) queremos que \(V\rightarrow 0\) V
    • Fechado (\(R=0\)) queremos que \(V\rightarrow 5\) V
  • Podemos usar um divisor de tensão
    • \(V_O = \frac{R_2}{R_1+R_2} V_{CC}\)
    • O botão deve ser \(R_1\) ou \(R_2\) para satisfazer as condições acima? O que acontece se trocarmos o resistor e o botão no circuito?

Leitura do estado do botão

  • Componentes necessários:
    • Botão
    • Resistor 10 K\(\Omega\)
  • O pino compartilhado entre o resistor e o botão deve ser conectado a D2
  • Abrir o exemplo em Arquivo\Exemplos\01. Basics\DigitalReadSerial
  • Compilar (\(\rightarrow\)), abrir Ferramentas/Monitor Serial(CTRL+SHIFT+M) e observar…
  • O estado do botão é exibido no Monitor Serial.

Analisando o DigitalReadSerial

  • Documentação
  • Declaração da variável pushButton
  • int pushButton indica um espaço na memória que será usado para armazenar um número (tipo int). A variável deve sempre ser definida antes de ser utilizada!
  • Para manipular esta informação na memória podemos nos referir ao nome pushButton.
  • Operador atribuição (=) armazena o valor 2 na variável pushButton
  • Em outras palavras, se nenhuma modificação for realizada em pushButton e perguntarmos o seu valor posteriormente, obteremos 2.

Algumas operações

  • Voltemos à declaração da variável pushButton. Poderíamos ter definido a variável de uma maneira alternativa:
  • Ou ainda, no lugar de pushButton = 2; poderíamos ter escrito pushButton = 1+1; (Verifiquem!)
  • Operações matemáticas: soma(+), subtração(-), multiplicação(*), divisão(/). Podemos também obter o resto da divisão de um inteiro por meio do operador módulo(%).
  • Operações matemáticas podem ser agrupadas utilizando-se parênteses (1+2)/3==1
  • Outras funções (\(\cos,\exp\)…) podem ser vistas em arduino->Refs.

Analisando o DigitalReadSerial

  • Continuando…
  • Inicializa a comunicação com o computador através de Serial.begin(9600);
  • pino pushButton(D2) será usado para medir tensões binárias pinMode(pushButton, INPUT);
  • As etapas acima configuram os periféricos de comunicação (Serial) e de medição binária de tensão (INPUT). O setup() termina então com }

Analisando o DigitalReadSerial

  • O loop contém tarefas que devem ser realizadas periodicamente enquanto o arduino estiver ligado
  • Neste caso, deve realizar medidas binárias de tensão
  • digitalRead(pushButton) lê o estado da tensão no pino pushButton (D2)
  • O valor medido é armazenado na nova variável int buttonState
  • O estado do botão é enviado ao computador via comunicação serial: Serial.println(buttonState);

Exercício

  1. Utilizando o circuito do exemplo Blink, e partindo do código do exemplo DigitalReadSerial, faça com que o LED acenda quando o botão é pressionado.

Leitura analógica da tensão

  • Nos exemplos anteriores, vimos como usar o arduino como uma fonte de tensão binária (0V e +5V, via digitalWrite) e como um medidor binário de tensão (usando o digitalRead).
  • Estamos interessados também em medir tensões analógicas
  • Sinal TTL (transistor transistor logic)

Conversor ADC

  • ADC (Analog to Digital Converter)
  • Medição da tensão entre 0 e 5V com uma resolução de 10 bits. Ou seja, o intervalo 0-5V é dividido em \(2^{10}=1024\) intervalos.
  • Osciloscópios digitais possuem tipicamente uma resolução de 8-10 bits.
  • Erro de quantização
  • Realiza até 10.000 medidas por segundo (10Ksps).

Sinal analógico de um potenciômetro

  • O potenciômetro funciona como um divisor de tensão, onde podemos variar a resistência de ambos os resistores.
  • Variando a posição do botão, podemos variar a tensão do pino do meio suavemente entre as tensões aplicadas nos pinos externos.
  • É muito usado para ajustar e calibrar o comportamento de circuitos.
  • Usaremos um potenciômetro para medir a posição do botão.

Medida de tensão analógica usando o arduino

Variáveis de ponto flutuante

  • Vale perceber no exemplo anterior que o resultado da medida analogRead(A0) é um valor inteiro, enquanto a tensão analógica \(V_{\text{pot}}\) é um número real.
  • Para calcular com números reais, utilizamos variáveis tipo ponto flutuante.
  • tipos principais (linguagem C): float e double.
    • declaração: float x = 1.135;
    • x é uma variável que armazena números inteiros, cujo valor é igual a 1.135
    • Separador decimal: .
    • No ATmega, float e double são equivalentes.
    • Num programa em C para computador, o double possui o dobro de bits, e pode ser usado para cálculos de maior precisão.

Detalhe importante sobre o cálculo com ponto flutuante

  • Consideremos o exemplo ao lado
  • Compare a saida no monitor serial
  • Pergunta: o que vocês esperam que aconteça se trocarmos var = 1+1; por var = 3/2;? (Não façam no programa ainda!)
  • Agora vejam o resultado no programa.

Detalhe importante sobre o cálculo com ponto flutuante

  • Ao avaliar expressões numéricas cujo resultado é um ponto flutuante, é importante indicar que os números iniciais são do tipo float. Caso contrário, o compilador interpretará a equação como sendo no domínio dos inteiros!
  • Testem agora var = 3./2.;
  • O número contendo um separador decimal é automaticamente interpretado como float.
  • Detalhe final: cálculos envolvendo float’s são bem mais complicados para o processador do que aqueles envolvendo inteiros. Desta forma, se quisermos cálculos mais rápidos devemos evitar usar float.

Exercício

  • Abram novamente o exemplo em Arquivo/Exemplos/01. Basics/AnalogReadSerial.
  • O sinal mostrado no monitor serial corresponde a um valor inteiro associado à medida de tensão no pino Analog 0 (A0). Sabendo que a resolução da medida é 10 bits (0-1023), e que o valor máximo corresponde a 5V, convertam sensorValue para tensão.
  • Nota: Em geral, quando utilizamos algum sensor, este sensor converte uma grandeza física em tensão. (ex.: \(^OC/V\)), enquanto o arduino mede tensões. Desta forma, para usar um sensor precisamos converter o sinal a ser medido para tensão para então saber qual foi o valor da grandeza medida.

Saída quase-analógica

  • O arduino também possui uma saída com características quase-analógicas.
  • Existem vários tipos de conversores de sinais digitais para analógicos. O arduino possui um PWM (Pulse-Width Modulation).
  • O arduino envia um sinal digital com um tempo variável. A forma que o PWM do arduino opera não é exatamente conforme a figura acima, pois não existem pulsos negativos.
  • A média da tensão no tempo é fornece o sinal analógico de saída. O valor médio pode ser controlado facilmente.
  • a função analogWrite implementada no arduino permite modular a potência de um sinal uma resolução de 8 bits (\(2^8=256\) valores de potência).

Exercício: LED com brilho ajustável

  • Componentes necessários: Resistor 220 \(\Omega\) e LED. O anodo do LED (terminal +) deve ser conectado em um pino com saída analógica (~Dx), como o pino 9
  • Abram o exemplo Exemplos\01.Basics\Fade
  • Vejam o que acontece com a intensidade do LED. a função analogWrite varia o brilho do LED a cada iteração do loop. Após modificar o brilho, varia o valor. brightness é mantido sempre entre 0 e 255, já que a resolução do analogWrite é de 8 bits

Análise do loop

  • analogWrite(led, brightness); O brilho do pino led é ajustado para o valor brightness
  • brightness = brightness + fadeAmount; O valor de brightness é incrementado pelo valor de fadeAmount
  • if (brightness <= 0 || brightness >= 255) Se o valor do brilho for menor que 0 ou (||) maior que 255, executa o bloco de código a seguir
    • fadeAmount = -fadeAmount; O valor do incremento do brightness deve ter o sinal invertido, para que o brilho volte a variar entre 0 e 255.
  • delay(30); Aguarda 30 ms antes de modificar novamente o valor do brilho

Timers

  • A saída PWM é um sinal oriundo de um relógio interno.
  • Conforme dito anteriormente, as medidas de tempo usando o arduino podem ser bastante precisas (\(<1\,\mu\text{s}\))
  • Algumas funções relevantes:
    • delay(ms): pausa o arduino por um tempo de ms milissegundos
    • delayMicroseconds(us): pausa o arduino por us microssegundos
    • unsigned long time = millis(): A função millis() lê o tempo do relógio interno em milissegundos. Este valor pode ser armazenado numa variável para comparação de tempos entre diferentes eventos. Neste caso, o valor é armazenado na variável time
    • millis(): Equivalente a função millis(), porem lê o tempo do relógio interno na escala de microssegundos

Análise do código

Desafio

  1. Faça um medidor de reflexo. Conecte um LED e um botão ao arduino. Ligue um LED um certo tempo após o início do arduino, e verifique com quanto tempo uma pessoa consegue acionar o botão. Mostre resultado da medida de tempo no monitor serial usando a função Serial.println(intervalo de tempo);

Sugestão: inicie partindo da seguinte configuração inicial: