Olá pessoal! Você sabia que é possível ler e gerar ondas quadradas, senoidais, triangulares e dente-de-serra utilizando o Arduino Giga R1? Neste artigo, conheceremos o uso da conversão analógica-digital e digital-analógica para ler ou gerar principais tipos de ondas. Vamos lá?
Lista de materiais
- 1 Arduino Giga R1 Wifi
- 1 gerador de sinais com cabo BNC – jacaré
- Kit jumpers macho-macho
- 1 osciloscópio digital com cabo BNC (pontas de prova)
Conversão Analógica-Digital usando Arduino Giga
Quando nos referimos a sinais, temos:
- Sinal analógico, que varia ao longo do tempo e pode assumir um valor qualquer dentro de um intervalo de valores;
- Sinal digital, que varia somente entre dois valores, pulsos binários.
No caso do Arduino e outras plataformas, seus sinais de operação são digitais. Para leitura de sinais analógicos, o sinal deve passar por um conversor. O conversor analógico-digital (ADC), como o próprio nome diz, realiza a conversão de um sinal analógico em sinal digital.
No Arduino Giga, temos os pinos A0 a A11, podendo estender para o A12 (DAC0), A13 (DAC1), A14 (CANRX) e A15 (CANTX) se necessário.
Para as placas Arduino Giga R1 e Arduino Portenta H7, existe uma biblioteca chamada Arduino_AdvancedAnalog, para lidar com sinais analógicos de entrada e de saída.
Através da biblioteca é possível configurar:
- Resolução (8, 10, 12, 14 ou 16 bits)
- Taxa de amostragem
- Número de amostras por canal
- Número de dados armazenados em buffer
Mostraremos aqui como realizar a leitura de uma onda quadrada de 8 kHz através de um canal ADC do Arduino Giga.
Esquemático do circuito ADC com Arduino Giga
A montagem do circuito encontra-se na imagem a seguir:
Onde:
Osciloscópio | Arduino Giga R1 | Gerador de sinais |
Negativo (com garra) | GND | Negativo (preto) |
Positivo (sonda) | A0 | Positivo (vermelho) |
Ajuste a onda de saída para:
- Onda quadrada (square) com 5 Vpp (pico a pico)
- Frequência: 8 kHz
- Offset: 2.5 VDC (Arduino Giga trabalha com a parte positiva da onda, por isto o offset deve ser ajustado)
Verifique se a onda gerada está correta conectando as pontas de prova do osciloscópio com o gerador de sinais. O meu osciloscópio está configurado com 1.00 V no vertical (amplitude) e 50.0 us no horizontal (tempo).
Sketch exemplo ADC
Você deve realizar a instalação da biblioteca Arduino_AdvancedAnalog em sua versão Arduino IDE. Para isto, acesse o menu Sketch => Incluir Biblioteca => Gerenciar Bibliotecas…
Digite o nome Arduino_AdvancedAnalog e clique em Install. Ao terminar, será mostrada a mensagem INSTALLED como mostrada a seguir. Clique em Fechar.
Utilize o sketch a seguir:
#include <Arduino_AdvancedAnalog.h> // Uso do conversor ADC1 no pino A0 AdvancedADC adc1(A0); // Uso de millis uint64_t last_millis = 0; void setup() { // Serial com 9600 bits por segundo Serial.begin(9600); // Resolução, taxa de amostragem, número de amostras, buffer if (!adc1.begin(AN_RESOLUTION_16, 16000, 32, 64)) { Serial.println("Falha no inicio da aquisicao analogica!"); while (1); } } // Função para armazenar leitura em buffer void adc_print_buf(AdvancedADC &adc) { if (adc.available()) { // Le ADC e guarda em buf SampleBuffer buf = adc.read(); // Imprime valor na serial Serial.println(buf[0]); // Retorna valor do buf buf.release(); } } void loop() { // Uso da função millis if (millis() - last_millis > 1) { // Imprime valor de ADC1 adc_print_buf(adc1); // Atualiza last_millis last_millis = millis(); } }
Ao carregar o sketch no Arduino Giga, abra o Plotter Serial no menu Ferramentas => Plotter Serial. Será mostrada uma janela como esta:
Utilizamos a resolução de 16 bits do conversor AD com 32 amostras e taxa de amostragem de 16000 para exibição desta onda quadrada no Plotter Serial. Isto significa que o valor máximo da onda é 2^16 = 65536, ou seja, 65536 possibilidades ao se dividir a tensão de 5V.
Se mudarmos a resolução de 16 bits para 10 bits:
if (!adc1.begin(AN_RESOLUTION_10, 16000, 32, 64)) {
Teremos uma onda com uma resolução de 2^10 = 1023, o mesmo valor de leitura analógica no Arduino Uno e Mega 2560. Portanto, o Arduino Giga nos possibilita ter leituras mais fieis às originais, com escolha do valor de resolução, taxa de amostragem e afins.
Obs: O resultado é bom para ondas quadradas, porém, para ondas senoidais, há um corte na onda (saturação) quando é mostrado no Plotter Serial.
Conversores Digital-Analógico usando Arduino Giga
O conversor digital-analógico (DAC), como o próprio nome diz, realiza a conversão de um sinal digital em sinal analógico. Em versões Arduino como Uno e Mega 2650, não há DAC, somente a opção de PWM. Na prática, o PWM é uma saída digital que varia o tempo em nível alto e a média desta saída nos dá valores entre 0 e 5V. Porém, trata-se de uma onda quadrada e não de fato uma saída anlógica.
No Arduino Giga, temos os pinos A12 (DAC0) e A13 (DAC1), dois canais disponíveis para o DAC. Faremos um gerador de ondas diversas, onde a escolha será realizada pelo Monitor Serial.
Esquemático do circuito DAC com Arduino Giga
A montagem do circuito encontra-se na imagem a seguir:
Onde:
Osciloscópio | Arduino Giga R1 |
Negativo (com garra) | GND |
Positivo (sonda) | A12 (DAC0) |
Ajuste o osciloscópio para 1.00 V no vertical (amplitude) e 10.0 us no horizontal (tempo).
Sketch exemplo DAC
Com a biblioteca Arduino_AdvancedAnalog é possível gerar diversos formatos de onda: quadrada, senoidal, triangular e afins. Faremos uso de um exemplo já incluso na biblioteca. Para acessá-lo, clique em Arquivo => Exemplos => Arduino_AdvancedAnalog => Beginner => Waveform_generator. A seguir temos o sketch traduzido:
// Exemplo Waveform_Generator para produzir ondas no DAC0 // Traduzido por Gedeane Kenshima #include <Arduino_AdvancedAnalog.h> #include <mbed_stats.h> // Constantes #define N_SAMPLES (64) #define DEFAULT_FREQUENCY (32000) // Uso do conversor DAC1 no pino A12 AdvancedDAC dac1(A12); // Uso da função para número de amostras uint8_t SAMPLES_BUFFER[N_SAMPLES]; // Função para placas MBED (Giga e Portenta) uint32_t get_current_heap() { mbed_stats_heap_t heap_stats; mbed_stats_heap_get(&heap_stats); return heap_stats.current_size; } // Função menu para Monitor Serial void print_menu() { Serial.println(); Serial.println("Digite um comando:"); Serial.println("t: Onda triangular"); Serial.println("q: Onda quadrada"); Serial.println("s: Onda senoidal"); Serial.println("r: Onda dente-de-serra"); Serial.println("k: Parar DAC"); Serial.println("+: Aumentar frequencia"); Serial.println("-: Diminuir frequencia"); } // Função para gerar onda escolhida void generate_waveform(int cmd) { static bool dac_started = false; static size_t dac_frequency = DEFAULT_FREQUENCY; static size_t starting_heap = get_current_heap(); // Uso de switch/case para escolha da forma de onda switch (cmd) { case 't': // Onda triangular Serial.print("Forma de onda: Triangular "); for (int i=0, j=N_SAMPLES-1; i<N_SAMPLES; i++, j--){ SAMPLES_BUFFER[i] = abs((i - j) * 256 / N_SAMPLES); } break; case 'q': // Onda senoidal Serial.print("Forma de onda: Quadrada "); for (int i=0; i<N_SAMPLES; i++){ SAMPLES_BUFFER[i] = i < (N_SAMPLES / 2) ? 0 : 255; } break; case 's': // Sine wave Serial.print("Forma de onda: Senoidal "); for (int i=0; i<N_SAMPLES; i++){ SAMPLES_BUFFER[i] = sin(2 * 3.14 * (i / (float) N_SAMPLES)) * 127 + 127; } break; case 'r': // Sawtooth Serial.print("Forma de onda: Dente-de-serra "); for (int i=0; i<N_SAMPLES; i++){ SAMPLES_BUFFER[i] = i * (256 / N_SAMPLES); } break; case '+': case '-': Serial.print("Frequencia atual: "); if (cmd == '+' && dac_frequency < 128000) { dac_frequency *= 2; } else if (cmd == '-' && dac_frequency > 1000) { dac_frequency /= 2; } else { break; } // Mudar frequencia. dac1.frequency(dac_frequency * N_SAMPLES); break; case 'k': // Parar DAC1 dac1.stop(); dac_started = false; break; default: Serial.print("Comando desconhecido "); Serial.println((char) cmd); return; } if (cmd == 'k') { Serial.println("Parar DAC!"); print_menu(); } else { Serial.print(dac_frequency/1000); Serial.println("KHz"); if (dac_started == false) { // Inicializar DAC1 if (!dac1.begin(AN_RESOLUTION_8, dac_frequency * N_SAMPLES, N_SAMPLES, 32)) { Serial.println("Falha ao iniciar DAC1 !"); while (1); } dac_started = true; } } Serial.print("Memoria utilizada: "); Serial.print(get_current_heap() - starting_heap); Serial.println(" bytes"); } void setup() { // Início da comunicação serial Serial.begin(115200); while (!Serial) { } // Listar comandos aceitos. print_menu(); // Iniciar gerando uma senoide. generate_waveform('s'); } void loop() { if (Serial.available() > 0) { int cmd = Serial.read(); if (cmd != '\n') { generate_waveform(cmd); } } if (dac1.available()) { // Get a free buffer for writing. SampleBuffer buf = dac1.dequeue(); // Write data to buffer. for (size_t i=0; i<buf.size(); i++) { buf[i] = SAMPLES_BUFFER[i]; } dac1.write(buf); } }
Ao carregar o sketch no Arduino Giga, abra o Monitor Serial no menu Ferramentas => Monitor Serial ou use o ícone de lupa no canto superior à esquerda. Será mostrada uma janela como esta:
Ao digitar o caractere e clicar em Enviar (ou apertar a tecla Enter), será mostrado o nome da forma de onda, sua frequência (em kHz) e quanto foi utilizado de memória para gerar a onda.
Você pode digitar os comandos conforme listados e verificar se as saídas em A12 correspondem. Caso queira aumentar ou diminuir a frequência da onda, utilize as teclas (-) e (+).
OBS: Este artigo foi realizado através de uma Raspberry Pi 400, que pode ser usada como um desktop. Para saber seus recursos, veja este artigo aqui.
Gostou de conhecer um pouco mais sobre o Arduino Giga e suas possibilidades para leitura e geração de ondas analógicas? Deixe um comentário abaixo contando o que achou. Para mais sobre os lançamentos do universo maker, acompanhe as novidades no nosso blog. E não esqueça de nos seguir no Instagram para não perder nenhuma novidade.