Projetos

Levitação Ultrassônica com Arduino

Eletrogate 17 de maio de 2022

Introdução

Não é nenhuma varinha mágica ou encantamento como “Wingardium Leviosa” que você vai precisar para esse projeto. Com um Arduino, um driver de motor ponte H e um sensor de distância ultrassônico HC-SR04 você consegue criar uma máquina capaz de fazer objetos levitarem.

Levitação acústica

Qualquer um que sentiu o peito vibrando com a energia das ondas sonoras em um show já está familiarizado com o princípio por trás da levitação acústica. A levitação sônica, ou acústica, usa ondas acústicas fortes e dirigidas para empurrar partículas e prendê-las em pontos precisos no ar. Usando ultrassom – um som agudo acima da capacidade da audição humana – é possível usar vibrações fortes sem causar danos a seus ouvidos. A levitação acústica não é tão forte quanto a levitação magnética, mas tem a vantagem de atuar sobre uma ampla gama de materiais.


Materiais necessários para o Projeto Levitação Ultrassônica com Arduino

Para este projeto, serão utilizados:


Circuito

Para montar o circuito desse projeto, precisamos desmontar o sensor ultrassônico. Para isso, iremos remover o emissor e o receptor, como na imagem:

Esquemático

Observações:

1 – Atente-se à polaridade dos sensores, em alguns casos, há um circulo preto envolvendo o terminal negativo.

2 – Dependendo do módulo ponte H, é necessário fechar os contatos referentes à habilitação do chip controlador (enable).


Montagem

Para montar nossa máquina de levitação, estou usando uns suportes impressos em 3D disponíveis nesse link. Se você não tem impressoras 3D, pode usar outros tipos de montagens como, por exemplo, garras jacaré ou parafusos.

Exemplo de montagem com parafuso e placa perfurada:

A montagem é simples, mas vale ficar atento ao alinhamento dos sensores. Eles devem estar próximos, com uma distancia de, no máximo, 4 cm e bem alinhados entre si. Caso contrário, sua máquina não vai funcionar. Outro ponto é que, ao testar sua máquina, evite a circulação de corrente de ar forte no local, para não tirar a bolinha do lugar.

Código

O firmware para o Arduino é responsável por gerar uma onda de 80kHz no sensor ultrassónico. No código, é definido que todas as portas analógicas sejam de saídas (Output).

/**
 * @file Levitador_ultrasonico.ino
 * Modificado por: Saulo Aislan
 * @brief Firmware responsável por gerar uma onda de 80kHz no sensor ultrassonico.
 * @version 0.1
 * 
 * @copyright Copyright (c) 2022
 * 
*/

#if defined(__arm__)   // Familia Arduino
#elif defined(__AVR__) // Familia Arduino e outras placas AVR
#else
  #error A Placa selecionada nao e suportada, selecione placas da familia Arduino.
#endif

byte TP = 0b10101010; // Alterna os valores entre 0 e 1, para setar nas portas

/**
 * @brief Interrupcao por comparacao de igualdade no TIMER1
 * Onde inverte o valor da porta a cada ciclo
 */
ISR(TIMER1_COMPA_vect)
{
  // PORTC contem os bits das portas 0 a 7 analogicas ou as portas PC
  PORTC = TP; // Envie o valor de TP para as portas PORTC
  TP = ~TP; // Inverter TP para a proxima execucao
}

void setup()
{
  // Registrador DDRC (Data Direction Register) das portas PC (PC1,PC2,PC3..)
  DDRC = 0b11111111; // Define todas as portas PC (PC1,PC2,PC3..) analogicas como saida (OUTPUT)
  
  noInterrupts(); // Desabilita a interrupcao

  // Configuracao do TIMER1
  TCCR1A = 0; // Registrador TCCR1A configurado para o timer1
  TCCR1B = 0; // Registrador TCCR1B configurado para o timer1
  TCNT1 = 0; // Zera o contador TCNT1 de 16bits
  OCR1A = 200; // Define o registrador de comparacao OCR1A (16MHz / 200 = onda quadrada de 80kHz -> onda completa de 40kHz)
  
  TCCR1B |= (1 << WGM12); // Modo CTC (WGM12 bit para o modo de geracao de onda)
  TCCR1B |= (1 << CS10); // Define prescaler para 1 = sem prescaling (CS10 bit para o clock interno - prescaler)
  // TIMSK1 máscara do registrador de interrupção do temporizador/contador
  TIMSK1 |= (1 << OCIE1A); // Habilita a interrupcao por comparação pela igualdade (OCIE1A bit que ativar interrupção de comparação pela igualdade do temporizador/contador1)

  interrupts(); // Ativa interrupcao 
}

void loop() {}

Explicando o Código

Nesse trecho, temos um IF e ELSE por diretiva de compilador para garantir que o código seja executado na arquitetura correta.

#if defined(__arm__)   // Familia Arduino
#elif defined(__AVR__) // Familia Arduino e outras placas AVR
#else
  #error A Placa selecionada nao e suportada, selecione placas da familia Arduino.
#endif

Já neste, temos uma interrupção por comparação de igualdade no TIMER1, em que são invertidos os valores (TP) das portas (PORTC) a cada chamada.

ISR(TIMER1_COMPA_vect)
{
  // PORTC contem os bits das portas 0 a 7 analogicas ou as portas PC
  PORTC = TP; // Envie o valor de TP para as portas PORTC
  TP = ~TP; // Inverter TP para a proxima execucao
}

Então, são definidas as portas PC como OUTPUT e é desabilitada a interrupção.

// Registrador DDRC (Data Direction Register) das portas PC (PC1,PC2,PC3..)
DDRC = 0b11111111; // Define todas as portas PC (PC1,PC2,PC3..) analogicas como saida (OUTPUT)

noInterrupts(); // Desabilita a interrupcao

Abaixo, são feitas as configurações do TIMER1.

TCCR1A = 0; // Registrador TCCR1A configurado para o timer1
TCCR1B = 0; // Registrador TCCR1B configurado para o timer1
TCNT1 = 0; // Zera o contador TCNT1 de 16bits
OCR1A = 200; // Define o registrador de comparacao OCR1A (16MHz / 200 = onda quadrada de 80kHz -> onda completa de 40kHz)

TCCR1B |= (1 << WGM12); // Modo CTC (WGM12 bit para o modo de geracao de onda)
TCCR1B |= (1 << CS10); // Define prescaler para 1 = sem prescaling (CS10 bit para o clock interno - prescaler)
// TIMSK1 máscara do registrador de interrupção do temporizador/contador
TIMSK1 |= (1 << OCIE1A); // Habilita a interrupcao por comparação pela igualdade (OCIE1A bit que ativar interrupção de comparação pela igualdade do temporizador/contador1)

O que é o TIMER 1

O TIMER1 é um temporizador de 16 bits que permite a contagem de eventos, geração de sinal PWM, medida de pulsos, etc. As configurações são feitas através de registradores.

Registradores

O controle do modo de operação do TIMER1 é feito nos registradores TCCR1A e TCCR1B. Sua função é configurar a relação de pré-escala do relógio, o modo do contador/temporizador e o controle de saída para os pinos PWM. O compilador GCC AVR utilizado pelo software Arduino gera automaticamente os dois acessos como se fosse um único registrador de 16 bits.

Descrição do registrador TCCR1A

Registrador TCCR1A

Detalhamento dos bits:

Bits 7:6 – COM1A1:0: Configuração da saída para comparação no canal A
Bits 5:4 – COM1B1:0: Configuração da saída para comparação no canal A

Os bits COM1A1:0 e COM1B1:0 controlam os pinos OC1A e OC1B, respectivamente, conforme tabelas a seguir:

Configuração para Modo não PWM

Configuração para modo PWM rápido

Configuração para modo PWM com fase e frequência

Bits 1:0 – WGM11:0: Waveform Generation Mode

Juntos com os bits WGM13:2, encontrados no registrador TCCR1B, controlam o funcionamento do TIMER1, conforme tabela a baixo:

Modos do TIMER 1

Descrição do registrador TCCR1B

TCCR1B

Bit 7 – ICNC1: Cancelamento de ruído na entrada de captura

Bit para habilitar filtro de ruído no pino de captura ICP1.

Bit 6 – ICES1: Seleção de borda da entrada de captura

Seleciona qual borda no pino de entrada (ICP1) será usada para disparar evento de captura.

Bit 5 – Reservado

Bit reservado, deve ser escrito zero.

Bit 4:3 – WGM13:2: Configuração da forma de onda ferada

Conforme apresentado anteriormente e exibido na tabela dos modos do TIMER 1

Bit 2:0 – CS12:0: Seleção de clock

Bits para seleção de clock, conforme tabela abaixo:

Configuração para seleção de clock

Existem outros registradores importantes para funcionamento do TIMER1:

TCNT1H e TCNT1L – Timer/Counter1:

Registradores de armazenamento de contagem do timer, utilizado no trecho:

TCNT1 = 0; // Zera o contador TCNT1 de 16bits
OCR1AH e OCR1AL – Valor a ser comparado com Timer 1 no canal A
OCR1BH e OCR1BL – Valor a ser comparado com Timer 1 no canal B

Registradores para comparação de contagem com o TCNT1.

OCR1A = 200; // Define o registrador de comparacao OCR1A (16MHz / 200 = onda quadrada de 80kHz -> onda completa de 40kHz)
ICR1H e ICR1L – Registradores do modo de captura:

Registradores para armazenar valor de comparação no modo de captura.

TIMSK1 – Registrador de mascara do Timer/Counter1:

Registrador para habilitar as interrupções disponíveis no TIMER1, utilizado no trecho:

TIMSK1 |= (1 << OCIE1A); // Habilita a interrupcao por comparação pela igualdade (OCIE1A bit que ativar interrupção de comparação pela igualdade do temporizador/contador1)
TIFR1 – Registrador para flag de interrupção do Timer/Counter1

Registrador para flags de interrupções.

Por fim, a interrupção é habilitada e o Loop() é declarado vazio.

interrupts(); // Ativa interrupcao 

Para mais informações sobre os registradores, acesse o datasheet nesse link.


Como Funciona o Levitador Acústico?

Um levitador acústico básico tem duas partes principais: um transdutor, que é uma superfície vibratória que emite som, e um refletor. Muitas vezes, o transdutor e o refletor têm superfícies côncavas para ajudar a focar o som. Uma onda sonora é gerada no transdutor e ricocheteia no refletor. Ao colocar um refletor longe de um transdutor por um múltiplo de meio comprimento de onda, o levitador acústico cria uma onda estacionária. Ondas sonoras estacionárias têm nós definidos (áreas de pressão mínima) e antinodos (áreas de pressão máxima). Os nós de uma onda estacionária estão no centro da levitação acústica. Embora o som seja uma onda longitudinal, a maioria das ilustrações descreve o som como uma onda transversal. Isso ocorre simplesmente porque as ondas transversais são mais fáceis de visualizar do que as ondas longitudinais.

Figura de demonstração das ondas

Figura de demonstração das ondas


Conclusão

Nesse tutorial, aprendemos mais sobre o sensor ultrassônico HC-SR04 e as ondas sonoras e estacionárias. Com isso, essa máquina é perfeita para feiras e demonstrações cientificas na escola. Para mais materiais como esse, continue acompanhando as postagens semanais do blog e não deixe de visitar nossa loja. Lá, você encontra todos os componentes necessários para desenvolver esse e muitos outros projetos! Que a força estejam com vocês e até mais!


Sobre o Autor


Saulo Aislan

Graduando em Tecnologia em Telemática pelo IFPB – Campus de Campina Grande – PB. Tenho experiência com os microcontroladores da família Arduino, ESP8266, ESP32, STM32 e microprocessador Raspberry Pi. Tenho projetos na áreas de IoTs voltada para a indústria 4.0, agroindústria e indústria aeroespacial civil utilizando LoRa, Bluetooth, ZigBee e Wi-Fi. Atualmente estudando e desenvolvendo em FreeRTOS para sistemas em tempo real com ESP32 e LoRaWan para Smart City e compartilhando alguns projetos no blog da Eletrogate.


Eletrogate

17 de maio de 2022

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!