amostra - Cuidando do som do seu carro... Cuidando do som do seu
Transcrição
amostra - Cuidando do som do seu carro... Cuidando do som do seu
SENSOR DE CHAMA COM ARDUINO UNO O Sensor de Chama pode ser usado para detectar fontes de fogo ou outras fontes de calor que possuam tamanho de onda entre 760 a 1100 nm. Seu ângulo de detecção pode chegar a 60 graus e no meio de sua placa há um buraco onde se encaixa um parafuso com o objetivo de direcionar o sensor conforme desejado. Características: - Alta sensibilidade receptor IR – Detecção ondas entre 760-1100nm – Saída Analógica – Ângulo de Detecção: 60 graus – Furo Central: 3mm – Tensão Operação: 5v DC – Dimensões: 36 x 16mm Conectando: Componentes necessários: 01 – Arduino Uno 01 – Sensor de Chama 01 – Kit Jumpers Macho-Fêmea Conecte a alimentação do Sensor ao Arduino Uno, VCC do Sensor nos 5v do Arduino e GND com GND. Conecte o pino OUT do sensor na porta analógica A0 do Arduino Uno. Se você tiver um Arduino Sensor Shield fica muito fácil conectar no estilo “Plug & Play” pois este sensor acompanha um Cabo Sensor Shield junto! Programando: 1 void setup() 2 { 3 Serial.begin(9600); // Inicia a conexão serial 4 } 5 6 void loop() 7 { 8 int sensorLevel; // Variável para guardar as leituras 9 sensorLevel=analogRead(0); // Lê o valor analógico do Pino 0 10 Serial.print("Nivel Chama = "); 11 Serial.print(sensorLevel); // Monstra o nível de chama 12 Serial.print("n"); 13 delay(500); // Leituras a 2Hz, este valor pode ser alterado 14 } MONITORANDO TEMPERATURA E UMIDADE COM O SENSOR DHT11 Em um país tropical como o nosso o clima em boa parte do Brasil é quente e úmido. Logo creio que este projeto irá te ajudar a monitorar com apenas 1 sensor a temperatura e umidade de seu clima local com este Sensor DHT11. Especificações DHT11: - Modelo: DHT11 (Datasheet) – Alimentação: 3,0 a 5,0 VDC (5,5 Vdc máximo) – Corrente: 200uA a 500mA, em stand by de 100uA a 150 uA – Faixa de medição de umidade: 20 a 90% UR – Faixa de medição de temperatura: 0º a 50ºC – Precisão de umidade de medição: ± 5,0% UR – Precisão de medição de temperatura: ± 2.0 ºC – Tempo de resposta: < 5s – Dimensões: 23mm x 12mm x 5mm (incluindo terminais) Este sensor inclui um componente medidor de umidade e um componente NTC para temperatura, ambos conectados a um controlador de 8-bits. O interessante neste componente é o protocolo usado para transferir dados entre o MCDU e DHT11, pois as leituras do sensor são enviadas usando apena um único fio de barramento. Formato dos dados: 8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal T data + 8bit check sum = 40 bits. 01 01 01 01 01 – – – – – Componentes necessários: Arduino Uno DHT11 Resistor 10k Protoboard 400 pontos Kit Jumpers Macho-Macho Conectando Dht11 Ao Arduino: O DHT11 possui 4 terminais sendo que somente 3 são usados: GND, VCC e Dados. Se desejar, pode-se adicionar um resistor pull up de 10K entre o VCC e o pino de dados. Conecte o pino de dados do DHT11 ao pino 2 do seu Arduino Uno como mostra o código exemplo abaixo, mas você poderá alterar por outro se desejar. Comunicação Arduino Com DHT11: Para facilitar o seu trabalho já existe uma bilioteca que pode ser baixada neste link. Após o download descompacte o arquivo .zip e mova-o para a pasta arduinosketchfolder/libraries/ e reinicie a IDE do Arduino. Não retire o arquivo dht.cpp. e não esqueça de renomear a pasta para “DHT”. Talvez será necessário criar uma sub-pasta da biblioteca caso não exista. Agora acesse Examples->DHT->DHTtester em sua IDE Arduino. 1 #include "DHT.h" 2 3 #define DHTPIN A1 // pino que estamos conectado 4 #define DHTTYPE DHT11 // DHT 11 5 6 // Conecte pino 1 do sensor (esquerda) ao +5V 7 // Conecte pino 2 do sensor ao pino de dados definido em seu Arduino 8 // Conecte pino 4 do sensor ao GND 9 // Conecte o resistor de 10K entre pin 2 (dados) 10 // e ao pino 1 (VCC) do sensor 11 DHT dht(DHTPIN, DHTTYPE); 12 13 void setup() 14 { 15 Serial.begin(9600); 16 Serial.println("DHTxx test!"); 17 dht.begin(); 18 } 19 20 void loop() 21 { 22 // A leitura da temperatura e umidade pode levar 250ms! 23 // O atraso do sensor pode chegar a 2 segundos. 24 float h = dht.readHumidity(); 25 float t = dht.readTemperature(); 26 // testa se retorno é valido, caso contrário algo está errado. 27 if (isnan(t) || isnan(h)) 28 { 29 Serial.println("Failed to read from DHT"); 30 } 31 else 32 { 33 Serial.print("Umidade: "); 34 Serial.print(h); 35 Serial.print(" %t"); 36 Serial.print("Temperatura: "); 37 Serial.print(t); 38 Serial.println(" *C"); 39 } 40 } TUTORIAL: COMUNICAÇÃO RF COM ARDUINO E MÓDULO APC220 Controle o Arduino à partir do seu computador com esse prático Módulo Rádio Wireless APC220, um kit composto por 2 módulos, 2 antenas e um adaptador USBTTL. Esse kit forma uma solução completa para quem precisa controlar o Arduino à grandes distâncias já que, segundo informação do fabricante, o alcance do sinal é de aproximadamente 1.000 metros (em área aberta). Por formar uma comunicação ponto-a-ponto, não depende de infraestrutura de rede, cabeamento ou outros equipamentos para funcionar. A frequência de operação pode ser ajustada via software (418 à 455 Mhz), e a taxa de transferência pode chegar a 19200 bps. REQUISITOS DE HARDWARE E SOFTWARE Iremos utilizar um computador com porta USB para programação dos módulos, além de um Arduino Uno para testar a comunicação. Na montagem do circuito, usaremos 3 leds (de preferência de cores variadas) e resistores para limitação de corrente nos leds. Para programação dos módulos APC220, será necessário baixar o software RFMagic nesse link. O arquivo compactado contém apenas um executável chamado APC22X_V12A.EXE. O programa não possui instalador, rodando direto desse executável. Antes de conectar o adaptador USB ao computador faça o download dos drivers, que você encontra nesse endereço. Estão disponíveis drivers para as versões mais comuns do Windows, como Windows XP, 7, 8, Server 2003, 2000 e Windows Vista, além de drivers para Macintosh e Linux. Após a instalação dos drivers, conecte o adaptador ao computador e o dispostivo será reconhecido automaticamente. Para verificar se o adaptador foi instalado de forma correta, verifique no painel de controle se existe um dispositivo chamado Silicon Labs CP210x USB to UART Bridge, como na figura abaixo: CONFIGURAÇÃO DO MÓDULO APC220 O RF-Magic é o software utilizado para definir as configurações do módulo, como frequência (418 à 455 Mhz), o NET ID (um número para identificar a rede, entre 0 e 65535) e configurações da serial, como velocidade e paridade. Dependendo do seu sistema operacional, o RF-Magic deve ser executado com direitos de administrador. Ao abrir o RF-Magic, será exibida uma tela como essa abaixo, informando os parâmetros iniciais do programa e na parte inferior a porta COM na qual o módulo foi detectado, assim como o seu modelo: As configurações padrão do programa podem ser utilizadas normalmente, mas se precisar alterar alguma coisa, não esqueça de configurar os dois módulos da mesma maneira, para evitar problemas na comunicação. CONEXÃO DO MÓDULO APC220 AO ARDUINO Dos sete pinos do módulo, vamos utilizar somente quatro para comunicação com o Arduino, que são os pinos de alimentação (3,5 à 5,5V), e também os pinos RXD e TXD, que serão ligados aos pinos TX (pino digital 1) e RX (pino digital 0) do Arduino Uno. No circuito, teremos 3 leds ligados às portas 5, 6 e 7 do Arduino. O circuito irá receber os dados via porta serial e enviará, também via porta serial, os dados para o módulo APC220 ligado ao computador. IMPORTANTE : Mantenha o pino 0 (RX) do Arduino desconectado antes de transferir o programa, caso contrário a IDE irá apresentar um erro informando que houve um problema no carregamento, pois a serial estará ocupada pelo módulo APC220. PROGRAMANDO O ARDUINO O que o programa faz é monitorar a serial (no caso, o módulo APC ligado aos pinos 0 (RX) e 1 (TX)), e tomar uma ação caso seja recebido algum caracter. Envie 1 para ligar ou desligar o led vermelho, 2 para ligar ou desligar o led amarelo e 3 para ligar ou desligar o led verde. A cada um desses acionamentos, o Arduino enviará de volta para o computador uma mensagem, informando o estado do led que foi alterado. 1 //Programa : Comunicacao utilizando modulo wireless APC220 2 //Autor : FILIPEFLOP 3 4 //Variavel que armazena os caracteres recebidos 5 char buf; 6 7 //Definicoes das portas dos leds 8 int porta_led_verm = 5; 9 int porta_led_amar = 6; 10 int porta_led_verd = 7; 11 12 //Variaveis para controle do estado dos leds 13 int estado_verm = 0; 14 int estado_amar = 0; 15 int estado_verd = 0; 16 17 void setup() 18 { 19 //Define portas dos leds como saida 20 pinMode(porta_led_verm, OUTPUT); 21 pinMode(porta_led_amar, OUTPUT); 22 pinMode(porta_led_verd, OUTPUT); 23 //Inicializa a serial 24 Serial.begin(9600); 25 //Informacoes iniciais 26 Serial.println("Digite : "); 27 Serial.println("1 - Para ligar/desligar o led vermelho"); 28 Serial.println("2 - Para ligar/desligar o led amarelo"); 29 Serial.println("3 - Para ligar/desligar o led verde"); 30 Serial.println(); 31 } 32 33 void loop() 34 { 35 //Aguarda os dados na serial 36 while(Serial.available() > 0) 37 { 38 buf = Serial.read(); 39 40 //Caso seja recebido o numero 1, altera o estado do led vermelho 41 if (buf == '1') 42 { 43 estado_verm = !estado_verm; 44 digitalWrite(porta_led_verm, estado_verm); 45 mensagem_estado_led("vermelho", estado_verm); 46 } 47 48 //Caso seja recebido o numero 2, altera o estado do led amarelo 49 if (buf == '2') 50 { 51 estado_amar = !estado_amar; 52 digitalWrite(porta_led_amar, estado_amar); 53 mensagem_estado_led("amarelo", estado_amar); 54 } 55 56 //Caso seja recebido o numero 3, altera o estado do led verde 57 if (buf == '3') 58 { 59 estado_verd = !estado_verd; 60 digitalWrite(porta_led_verd, estado_verd); 61 mensagem_estado_led("verde", estado_verd); 62 } 63 } 64 } 65 66 //Rotina de envio da mensagem de retorno sobre o estado do led 67 void mensagem_estado_led(String led, int estado) 68 { 69 Serial.print("Led "); 70 Serial.print(led); 71 if (estado == 1) 72 { 73 Serial.println(" ligado"); 74 } 75 else 76 { 77 Serial.println(" desligado"); 78 } 79 } TESTANDO A COMUNICAÇÃO Antes de mais nada, agora que o Arduino já está pronto para receber os dados via serial, desconecte-o do computador, conecte o fio do pino 0 (RX) ao Arduino, e utilize uma fonte externa para alimentação da placa. Fazendo isso, está tudo preparado para o teste de comunicação. Você pode utilizar o próprio Serial Monitor da IDE para enviar dados para o Arduino, ou então utilizar um software de terminal como o Termite. Se for utilizar o Serial Monitor, não esqueça de selecionar, no menu Ferramentas = > Porta Serial, a porta utilizada pelo adaptador USB (no nosso caso, estamos utilizando a porta 8, conforme mostramos no início no painel de controle do Windows). Dentro do Serial Monitor, utilize a barra na parte superior para enviar os comandos 1, 2 ou 3, acionar as portas do Arduino e receber de volta a informação sobre o estado dos leds: TUTORIAL: ACELERÔMETRO MPU6050 COM ARDUINO Nesse módulo GY-521 você tem em uma mesma placa um acelerômetro e um giroscópio de alta precisão, tudo isso controlado por um único CI, o MPU6050: O CI MPU6050 (datasheet), além dos dois sensores, tem embutido um recurso chamado DMP (Digital Motion Processor), responsável por fazer cálculos complexos com os sensores e cujos dados podem ser usados para sistemas de reconhecimento de gestos, navegação (GPS), jogos e diversas outras aplicações. Outro recurso adicional é o sensor de temperatura embutido no CI, que permite medições entre -40 e +85 ºC. PINAGEM E ENDEREÇAMENTO DO MPU6050 A comunicação com o microcontrolador usa a interface I2C, por meio dos pinos SCL e SDA do sensor. Nos pinos XDA e XCL você pode ligar outros dispositivos I2C, como um magnetômetro por exemplo, e criar um sistema de orientação completo. A alimentação do módulo pode variar entre 3 e 5v, mas para melhores resultados e precisão recomenda-se utilizar 5v. O pino AD0 desconectado define que o endereço I2C do sensor é 0x68. Conecte o pino AD0 ao pino 3.3V do Arduino para que o endereço seja alterado para 0x69. Essa mudança permite que você tenha dois módulos MPU-6050 em um mesmo circuito. ACELERÔMETRO MPU6050 COM ARDUINO E DISPLAY LCD 20×4 Vamos utilizar um Display LCD 20×4 para mostrar os valores lidos do MPU6050 em conjunto com um Arduino Uno. Nas duas primeiras linhas do display, além da temperatura no canto superior direito, temos os valores de X, Y e Z para o Acelerômetro, e nas duas últimas linhas os valores de X, Y e Z para o giroscópio. O potenciômetro de 10 K serve para ajuste do contraste do display: PROGRAMANDO ARDUINO COM MPU6050 O programa envia os dados tanto para o LCD como para o serial monitor, e utiliza apenas as biblioteca Wire para ler os dados da interface I2C e LiquidCrystal para enviar os dados para o display. Observe no circuito acima que utilizamos um miniprotoboard para conectar o MPU6050 e deixá-lo separado do display, para facilitar a movimentação do sensor e observar a alteração dos valores mostrados. 1 //Programa : Teste MPU6050 e LCD 20x4 2 //Alteracoes e adaptacoes : FILIPEFLOP 3 // 4 //Baseado no programa original de JohnChi 5 6 //Carrega a biblioteca Wire 7 #include<Wire.h> 8 //Carrega a biblioteca do LCD 9 #include <LiquidCrystal.h> 10 11 // Inicializa o LCD 12 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 13 14 //Endereco I2C do MPU6050 15 const int MPU=0x68; 16 //Variaveis para armazenar valores dos sensores 17 int AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; 18 void setup() 19 { 20 Serial.begin(9600); 21 //Inicializa o LCD 22 lcd.begin(20, 4); 23 Wire.begin(); 24 Wire.beginTransmission(MPU); 25 Wire.write(0x6B); 26 27 //Inicializa o MPU-6050 28 Wire.write(0); 29 Wire.endTransmission(true); 30 31 //Informacoes iniciais do display 32 lcd.setCursor(0,0); 33 lcd.print("Acelerometro"); 34 lcd.setCursor(0,2); 35 lcd.print("Giroscopio"); 36 } 37 void loop() 38 { 39 Wire.beginTransmission(MPU); 40 Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) 41 Wire.endTransmission(false); 42 //Solicita os dados do sensor 43 Wire.requestFrom(MPU,14,true); 44 //Armazena o valor dos sensores nas variaveis correspondentes 45 46 47 48 49 AcX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) 50 Tmp=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) 51 GyX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) 52 GyY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) 53 GyZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) 54 55 //Envia valor X do acelerometro para a serial e o LCD 56 Serial.print("AcX = "); Serial.print(AcX); 57 lcd.setCursor(0,1); 58 lcd.print("X="); 59 lcd.print(AcX); 60 61 //Envia valor Y do acelerometro para a serial e o LCD 62 Serial.print(" | AcY = "); Serial.print(AcY); 63 lcd.setCursor(7,1); 64 lcd.print("Y="); 65 lcd.print(AcY); 66 67 //Envia valor Z do acelerometro para a serial e o LCD 68 Serial.print(" | AcZ = "); Serial.print(AcZ); 69 lcd.setCursor(13,1); 70 lcd.print("Z="); 71 lcd.print(AcZ); 72 73 //Envia valor da temperatura para a serial e o LCD 74 //Calcula a temperatura em graus Celsius 75 Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); 76 lcd.setCursor(13,0); 77 lcd.print("T:"); 78 lcd.print(Tmp/340.00+36.53); 79 80 //Envia valor X do giroscopio para a serial e o LCD 81 Serial.print(" | GyX = "); Serial.print(GyX); 82 lcd.setCursor(0,3); 83 lcd.print("X="); 84 lcd.print(GyX); 85 86 //Envia valor Y do giroscopio para a serial e o LCD 87 Serial.print(" | GyY = "); Serial.print(GyY); 88 lcd.setCursor(7,3); 89 lcd.print("Y="); 90 lcd.print(GyY); 91 92 //Envia valor Z do giroscopio para a serial e o LCD 93 Serial.print(" | GyZ = "); Serial.println(GyZ); 94 lcd.setCursor(13,3); 95 lcd.print("Z="); 96 lcd.print(GyZ); 97 98 //Aguarda 300 ms e reinicia o processo delay(300); } Se você prefere visualizar os dados no serial monitor, terá uma saída como essa: COMO USAR O ARDUINO BLUETOOTH HC-05 EM MODO MESTRE Os módulos arduino bluetooth são divididos em dois tipos: os que trabalham no modo escravo (slave), ou seja, apenas aceitam conexões de outros dispositivos, e os que trabalham tanto no modo escravo como no modo mestre (master), permitindo que se conectem à outros dispositivos bluetooth. Nesse tutorial, vamos mostrar como interligar 2 módulos bluetooth: um Arduino Bluetooth HC-05em modo master, e um HC-06 em modo slave. Você pode utilizar também, se preferir, dois módulos HC-05, já que ele aceita tanto o modo mestre como o modo escravo. Os módulos em si são muito parecidos, o que muda é a versão do firmware, e geralmente os módulos arduino bluetooth HC-06 possuem apenas 4 pinos, e o HC-05 tem 6 pinos. Na dúvida, consulte a documentação do módulo que você tem em mãos. Um dos pinos adicionais é o pino Status/Key, que vamos utilizar para programar o HC-05 em modo master, pareando-o com o HC-06. O processo é um pouco extenso e recomendamos não pular nenhum passo, pois cada etapa depende da correta execução da etapa anterior. O material que vamos utilizar é o seguinte : 2 Arduino Uno (podem ser utilizadas outras placas) 1 módulo Arduino Bluetooth HC-05 1 módulo Arduino Bluetooth HC-06 4 resistores para montagem do divisor de tensão 1 led de qualquer cor 1 resistor limitador de corrente para o led Antes de iniciarmos a ligação dos componentes, vamos relembrar que esses módulos trabalham com nível de sinal de 3.3v, o que significa que vamos precisar de um divisor de tensão para evitar a queima do módulo. O divisor de tensão é composto por dois resistores, e você pode calcular a tensão de saída acessando o calculador desse link. Na página, digite 5 para a tensão de entrada (Input Voltage), digite os valores dos resistores (R1 e R2) que você possui, e pressione o botão Compute para verificar no campo Output Voltage qual será a tensão de saída, lembrando que por segurança esta deve ser, no máximo, de 3.3v. CONFIGURANDO ARDUINO BLUETOOTH HC-05 EM MODO MESTRE: Monte primeiro o circuito acima, que será usado para programar o HC-05 em modo master. Agora, carregue o seguinte programa no segundo Arduino antes de montar o circuito do módulo escravo: 1 //Programa : Modulo Arduino Bluetooth HC-05 - Recepcao 2 //Autor : FILIPEFLOP 3 4 //Armazena o caracter recebido 5 char buf; 6 7 void setup() 8 { 9 //Define o pino 13 como saida 10 pinMode(13, OUTPUT); 11 Serial.begin(9600); 12 } 13 14 void loop() 15 { 16 while(Serial.available() > 0) 17 { 18 buf = Serial.read(); 19 //Caso seja recebido o caracter L, acende o led 20 if (buf == 'L') 21 { 22 digitalWrite(13, HIGH); 23 } 24 //Caso seja recebido o caracter D, apaga o led 25 if (buf == 'D') 26 { 27 digitalWrite(13, LOW); 28 } 29 30 } } CONFIGURANDO ARDUINO BLUETOOTH HC-06 EM MODO ESCRAVO: Efetue a ligação dos componentes no segundo Arduino e utilize uma fonte externa para alimentação. Note que no primeiro circuito estamos utilizando os pinos 10 e 11 do Arduino como pinos RX e TX de uma porta serial. Isso é possível pois vamos utilizar a biblioteca Software Serial.No Arduino desse circuito, carregue o seguinte programa: 1 //Programa : Modulo Arduino Bluetooth HC-05 - Programacao 2 //Autor : TECNOTRONICS 3 4 //Carrega a biblioteca SoftwareSerial 5 #include <SoftwareSerial.h> 6 7 //Define os pinos para a serial 8 SoftwareSerial mySerial(10, 11); // RX, TX 9 String command = ""; // Stores response of bluetooth device 10 // which simply allows n between each 11 // response. 12 13 void setup() 14 { 15 //Inicia a serial 16 Serial.begin(115200); 17 Serial.println("Digite os comandos AT :"); 18 //Inicia a serial configurada nas portas 10 e 11 19 mySerial.begin(38400); 20 } 21 22 void loop() 23 { 24 // Read device output if available. 25 if (mySerial.available()) 26 { 27 while(mySerial.available()) 28 { // While there is more to be read, keep reading. 29 command += (char)mySerial.read(); 30 } 31 Serial.println(command); 32 command = ""; // No repeats 33 } 34 35 // Read user input if available. 36 if (Serial.available()) 37 { 38 delay(10); // The DELAY! 39 mySerial.write(Serial.read()); 40 41 } } COMANDOS AT: Entre no serial monitor e selecione a velocidade de 115200 na parte inferior (destaque emvermelho), assim como o comando de fim de linha para Ambos NL & CR (destaque em azul). A mensagem “Digite os comandos AT :” será exibida: Digite o comando AT, que deve retornar com a mensagem “OK” indicando que o módulo está respondendo aos comandos. Digite AT+VERSION para exibir a versão do firmware, que pode ser diferente da imagem abaixo: Digite agora os seguintes comandos na sequência. Cada um deles deve retornar “OK“, indicando que o comando foi aceito pelo módulo: AT+ORGL (Reseta o módulo para a configuração padrão) AT+RMAAD (remove dispositivos anteriormente pareados) AT+ROLE=1 (define o modo de operação do módulo como MASTER) AT+RESET (Reset do módulo após a definição do modo de operação) AT+CMODE=1 (Permite a conexão a qualquer endereço) AT+INQM=0,5,10 (Modo de varredura : padrão, procura por 5 dispositivos ou pára a varredura após 10 s) AT+PSWD=1234 (define a senha do módulo mestre, que deve ser a mesma do módulo slave/escravo) AT+INIT (inicializa o perfil para transmissão/recepção) AT+INQ (inicializa a varredura por dispositivos bluetooth) Essa varredura vai mostrar o endereço dos dispositivo bluetooth detectados. No nosso caso temos apenas um dispositivo escravo: A parte que nos interessa dessa tela é o endereço, que no nosso caso é 2013:7:183190. Vamos precisar dessa informação para efetuar o pareamento, trocando os símbolos de “dois pontos” por vírgulas, ficando assim: 2013,7,183190 Digite agora o comando AT+PAIR=<endereco>,<timeout>. No nosso caso, o comando ficaria assim : AT+PAIR=2013,7,183190, 10 O serial monitor retornará “OK”. Por fim, digite o comando AT+LINK=<endereco>, que vai conectar os dois dispositivos. Nesse momento o led do módulo HC-05 em modo master deve piscar de forma mais lenta, indicando conexão ao módulo HC-06, cujo led deve parar de piscar. Essa série de comandos AT não precisa ser repetida a cada montagem. Uma vez configurado o módulo HC-05 em modo master, ele se conectará automaticamente ao módulo escravo todo vez que você energizar os módulos. PROGRAMANDO O ARDUINO: Para finalizar, desconecte o pino Key do HC-05 do pino 3.3v do Arduino, e carregue o seguinte programa no Arduino: 1 //Programa : Modulo Arduino Bluetooth HC-05 - Envio 2 //Autor : FILIPEFLOP 3 4 //Carrega a biblioteca SoftwareSerial 5 #include <SoftwareSerial.h> 6 7 //Define os pinos para a serial 8 SoftwareSerial mySerial(10, 11); // RX, TX 9 10 void setup() 11 { 12 //Inicializa a serial nas portas 10 e 11 13 mySerial.begin(38400); 14 } 15 16 void loop() 17 { 18 //Envia pela serial o caracter L 19 mySerial.print("L"); 20 delay(3000); 21 //Envia pela serial o caracter D 22 mySerial.print("D"); 23 delay(3000); 24 } Esse programa envia os caracteres L (para acender o led) e D (para apagar o led) para a serial das portas 10 e 11, onde está ligado o HC-05 no primeiro Arduino. O segundo Arduino, com o HC-06, recebe esses caracteres, e acende o led ao receber o caracter L, e apaga o led ao receber o caracter D. LIGANDO DISPLAY LCD 16×2 AO PIC 16F628A Para ligarmos um display LCD 16×2 ao PIC, precisamos antes de mais nada saber como programar pic e entender um pouco sobre a forma como esse tipo de display trabalha. Um dos tipos mais comuns de controlador utilizados em displays LCD é o HD44780, que pode ser ligado ao microcontrolador usando-se 4 ou 8 fios, e que vai determinar a velocidade de comunicação entre eles. Não podemos simplesmente enviar dados à um LCD sem uma sequencia lógica. Antes de utilizá-lo, é necessário o envio de comandos que preparam o display para receber caracteres. Vamos tomar como exemplo o display LCD 16×2 com controlador HD44780, Esse tipo de display tem 16 pinos : 3 pinos de alimentação, 3 de controle, 8 de dados e 2 para acionar o backlight (ou luz de fundo), que você pode ver em detalhes na imagem abaixo : Os pinos de controle do display LCD 16×2 são o RS, o R/W e o E. O pino RS tem a função de mostrar ao display que tipo de dados estamos transmitindo. Em nível baixo (0), os dados são tratados como comandos, e em nível alto (1), os dados são tratados como caracteres. O pino R/W (Read/Write) é utilizado para determinar se estamos lendo ou transmitindo dados para o display. Já o pino ENABLE é utilizado para determinar o início da transferência de dados entre o microcontrolador e o display. Os pinos de dados D0 a D7 formam o barramento de dados. O mais comum é utilizarmos apenas 4 pinos para comunicação com o microcontrolador, mas nada impede que em aplicações mais elaboradas sejam utilizados todos os 8 pinos. Essa é uma das funções do envio de comandos que preparam o display, pois é nesse momento que determinamos se vamos usar 4 ou 8 pinos para comunicação. No Arduino temos várias bibliotecas prontas que fazem todo esse trabalho pesado. No caso do PIC, podemos agrupar os comandos também em um arquivo texto e criar uma biblioteca própria. Esse é o método que vamos utilizar nesse post, contando com a ajuda das rotinas de comando do display. Para controle do display LCD 16×2 vamos utilizar o microcontrolador PIC16F628A, e o programa desenvolvido para uso no software MPLab. Crie no MPLab a estrutura básica do projeto, e na mesma pasta do projeto crie um arquivo texto com o nome de lcd.h. Dentro desse arquivo, copie o seguinte código : 1 /***************************************************************************/ 2 /* Rotinas para o LCD */ 3 /***************************************************************************/ 4 5 //Este é o bloco com as rotinas necessárias para manipular o LCD 6 7 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8 * Envio de "Nibble" para o LCD * 9 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 10 11 //Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD. 12 void envia_nibble_lcd(int dado) 13 { 14 //Carrega as vias de dados (pinos) do LCD de acordo com o nibble lido 15 output_bit(lcd_db4, bit_test(dado,0)); //Carrega DB4 do LCD com o bit DADO<0> 16 output_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADO<1> 17 output_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADO<2> 18 output_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO<3> 19 20 //Gera um pulso de enable 21 output_high(lcd_enable); 22 delay_us(1); // Recomendado para estabilizar o LCD 23 output_low(lcd_enable); 24 return; // ENABLE = 1 // ENABLE = 0 // Retorna ao ponto de chamada da função 25 } 26 27 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 28 * Envio de Byte para o LCD * 29 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 30 31 //Esta rotina irá enviar um dado ou um comando para o LCD conforme abaixo: 32 // ENDEREÇO = 0 -> a variável DADO será uma instrução 33 // ENDEREÇO = 1 -> a variável DADO será um caractere 34 35 void envia_byte_lcd(boolean endereco, int dado) 36 { 37 output_bit(lcd_rs,endereco); // Seta o bit RS para instrução ou caractere 38 delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD 39 output_low(lcd_enable); // Desativa a linha ENABLE 40 envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando 41 envia_nibble_lcd(dado & 0x0f); // Limpa a parte ALTA e envia a parte BAIXA do 42 43 delay_us(40); 44 return; // dado/comando // Aguarda 40us para estabilizar o LCD // Retorna ao ponto de chamada da função 45 } 46 47 48 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 49 * Envio de caractere para o LCD * 50 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 51 // Esta rotina serve apenas como uma forma mais fácil de escrever um caractere 52 // no display. Ela pode ser eliminada e ao invés dela usaremos diretamente a 53 // função envia_byte_lcd(1,"<caractere a ser mostrado no LCD>"); ou 54 // envia_byte_lcd(1,<código do caractere a ser mostrado no LCD>); 55 56 void escreve_lcd(char c) 57 // envia caractere para o display 58 { 59 envia_byte_lcd(1,c); 60 } 61 62 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 63 * Função para limpar o LCD * 64 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 65 // Como esta operação pode ser muito utilizada, transformando-a em função 66 // faz com que o código compilado seja menor. 67 68 void limpa_lcd() 69 { 70 envia_byte_lcd(0,0x01); 71 delay_ms(2); 72 return; // Envia instrução para limpar o LCD // Aguarda 2ms para estabilizar o LCD // Retorna ao ponto de chamada da função 73 } 74 75 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 76 * Inicializa o LCD * 77 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 78 79 void inicializa_lcd() 80 { 81 output_low(lcd_db4); // Garante que o pino DB4 estão em 0 (low) 82 output_low(lcd_db5); // Garante que o pino DB5 estão em 0 (low) 83 output_low(lcd_db6); // Garante que o pino DB6 estão em 0 (low) 84 output_low(lcd_db7); // Garante que o pino DB7 estão em 0 (low) 85 output_low(lcd_rs); // Garante que o pino RS estão em 0 (low) 86 output_low(lcd_enable); // Garante que o pino ENABLE estão em 0 (low) 87 delay_ms(15); // Aguarda 15ms para estabilizar o LCD 88 envia_nibble_lcd(0x03); // Envia comando para inicializar o display 89 delay_ms(5); // Aguarda 5ms para estabilizar o LCD 90 envia_nibble_lcd(0x03); // Envia comando para inicializar o display 91 delay_ms(5); // Aguarda 5ms para estabilizar o LCD 92 envia_nibble_lcd(0x03); // Envia comando para inicializar o display 93 delay_ms(5); // Aguarda 5ms para estabilizar o LCD 94 envia_nibble_lcd(0x02); // CURSOR HOME - Envia comando para zerar o 95 //contador de caracteres e retornar à posição 96 // inicial (0x80). 97 delay_ms(1); // Aguarda 1ms para estabilizar o LCD 98 envia_byte_lcd(0,0x28); // FUNCTION SET - Configura o LCD para 4 bits, 99 // 2 linhas, fonte 5X7. 100envia_byte_lcd(0,0x0c); // DISPLAY CONTROL - Display ligado, sem cursor 101limpa_lcd(); // Limpa o LCD 102envia_byte_lcd(0,0x06); // ENTRY MODE SET - Desloca o cursor para a direita 103return; // Retorna ao ponto de chamada da função 104} 105 106/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 107* Define inicio da escrita * 108* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 109//Esta função foi adicionada e serve para se definir em que posição do 110//LCD deseja-se iniciar a escrita. Para isto basta chamar a Função 111//"caracter_Inicio()" indicando a linha e a coluna onde o cursor será 112// posicionado antes de se mandar escrever 113 114void caracter_inicio(int linha, int coluna)//define a posicão de inicio da frase 115{ 116int16 posicao=0; 117 if(linha == 1) 118 { 119 posicao=0x80; //Se setado linha 1, end incial 0x80 120 } 121 if(linha == 2) 122 { 123 posicao=0xc0; //Se setado linha 2, end incial 0xc0 124 } 125 126posicao=posicao+coluna; 127posicao--; //soma ao end inicial, o numero da coluna //subtrai 1 para corrigir posição 128 129envia_byte_lcd(0,posicao); 130return; 131} 132/***************************************************************************/ 133/* Final das rotinas para o LCD */ 134/***************************************************************************/ A estrutura da pasta do projeto vai ficar mais ou menos assim : No MPLab, coloque o código abaixo, que chama as rotinas contidas no arquivo lcd.h para inicializar o display, apagar a tela, enviar caracteres, etc. No circuito vamos usar um cristal de 16Mhz, mas você pode utilizar, por exemplo um de 20Mhz. Para isso, altere a linha com o comando #use delay(clock=16000000) no início do programa: 1 #include <16F628A.h> //Define o modelo do microcontrolador 2 3 // Fusíveis de configuração do microcontrolador 4 5 #FUSES NOWDT //Watch Dog Timer desabilitado 6 #FUSES HS //oscilador cristal 7 #FUSES PUT //Power Up Timer 8 #FUSES NOPROTECT //sem proteção para leitura da eprom 9 #FUSES BROWNOUT //Resetar quando detectar brownout 10 #FUSES NOMCLR 11 #FUSES NOLVP //prog. baixa voltagem desabilitado 12 #FUSES NOCPD //Sem travar o chip //Reset desabilitado 13 14 #use delay(clock=16000000) //Define o cristal utilizado 15 16 17 //Definição de entradas e saídas 18 //Cada bit representa um pino físico de I/O 19 // 0 significa que o pino será uma saída 20 // 1 significa que o pino será uma entrada 21 #define trisa 0b00000000 22 #define trisb 0b00000000 23 24 // Estas são as definições dos pinos que o LCD utiliza. 25 // Definem quais pinos do PIC controlarão os pinos do LCD 26 27 #define lcd_enable pin_a1 28 #define lcd_rs pin_a0 29 // pino enable do LCD // pino rs (register select)do LCD // (0) para comandos (1) para dados 30 31 #define lcd_db4 pin_b4 // pino de dados d4 do LCD 32 #define lcd_db5 pin_b5 // pino de dados d5 do LCD 33 #define lcd_db6 pin_b6 // pino de dados d6 do LCD 34 #define lcd_db7 pin_b7 // pino de dados d7 do LCD 35 #include <lcd.h> //declaração da biblioteca do LCD 36 37 //Programa principal 38 void main(){ 39 40 inicializa_lcd(); //Inicializa o LCD 41 42 43 while(1){ //limpa_lcd(); //Limpa o display do LCD 44 caracter_inicio(2,6); 45 printf(escreve_lcd," 46 delay_ms(500); 47 caracter_inicio(1,4); //Define o caracter de inicio da escrita 48 printf(escreve_lcd,"FILIPEFLOP"); //Escreve no LCD 49 delay_ms(2000); "); 50 51 caracter_inicio(1,4); 52 printf(escreve_lcd," 53 delay_ms(500); 54 caracter_inicio(2,6); 55 printf(escreve_lcd,"P I C"); 56 delay_ms(2000); 57 } 58 "); } //fecha void main Grave o programa utilizando o software MicroBRN, ou outro de sua preferência, e teste o microcontrolador ligando-o ao display seguindo a tabela e circuito mostrados abaixo : Além disso, ligue o pino 5 do PIC ao GND e o pino 14 ao 5v. O cristal deve ser ligado aos pinos 15 e 16 do PIC. A alimentação do circuito é de 5v e o potenciômetro é de 10 K, utilizado para controle do contraste do display LCD 16×2. Se necessário, coloque um resistor no pino 15 ou 16 para reduzir a intensidade da luz de fundo. SENSOR DE CHUVA YL-83 Se você já montou ou vai montar uma estação de monitoração climática, usando sensores de temperatura, umidade e pressão, agora tem mais um componente à disposição : o Sensor de chuva YL-83. Este conjunto é formado por uma placa que forma o sensor propriamente dito, com várias trilhas nos dois lados e material resistente à oxidação , que se encarrega de detectar o nível de chuva/umidade do ambiente. Esta placa, por sua vez, é ligada por meio de 2 fios ao módulo principal, que contém o circuito de controle que vai se comunicar com o microcontrolador. No caso deste post, o Arduino. O módulo de controle, como podemos ver acima, tem 2 pinos que vão se comunicar com a placa do sensor, e na outra extremidade, 4 pinos de sinal e alimentação : A0 (sinal analógico), D0 (sinal digital), GND e Vcc. A alimentação vai de 3.3 à 5 volts. A placa também possui, logo acima dos pinos, 2 leds. O da esquerda (verde) permanece apagado quando não há sinal no sensor, e começa a piscar ou permanece aceso quando o sensor é acionado. O led da direita (vermelho), indica que o módulo está ligado : Existem 2 formas bem simples de se trabalhar com esse sensor. Uma delas é utilizando a saída digital, que simplesmente informa se foi detectada chuva/líquido (saída em nível baixo / low) ou se o sensor está seco (saída em nível alto / high). Outra maneira, que permite maiores variações, é utilizar a saída analógica, cujo valor vai de 0 a 1023, e dessa maneira dimensionar o que você quer fazer com esse valor, indicando em um painel, por exemplo, se não há chuva, ou se ela está fraca, forte, moderada, etc. Mas chega de teoria e vamos à prática, mostrando a ligação do sensor e do módulo de controle ao Arduino, juntamente com um display LCD 16×2 : O programa abaixo lê as informações tanto da saída digital D0 do módulo, ligada ao pino 7 do Arduino, como da saída analógica A0 , ligada ao pino A5 : 1 //Programa : Teste sensor de chuva YL-83 2 //Autor : TECNOTRONICS 3 4 #include <LiquidCrystal.h> //Carrega a biblioteca LiquidCrystal 5 6 int pino_d = 7; //Pino ligado ao D0 do sensor 7 int pino_a = A5; //Pino ligado ao A0 do sensor 8 int val_d = 0; //Armazena o valor lido do pino digital 9 int val_a = 0; //Armazena o valor lido do pino analogico 10 11 //Define os pinos que serão utilizados para ligação ao display 12 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 13 14 void setup() 15 { 16 lcd.begin(16, 2); 17 pinMode(pino_d, INPUT); 18 pinMode(pino_a, INPUT); 19 Serial.begin(9600); 20 lcd.setCursor(0,0); 21 lcd.print("Chuva : "); 22 lcd.setCursor(0,1); 23 lcd.print("Intens.: "); 24 } 25 26 void loop() 27 { 28 //Le e arnazena o valor do pino digital 29 val_d = digitalRead(pino_d); 30 //Le e armazena o valor do pino analogico 31 val_a = analogRead(pino_a); 32 //Envia as informacoes para o serial monitor 33 Serial.print("Valor digital : "); 34 Serial.print(val_d); 35 Serial.print(" - Valor analogico : "); 36 Serial.println(val_a); 37 //Mostra no display se ha chuva ou nao 38 if (val_d == 1) 39 { 40 lcd.setCursor(10,0); 41 lcd.print("Nao"); 42 } 43 else 44 { 45 lcd.setCursor(10,0); 46 lcd.print("Sim"); 47 48 } 49 //Mostra no display o nivel de intensidade 50 //da chuva 51 if (val_a >900 && val_a <1023) 52 { 53 lcd.setCursor(10,1); 54 lcd.print(" 55 lcd.setCursor(10,1); 56 lcd.print("----"); "); 57 } 58 else if (val_a >600 && val_a <900) 59 { 60 lcd.setCursor(10,1); 61 lcd.print(" 62 lcd.setCursor(10,1); 63 lcd.print("Fraca"); "); 64 } 65 else if (val_a >400 && val_a <600) 66 { 67 lcd.setCursor(10,1); 68 lcd.print(" 69 lcd.setCursor(10,1); 70 lcd.print("Moder."); "); 71 } 72 else if (val_a <400) 73 { 74 lcd.setCursor(10,1); 75 lcd.print(" 76 lcd.setCursor(10,1); 77 lcd.print("Forte"); "); 78 } 79 delay(1000); 80 } No display, é mostrada a indicação de chuva, e se a mesma é fraca, moderada ou intensa : As informações sobre o sensor também são enviadas para o serial monitor, caso você não tenha um display à disposição. MOSTRANDO INFORMAÇÕES DE TEMPERATURA NO LCD 16×2 COM O DHT11 No nosso primeiro artigo sobre o sensor de temperatura e umidade DHT11 , mostramos como acompanhar as informações de temperatura e umidade no monitor serial, método ideal para quem ainda não tem um display LCD. Para quem já tem um LCD 16×2 e quer melhorar o projeto, vamos mostrar como ligar o DHT11juntamente com o display e mostrar nele as informações que precisamos. Para este circuito, você pode utilizar o módulo DHT11 ou apenas o sensor DHT11. A ligação dos dois é idêntica e utiliza apenas um pino para ligação ao Arduino. Uma característica do DHT11 é que ele não fornece informações “quebradas” de temperatura. Isso significa que o sensor vai mostrar as informações de, por exemplo, 18, 20, 25 graus, mas não as casas decimais de 18,2 ou 25,6 graus. Os números fornecidos pelo sensor são redondos. O display LCD 16×2 que vamos utilizar, baseado no controlador HD44780, é um display com backlight azul e caracteres na cor branca, com os pinos de conexão na parte superior numerados de 1 a 16. A conexão básica ao Arduino usa 6 pinos : Pino 4 (RS) ligado ao pino 12 do Arduino Pino 6 (E) ligado ao pino 11 do Arduino Pino 11 (D4) ligado ao pino 5 do Arduino Pino 12 (D5) ligado ao pino 4 do Arduino Pino 13 (D6) ligado ao pino 3 do Arduino Pino 14 (D7) ligado ao pino 2 do Arduino O pino 3 do display será ligado ao pino central de um potenciômetro de 10K, que tem a função de regular o contraste. As demais ligações são feitas ao GND (pinos 1, 5 e 16) e aos 5v do Arduino (pinos 2 e 15) , e qualquer inversão pode impedir a exibição dos caracteres : No programa, vamos utilizar a biblioteca LiquidCrystal para controle do LCD (esta biblioteca já vêm instalada na IDE), e também a biblioteca DHT, que pode ser baixada neste link. Para mostrar o símbolo do grau (º), podemos utilizar um dos caracteres especiais disponíveis nesse display, usando o comando lcd.print((char)223); Ou criar um caractere customizado, com a forma mais arredondada. Para isso, criamos um array e desenhamos nosso próprio símbolo, e para utilizá-lo no programa, usamos o comando lcd.createChar(valor, data); onde valor se refere ao nome que daremos ao caractere especial, podendo ser um número de 0 a 7, e data se refere ao array criado para formar o símbolo do grau. O comando delay no final do programa não deve ter um valor abaixo de 2000 (2 segundos), que é o valor mínimo para que o sensor possa fornecer os dados corretamente. 1 //Programa : Temperatura e umidade com o DHT11 e LCD 16x2 2 //Autor : FILIPEFLOP 3 4 #include <LiquidCrystal.h> //Carrega a biblioteca LCD 5 #include <DHT.h> //Carrega a biblioteca DHT 6 7 //Define a ligação ao pino de dados do sensor 8 #define DHTPIN A5 9 10 //Define o tipo de sensor DHT utilizado 11 #define DHTTYPE DHT11 12 13 DHT dht(DHTPIN, DHTTYPE); 14 15 //Define os pinos que serão ligados ao LCD 16 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 17 18 //Array simbolo grau 19 byte grau[8] ={ B00001100, 20 B00010010, 21 B00010010, 22 B00001100, 23 B00000000, 24 B00000000, 25 B00000000, 26 B00000000,}; 27 28 void setup() 29 { 30 Serial.begin(9600); //Inicializa a serial 31 lcd.begin(16,2); //Inicializa LCD 32 lcd.clear(); //Limpa o LCD 33 //Cria o caractere customizado com o simbolo do grau 34 lcd.createChar(0, grau); 35 } 36 37 void loop() 38 { 39 float h = dht.readHumidity(); //Le o valor da umidade 40 float t = dht.readTemperature(); //Le o valor da temperatura 41 lcd.setCursor(0,0); 42 lcd.print("Temp : "); 43 lcd.print(" "); 44 lcd.setCursor(7,0); 45 lcd.print(t,1); 46 lcd.setCursor(12,0); 47 48 //Mostra o simbolo do grau formado pelo array 49 lcd.write((byte)0); 50 51 //Mostra o simbolo do grau quadrado 52 //lcd.print((char)223); 53 54 lcd.setCursor(0,1); 55 lcd.print("Umid : "); 56 lcd.print(" "); 57 lcd.setCursor(7,1); 58 lcd.print(h,1); 59 lcd.setCursor(12,1); 60 lcd.print("%"); 61 62 //Intervalo recomendado para leitura do sensor 63 delay(2000); 64 } ACENDENDO UMA LÂMPADA COM SENSOR DE PRESENÇA Neste post vamos montar um sensor de presença com componentes fáceis de encontrar, e que pode ser utilizado para acionar um portão, acender uma lâmpada, tocar uma campainha ou acionar qualquer outro dispositivo por meio de um relé. Utilizaremos nesse projeto o eficiente módulo sensor de movimento PIR, um módulo compacto com sensor infravermelho e ajustes de sensibilidade e tempo de acionamento : Este módulo permite o ajuste da sensibilidade do sensor, ou seja, à qual distância um objeto será detectado (3 à 7 metros) , e também o tempo de delay (tempo que a saída permanece acionada, em nível alto), de 5 a 200 segundos. Os ajustes são feitos nos 2 potenciômetros soldados à placa. Observando a foto, vemos que o da esquerda ajusta a sensibilidade, e o da direita ajusta o tempo : O sensor aceita alimentação de 4,5 à 20V, e a conexão com o Arduino utiliza apenas um pino, que apresenta o estado HIGH (alto), ao detectar um movimento, e LOW (baixo) quando não há movimentação perto do sensor. Maiores informações sobre o funcionamento do módulo podem ser obtidas no datasheet do produto, nesse link. Para utilização com um relé, precisaremos construir um circuito de proteção para evitar danos ao Arduino. Se você utilizar um módulo relé, o circuito de proteção não será necessário, pois ele já está embutido no módulo. Aproveite e confira um post usando este sensor de presença PIR para Acionar lâmpadas com módulo relé arduino. Os componentes para o circuito do relé são os seguintes: 1 relé 5V 1 diodo 1N4007 ou equivalente 1 Transistor BC548 (ou equivalente NPN) 1 Resistor de 10 K IMPORTANTE : Neste circuito, estamos utilizando uma lâmpada ligada à rede elétrica (110 volts). Ao montar o circuito, confira com cuidado a ligação dos componentes para evitar choques. Lembre-se que dependendo do tipo de relé que você estiver utilizando, a disposição dos pinos pode variar. No circuito, NO corresponde ao pino Normal Open (Aberto), NC ao Normal Close (Fechado), e C ao comum. Siga a mesma ligação ao relé que você estiver usando. O programa abaixo verifica se o pino 7 (entrada do sensor de movimento) foi acionado, ou seja, se está em estado alto (HIGH), e então aciona o pino 2 (saída para o relé), que por sua vez aciona o relé e acende a lâmpada. 1 //Programa : Sensor de presenca com modulo PIR 2 //Autor : TECNOTRONICS 3 4 int pinorele = 2; //Pino ligado ao rele 5 int pinopir = 7; //Pino ligado ao sensor PIR 6 int acionamento; //Variavel para guardar valor do sensor 7 8 void setup() 9 { 10 pinMode(pinorele, OUTPUT); //Define pino rele como saida 11 pinMode(pinopir, INPUT); //Define pino sensor como entrada 12 Serial.begin(9600); 13 } 14 15 void loop() 16 { 17 acionamento = digitalRead(pinopir); //Le o valor do sensor PIR 18 19 if (acionamento == LOW) //Sem movimento, mantem rele desligado 20 { 21 digitalWrite(pinorele, LOW); 22 Serial.println("Parado"); 23 } 24 else //Caso seja detectado um movimento, aciona o rele 25 { 26 digitalWrite(pinorele, HIGH); 27 Serial.println("Movimento !!!"); 28 } 29 } Opcionalmente, você pode acrescentar um LDR (resistor sensível à luz) ao circuito para que a lâmpada seja acionada apenas durante a noite, evitando desperdício de energia. CONTROLANDO MOTOR DE PASSO 5V 28BYJ-48 COM ARDUINO MOTOR SHIELD L293D Já falamos sobre Como controlar um motor de passo 5v utilizando o driver de controle ULN2003. O post de hoje vai utilizar o mesmo motor de passo 5v, o 28BYJ-48, mas desta vez controlado peloArduino Motor Shield L293D. Este Arduino Motor Shield é muito prático, e pode controlar até 4 motores DC, 2 servos e 2 motores de passo. Já mostramos a utilização deste shield no artigo Controlando motor DC 12v com Arduino Motor Shield. O Motor de passo 5v Arduino é muito utilizado para controle de robôs e posicionamento de braços mecânicos, suportes e outros dispositivos. Tem um bom torque, graças à caixa de redução, e trabalha em baixa velocidade. Este motor é alimentado por 5v, possui uma redução de 1/64 e segundo o datasheet , são necessários 64 passos para que o motor dê uma volta completa (5,625º / 64 passos ), isso em modo “puro” (sem redução). Com a redução de 1/64 ,o número de passos aumenta para 4096 (64 * 64 = 4096). Esses valores são válidos se utilizarmos o esquema de ativação das bobinas em 8 passos (half-mode, ou meio-passo). Se utilizarmos o esquema de ativação de 4 passos (full-step, ou passo inteiro), que é o padrão utilizado pela biblioteca do Arduino, o número de passos necessários cai pela metade, para 2048. Para entendermos essa diferença, vamos dar uma olhada na tabela abaixo, que mostra o acionamento das bobinas do motor em 8 etapas : Nesse modo, primeiro é acionada uma bobina, depois duas, depois uma novamente, depois duas, e assim por diante, em 8 etapas. Já no modo de 4 passos, são acionadas 2 bobinas de cada vez, o que reduz o número de acionamentos necessários para girar o motor : Também no modo 4 passos, teoricamente teremos mais força no motor, pois estamos acionando duas bobinas ao mesmo tempo. Muitas vezes queremos que o motor de passo gire apenas um determinado número de graus. Tendo em mãos o número total de passos utilizados pelo motor para dar uma volta completa, fica fácil calcular o ângulo de cada passo. Basta dividir 360 graus pelo número de passos. No caso do nosso motor de passo 5v 28BYJ-48, fica assim : 360 º / 2048 passos = 0,17578125 graus/passo Dessa forma, se quisermos movimentar o motor 90 graus, por exemplo, dividimos 90 pelo valor que obtivemos anteriormente : 90 º / 0,17578125 graus/passo = 512 passos É importante destacar que algumas bibliotecas já fazem isso automaticamente, com funções onde você apenas fornece o ângulo de deslocamento e a biblioteca se encarrega de movimentar o eixo do motor até o ponto desejado. O shield motor utilizado nos testes tem a capacidade de controlar 2 motores de passo ao mesmo tempo. Para isso, utilizamos os conectores M1, GND e M2 do lado esquerdo da placa, ou os conectores M3, GND e M4 do lado direito. No programa, isso é referenciado como Porta 1 (motor de passo ligado ao M1/M2), e Porta 2 (motor de passo ligado ao M3/M4). Não é necessária alimentação externa, pois os 5v serão fornecidos pelo Arduino, assim podemos manter o jumper no conector PWR, confome indicado : No programa vamos utilizar a biblioteca AFMotor, específica para este motor shield. Baixe a biblioteca em formato ZIP, descompacte a pasta, renomeie para AFMotor, e coloque essa pasta dentro da pasta LIBRARIES do programa (IDE) do seu Arduino. Para definirmos o motor que está sendo utilizado, usamos o comando AF_Stepper nome(passos_total, porta_motor) Onde nome será utilizado para se referir ao motor que estamos definindo, e pode ser um nome qualquer, para facilitar a identificação (ex. motor1, motor2, motorprincipal, motorsecundario, etc) , passos_total se refere ao número de passos que o motor necessita para dar uma volta completa no eixo, e porta_motor se refere ao conector onde foi ligado fisicamente o motor de passo. (Relembrando : 1 para motor de passo no conector M1/M2 e 2 para conector M3/M4). No circuito acima, estamos utilizando o motor na porta 2. O movimento do motor de passo 5v, propriamente dito, é determinado pelo comando nome.step(numero_de_passos, direção, tipo_de_passo) onde direção pode ter os valores FORWARD (giro do motor no sentido horário), ou BACKWARD(sentido anti-horário). A variável tipo_de_passo determina o modo como as bobinas serão acionadas, e pode ter o valor SINGLE (uma bobina por vez), DOUBLE (duas bobinas, aumentando o torque), INTERLEAVE (alternando entre 1 e 2 bobinas, aumentando a precisão), eMICROSTEPPING, que gera um movimento mais suave e preciso. Esses dois últimos métodos, entretanto, podem não funcionar com qualquer tipo de motor. Juntando todas essas informações, temos um programa que move o motor no sentido horário, calculando o número de passos baseado no ângulo fornecido no início do programa : 1 //Programa : Motor de passo 5v 28BYJ-48 com Arduino Motor Shield L293D 2 //Autor : FILIPEFLOP 3 4 #include <AFMotor.h> 5 double passos_total = 2048; //Numero de passos para 1 rotacao total 6 7 int porta_motor = 2; //1 para motor em M1/M2 e 2 para motor em M3/M4 8 int angulo = 30; //Angulo de rotacao do eixo 9 10 11 double numero_de_passos = 0; //Armazena o numero de passos que o motor vai girar 12 13 AF_Stepper arduino(passos_total, porta_motor); //Define os parametros do motor 14 15 void setup() 16 { 17 arduino.setSpeed(10); //Define a velocidade de rotacao 18 Serial.begin(9600); 19 } 20 21 void loop() 22 { 23 //Calcula a quantidade de passos, baseado no angulo determinado 24 numero_de_passos = angulo / (360 / passos_total); 25 26 //Mostra no serial monitor o numero de passos calculados 27 Serial.println(numero_de_passos); 28 29 //Move o motor. Use FORWARD para sentido horario, 30 //BACKWARD para anti-horario 31 arduino.step(numero_de_passos, FORWARD, SINGLE); 32 arduino.release(); 33 34 delay(2000); } CONTROLE MOTOR DC 12V COM ARDUINO MOTOR SHIELD L293D Controlar um motor DC usando o Arduino é uma tarefa simples que não exige muitos componentes. Geralmente um chip controlador de motor, como o L293D ou L298N (Ponte H), Acontece que conforme os projetos vão ficando mais elaborados você precisará misturar mais motores DC ou acrescentar motores de passo, e apenas um circuito integrado não será suficiente. Uma forma de interligar tudo isso é usando um Arduino Motor Shield L293D, como esse: Esse Arduino Motor Shield tem 2 chips L293D (datasheet) e um 74HC595, o que permite o controle de 4 motores DC, 2 servos ou 2 motores de passo e suporta motores com tensões de 4,5 à 25 Vcc. É com este shield que vamos mostrar como controlar um Motor DC Arduino: Este é um motor com construção robusta, rotação máxima de 80 RPM, alto torque (3 Kg/cm) e consumo de corrente de 100 mA (sem carga). O diâmetro do eixo mede 4mm de diâmetro por 9,5mm de comprimento, o que torna prático o encaixe de engrenagens, polias ou qualquer outro acessório, como nesta configuração: PRINCÍPIO DE FUNCIONAMENTO PONTE H: Vamos controlar este motor usando o Arduino Motor Shield mencionado anteriormente, mas antes, vamos ver como funciona o conceito de Ponte H, utilizado para inverter a rotação do motor. Ponte H é um circuito bem simples composto por 4 chaves, um motor e uma fonte de energia : Observe a figura abaixo. Acionando a chave S1 e a chave S4, o sentido da corrente será da esquerda para a direita, acionando o motor. Se desligarmos as chaves S1 e S4 e ligarmos as chavesS2 e S3, o sentido da corrente passa a ser da direita para a esquerda, invertendo o sentido de rotação do motor. Este é o conceito de ponte H. O que o circuito integrado L293D faz é utilizar transistores e diodos para fazer esse chaveamento, com a vantagem de ter um tamanho bem reduzido. Além disso, ele é composto por duas pontes H, ou seja, cada CI consegue controlar 2 motores. CONECTANDO O ARDUINO MOTOR SHIELD L293D: Encaixe o shield no Arduino (compatível Uno e Mega) e siga o esquema abaixo : conecte o motor DC às saídas M1-A e M1-B. Como o motor é de 12 Vdc, não podemos usar a alimentação do Arduino (5v), logo, retire o jumper indicado (PWR), e conecte uma fonte de 12 Vdc ao conector EXT_PWR : CONTROLE DE MOTOR DC COM ARDUINO: Antes de montar e ligar o shield, baixe a biblioteca do Arduino Motor Shield neste link. Descompacte a pasta, renomeie para AFMotor, e coloque essa pasta dentro da pasta LIBRARIESdo programa (IDE) do seu Arduino. Não esqueça de sair e carregar a IDE novamente para que a biblioteca seja reconhecida pelo programa. Com o uso da biblioteca, a programação fica bem simplificada. O programa abaixo rotaciona o motor no sentido horário, pára por 5 segundos, e depois inverte o sentido de rotação : motor.setSpeed(velocidade) = define a velocidade de rotação do motor, podendo ser um valor entre 0 (motor parado) e 255 (rotação máxima) motor.run(sentido) = aciona o motor no sentido definido : FORWARD (frente/horário), BACKWARD(sentido contrário/anti- horário), ou pára o motor (RELEASE). 1 //Programa : Teste de motor DC12V com motor shield ponte H 2 //Autor : Equipe FILIPEFLOP 3 4 #include <AFMotor.h> 5 6 7 AF_DCMotor motor(1); //Seleciona o motor 1 8 void setup() 9 {} 10 11 void loop() 12 { 13 motor.setSpeed(255); //Define a velocidade maxima 14 motor.run(FORWARD); //Gira o motor sentido horario 15 16 delay(5000); 17 motor.setSpeed(0); 18 motor.run(RELEASE); //Desliga o motor 19 20 delay(5000); 21 motor.setSpeed(50); //Define velocidade baixa 22 motor.run(BACKWARD); //Gira o motor sentido anti-horario 23 24 delay(5000); 25 motor.setSpeed(0); 26 motor.run(RELEASE); //Desliga o motor 27 28 delay(5000); //Aguarda 5 segundos e repete o processo 29 } DISPLAY DE LEDS MATRIZ BICOLOR 8×8 Existem vários tipos de displays LCD, muito úteis quando queremos mostrar alguma mensagem ou acompanhar um estado de um sensor conectado ao Arduino. Esses displays, entretanto, até pelo tamanho geralmente reduzido, não são suficientes quando precisamos montar algum sistema de alarme ou apresentar uma informação que seja facilmente vista de longe. Para esses casos, o mais indicado é o display LED matricial 8×8 bicolor , um display de anodo comum, tamanho 3cm x 3cm, composto por 64 leds bicolores. Com ele, você pode desenvolver painéis gráficos, indicativos de alarme, letreiros e outras aplicações utilizando efeitos visuais variados. Para controle deste tipo de display, vamos utilizar o CI 74HC595, um registrador de deslocamento de 8 bits, que recebe os dados de forma serial (1 bit de cada vez), e consegue enviá-los de forma serial ou paralela (8 bits de cada vez). Olhando a figura abaixo, retirada do datasheet, vemos que o display tem 24 pinos, sendo 8 para as linhas, 8 para os leds verdes e 8 para os leds vermelhos: Desta forma, para controlar este display, vamos utilizar 3 CI´s 74HC595 : um para as 8 linhas, um para os 8 leds verdes e um para os 8 leds vermelhos. Além disso, vamos utilizar também o CI driver de corrente, o UDN2981. O uso deste CI evita que o 74HC595 seja danificado em razão do excesso de corrente exigida para o funcionamento do display quando há a necessidade de ligar vários leds ao mesmo tempo. A ligação do circuito exige bastante atenção, pela quantidade de fios envolvida e também porque qualquer inversão de fios pode danificar os componentes ou causar mal funcionamento do circuito. O CI 74HC595 que vai controlar os leds verdes, deve ser ligado aos pinos 24, 21, 18, 15, 1, 4, 7 e 10 do display.O CI controlador dos leds vermelhos será ligado aos pinos 23, 20, 17, 14, 2, 5, 8 e 11do display. Já o CI que vai controlar as linhas será ligado ao UDN2981 de forma inversa, ou seja, o Q7 do 74HC595 será ligado ao pino 1 do UDN2981, que por sua vez será ligado ao pino 22 do display (linha 1), o Q6 do 74HC595 será ligado ao pino 2 do UDN2981, que será ligado ao pino 19 do display (linha 2), e assim por diante. O valor dos resistores que utilizamos para ligação aos catodos é de 220 ohms, mas outros valores podem ser utilizados, observando o fato que isso pode gerar alteração na luminosidade do display : Preste atenção também à disposição dos CI´s no circuito. Os 74HC595 estão com o pino 1 do lado esquerdo, já o UDN2981 está invertido, com o pino 1 no lado direito. Observe abaixo a pinagem dos dois CI´s : Por fim, utilizamos o programa abaixo, que gera uma animação no display com os leds vermelhos e verdes “percorrendo” a tela na vertical : 1 //Programa : Teste Matriz de leds bicolor 8x8 2 // 3 //Baseado no programa original de Derek Molloy : derekmolloy.ie 4 //Alteracao e adaptacao : FILIPEFLOP 5 6 const int NUM_ROWS = 8; 7 const int NUM_COLS = 8; 8 9 const int dataPin = 8; 10 const int clockPin = 9; 11 const int latchPin = 10; 12 13 int gdataset[13][8] = {{1,1,1,1,1,1,1,1}, {2,2,2,2,2,2,2,2}, 14 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 15 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 16 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 17 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 18 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 19 {0,0,0,0,0,0,0,0,}}; 20 21 int rdataset[13][8] = {{1,1,1,1,1,1,1,1}, {2,1,2,1,2,1,2,1}, 22 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 23 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 24 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 25 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 26 {0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,0,}, 27 {0,0,0,0,0,0,0,0,}}; 28 29 void setup() 30 { 31 pinMode(clockPin, OUTPUT); 32 pinMode(dataPin, OUTPUT); 33 pinMode(latchPin, OUTPUT); 34 } 35 36 void loop() 37 { 38 int i=0; 39 while (true) 40 { 41 displayPixels(i,20); 42 i++; 43 if (i==11) (i=0); 44 45 } } 46 47 void displayPixels(int val, int delay) 48 { 49 for (int i=0; i<delay ; i++) 50 { 51 for (int row=0; row<NUM_ROWS; row++) 52 { 53 int rcur = rdataset[val][row]; 54 int gcur = gdataset[val][row]; 55 shiftOut(dataPin, clockPin, MSBFIRST, 255-rcur); 56 shiftOut(dataPin, clockPin, MSBFIRST, 255-gcur); 57 shiftOut(dataPin, clockPin, MSBFIRST, B00000001 <<row); 58 digitalWrite(latchPin, HIGH); 59 digitalWrite(latchPin, LOW); 60 delayMicroseconds(100); 61 shiftOut(dataPin, clockPin, MSBFIRST, 255); 62 shiftOut(dataPin, clockPin, MSBFIRST, 255); 63 shiftOut(dataPin, clockPin, MSBFIRST, B00000001 <<row); 64 digitalWrite(latchPin, HIGH); 65 digitalWrite(latchPin, LOW); 66 } 67 68 } } CONTROLANDO MICRO SERVO 9G USANDO JOYSTICK Quem começa a mexer com servo motores no Arduino geralmente tem, como um dos primeiros projetos, controlar o ângulo de rotação do motor usando um potenciômetro, ou utilizar botões para girar o eixo para a direita ou para a esquerda. Hoje mostraremos uma outra alternativa, que é o uso de um Módulo Joystick para controle de Micro Servos 9g. O módulo joystick trabalha com potenciômetros para definir o deslocamento dos eixos X e Y, e um push button para o eixo Z. Cada eixo se comunica com o Arduino por meio de um conector de 3 pinos, sendo que 2 desses pinos são ligados ao GND (pino -) e Vcc (pino +), e o terceiro pino (pino S) corresponde ao sinal de dados. O servo que vamos utilizar, o micro servo 9g, é muito utilizado em aeromodelismo e projetos de robótica por seu tamanho e peso reduzidos, que não comprometem o torque e o desempenho do motor: No nosso circuito, vamos ligar dois servo motores ao Arduino, e controlar um deles pelo movimento do joystick no eixo X, e outro pelo movimento do eixo Y. Um exemplo de utilização de dois servo motores é o controle de câmeras com função pan/tilt. Nesse tipo de dispositivo, é utilizado um servo para controlar a rotação da base, e outro para alterar a inclinação da câmera : Como o joystick é formado basicamente por dois potenciômetros e um push button, não há necessidade de utilizar bibliotecas específicas para o módulo. Já para o servo, utilizaremos a biblioteca SERVO. Criamos dois objetos dentro do programa, para controlar os dois motores. Um é o servo_base, ligado à porta 7 do Arduino, e o outro o servo_inclinacao, ligado à porta 8. Dentro do loop, simplesmente vamos ler os valores recebidos dos potenciômetros (eixo X, porta analógica 4 e eixo Y, porta analógica 5), e utilizar esses valores para movimentar o servo correspondente dentro do limite de 180 graus. 1 //Programa : Controle servo motor com joystick 2 //Autor : FILIPEFLOP 3 4 #include <Servo.h> 5 6 //Cria objeto para controlar o servo base 7 Servo servo_base; 8 //Cria objeto para controlar o servo inclinacao 9 Servo servo_inclinacao; 10 11 int pino_x = A4; //Pino ligado ao X do joystick 12 int pino_y = A5; //Pino ligado ao Y do joystick 13 int val_x; //Armazena o valor do eixo X 14 int val_y; //Armazena o valor do eixo Y 15 16 void setup() 17 { 18 //Define a porta a ser ligada ao servo base 19 servo_base.attach(7); 20 //Define a porta a ser ligada ao servo inclinacao 21 servo_inclinacao.attach(8); 22 } 23 24 void loop() 25 { 26 //Recebe o valor do joystick, eixo X 27 val_x = analogRead(pino_x); 28 //Converte o valor lido para um valor entre 1 e 180 graus 29 val_x = map(val_x, 0, 1023, 1, 180); 30 //Move o servo base para a posicao definida pelo joystick 31 servo_base.write(val_x); 32 //Recebe o valor do joystick, eixo Y 33 val_y = analogRead(pino_y); 34 //Converte o valor lido para um valor entre 1 e 180 graus 35 val_y = map(val_y, 0, 1023, 1, 180); 36 //Move o servo inclinacao para a posicao definida pelo joystick 37 servo_inclinacao.write(val_y); 38 //Aguarda a movimentacao do servo e reinicia a leitura 39 delay(15); 40 } PROGRAMANDO UM ARDUINO PRO MINI COM ARDUINO UNO Mexer com o Arduino é muito prático quando você está em um ambiente de testes, em cima da bancada, com uma infinidade de fios encaixados na protoboard. Por outro lado, às vezes existe a necessidade de se fazer instalações permanentes do Arduino, em espaços restritos. Vamos pegar como exemplo um projeto de acionamento de lâmpada utilizando relé e controle remoto IR, controlado pelo Arduino Uno. Se você for utilizar isso em algum cômodo da sua residência, provavelmente vai ter que colocar o Arduino perto do interruptor para ligar os fios, e improvisar uma caixa ou algum tipo de suporte para a placa. Seria bem mais prático se você pudesse colocar todo o circuito dentro da própria caixa do interruptor, embutida na parede. Para esses casos, existe uma versão reduzida do Arduino chamada Arduino Pro Mini, uma placa de 34 x 19 mm que faz tudo o que um Arduino “normal” faz, sem ocupar tanto espaço. Antes de detalharmos as conexões da placa, vamos dar uma olhada em suas principais características: Microcontrolador ATmega328p 14 Portas digitais, das quais 6 podem ser usadas como PWM 8 portas analógicas Botão de reset Alimentação : 5 à 12v Memória de 32K Led indicador de funcionamento e led ligado à porta 13, como no Arduino Uno Corrente máxima por porta : 40 mA Clock : 16 Mhz O modelo da imagem acima, vem com 2 barras de pinos para os conectores das portas laterais, e 1 barra de pinos 90 graus para conexão dos pinos de comunicação com o módulo FTDI, já que essa placa não vem com a parte de comunicação USB embutida. Os pinos no lado direito (GRN, TX, RX, Vcc, GND e BLK) são usados para alimentação e programação, e devem ser ligados na seguinte ordem : GRN – Ligado à porta RESET do Arduino TXD – Ligado ao pino 1 (TX) do Arduino RX – Ligado ao pino 0 (RX) do Arduino Vcc – Ligado ao 5v do Arduino GND – Ligado ao GND do Arduino BLK – Não conectado Atenção nessa ligação, pois alguns módulos podem vir com essa pinagem invertida, mas você deve seguir o esquema de ligação listado acima, ok Finalmente, os pinos nas laterais são utilizados pelas portas e também para alimentação do Arduino Mini utilizando uma fonte externa. Como eu comentei acima, o Arduino Mini vem com 3 barras de pinos, mas elas não vem soldadas. Assim, você pode escolher a configuração que seja mais adequada ao seu projeto, e até mesmo nem usar a barra de pinos, soldando direto os fios nas portas ou utilizando algum outro tipo de conector. A parte de programação é semelhante às outras placas Arduino, com a diferença que no Arduino Mini o circuito de comunicação USB não está embutido na placa. Logo tem a opção de adquirir um módulo FTDI, como esse… …ou então, se você tem um Arduino Uno disponível, pode usar o procedimento a seguir para programar seu Arduino Mini. Antes de mais nada, é necessário retirar o microcontrolador Atmega do Arduino Uno, para evitar qualquer tipo de conflito que atrapalhe o funcionamento do circuito. Retirado o chip, monte o circuito da seguinte maneira : Conecte o cabo USB no Arduino Uno e abra a IDE do Arduino. Observe que o Arduino Mini também será ligado, já que está sendo alimentado pelos 5v do Arduino Uno. Na IDE, vá no menu FERRAMENTAS, depois em PLACA, e escolha “ARDUINO PRO or PRO MINI (5V, 16 Mhz) W/ ATmega328″ : Feito isso, utilize a IDE para carregar normalmente seu programa no Arduino Mini. Para teste, utilizei a porta 7 para piscar um led : 1 //Programa : Teste Arduino Mini 2 //Autor : Arduino e Cia 3 4 int portaled = 7; 5 6 void setup() 7 { 8 9 10 pinMode(portaled, OUTPUT); } 11 void loop() 12 { 13 digitalWrite(portaled, HIGH); 14 delay(1000); 15 digitalWrite(portaled, LOW); 16 delay(1000); 17 } Para usar o seu Arduino Mini depois de programado, sem depender do Arduino Uno, conecte uma fonte de alimentação 5v utilizando as portas laterais: COMO COMUNICAR COM O ARDUINO ETHERNET SHIELD W5100 Controlar sensores ou enviar informações remotamente é um dos grandes objetivos de quem mexe com Arduino. O Arduino Ethernet Shield W5100 é outro dispositivo dessa família, que além de possibilitar o acesso às informações na sua rede local, ainda pode ser conectado à internet e permitir o seu monitoramento de qualquer lugar do mundo. Acoplando o Arduino Ethernet Shield W5100 ao seu Arduino, basta um simples cabo de rede para que, em poucos minutos, você passe a monitorar o estado de sensores, chaves e outros dispositivos à partir do browser do seu computador ou celular. Este Shield é baseado no ethernet chip Wiznet W5100 (datasheet) e fornece um endereço IP compatível com os protocolos TCP e UDP. O primeiro passo deste tutorial para setar corretamente o seu shield ethernet é configurá-lo com um endereço IP válido da sua rede. Vamos mostrar como obter as informações de rede no Windows 7, mas você pode usar o mesmo princípio para outros sistemas operacionais. CONFIGURAÇÃO IP: Clique em INICIAR e, na caixa de diálogo, digite CMD. Em seguida pressione a tecla ENTER : Na janela de prompt de comando, digite “ipconfig /all” (sem as aspas) e aperte ENTER : O comando será executado e várias informações aparecerão na tela. Procure pela informação referente à sua placa de rede principal, semelhante à esta destacada na imagem, pois são essas informações que você irá precisar para configurar o shield : Endereço IP, Máscara de sub-rede e Gateway Padrão : Esses três parâmetros são definidos logo no início do programa, e devem ser alterados de acordo com a configuração da sua rede : IPAddress ip(192,168,1,88) : Troque por um endereço IP no mesmo formato daquele que você copiou na janela de prompt de comando, mas o último número deve ser diferente. Exemplo : o IP do nosso equipamento é 192.168.1.120, e no programa utilizamos o 192.168.1.88. Antes de usar qualquer endereço da rede, certifique-se que o mesmo ainda não está em uso por nenhum outro equipamento. IPAddress gateway(192,168,1,1) : Utilize o mesmo endereço do Gateway Padrão que você obteve na janela de prompt de comando. No nosso caso, 192.168.1.1 IPAddress subnet(255,255,255,0) : Utilize o mesmo endereço referente à máscara de sub-rede, que você obteve na janela de prompt de comando : 255.255.255.0 Altere esses parâmetros de acordo com a sua configuração de rede, salve o programa e carregue-o no seu Arduino. Lembrando que a biblioteca Ultrasonic pode ser encontrada nesse link. 1 //Programa : Arduino Ethernet Shield W5100 e HC-SR04 2 //Alteracoes e adaptacoes : FILIPEFLOP 3 // 4 //Baseado no programa exemplo de 5 //by David A. Mellis e Tom Igoe 6 7 #include <Ultrasonic.h> 8 #include <SPI.h> 9 #include <Ethernet.h> 10 11 //Define os parametros para o sensor ultrasonico HC-SR04 12 #define PINO_TRIGGER 6 //Porta ligada ao pino Trigger do sensor 13 #define PINO_ECHO 14 //Inicializa o sensor ultrasonico 15 Ultrasonic ultrasonic(PINO_TRIGGER, PINO_ECHO); 7 //Porta ligada ao pino Echo do sensor 16 17 //Definicoes de IP, mascara de rede e gateway 18 byte mac[] = { 19 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 20 IPAddress ip(192,168,1,88); 21 IPAddress gateway(192,168,1,1); //Define o endereco IP //Define o gateway 22 IPAddress subnet(255, 255, 255, 0); //Define a máscara de rede 23 24 //Inicializa o servidor web na porta 80 25 EthernetServer server(80); 26 27 void setup() 28 { 29 //Inicializa a interface de rede 30 Ethernet.begin(mac, ip, gateway, subnet); 31 server.begin(); 32 } 33 34 void loop() { 35 float cmMsec; 36 long microsec = ultrasonic.timing(); 37 //Le e armazena as informacoes do sensor ultrasonico 38 cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); 39 40 //Aguarda conexao do browser 41 EthernetClient client = server.available(); 42 if (client) { 43 Serial.println("new client"); 44 // an http request ends with a blank line 45 boolean currentLineIsBlank = true; 46 while (client.connected()) { 47 if (client.available()) { 48 char c = client.read(); 49 Serial.write(c); 50 // if you've gotten to the end of the line (received a newline 51 // character) and the line is blank, the http request has ended, 52 // so you can send a reply 53 if (c == 'n' && currentLineIsBlank) { 54 // send a standard http response header 55 client.println("HTTP/1.1 200 OK"); 56 client.println("Content-Type: text/html"); 57 client.println("Connection: close"); 58 client.println("Refresh: 2"); //Recarrega a pagina a cada 2seg 59 client.println(); 60 client.println("<!DOCTYPE HTML>"); 61 client.println("<html>"); 62 //Configura o texto e imprime o titulo no browser 63 client.print("<font color=#FF0000><b><u>"); 64 client.print("Envio de informacoes pela rede utilizando Arduino"); 65 client.print("</u></b></font>"); 66 client.println("<br />"); 67 client.println("<br />"); 68 //Mostra o estado da porta digital 3 69 int porta_digital = digitalRead(3); 70 client.print("Porta Digital 3 : "); 71 client.print("<b>"); 72 client.print(porta_digital); 73 client.println("</b>"); 74 client.print(" (0 = Desligada, 1 = Ligada)"); 75 client.println("<br />"); 76 //Mostra as informacoes lidas pelo sensor ultrasonico 77 client.print("Sensor Ultrasonico : "); 78 client.print("<b>"); 79 client.print(cmMsec); 80 client.print(" cm"); 81 client.println("</b></html>"); 82 break; 83 } 84 if (c == 'n') { 85 // you're starting a new line 86 currentLineIsBlank = true; 87 } 88 else if (c != 'r') { 89 // you've gotten a character on the current line 90 currentLineIsBlank = false; 91 } 92 } 93 } 94 // give the web browser time to receive the data 95 delay(1); 96 // close the connection: 97 client.stop(); 98 } 99 } ENVIANDO INFORMAÇÕES PELA REDE: Encaixe o Arduino Ethernet Shield W5100 ao seu Arduino e ligue-o à um roteador ou hub usando um cabo de rede comum. Vamos usar o webserver embutido na placa para enviar ao browser duas informações sobre as portas do Arduino, uma informando sobre o estado (ligado/desligado) de um botão ligado à porta 3, e outro com informações sobre o Sensor Ultrasonico HC-SR04, ligado às portas 6 (pino trigger do sensor) e 7 (pino echo do sensor): Para testar o funcionamento, abra o browser no seu computador e digite na barra de endereços o IP que você configurou no programa. No nosso caso 192.168.1.88 : Você também pode acessar pelo celular: As informações serão enviadas pelo webserver da placa ethernet à cada 2 segundos (veja no programa que esse tempo é configurável). Também podemos configurar no programa os comandos html para formatação, como por exemplo <font> para exibir o texto do título na cor vermelha, <b> para negrito e <u> para sublinhado. Você também pode utilizar outros comandos HTML. COMO MONTAR UM ROBÔ SEGUIDOR DE LINHA COM ARDUINO MOTOR SHIELD Quando publicamos o post Controle motor DC 12V com o Motor Shield Arduino, recebemos várias mensagens dos leitores, com dúvidas sobre como utilizar as portas que “sobram” no shield para ligar lâmpadas e sensores. Por isso vamos apresentar um projeto de um Robô seguidor de linha, por muito conhecido também por robô segue faixa. Segundo o fabricante deste shield, as portas utilizadas pelos motores são as seguintes : Controle de motores DC : Pinos 11, 3, 5 e 6 Controle de motores de passo : Pinos 4, 7, 8 e 12 Controle de servo motores : Pinos 9 e 10 Desta forma, as portas que podemos utilizar livremente são as 6 portas analógicas, assim como as digitais 2 e 13, isso se estivermos falando de um Arduino Uno. Em um Arduino Mega, por exemplo, todas as demais portas também estarão disponíveis. MONTANDO UM ROBÔ SEGUIDOR DE LINHA: Um bom exemplo de utilização deste Arduino motor shield é em aplicações de robótica, como por exemplo na montagem de um robô seguidor de linha. Para facilitar sua vida existem Kits de chassi para robôs com 2 ou 4 rodas. Esses kits já vem com motores, suporte de baterias, acessórios e você só precisa adicionar o Arduino (ou outra placa de sua preferência), os sensores e o circuito controlador de motores. Para o caso do Arduino, recomendamos a utilização do Motor Shield citado acima, já que ele se encaixa perfeitamente em um Arduino Uno economizando espaço na montagem do robô. Podemos utilizar como sensor os LDR´s (resistores dependentes de luz), ou então sensores ópticos reflexivos, como o TCRT5000, que terão a função de “enxergar” a linha e transmitir essa informação para o Arduino. PROJETO ROBÔ SEGUIDOR DE LINHA: Para o nosso “carrinho” segue faixa, vamos utilizar 3 sensores ópticos ligados lado a lado. Conforme a linha for detectada (ou não), cada sensor enviará ao Arduino as informações sobre a intensidade do sinal infravermelho refletido, e o programa usará essas informações para calcular a velocidade de cada motor. A ilustração abaixo mostra, de forma resumida, como os sensores se comportam: Transportando essa idéia para o nosso motor shield, vamos utilizar as portas A0, A1 e A2 para ligação dos sensores. O motor da esquerda será ligado ao conector M1, e o motor da direita ao conector M4, utilizando a própria alimentação do Arduino (mantenha o jumper PWR na placa). Demonstramos a ligação dos sensores em uma protoboard, utilizando resistores de 330 ohms para o led infravermelho (parte superior/azul do sensor), e resistores de 10 K na parte inferior (receptor) : A maneira mais conveniente de ligar os sensores ao shield é utilizar uma barra de pinos (macho ou fêmea) soldada à placa, como na imagem abaixo : CONTROLE DO ROBÔ SEGUIDOR DE LINHA COM ARDUINO: Para acionar o circuito vamos utilizar, com algumas adaptações, o programa criado por Michael McRoberts e disponível no livro Arduíno Básico. Adicionamos as funções da biblioteca AFMotor, responsável por comandar o motor shield. A biblioteca AFMotor pode ser encontrada nesse link. Descompacte a pasta, renomeie para AFMotor, e coloque essa pasta dentro da pastaLIBRARIES do programa (IDE) do seu Arduino. Não esqueça de sair e carregar a IDE novamente para que a biblioteca seja reconhecida pelo programa. 1 //Programa : Motor shield com sensor TCRT5000 2 //Adaptacoes : FILIPEFLOP 3 // 4 //Baseado no programa original de Michael McRoberts 5 6 #include <AFMotor.h> 7 8 AF_DCMotor motor_esq(1); //Seleciona o motor 1 9 AF_DCMotor motor_dir(4); //Seleciona o motor 4 10 11 int SENSOR1, SENSOR2, SENSOR3; 12 13 //deslocamentos de calibracao 14 int leftOffset = 0, rightOffset = 0, centre = 0; 15 //pinos para a velocidade e direcao do motor 16 int speed1 = 3, speed2 = 11, direction1 = 12, direction2 = 13; 17 //velocidade inicial e deslocamento de rotacao 18 int startSpeed = 70, rotate = 30; 19 //limiar do sensor 20 int threshold = 5; 21 //velocidades iniciais dos motores esquerdo e direito 22 int left = startSpeed, right = startSpeed; 23 24 //Rotina de calibracao do sensor 25 void calibrate() 26 { 27 for (int x=0; x<10; x++) //Executa 10 vezes para obter uma media 28 { 29 delay(100); 30 SENSOR1 = analogRead(0); 31 SENSOR2 = analogRead(1); 32 SENSOR3 = analogRead(2); 33 leftOffset = leftOffset + SENSOR1; 34 centre = centre + SENSOR2; 35 rightOffset = rightOffset + SENSOR3; 36 delay(100); 37 } 38 //obtem a media para cada sensor 39 leftOffset = leftOffset /10; 40 rightOffset = rightOffset /10; 41 centre = centre / 10; 42 //calcula os deslocamentos para os sensores esquerdo e direito 43 leftOffset = centre - leftOffset; 44 rightOffset = centre - rightOffset; 45 } 46 47 void setup() 48 { 49 calibrate(); 50 delay(3000); 51 } 52 53 void loop() 54 { 55 //utiliza a mesma velocidade em ambos os motores 56 left = startSpeed; 57 right = startSpeed; 58 59 //le os sensores e adiciona os deslocamentos 60 SENSOR1 = analogRead(0) + leftOffset; 61 SENSOR2 = analogRead(1); 62 SENSOR3 = analogRead(2) + rightOffset; 63 64 65 //Se SENSOR1 for maior do que o sensor do centro + limiar, // vire para a direita 66 if (SENSOR1 > SENSOR2+threshold) 67 { 68 left = startSpeed + rotate; 69 right = startSpeed - rotate; 70 } 71 72 73 //Se SENSOR3 for maior do que o sensor do centro + limiar, // vire para a esquerda 74 if (SENSOR3 > (SENSOR2+threshold)) 75 { 76 left = startSpeed - rotate; 77 right = startSpeed + rotate; 78 } 79 80 //Envia os valores de velocidade para os motores 81 motor_esq.setSpeed(left); 82 motor_esq.run(FORWARD); 83 motor_dir.setSpeed(right); 84 motor_dir.run(FORWARD); 85 } Conforme o motor e chassi que for utilizar, você deve ajustar os parâmetros de velocidade (startSpeed) e deslocamento de rotação (rotate), evitando que os motores girem muito rápido ou muito devagar. TUTORIAL: COMUNICAÇÃO WIRELESS COM ARDUINO E MÓDULO NRF24L01 Montar uma rede de comunicação sem fio utilizando Arduino é muito simples, como você já viu no post Módulo RF Transmissor + Receptor 433 Mhz AM, onde mostramos um tutorial de como utilizar esse módulo para enviar dados de um Arduino para outro. Outra forma muito fácil e barata de se montar uma rede sem fio é utilizando o módulo wireless NRF24L01 como esse abaixo: PINAGEM E DATASHEET NRF24L01: Este módulo utiliza o chip NRF24L01+ fabricado pela Nordic (NRF24L01 datasheet), trabalha na frequência de 2.4 Ghz e possui uma antena embutida, o que faz desse um dos módulos mais compactos do mercado. Possui um conector de 10 pinos (figura abaixo) com os pinos muito próximos uns dos outros, o que limita o seu uso na protoboard. Nessa configuração, o ideal é a utilização de algum outro tipo de conector, como o jumper macho-fêmea, e ligá-lo diretamente aos pinos do Arduino. Dos 10 pinos do conector, vamos utilizar 9 (não vamos utilizar o IRQ nesse momento). Como o módulo utiliza a interface SPI do Arduino, temos que obrigatoriamente utilizar os pinos 11, 12, e 13 para os sinais MOSI, MISO e SCK, respectivamente. Os pinos CSN e CE serão ligados aos pinos 7 e 8 do Arduino, ou algum outro de sua preferência. Atenção para a tensão de alimentação : este módulo trabalha com alimentação de 1,9 à 3.6 Volts : MONTAGEM NRF24L01 COM ARDUINO: Podemos testar o módulo utilizando um dos vários exemplos contidos na biblioteca RF24. O ideal é a utilização de 2 módulos com 2 Arduinos diferentes. Como o mesmo módulo pode ser utilizado tanto para transmissão como para recepção, a ligação é a mesma : PROGRAMANDO ARDUINO COM NRF24L01: Carregue em cada um deles o programa abaixo, que é o programa GettingStarted, contido na base de exemplos da biblioteca : 1 /* 2 Copyright (C) 2011 J. Coliz <[email protected]> 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 version 2 as published by the Free Software Foundation. 7 */ 8 9 /** 10 * Example for Getting Started with nRF24L01+ radios. 11 * 12 * This is an example of how to use the RF24 class. Write this sketch to two 13 * different nodes. Put one of the nodes into 'transmit' mode by connecting 14 * with the serial monitor and sending a 'T'. The ping node sends the current 15 * time to the pong node, which responds by sending the value back. The ping 16 * node can then see how long the whole cycle took. 17 */ 18 19 #include <SPI.h> 20 #include "nRF24L01.h" 21 #include "RF24.h" 22 #include "printf.h" 23 24 // 25 // Hardware configuration 26 // 27 28 29 // Set up nRF24L01 radio on SPI bus plus pins 9 & 10 30 RF24 radio(9,10); 31 32 // 33 // Topology 34 // 35 36 // Radio pipe addresses for the 2 nodes to communicate. 37 const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; 38 39 // 40 // Role management 41 // 42 // Set up role. This sketch uses the same software for all the nodes 43 // in this system. Doing so greatly simplifies testing. 44 // 45 46 // The various roles supported by this sketch 47 typedef enum { role_ping_out = 1, role_pong_back } role_e; 48 49 // The debug-friendly names of those roles 50 const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; 51 52 // The role of the current running sketch 53 role_e role = role_pong_back; 54 55 void setup(void) 56 { 57 // 58 // Print preamble 59 // 60 61 Serial.begin(57600); 62 printf_begin(); 63 printf("nrRF24/examples/GettingStarted/nr"); 64 printf("ROLE: %snr",role_friendly_name[role]); 65 printf("*** PRESS 'T' to begin transmitting to the other nodenr"); 66 67 // 68 // Setup and configure rf radio 69 // 70 71 radio.begin(); 72 73 // optionally, increase the delay between retries & # of retries 74 radio.setRetries(15,15); 75 76 // optionally, reduce the payload size. seems to 77 // improve reliability 78 //radio.setPayloadSize(8); 79 80 // 81 // Open pipes to other nodes for communication 82 // 83 84 // This simple sketch opens two pipes for these two nodes to communicate 85 // back and forth. 86 // Open 'our' pipe for writing 87 // Open the 'other' pipe for reading, in position #1 88 89 //(we can have up to 5 pipes open for reading) 90 91 //if ( role == role_ping_out ) 92 { 93 //radio.openWritingPipe(pipes[0]); 94 radio.openReadingPipe(1,pipes[1]); 95 } 96 //else 97 { 98 //radio.openWritingPipe(pipes[1]); 99 //radio.openReadingPipe(1,pipes[0]); 100 } 101 102 // 103 // Start listening 104 // 105 106 radio.startListening(); 107 108 // 109 // Dump the configuration of the rf unit for debugging 110 // 111 112 radio.printDetails(); 113 } 114 115 void loop(void) 116 { 117 // 118 // Ping out role. Repeatedly send the current time 119 // 120 121 if (role == role_ping_out) 122 { 123 // First, stop listening so we can talk. 124 radio.stopListening(); 125 126 // Take the time, and send it. This will block until complete 127 unsigned long time = millis(); 128 printf("Now sending %lu...",time); 129 bool ok = radio.write( &time, sizeof(unsigned long) ); 130 131 if (ok) 132 printf("ok..."); 133 else 134 printf("failed.nr"); 135 136 // Now, continue listening 137 radio.startListening(); 138 139 // Wait here until we get a response, or timeout (250ms) 140 unsigned long started_waiting_at = millis(); 141 bool timeout = false; 142 while ( ! radio.available() && ! timeout ) 143 if (millis() - started_waiting_at > 200 ) 144 timeout = true; 145 146 // Describe the results 147 if ( timeout ) 148 { 149 printf("Failed, response timed out.nr"); 150 } 151 else 152 { 153 // Grab the response, compare, and send to debugging spew 154 unsigned long got_time; 155 radio.read( &got_time, sizeof(unsigned long) ); 156 157 // Spew it 158 printf("Got response %lu,round-trip delay: %lunr",got_time,millis()-got_time); 159 } 160 161 // Try again 1s later 162 delay(1000); 163 } 164 165 // 166 // Pong back role. Receive each packet, dump it out, and send it back 167 // 168 169 if ( role == role_pong_back ) 170 { 171 // if there is data ready 172 if ( radio.available() ) 173 { 174 // Dump the payloads until we've gotten everything 175 unsigned long got_time; 176 bool done = false; 177 while (!done) 178 { 179 // Fetch the payload, and see if this was the last one. 180 done = radio.read( &got_time, sizeof(unsigned long) ); 181 182 // Spew it 183 printf("Got payload %lu...",got_time); 184 185 // Delay just a little bit to let the other unit 186 // make the transition to receiver 187 delay(20); 188 } 189 190 // First, stop listening so we can talk 191 radio.stopListening(); 192 193 // Send the final one back. 194 radio.write( &got_time, sizeof(unsigned long) ); 195 printf("Sent response.nr"); 196 197 // Now, resume listening so we catch the next packets. 198 radio.startListening(); 199 } 200 } 201 202 // 203 // Change roles 204 // 205 206 if ( Serial.available() ) 207 { 208 char c = toupper(Serial.read()); 209 if ( c == 'T' && role == role_pong_back ) 210 { 211 printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACKnr"); 212 213 // Become the primary transmitter (ping out) 214 role = role_ping_out; 215 radio.openWritingPipe(pipes[0]); 216 radio.openReadingPipe(1,pipes[1]); 217 } 218 else if ( c == 'R' && role == role_ping_out ) 219 { 220 printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACKnr"); 221 222 // Become the primary receiver (pong back) 223 role = role_pong_back; 224 radio.openWritingPipe(pipes[1]); 225 radio.openReadingPipe(1,pipes[0]); 226 } 227 } 228 } 229 // vim:cin:ai:sts=2 sw=2 ft=cpp Abra o serial monitor e selecione a velocidade de transmissão para 57600 bauds, conforme destacado : O Arduino faz a comunicação com o módulo NRF24L01 e mostra os dados na tela do serial monitor, indicando o status do módulo : No serial monitor, pressione T e clique em ENVIAR em um dos Arduinos e será iniciado o processo de transmissão de dados. No outro Arduino, pressione R e será iniciado o processo de recepção. Lembre que um mesmo módulo pode ser utilizado tanto para transmissão, como para recepção. ALARME COM O SENSOR DE VIBRAÇÃO SW18010P Componente recomendado para alarmes, sensores de presença e brinquedos, entre outros, o módulo Sensor de Vibração SW18010P é uma placa composta pelo sensor de vibração SW18010Ppropriamente dito, um chip comparador de tensão LM393, e um potenciômetro para ajuste da sensibilidade do módulo. Possui também em sua estrutura dois leds: um verde, indicando que o módulo está ligado (tensão de operação de 3.3 à 5 volts), e outro vermelho, que acende quando há mudança de estado da saída digital (pino D0). Na ausência de vibração, a saída digital se mantém em estado alto (HIGH). Da mesma forma, a saída analógica A0 mantém o seu valor máximo, variando a tensão conforme a movimentação do sensor. Sua estrutura e funcionamento permitem que o módulo seja conectado diretamente a um microcontrolador como o Arduino, onde podemos verificar tanto o estado da saída digital D0 como da analógica A0, observando essa variação de valores no Serial Monitor. Como sugestão de utilização, vamos utilizar este sensor de vibração para acionar um buzzer quando for detectada vibração, manter o buzzer ativo por 5 segundos, e depois deixar o módulo novamente em estado de espera. Esse princípio pode ser usado para criar um alarme e acionar, por exemplo, relés, lâmpadas ou sistemas de som, tudo vai depender da sua criatividade na utilização das saídas do Arduino ou qualquer outro microcontrolador que você estiver usando. Observe no programa que estamos lendo os valores das saídas A0 e D0 do módulo, e mostrando esses valores no serial monitor. Para acionamento da porta 4, onde se encontra o buzzer, o programa verifica se o valor da saída D0 é diferente de 1 (1 = sem vibração) e, caso positivo, aciona a porta 4 por 5 segundos, retornando depois ao loop do programa e aguardando o próximo acionamento : 1 //Programa : Sensor de vibração com buzzer 2 //Autor : FILIPEFLOP 3 4 //Pino ligado a porta A0 do sensor 5 int porta_a0 = A0; 6 //Pino ligado a porta D0 do sensor 7 int porta_D0 = 2; 8 int leitura_porta_analogica = 0; 9 int leitura_porta_digital = 0; 10 //Pino ligado ao buzzer 11 int pinobuzzer = 4; 12 13 void setup() 14 { 15 pinMode(porta_a0, INPUT); 16 pinMode(porta_D0, INPUT); 17 pinMode(pinobuzzer, OUTPUT); 18 Serial.begin(9600); 19 } 20 21 void loop() 22 { 23 //Leitura dos dados das portas do sensor 24 leitura_porta_analogica = analogRead(porta_a0); 25 leitura_porta_digital = digitalRead(porta_D0); 26 //Mostra os valores no serial monitor 27 Serial.print("Porta Digital : "); 28 Serial.print(leitura_porta_digital); 29 Serial.print(" Porta Analogica : "); 30 Serial.println(leitura_porta_analogica); 31 32 //Testa se o sensor foi acionado e liga o buzzer 33 if (leitura_porta_digital != 1) 34 { 35 digitalWrite(pinobuzzer, HIGH); 36 delay(5000); 37 digitalWrite(pinobuzzer, LOW); 38 } 39 delay(100); 40 } O ajuste da sensibilidade do módulo é feito girando o potenciômetro para a esquerda (diminui a sensibilidade), ou para a direita (aumenta a sensibilidade). SENSOR HALL KY-003 COM SERVO TOWER PRO SG-5010 Sensor Hall é um sensor que utiliza o efeito hall para verificar se foi detectado algum campo magnético na área do sensor. No Arduino, podemos utilizar o Sensor Hall como um prático dispositivo para determinar se algum objeto magnético se aproximou do sensor, e assim acionar outras portas do Arduino. O sensor hall funciona com uma simples chave ou botão, sendo que, na ausência de campo magnético, o sensor envia o sinal 1 (HIGH) para o Arduino, e ao detectar algum campo magnético, a porta vai à nível 0 (LOW). Como é comum em outros módulos para o Arduino, o Sensor Hall KY-003 tem apenas 3 pinos :Vcc, GND e Sinal, sendo que este módulo funciona com tensões de 4,5 à 24 volts DC. O módulo também possui um led que permanece aceso ao detectar um campo magnético. Detectar a abertura de portas e janelas em um sistema de alarme ou montar um contador de RPM para motores são algumas das aplicações sugeridas. Neste post, ilustramos a utlização deste sensor de efeito hall em conjunto com um Servo Tower Pro com rotação infinita, onde fixamos um ímã no motor, e a cada acionamento do sensor, o sentido de rotação é invertido. Lembrando que no servo motor que estamos utilizando, o Tower Pro SG-5010, o fio laranja corresponde ao pino de dados/controle, o fio vermelho ao Vcc 5v, e o fio marrom ao GND. O programa utiliza apenas a biblioteca Servo, já que o sensor hall não exige biblioteca própria. No ínicio do programa definimos os pinos do sensor (pino_hall) e o de controle do servo (sinal_servo). Dentro do loop, uma rotina inverte o valor da variável estado a cada acionamento do sensor, e essa variável, por sua vez, é responsável por inverter o sentido de rotação do motor, por meio da variável sentido. 1 // Programa : Sensor Hall com Servo Tower Pro SG-5010 2 // Autor : FILIPEFLOP 3 4 #include <Servo.h> 5 6 Servo myservo; 7 8 int sinal_servo = 2; //Pino de sinal para o servo 9 int pino_hall = 4; //Pina de sinal do sensor 10 int leitura; 11 int estado = 0; //Variavel auxiliar 12 int sentido = 0; //Armazena o sentido de rotacao //Armazena informações sobre a leitura do sensor 13 14 void setup() 15 { 16 pinMode(sinal_servo, OUTPUT); //Define o pino como saida 17 pinMode(pino_hall, INPUT); 18 myservo.attach(2); 19 myservo.write(0); 20 } 21 22 void loop() 23 { 24 leitura = digitalRead(pino_hall); 25 if (leitura != 1) 26 { 27 if (estado == 0) 28 { 29 sentido = 180; 30 estado = !estado; 31 myservo.write(sentido); //Define o pino como entrada 32 } 33 else if (estado == 1) 34 { 35 sentido = 0; 36 estado = !estado; 37 myservo.write(sentido); 38 } 39 delay(300); 40 } 41 } Você pode utilizar o mesmo princípio de funcionamento e utilizar o sensor hall para contar o número de rotações do motor, por exemplo, ou para executar determinada tarefa um certo número de vezes. CONTROLE DE ACESSO USANDO LEITOR RFID COM ARDUINO Leitores e tags RFID (Radio Frequency Identification, ou Identificação por Radiofrequência) costumam ser utilizados para controle de acesso e identificação de pessoas e equipamentos, seja por meio de crachás ou etiquetas aplicadas à produtos. No nosso dia-a-dia, podemos encontrar atecnologia RFID nos pedágios (no popular “Sem Parar”), ou em cartões tipo Bilhete Único, utilizados em várias cidades brasileiras para acesso ao transporte coletivo. As etiquetas (ou tags) RFID, podem conter vários dados sobre o proprietário do cartão, como nome e endereço e, no caso de produtos, informações sobre procedência e data de validade, apenas para citar alguns exemplos. Como são compostas apenas por um pequeno circuito, as tags RFID podem ser embutidas facilmente em vários objetos, nos mais variados tamanhos e formatos. No caso do Kit Leitor Rfid Mfrc522 Mifare disponível na loja FILIPEFLOP (imagem acima), temos duas tags: uma no formato de chaveiro, outra em formato de cartão. Cada etiqueta/tag do leitor RFID tem a sua própria identificação (UID), e é com essa identificação que vamos montar um controle de acesso que irá ler o UID do cartão e exibir as informações de acesso num display LCD 16×2. Com pequenas alterações no programa é possível acionar as outras portas do Arduino e ligar motores, sensores, luzes e outros dispositivos. PINAGEM LEITOR RFID: O leitor RFID tem 8 pinos que seguem a seguinte sequência de ligação. Atenção à tensão de alimentação, que neste caso é de 3.3 volts Pino SDA ligado na porta 10 do Arduino Pino SCK ligado na porta 13 do Arduino Pino MOSI ligado na porta 11 do Arduino Pino MISO ligado na porta 12 do Arduino Pino NC – Não conectado Pino GND ligado no pino GND do Arduino Pino RST ligado na porta 9 do Arduino Pino 3.3 – ligado ao pino 3.3 V do Arduino MONTAGEM LEITOR RFID COM ARDUINO: Utilizamos no circuito o Display 16×2 HD44780 com ligação semelhante ao do artigo Mostrando informações de temperatura no LCD 16×2 com o DHT11. Trocamos apenas os pinos 12 do Arduino Uno pelo pino 6, e o 11 pelo 7, pois os mesmos já estão sendo utilizados pelo leitor RFID. O potenciômetro é utilizado para controlar o contraste do LCD, e no circuito foi usado um de 10 K : PROGRAMANDO ARDUINO COM LEITOR RFID: Para o programa, baixe a biblioteca MFRC522 nesse link. Descompacte o arquivo e renomeie a pasta rfid-master para MFRC522, colocando-a dentro da pasta LIBRARIES da IDE do seu Arduino. O programa exibe na tela mensagens referentes ao cartão utilizado, sendo que no nosso caso, o display apresenta mensagem de “Acesso Liberado” para a tag no estilo chaveiro, e “Acesso Negado” para a tag no estilo cartão. Adapte o programa às tags que você possui, alterando as linhas com “UID 1 – Chaveiro” e “UID 2 – Cartao” (Linhas 54 e 67), lembrando que o formato da UID deve ser mantido (XX YY ZZ WW). Para descobrir o número da tag do seu dispositivo, aproxime-o do leitor RFID e verifique o serial monitor : 1 //Programa : RFID - Controle de Acesso leitor RFID 2 //Autor : TECNOTRONICS 3 4 #include <SPI.h> 5 #include <MFRC522.h> 6 #include <LiquidCrystal.h> 7 8 #define SS_PIN 10 9 #define RST_PIN 9 10 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance. 11 12 13 LiquidCrystal lcd(6, 7, 5, 4, 3, 2); 14 char st[20]; 15 16 void setup() 17 { 18 Serial.begin(9600); // Inicia a serial 19 SPI.begin(); 20 mfrc522.PCD_Init(); // Inicia MFRC522 21 Serial.println("Aproxime o seu cartao do leitor..."); 22 Serial.println(); 23 //Define o número de colunas e linhas do LCD: 24 lcd.begin(16, 2); 25 mensageminicial(); 26 // Inicia SPI bus } 27 28 void loop() 29 { 30 // Look for new cards 31 if ( ! mfrc522.PICC_IsNewCardPresent()) 32 { 33 return; 34 } 35 // Select one of the cards 36 if ( ! mfrc522.PICC_ReadCardSerial()) 37 { 38 return; 39 } 40 //Mostra UID na serial 41 Serial.print("UID da tag :"); 42 String conteudo= ""; 43 byte letra; 44 for (byte i = 0; i < mfrc522.uid.size; i++) 45 { 46 Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); 47 Serial.print(mfrc522.uid.uidByte[i], HEX); 48 conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); 49 conteudo.concat(String(mfrc522.uid.uidByte[i], HEX)); 50 } 51 Serial.println(); 52 Serial.print("Mensagem : "); 53 conteudo.toUpperCase(); 54 if (conteudo.substring(1) == "ED 78 03 CA") //UID 1 - Chaveiro 55 { 56 Serial.println("Ola FILIPEFLOP !"); 57 Serial.println(); 58 lcd.clear(); 59 lcd.setCursor(0,0); 60 lcd.print("Ola FILIPEFLOP !"); 61 lcd.setCursor(0,1); 62 lcd.print("Acesso liberado!"); 63 delay(3000); 64 mensageminicial(); 65 } 66 67 if (conteudo.substring(1) == "BD 9B 06 7D") //UID 2 - Cartao 68 { 69 Serial.println("Ola Cartao !!!"); 70 Serial.println(); 71 lcd.clear(); 72 lcd.setCursor(0,0); 73 lcd.print("Ola Cartao !"); 74 lcd.setCursor(0,1); 75 lcd.print("Acesso Negado !"); 76 delay(3000); 77 mensageminicial(); 78 79 } } 80 81 void mensageminicial() 82 { 83 lcd.clear(); 84 lcd.print(" Aproxime o seu"); 85 lcd.setCursor(0,1); 86 lcd.print("cartao do leitor"); 87 } RELÓGIO COM O MÓDULO RTC DS1307 Com o módulo RTC DS1307 você tem um componente muito útil para montar algum tipo de relógio com o Arduino, setar alarmes e assim executar ações em horários predeterminados. Neste post vamos apresentar um tutorial de como conectar este módulo RTC DS1307 com um Arduino Uno, mostrando as informações de data e hora no Serial Monitor da IDE Arduino. A sigla RTC significa Real Time Clock, ou seja, um Relógio de Tempo Real (RTC). Esse módulo tem 56 bytes de memória não-volátil disponível para uso, é capaz de armazenar e fornecer informações completas de data como dia da semana, dia do mês, mês, ano e além é claro, das funções de horas, minutos e segundos, nos formatos de 12 ou 24 horas. Meses com menos de 31 dias e anos bissextos são ajustados automaticamente. Uma bateria de lítio garante que os dados sejam preservados mesmo sem alimentação externa, e é acionada automaticamente em caso de falta de energia no módulo. Uma outra característica desse módulo é que você pode utilizar um sensor de temperatura DS18B20 (não incluso), e ler as informações do sensor à partir do pino DS do módulo, o que faz com que seja possível montar um relógio completo com data, hora, dia da semana e temperatura, sem a necessidade de outros componentes. CONECTANDO RTC DS1307 AO ARDUINO: Neste post vamos mostrar um breve tutorial de como ligar esse módulo RTC DS1307 ao Arduino e exibir todas essas informações no serial monitor. Olhando o módulo pela parte inferior, podemos ver na parte esquerda os pinos GND, Vcc, SDA e SCL, utilizados para cascatear dispositivos I2C, e também o pino DS, que fornece os dados do sensor de temperatura, se o mesmo estiver instalado. No lado direito, vamos utilizar apenas os pinos SCL, SDA, Vcc e GND para ligação ao Arduino. Conecte o módulo RTC DS1307 ao Arduino, tomando cuidado para não inverter as ligações, pois como vimos acima existem pinos com o mesmo nome dos dois lados do módulo : Antes de carregar o programa, baixe a biblioteca RTC DS1307 nesse link, descompacte o arquivo e copie o conteúdo para a pasta LIBRARIES da IDE do seu Arduino. No programa, a parte do código que contém os comandos rtc.setDOW(MONDAY); rtc.setTime(16, 30, 47); rtc.setDate(5, 6, 2014); só deve ser utilizada para setar a hora e data do RTC DS1307. Depois disso, essas linhas podem ser comentadas ou excluídas e o programa deve ser novamente carregado no Arduino. 1 //Programa : Relogio com modulo RTC DS1307 2 //Autor : FILIPEFLOP 3 4 //Carrega a biblioteca do RTC DS1307 5 #include <DS1307.h> 6 7 //Modulo RTC DS1307 ligado as portas A4 e A5 do Arduino 8 DS1307 rtc(A4, A5); 9 10 void setup() 11 { 12 //Aciona o relogio 13 rtc.halt(false); 14 15 //As linhas abaixo setam a data e hora do modulo 16 //e podem ser comentada apos a primeira utilizacao 17 rtc.setDOW(FRIDAY); //Define o dia da semana 18 rtc.setTime(20, 37, 0); //Define o horario 19 rtc.setDate(6, 6, 2014); //Define o dia, mes e ano 20 21 //Definicoes do pino SQW/Out 22 rtc.setSQWRate(SQW_RATE_1); 23 rtc.enableSQW(true); 24 25 26 Serial.begin(9600); } 27 28 void loop() 29 { 30 //Mostra as informações no Serial Monitor 31 Serial.print("Hora : "); 32 Serial.print(rtc.getTimeStr()); 33 Serial.print(" "); 34 Serial.print("Data : "); 35 Serial.print(rtc.getDateStr(FORMAT_SHORT)); 36 Serial.print(" "); 37 Serial.println(rtc.getDOWStr(FORMAT_SHORT)); 38 39 //Aguarda 1 segundo e repete o processo 40 delay (1000); 41 } Execute o programa, abra o Serial Monitor e você terá as informações do RTC DS1307 dessa maneira : Essa biblioteca pode mostrar as informações da data em formato completo bastando retirar as informações de FORMAT_SHORT (formato reduzido) do programa. CONECTANDO ACELERÔMETRO 3 EIXOS MMA7361 NO ARDUINO Acelerômetro é um dispositivo que serve para medir a aceleração de um objeto em relação à gravidade. Acelerômetros são muito utilizados em celulares e videogames para executar algum tipo de ação dependendo da movimentação do aparelho. No Arduino, segue o mesmo princípio e podemos utilizá-lo para controlar robôs ou algum outro tipo de dispositivo, apenas movimentando o sensor. Um dos melhores sensores para Arduino, e também um dos mais fáceis de utilizar, é oAcelerômetro 3 Eixos MMA7361. Este acelerômetro 3 eixos MMA7361 possui alta sensibilidade e baixo consumo de energia, facilitando o uso com o Arduino. Além disso, possui um eficiente modo Sleep, ideal para circuitos que utilizam baterias. Pode ser ajustado para 2 níveis de sensibilidade (1,5g ou 6g), e já vem com os pinos soldados na placa, o que ajuda bastante na montagem do circuito. São dois conectores de cinco pinos nas laterais da placa, e o módulo pode ser alimentado por 3.3 v ou 5v. Alimentando-o com 3.3 v, há um incremento na precisão da leitura. As funções dos demais pinos do módulo e a ligação ao Arduino estão mostrados na tabela abaixo : Para utilizarmos o acelerômetro com o Arduino, primeiro precisamos da bibliotecaAcceleroMMA7361, disponível nesse link. Faça o download da biblioteca, descompacte e coloque na pasta LIBRARIES da IDE do seu Arduino. Vamos testar esse acelerômetro 3 eixos MMA7361 utilizando o arquivo exemplo RawData, que já vem na biblioteca do módulo, com algumas alterações para que os dados referentes aos eixos X, Y e Z sejam mostrados no Display LCD 16×2. O potenciômetro utilizado é de 10K, usado somente para controle de contraste : Os pinos X, Y e Z do módulo são ligados às entradas analógicas. Um detalhe importante é a ligação do pino de 3.3v do Arduino ao pino AREF, também no Arduino. É essa ligação que fornecerá uma tensão de referência ao circuito, evitando erros na leitura dos dados. O programa exemplo RawData originalmente lê as informações relativas às variações dos eixos X, Y e Z e as mostra no serial monitor. Vamos manter essa função, mas também enviar esses dados para o display LCD 16×2. 1 //Programa : Conectando Acelerômetro 3 Eixos MMA7361 no Arduino 2 //Autor : TECNOTRONICS 3 4 #include <AcceleroMMA7361.h> 5 #include <LiquidCrystal.h> 6 7 LiquidCrystal lcd(7, 6, 5, 4, 3, 2); 8 AcceleroMMA7361 accelero; 9 int x; 10 int y; 11 int z; 12 13 void setup() 14 { 15 lcd.begin(16, 2); 16 Serial.begin(9600); 17 accelero.begin(13, 12, 11, 10, A0, A1, A2); 18 accelero.setARefVoltage(3.3); //sets the AREF voltage to 3.3V 19 accelero.setSensitivity(LOW); //sets the sensitivity to +/-6G 20 accelero.calibrate(); 21 lcd.setCursor(0,0); 22 lcd.print("X: "); 23 lcd.setCursor(8,0); 24 lcd.print("Y: "); 25 lcd.setCursor(0,1); 26 lcd.print("Z: "); 27 } 28 29 void loop() 30 { 31 x = accelero.getXRaw(); 32 lcd.setCursor(3,0); 33 lcd.print(x); 34 y = accelero.getYRaw(); 35 lcd.setCursor(11,0); 36 lcd.print(y); 37 z = accelero.getZRaw(); 38 lcd.setCursor(3,1); 39 lcd.print(z); 40 Serial.print("nx: "); 41 Serial.print(x); 42 Serial.print("ty: "); 43 Serial.print(y); 44 Serial.print("tz: "); 45 Serial.print(z); 46 delay(500); 47 } Movimente o sensor e observe no display os dados relativos aos eixos do acelerômetro. Você pode utilizar esses dados para movimentar, por exemplo, motores de acordo com as variações de cada eixo. RELÓGIO COM O MÓDULO RTC DS1307 E LCD 20×4 Já trabalhamos anteriormente com o módulo RTC DS1307, mostrando como ligar o módulo ao Arduino e exibir as informações de data e hora no serial monitor. Agora nesse post, vamos utilizar como base esse mesmo artigo (Relógio com o módulo RTC DS1307) e exibir essas informações em um Display LCD 20×4, deixando o nosso relógio muito mais profissional. Antes de carregar o programa, baixe a biblioteca DS1307 nesse link, descompacte o arquivo e copie o conteúdo para a pasta LIBRARIES da IDE do seu Arduino. No programa, a parte do código que contém os comandos rtc.setDOW(MONDAY); rtc.setTime(16, 30, 47); rtc.setDate(5, 6, 2014); só deve ser utilizada para setar a hora e data do DS1307. Depois disso, essas linhas podem ser comentadas ou excluídas e o programa deve ser novamente carregado no Arduino. 1 //Programa : Relogio com modulo DS1307 e LCD 20x4 2 //Autor : FILIPEFLOP 3 4 //Carrega as bibliotecas do LCD e do DS1307 5 #include <LiquidCrystal.h> 6 #include <DS1307.h> 7 8 //Modulo DS1307 ligado as portas A4 e A5 do Arduino 9 DS1307 rtc(A4, A5); 10 11 //Inicializa o LCD 12 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 13 14 void setup() 15 { 16 //Aciona o relogio 17 rtc.halt(false); 18 19 //Define o LCD com 20 colunas e 4 linhas 20 lcd.begin(20, 4); 21 22 //As linhas abaixo setam a data e hora do modulo 23 //e podem ser comentada apos a primeira utilizacao 24 25 //rtc.setDOW(MONDAY); //Define o dia da semana 26 //rtc.setTime(16, 30, 47); //Define o horario 27 //rtc.setDate(5, 6, 2014); //Define o dia, mes e ano 28 29 //Definicoes do pino SQW/Out 30 rtc.setSQWRate(SQW_RATE_1); 31 rtc.enableSQW(true); 32 } 33 34 void loop() 35 { 36 //Imprime mensagem na primeira linha do display 37 lcd.setCursor(0,0); 38 lcd.print("---- FILIPEFLOP ----"); 39 40 //Mostra a hora atual no display 41 lcd.setCursor(6, 2); 42 lcd.print(rtc.getTimeStr()); 43 44 //Mostra a data atual no display 45 lcd.setCursor(0, 3); 46 lcd.print("Data : "); 47 lcd.setCursor(7,3); 48 lcd.print(rtc.getDateStr(FORMAT_SHORT)); 49 50 //Mostra o dia da semana no display 51 lcd.setCursor(17, 3); 52 lcd.print(rtc.getDOWStr(FORMAT_SHORT)); 53 54 //Aguarda 1 segundo e repete o processo 55 delay (1000); 56 } Essa biblioteca pode mostrar as informações da data em formato completo bastando retirar as informações de FORMAT_SHORT (formato reduzido) do programa. Uma sugestão de utilização é alterar o programa para que ele mostre na tela, alternadamente, as informações de data e hora, ou até mesmo informações sobre as outras portas do Arduino. COMO USAR O TECLADO MATRICIAL 4×4 COM ARDUINO Este Teclado Matricial 4×4 é um componente do Arduino muito utilizado para entrada de dados. Ele possui 16 teclas dispostas em 4 linhas x 4 colunas, e um conector de 8 pinos para ligação: PINAGEM TECLADO MATRICIAL 4X4: Internamente são 16 teclas push-buttons tipo membrana dispostos na configuração abaixo em um formato keypad. Conforme a tecla é pressionada, é feita a conexão entre a linha e a coluna correspondentes. Se pressionarmos a tecla A no teclado matricial, será feita a conexão entre os pinos 1 (linha 1) e 8 (coluna 4), se pressionarmos a tecla 7, será feita uma conexão entre os pinos3 (linha 3) e 5 (coluna 1), e assim por diante: CONECTANDO TECLADO MATRICIAL AO ARDUINO: Neste tutorial vamos utilizar 8 portas do Arduino para ligação ao teclado matricial, sendo 4 para as linhas, e 4 para as colunas. Os pinos das linhas deverão ser configurados como OUTPUT (Saída), e os pinos das colunas como INPUT (Entrada). Nos pinos referente às colunas, vamos utilizar 4 resistores pull-down, mantendo-as em nível baixo quando não houver acionamento das teclas: PROGRAMANDO O ARDUINO PARA MAPEAMENTO DAS TECLAS: No programa, primeiro definimos todos os pinos das linhas como entrada (pinos 3, 4, 5 e 6), e os pinos de colunas como saídas (pinos 8,9,10 e 11). Um loop se encarrega de colocar cada pino de saída (linhas) em estado alto (HIGH), e verificar se alguma tecla foi pressionada, por meio de um comando IF para cada coluna. Caso isso aconteça, é gerada uma saída no serial monitor com a informação correspondente à qual tecla foi pressionada no teclado matricial: 1 //Programa : Teste teclado matricial 4x4 2 //Autor : FILIPEFLOP 3 4 void setup() 5 { 6 //Pinos ligados aos pinos 1, 2, 3 e 4 do teclado - Linhas 7 pinMode(3, OUTPUT); 8 pinMode(4, OUTPUT); 9 pinMode(5, OUTPUT); 10 pinMode(6, OUTPUT); 11 12 //Pinos ligados aos pinos 5, 6, 7 e 8 do teclado - Colunas 13 pinMode(8, INPUT); 14 pinMode(9, INPUT); 15 pinMode(10, INPUT); 16 pinMode(11, INPUT); 17 18 Serial.begin(9600); 19 Serial.println("Aguardando acionamento das teclas..."); 20 Serial.println(); 21 } 22 23 void loop() 24 { 25 for (int ti = 3; ti<7; ti++) 26 { 27 //Alterna o estado dos pinos das linhas 28 digitalWrite(3, LOW); 29 digitalWrite(4, LOW); 30 digitalWrite(5, LOW); 31 digitalWrite(6, LOW); 32 digitalWrite(ti, HIGH); 33 //Verifica se alguma tecla da coluna 1 foi pressionada 34 if (digitalRead(8) == HIGH) 35 { 36 imprime_linha_coluna(ti-2, 1); 37 while(digitalRead(8) == HIGH){} 38 } 39 40 //Verifica se alguma tecla da coluna 2 foi pressionada 41 if (digitalRead(9) == HIGH) 42 { 43 imprime_linha_coluna(ti-2, 2); 44 while(digitalRead(9) == HIGH){}; 45 } 46 47 //Verifica se alguma tecla da coluna 3 foi pressionada 48 if (digitalRead(10) == HIGH) 49 { 50 imprime_linha_coluna(ti-2, 3); 51 while(digitalRead(10) == HIGH){} 52 } 53 54 //Verifica se alguma tecla da coluna 4 foi pressionada 55 if (digitalRead(11) == HIGH) 56 { 57 imprime_linha_coluna(ti-2, 4); 58 while(digitalRead(11) == HIGH){} 59 60 } } 61 62 delay(10); } 63 64 void imprime_linha_coluna(int x, int y) 65 { 66 Serial.print("Linha : "); 67 Serial.print(x); 68 Serial.print(" x Coluna : "); 69 Serial.print(y); 70 delay(10); 71 Serial.println(); 72 } Configuramos o programa para mostrar a informação Linha x Coluna da tecla pressionada. Carregado o programa no Arduino, abra o serial monitor e acione as teclas, e você terá um resultado como esse abaixo: Com a posição das teclas, é possível configurar o teclado para exibir os caracteres que você desejar, ou até mesmo acionar outras portas do Arduino, já que , como comentamos no início, o teclado nada mais é do que uma série de push-buttons dispostos em forma de matriz. COMO CONECTAR O ARDUINO A UMA REDE WI-FI Liberte-se dos fios e conecte o seu Arduino à redes wireless com o Wifi Shield CC3000 da Sparkfun. Com esse módulo você consegue se conectar às redes wireless mais comuns do mercado (padrão 802.11 b/g), utilizando criptografia WEP, WPA ou WPA2. Também é possível utilizar o slot para cartão microSD para armazenar dados de sensores ou mesmo da internet. Este Wifi Shield também possui embutida uma antena WIMAX, suficiente para a maioria das aplicações, mas se você precisar de um alcance maior, pode fazer uma pequena modificação no hardware da placa e utilizar o conector para antena externa. Gostou? Então vamos as configurações para deixar o seu Arduino conectado a internet. MONTAGEM E CONEXÃO DO WIFI SHIELD SPARKFUN AO ARDUINO Essa placa é enviada sem os pinos de conexão ao Arduino, assim você pode escolher entre uma configuração com uma barra de pinos normal ou uma configuração com pinos macho/femea, do tipo empilhável. Na foto abaixo temos 2 modos de configurações, uma usando somente pinos macho soldados ao shield e a outra com barra de pinos empilhável, permitindo que você encaixe outros shields no Arduino. BIBLIOTECAS E FUNÇÕES A biblioteca padrão para esta placa é fornecida pela própria Sparkfun, distribuidora da placa, e está disponível nesse link. Esta biblioteca vem com exemplos para rastreamento de redes Wifi, ping, Webclient e testes gerais na placa. Podemos usar também uma outra biblioteca, essa da Adafruit, que também suporta o CC3000(datasheet), o chip da Texas Instruments que controla a placa. Essa biblioteca você pode baixarnesse link, e é um pouco mais completa, com exemplos para geolocalização, servidor de chat e o principal, que não está disponível na biblioteca da Sparkfun até o momento, que é o HTTP Server. PROGRAMANDO O WIFI SHIELD CC3000 Para testar a placa, vamos utilizar as duas bibliotecas e ver algumas configurações para cada uma neste tutorial. Primeiro, vamos utilizar a biblioteca da Sparkfun (SFE_CC3000.h) e juntar três exemplos dessa biblioteca em um programa só. A primeira parte do programa vai testar a comunicação com a placa e verificar se as conexões estão OK, retornando a versão do firmware e o MAC Address da placa. Em seguida, é feito um rastreamento para detectar as redes Wifi disponíveis. Por último, é feita a conexão à uma das redes e um teste de ping para o site www.tecnotronics.com.br No programa, não se esqueça de alterar as linhas abaixo, que definem o nome da rede wifi à qual o shield irá se conectar, assim como a senha e o tipo de segurança da rede: char ap_ssid[] = “SSID”; // Nome da rede Wireless char ap_password[] = “PASSWORD”; // Senha da rede Wireless unsigned int ap_security = WLAN_SEC_WPA2; // Tipo de seguranca da rede 1 //Programa : Wifi Shield CC3000 Sparkfun 2 //Biblioteca : Sparkfun SFE_CC3000 3 //Alteracoes e adaptacoes : FILIPEFLOP 4 5 #include <SPI.h> 6 #include <SFE_CC3000.h> 7 8 // Pinos 9 #define CC3000_INT 2 //Pino de interrupcao (D2 ou D3) 10 #define CC3000_EN 7 //Pode ser qualquer pino digital 11 #define CC3000_CS 10 //Preferencialmente pino 10 do Arduino Uno 12 13 #define FW_VER_LEN 14 #define MAC_ADDR_LEN 15 #define IP_ADDR_LEN 2 //Armazena o valor do firmware 6 //Armazena o endereço MAC 4 //Tamanho do endereco IP, em bytes 16 17 char ap_ssid[] = "FILIPEFLOP"; //Nome da rede Wireless 18 char ap_password[] = "12345678"; 19 unsigned int ap_security = WLAN_SEC_WPA2; //Tipo de seguranca da rede 20 unsigned int timeout = 30000; 21 char remote_host[] = "www.filipeflop.com"; //Site para teste 22 unsigned int num_pings = 3; //Senha da rede Wireless //Milisegundos // Numero de pings 23 24 SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 25 26 void setup() 27 { 28 29 Serial.begin(115200); } 30 31 void loop() 32 { 33 Serial.println("--------------------------------"); 34 Serial.println("- 35 Serial.println("--------------------------------"); 36 Teste_Placa(); 37 Serial.println("--------------------------------"); 38 Serial.println(" 39 Serial.println("--------------------------------"); 40 Procura_redes(); 41 Serial.println("--------------------------------"); 42 Serial.println(" 43 Serial.println("--------------------------------"); 44 ping_site(); 45 Serial.println("--------------------------------"); 46 while(1) 47 {} 48 SparkFun CC3000 Procurando redes wifi -"); "); Conexao e teste de ping } 49 50 void Teste_Placa() 51 { 52 int i; 53 unsigned char fw_ver[FW_VER_LEN]; 54 unsigned char mac_addr[MAC_ADDR_LEN]; 55 56 // Inicializa o shield CC3000 57 if ( wifi.init() ) 58 { "); 59 60 Serial.println("Inicializacao completa - CC3000 "); } else { 61 62 Serial.println("Erro durante a inicializacao da CC3000 !"); } 63 64 //Le e mostra a versao de firmware 65 if ( wifi.getFirmwareVersion(fw_ver) ) 66 { 67 Serial.print("Versao de firmware : "); 68 Serial.print(fw_ver[0], DEC); 69 Serial.print("."); 70 Serial.print(fw_ver[1], DEC); 71 Serial.println(); 72 } 73 else 74 { 75 76 Serial.println("Nao foi possivel ler a versao de firmware."); } 77 78 //Le e mostra o endereco MAC 79 if ( wifi.getMacAddress(mac_addr) ) 80 { 81 Serial.print("Endereco MAC : "); 82 for ( i = 0; i < MAC_ADDR_LEN; i++ ) 83 { 84 if ( mac_addr[i] < 0x10 ) 85 { 86 87 Serial.print("0"); } 88 Serial.print(mac_addr[i], HEX); 89 if ( i < MAC_ADDR_LEN - 1 ) 90 { 91 Serial.print(":"); 92 } 93 } 94 Serial.println(); 95 } 96 else 97 { 98 Serial.println("Nao foi possivel ler o endereco MAC"); 99 100 } } 101 102 void Procura_redes() 103 { 104 int i; 105 AccessPointInfo ap_info; 106 107 unsigned char fw_ver[FW_VER_LEN]; 108 unsigned char mac_addr[MAC_ADDR_LEN]; 109 110 if ( wifi.scanAccessPoints(4000) != true ) { 111 112 Serial.println("Erro ao procurar redes wifi"); } 113 114 //Procura por redes wifi e exibe o nome 115 Serial.println("Redes Wifi encontradas:"); 116 Serial.println(); 117 while ( wifi.getNextAccessPoint(ap_info) ) { 118 Serial.print("SSID: "); 119 Serial.println(ap_info.ssid); 120 Serial.print("Seguranca : "); 121 switch(ap_info.security_mode) { 122 case WLAN_SEC_UNSEC: 123 Serial.println("Sem seguranca"); 124 break; 125 case WLAN_SEC_WEP: 126 Serial.println("WEP"); 127 break; 128 case WLAN_SEC_WPA: 129 Serial.println("WPA"); 130 break; 131 case WLAN_SEC_WPA2: 132 Serial.println("WPA2"); 133 break; 134 default: 135 break; 136 } 137 Serial.println(); 138 139 } } 140 141 void ping_site() 142 { 143 ConnectionInfo connection_info; 144 IPAddress ip_addr; 145 IPAddress remote_ip; 146 PingReport ping_report = {0}; 147 int i; 148 149 //Conecta e aguarda endereco via DHCP 150 Serial.print("Conectando a rede : "); 151 Serial.print(ap_ssid); 152 if(!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) { 153 154 Serial.println("Erro: Nao foi possivel conectar !"); } 155 156 //Le os dados de conexao 157 if ( !wifi.getConnectionInfo(connection_info) ) 158 { 159 Serial.println("Erro: Nao foi possivel obter dados de conexao"); 160 } 161 else 162 { 163 Serial.println(" - Conectado !"); 164 Serial.print("Endereco IP recebido : "); 165 for (i = 0; i < IP_ADDR_LEN; i++) 166 { 167 Serial.print(connection_info.ip_address[i]); 168 if ( i < IP_ADDR_LEN - 1 ) 169 { 170 Serial.print("."); 171 } 172 } 173 Serial.println(); 174 } 175 176 //Usa DNSLookup para encontrar o endereco do site 177 Serial.print("Aguardando endereco IP de : "); 178 Serial.println(remote_host); 179 if ( !wifi.dnsLookup(remote_host, &remote_ip) ) 180 { 181 Serial.println("Error: Could not lookup host by name"); 182 } 183 else 184 { 185 Serial.print("Endereco IP encontrado: "); 186 for (i = 0; i < IP_ADDR_LEN; i++) 187 { 188 Serial.print(remote_ip[i], DEC); 189 if ( i < IP_ADDR_LEN - 1 ) 190 { 191 Serial.print("."); 192 } 193 } 194 Serial.println(); 195 } 196 197 //Realiza o teste de ping 198 Serial.print("Teste de Ping IP "); 199 for (i = 0; i < IP_ADDR_LEN; i++) 200 { 201 Serial.print(remote_ip[i], DEC); 202 if ( i < IP_ADDR_LEN - 1 ) 203 { 204 Serial.print("."); 205 } 206 } 207 Serial.print(" "); 208 Serial.print(num_pings, DEC); 209 Serial.println(" vezes..."); 210 if ( !wifi.ping(remote_ip, ping_report, 3, 56, 1000) ) { 211 Serial.println("Error: no ping response"); 212 } else { 213 Serial.print("Pacotes enviados : "); 214 Serial.println(ping_report.packets_sent); 215 Serial.print("Pacotes recebidos: "); 216 Serial.println(ping_report.packets_received); 217 } 218 219 //Desconecta da rede 220 if ( wifi.disconnect() ) { 221 Serial.println("Desconectando da rede wifi"); 222 } else { 223 Serial.println("Erro: Nao foi possivel desconectar !"); 224 225 } } Ao final do processo, abra o serial monitor e você terá uma tela como essa após os testes de conexão e ping: No segundo exemplo, vamos utilizar a biblioteca da Adafruit (Adafruit_CC3000.h) e criar um webserver que vai ler o valor de um potenciômetro ligado à porta analógica A2 do Arduino e atualizar uma página acessada via browser. Nessa biblioteca, por padrão são utilizadas as portas 3 para IRQ (Interrrupção), 5 para VBAT e 10 para CS. Vamos substituir os valores de IRQ e VBAT para 2 e 7, respectivamente, para que funcionem com a placa da Sparkfun. As definições de portas no início do programa ficarão assim : #define ADAFRUIT_CC3000_IRQ 2 #define ADAFRUIT_CC3000_VBAT 7 #define ADAFRUIT_CC3000_CS 10 Monte o circuito abaixo, utilizando um potenciômetro de qualquer valor: Assim, como no primeiro programa, altere as definições da sua rede wifi modificando essas linhas : #define WLAN_SSID “FILIPEFLOP” //Nome da rede – Ate 32 caractereres #define WLAN_PASS “12345678” //Senha da rede #define WLAN_SECURITY WLAN_SEC_WPA2 //Tipo de seguranca 1 //Programa : Wifi Shield CC3000 Sparkfun 2 //Biblioteca : Adafruit_CC3000 3 //Alteracoes e adaptacoes : FILIPEFLOP 4 5 #include <Adafruit_CC3000.h> 6 #include <SPI.h> 7 #include "utility/debug.h" 8 #include "utility/socket.h" 9 10 //Pinos 11 #define ADAFRUIT_CC3000_IRQ 2 //Pino de interrupcao (D2 ou D3) 12 #define ADAFRUIT_CC3000_VBAT 7 //Pode ser qualquer pino digital 13 #define ADAFRUIT_CC3000_CS 10 //Preferencialmente pino 10 do Arduino Uno 14 15 //O clock pode ser alterado 16 Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, 17 ADAFRUIT_CC3000_VBAT,SPI_CLOCK_DIVIDER); 18 19 20 21 22 23 #define WLAN_SSID "FILIPEFLOP" //Nome da rede - Ate 32 caractereres #define WLAN_PASS "12345678" //Senha da rede //Tipo de seguranca: WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 #define WLAN_SECURITY WLAN_SEC_WPA2 //Tipo de seguranca 24 25 26 27 28 29 #define LISTEN_PORT 80 #define MAX_ACTION 10 #define MAX_PATH 64 #define BUFFER_SIZE MAX_ACTION + MAX_PATH + 20 #define TIMEOUT_MS 500 30 31 Adafruit_CC3000_Server httpServer(LISTEN_PORT); 32 33 34 35 36 uint8_t buffer[BUFFER_SIZE+1]; int bufindex = 0; char action[MAX_ACTION+1]; char path[MAX_PATH+1]; 37 38 39 40 41 42 void setup(void) { pinMode(A2, INPUT); //Define o pino para o potenciometro Serial.begin(115200); 43 Serial.println(F("nInicializando...")); 44 if (!cc3000.begin()) 45 { 46 Serial.println(F("Shield nao encontrado. Verifique as conexoes !")); 47 while(1); 48 } 49 50 Serial.print(F("nTentando conectar-se a rede ")); Serial.println(WLAN_SSID); 51 if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) 52 { 53 Serial.println(F("Falha !")); 54 while(1); 55 } 56 Serial.println(F("Conectado!")); 57 58 Serial.println(F("Requisitando endereco DHCP")); 59 while (!cc3000.checkDHCP()) 60 { 61 delay(100); 62 } 63 //Exibe as informacoes da conexao 64 while (! displayConnectionDetails()) 65 { 66 delay(1000); 67 } 68 //Aguarda conexao do browser 69 httpServer.begin(); 70 71 Serial.println(F("Aguardando conexao...")); 72 } 73 74 void loop(void) 75 { 76 //Armazena o valor lido do potenciometro 77 int valor_potenciometro = analogRead(A2); 78 79 Adafruit_CC3000_ClientRef client = httpServer.available(); 80 if (client) 81 { 82 Serial.println(F("Client connected.")); 83 bufindex = 0; 84 memset(&buffer, 0, sizeof(buffer)); 85 memset(&action, 0, sizeof(action)); 86 memset(&path, 0, sizeof(path)); 87 unsigned long endtime = millis() + TIMEOUT_MS; 88 89 bool parsed = false; 90 while (!parsed && (millis() < endtime) && (bufindex < BUFFER_SIZE)) 91 { 92 if (client.available()) { 93 buffer[bufindex++] = client.read(); 94 } 95 96 parsed = parseRequest(buffer, bufindex, action, path); } 97 98 if (parsed) 99 { 100 Serial.println(F("Processing request")); 101 Serial.print(F("Action: ")); Serial.println(action); 102 Serial.print(F("Path: ")); Serial.println(path); 103 if (strcmp(action, "GET") == 0) { 104 client.println(F("HTTP/1.1 200 OK")); 105 client.println(F("Content-Type: text/plain")); 106 client.println(F("Connection: close")); 107 client.println(F("Refresh: 0")); 108 client.println(F("Server: Adafruit CC3000")); 109 client.println(F("")); 110 //Inicio do envio de dados para o browser 111 client.println(F("-----------------------------")); 112 client.println(F(" 113 client.println(F("-----------------------------")); 114 client.println(); 115 client.print(F("Valor do potenciometro : ")); 116 client.println(valor_potenciometro); 117 client.println(F("")); 118 } 119 else 120 { FILIPEFLOP ")); 121 client.fastrprintln(F("HTTP/1.1 405 Method Not Allowed")); 122 client.fastrprintln(F("")); 123 124 } } 125 126 //Delay antes de desconectar 127 delay(100); 128 Serial.println(F("Client disconnected")); 129 client.close(); 130 131 } } 132 133 bool parseRequest(uint8_t* buf, int bufSize, char* action, char* path) { 134 //Check if the request ends with rn to signal end of first line. 135 if (bufSize < 2) 136 return false; 137 if (buf[bufSize-2] == 'r' && buf[bufSize-1] == 'n') { 138 parseFirstLine((char*)buf, action, path); 139 return true; 140 } 141 return false; 142 } 143 144 void parseFirstLine(char* line, char* action, char* path) { 145 //Parse first word up to whitespace as action. 146 char* lineaction = strtok(line, " "); 147 if (lineaction != NULL) 148 strncpy(action, lineaction, MAX_ACTION); 149 //Parse second word up to whitespace as path. 150 char* linepath = strtok(NULL, " "); 151 if (linepath != NULL) 152 153 strncpy(path, linepath, MAX_PATH); } 154 155 //Leitura do endereco IP e outras informacoes de conexao 156 bool displayConnectionDetails(void) 157 { 158 uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 159 160 if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 161 { 162 Serial.println(F("Nao foi possivel ler o endereco IP!rn")); 163 return false; 164 } 165 else 166 { 167 Serial.print(F("nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 168 Serial.print(F("nNetmask: ")); cc3000.printIPdotsRev(netmask); 169 Serial.print(F("nGateway: ")); cc3000.printIPdotsRev(gateway); 170 Serial.print(F("nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 171 Serial.print(F("nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 172 Serial.println(); 173 return true; 174 } } No browser, acesse o endereço do Wifi Shield utilizando o endereço do campo ENDEREÇO IP RECEBIDO, que vimos no primeiro teste. No nosso caso, o endereço DHCP é 192.168.0.100: SENSOR INFRAVERMELHO Este Sensor Infravermelho para Arduino é um módulo de reflexão fotoelétrico que integra um transmissor IR e um receptor IR. Seu funcionamento é através do envio de feixes de luz invisível infravermelha que possui pouca interferência com a luz visível. O fotodetector percebe qualquer reflexão desta luz, sendo que com esta reflexão é possível dizer se há um objeto/obstáculo próximo ao sensor. Características: - Tensão: 5vDC – Corrente: 10-15mA – Distância de Percepção: 3-80cm ajustáveis – Tipo Conexão: 3 Fios (Normal Aberto) – Nível Alto: 2,3v-5v – Nível Baixo: -0,3v-1,5v O alcance deste sensor pode ser ajustado pelo parafuso na parte de trás do sensor, podendo variar sua sensibilidade de 3 à 80cm. Pinagem: - Vermelho: VCC – Preto: GND – Amarelo: Sinal Código: 1 // Escolhe pino para LED 2 int ledPin = 13; 3 // Escolhe pino de entrada para Sensor Infravermelho 4 int inputPin = 2; 5 // variável para leitura de status 6 int val = 0; 7 8 void setup() 9 { 10 // LED como saída 11 pinMode(ledPin, OUTPUT); 12 // Sensor Infravermelho como entrada 13 pinMode(inputPin, INPUT); 14 } 15 16 void loop() 17 { 18 val = digitalRead(inputPin); // lê valor da entrada 19 if (val == HIGH){ // Se nível alto 20 digitalWrite(ledPin, LOW); // desliga LED 21 } 22 else 23 { 24 digitalWrite(ledPin, HIGH); // acende LED 25 } 26 } Este Sensor Infravermelho pode ser conectado com um Arduino Sensor Shield. Agora mesmo é só plugar e ligar! COMO MEDIR CORRENTE COM ARDUINO? Agora você pode medir correntes de -30A à +30A utilizando o seu Arduino ou outro microcontrolador de sua preferência. Com o módulo Sensor de Corrente ACS714 da Pololu você tem um dispositivo alimentado por 5v e que permite medir essa faixa de corrente com uma margem de erro de apenas ±1,5%. Esse sensor utiliza um CI Allegro ACS714 com sensor de efeito hall (datasheet) para medição da corrente, o que garante um perfeito isolamento do circuito. Nesse post vamos trabalhar com baixa tensão e corrente, mas o ACS714 suporte tensões de até 2.1 kV RMS. Confira o tutorial abaixo! MEDINDO CORRENTE E TENSÃO Antes de mostrarmos de mostrar como medir corrente com Arduino, vamos ver de uma maneira resumida a diferença de procedimento entre medir tensão e medir corrente, já que uma ligação incorreta pode danificar o circuito ou até mesmo o aparelho medidor. Para medir tensão, veja este exemplo usando um multiteste (multímetro), um circuito com uma lâmpada e uma bateria. Devemos colocar o multiteste na escala de tensão (V), e medir dessa maneira, com as pontas de prova em paralelo ao circuito: Já para a medição da corrente, que é o assunto desse post, devemos ligar um multiteste em série com o circuito, na escala de Ampéres: LIGAÇÃO DO SENSOR DE CORRENTE COM ARDUINO Vamos testar o sensor utilizando um motor DC de 5v, ligado em SÉRIE com o Sensor de Corrente ACS714. O sensor irá enviar os dados ao Arduino por meio do pino analógico A3. A alimentação do sensor é feita pelo próprio Arduino (5v), e para a alimentação do motor utilizamos pilhas comuns. Assim, podemos mostrar o isolamento do circuito do motor em relação ao Arduino e o restante dos componentes: No display LCD 20×4, teremos as informações do valor “puro” lido do sensor (entre 0 e 1024) e o valor da amperagem calculada pelo programa abaixo. A cada ampere de variação na entrada do sensor, a tensão de saída varia 66mV. A atualização é feita a cada 1 segundo. 1 //Programa : Teste sensor ACS714 corrente com Arduino 2 //Alteracoes e adaptacoes : 3 4 //Carrega a biblioteca do LCD 5 #include <LiquidCrystal.h> 6 7 //Inicializa o LCD 8 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 9 10 //Define o pino analogico usado pelo ACS714 11 int AnalogInputPin = 3; 12 13 14 void setup() 15 { 16 //Define o LCD com 20 colunas e 4 linhas 17 lcd.begin(20, 4); 18 //Informacoes iniciais no display 19 lcd.setCursor(1,0); 20 lcd.print("--- FILIPEFLOP ---"); 21 lcd.setCursor(0,1); 22 lcd.print("Sensor : "); 23 lcd.setCursor(0,2); 24 lcd.print("Amp :"); 25 26 27 Serial.begin(9600); } 28 29 void loop() 30 { 31 //Chama rotina que calcula a corrente 32 double Current = currentSensor(analogRead(AnalogInputPin)); 33 //Imprime as informacoes no display e na serial 34 Serial.print(" Amp : "); 35 printDouble(Current, 2); 36 Serial.print(" A"); 37 Serial.println(""); 38 lcd.setCursor(11,2); 39 lcd.print("A"); 40 delay(1000); 41 } 42 43 void printDouble(double val, byte precision) 44 { 45 Serial.print (int(val)); 46 if( precision > 0) 47 { 48 Serial.print("."); 49 lcd.setCursor(7,2); 50 lcd.print("."); 51 unsigned long frac, mult = 1; 52 byte padding = precision -1; 53 while(precision--) mult *=10; 54 if(val >= 0) frac=(val-int(val))*mult; 55 else frac=(int(val)-val)*mult; 56 unsigned long frac1 = frac; 57 while(frac1 /= 10) padding--; 58 while(padding--) Serial.print("0"); 59 lcd.setCursor(6,2); 60 lcd.print("0"); 61 Serial.print(frac,DEC) ; 62 lcd.setCursor(8,2); 63 lcd.print(frac, DEC); 64 65 } } 66 67 long readInternalVcc() 68 { 69 long result; 70 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 71 delay(2); 72 ADCSRA |= _BV(ADSC); 73 while (bit_is_set(ADCSRA,ADSC)); // Wait for Vref to settle // Convert 74 result = ADCL; 75 result |= ADCH<<8; 76 result = 1126400L / result; 77 return result; 78 // Back-calculate AVcc in mV } 79 80 81 // Calculate current with Allegro ACS714 82 double currentSensor(int RawADC) 83 { 84 int 85 long InternalVcc 86 double ZeroCurrentVcc = InternalVcc / 2; 87 double SensedVoltage = (RawADC * InternalVcc) / 1024; 88 double Difference 89 double SensedCurrent = Difference / Sensitivity; 90 Serial.print("Sen: "); 91 Serial.print(RawADC); 92 Serial.print("/1024"); 93 lcd.setCursor(9,1); 94 lcd.print(RawADC); 95 return SensedCurrent; 96 Sensitivity = 66; // mV/A = readInternalVcc(); = SensedVoltage - ZeroCurrentVcc; } Para utilização do programa sem precisar de um LCD, os resultados são impressos também na serial, e você pode checar os valores no serial monitor: CONTROLANDO TEMPERATURA E PRESSÃO COM O BMP180 O sensor de temperatura e pressão BMP180 é o sucessor do BMP085, e foi desenvolvido para ser um sensor ainda mais compacto e econômico em termos de energia (por volta de 3 µA). Devemos destacar que esse sensor é totalmente compatível com o BMP085, tanto em termos de software como em termos de firmware e interface. Apesar de também medir a temperatura, ele foi desenvolvido com o objetivo de medir a pressão atmosférica, e com base nesses dados podemos determinar a altitude e realizar previsões do tempo com grande precisão. graças ao baixíssimo consumo de energia, o CI BMP180 (datasheet) é indicado para utilização em equipamentos compactos como GPS, smartphones, tablets e equipamentos esportivos. No Arduino, também temos esse conceito de compactação, com o CI instalado em uma placa de 12 x 10 mm. Ele funciona com alimentação de 1,8 à 3.6V, e possui um regulador de tensão embutido que permite que você o conecte normalmente às placas Arduino com nível de sinal de 5V, como o Arduino Uno. A conexão ao Arduino utiliza a interface I2C, por meio dos pinos analógicos 4 (SDA) e 5 (SCL). No módulo temos somente 4 pinos : Vin (1,8 à 3.6V), GND, SCL e SDA : LIGAÇÃO DO BMP180 AO ARDUINO A ligação do sensor BMP180 ao Arduino é muito simples, e vamos utilizá-lo em conjunto com um Display LCD 16×2 para mostrar as informações de temperatura, pressão e altitude. O potenciômetro utilizado no circuito é de 10 K, e serve para ajuste de contraste. Atenção para a alimentação do módulo, que como comentamos anteriormente, vai de 1,8 à 3.6V, e no nosso exemplo vamos conectar o Vin do módulo ao pino 3.3V do Arduino. BIBLIOTECA E PROGRAMA Por ser totalmente compatível com o BMP085, podemos inclusive utilizar a mesma biblioteca, encontrada neste link. Faça o download, descompacte o arquivo e coloque a pasta com a biblioteca dentro da pasta LIBRARIES da IDE do seu Arduino. O programa apresenta na tela as informações de temperatura, na primeira linha, e vai alternando as informações de pressão (em Pa) e altitude (em metros) na segunda linha, atualizando as informações a cada 3 segundos. 1 // Programa : Sensor de temperatura e pressao BMP180 2 // Autor : 3 4 #include <Wire.h> 5 #include <Adafruit_BMP085.h> 6 #include <LiquidCrystal.h> 7 8 LiquidCrystal lcd(12,11, 5, 4, 3, 2); 9 10 Adafruit_BMP085 bmp180; 11 12 int mostrador = 0; 13 14 void setup() 15 { 16 Serial.begin(9600); 17 lcd.begin(16,2); 18 if (!bmp180.begin()) 19 { 20 Serial.println("Sensor nao encontrado !!"); 21 while (1) {} 22 23 24 } } 25 void loop() 26 { 27 lcd.setCursor(0, 0); 28 lcd.print("Temp. : "); 29 Serial.print("Temperatura : "); 30 if ( bmp180.readTemperature() < 10) 31 { 32 lcd.print(" "); 33 lcd.print(bmp180.readTemperature()); 34 Serial.print(bmp180.readTemperature()); 35 Serial.println(" C"); 36 } 37 else 38 { 39 lcd.print(bmp180.readTemperature(),1); 40 Serial.print(bmp180.readTemperature(),1); 41 Serial.println(" C"); 42 } 43 lcd.print(" "); 44 lcd.print((char)223); 45 lcd.print("C "); 46 47 if (mostrador == 0) 48 { 49 lcd.setCursor(0, 1); 50 lcd.print(" 51 lcd.setCursor(0, 1); 52 lcd.print("Altit.: "); 53 Serial.print("Altitude : "); "); 54 lcd.print(bmp180.readAltitude()); 55 Serial.print(bmp180.readAltitude()); 56 Serial.println(" m"); 57 lcd.print(" m"); 58 } 59 if (mostrador == 1) 60 { 61 lcd.setCursor(0, 1); 62 lcd.print(" 63 lcd.setCursor(0, 1); 64 lcd.print("Press.: "); 65 Serial.print("Pressao : "); 66 lcd.print(bmp180.readPressure()); 67 Serial.print(bmp180.readPressure()); 68 Serial.println(" Pa"); 69 lcd.print(" Pa"); 70 "); } 71 72 delay(3000); 73 mostrador = !mostrador; 74 } Essas informações também são mostradas no Serial Monitor : Abaixo, foto do circuito em funcionamento: COMO CONSTRUIR UM RELÓGIO COM ARDUINO Hoje vamos ver alguns conceitos sobre displays LCD 7 segmentos e mostrar como construir um relógio com Arduino utilizando o display LED 7 segmentos 4 dígitos: Esse display possui leds na cor vermelha e dígitos com 1,4cm de altura. Por meio dos 12 pinos na base podemos controlar individualmente os leds, gerando número e letras no display. COMO FUNCIONA UM DISPLAY 7 SEGMENTOS O display de 7 segmentos contém 7 leds (ou segmentos), que acionados em conjunto podem formar os caracteres que precisamos. Basicamente os números e algumas letras. No lado esquerdo da imagem temos a disposição dos segmentos, que são nomeados com as letras de A a G. Para formar o número dois, por exemplo, precisamos acionar os segmentos A, B, D, E e G (lado direito da imagem): Além disso esse tipo de display pode ser catodo comum (o catodo de todos os leds conectados ao GND), ou anodo comum (o anodo de todos os leds conectados ao Vcc), o que vai influenciar no tipo de ligação que vamos ter com o microcontrolador. Em um display de 4 dígitos como este que vamos utilizar no artigo, temos também os pinos Digito 1, Digito 2, Digito 3 e Digito 4 (D1, D2, D3 e D3), que correspondem ao anodo de cada dígito, e que são acionados de forma sequencial. Para mostrar um número no display, acionamos o pino dígito 1 (Dig1), e também os leds correspondentes para formar o número. Em seguida, é feita a mesma coisa com o segundo dígito : desliga-se o dígito anterior (Dig1), liga-se o Dig2 e acende os leds, e assim sucessivamente até o 4° dígito, quando o processo se repete. Usando técnicas de multiplexação, esse processo de acionamento de cada dígito é feito de maneira muito rápida, de forma que não percebemos que o display na verdade está “piscando”. CIRCUITO DISPLAY 7 SEGMENTOS 4 DÍGITOS Como exemplo vamos utilizar o display 7 segmentos 4 dígitos e montar um relógio com Arduino usando também o módulo Real Time Clock RTC DS1307, que se comunica com o Arduino pela interface I2C. Do DS1307 vamos obter o valor das horas e minutos, e mostrar essa informação no display. Os resistores utilizados no circuito são de 1 K, sendo um para cada segmento e um também para acionar o separador (dois pontos) na parte central do display: A biblioteca responsável por fazer o trabalho de multiplexação é a SevSeg, disponível para download neste link. Descompacte o arquivo e coloque a pasta SevSeg dentro da pasta Librariesda IDE do Arduino. No início do programa definimos quais serão os pinos dos dígitos (usaremos os pinos de 10 à 13 para os dígitos de 1 à 4), e quais serão os pinos dos segmentos (usaremos os pinos de 2 à 9), sendo que o pino 9 é o responsável por acender o separador (dois pontos). A linha SelecionaDataeHora() é utilizada para acertar a hora do relógio, e deve ser comentada depois de utilizada. 1 //Programa : Relogio com Arduino, DS1307 e Display 7 Seg 2 //Autor : FILIPEFLOP 3 4 #include "Wire.h" 5 #include "SevSeg.h" 6 7 #define DS1307_ADDRESS 0x68 8 9 //Create an instance of the object. 10 SevSeg display7seg; 11 12 int valor = 0; 13 14 byte zero = 0x00; 15 unsigned long timer; 16 void setup() 17 { 18 Wire.begin(); 19 //A linha abaixo pode ser retirada apos setar a data e hora 20 // SelecionaDataeHora(); 21 22 //Selecao tipo de display anodo comum 23 int displayType = COMMON_ANODE; 24 25 //Definicao dos pinos dos digitos 26 int digit1 = 10; //Pino Digito1 do display 27 int digit2 = 11; //Pino Digito2 do display 28 int digit3 = 12; //Pino Digito3 do display 29 int digit4 = 13; //Pino Digito4 do display 30 31 //Pinos ligados aos segmentos A - H 32 int segA = 2; //Pino segmento A 33 int segB = 3; //Pino segmento B 34 int segC = 4; //Pino segmento C 35 int segD = 5; //Pino segmento D 36 int segE = 6; //Pino segmento E 37 int segF = 7; //Pino segmento F 38 int segG = 8; //Pino segmento G 39 int segDP= 9; //Pino segmento H 40 41 //Define o numero de digitos do display 42 int numberOfDigits = 4; 43 44 //Inicializa o display 45 display7seg.Begin(displayType, numberOfDigits, digit1, digit2, digit3, digit4, segA, segB, segC 46 47 //Nivel de brilho do display 48 display7seg.SetBrightness(50); 49 timer = millis(); 50 } 51 52 void loop() 53 { 54 char tempString[10]; //Used for sprintf 55 Wire.beginTransmission(DS1307_ADDRESS); 56 Wire.write(zero); 57 Wire.endTransmission(); 58 Wire.requestFrom(DS1307_ADDRESS, 7); 59 int segundos = ConverteparaDecimal(Wire.read()); 60 int minutos = ConverteparaDecimal(Wire.read()); 61 int horas = ConverteparaDecimal(Wire.read() & 0b111111); 62 sprintf(tempString, "%02d%02d", horas, minutos); 63 display7seg.DisplayString(tempString, 3); 64 } 65 66 void SelecionaDataeHora() //Seta a data e a hora do DS1307 67 { 68 byte segundos = 10; //Valores de 0 a 59 69 byte minutos = 32; //Valores de 0 a 59 70 byte horas = 19; //Valores de 0 a 23 71 Wire.beginTransmission(DS1307_ADDRESS); 72 Wire.write(zero); //Stop no CI para que o mesmo possa receber os dados 73 74 //As linhas abaixo escrevem no CI os valores de 75 //data e hora que foram colocados nas variaveis acima 76 Wire.write(ConverteParaBCD(segundos)); 77 Wire.write(ConverteParaBCD(minutos)); 78 Wire.write(ConverteParaBCD(horas)); 79 Wire.write(zero); 80 Wire.endTransmission(); 81 } 82 83 byte ConverteParaBCD(byte val) 84 { 85 //Converte o número de decimal para BCD 86 return ( (val/10*16) + (val%10) ); 87 } 88 89 byte ConverteparaDecimal(byte val) 90 { 91 //Converte de BCD para decimal 92 return ( (val/16*10) + (val%16) ); 93 } Na imagem abaixo temos o circuito em funcionamento. ESTAÇÃO METEOROLÓGICA COM ARDUINO Apresentamos um projeto de Estação Meteorológica com Arduino, utilizando vários componentes compactos e de baixo custo para exibir em um display gráfico informações sobre temperatura, umidade e pressão: Para a montagem dessa estação, usaremos: um sensor de temperatura e umidade DHT22, umsensor de pressão BMP180 e um display LCD Nokia 5110. Vamos apresentar mais informações sobre eles antes de mostrar o processo de montagem da Estação Meteorológica com Arduino. SENSOR DE TEMPERATURA E UMIDADE DHT22 O DHT22 é um sensor de temperatura e umidade sucessor do DHT11. Efetua medições de temperatura entre -40 e 125 ºC, e umidade entre 0 e 100%. Pode ser alimentado com tensões entre 3.3 e 6V e, como o DHT11, possui 4 pinos mas apenas 3 são utilizados: Vcc, Data e GND. O DHT22 tem baixo consumo de corrente (2,5 mA durante as medições e entre 100 e 150 µA em standby), possuindo internamente um sensor de umidade capacitivo e um termistor. Nesse sensor, o intervalo recomendado entre medições é de 2 segundos (contra 1 segundo no DHT11). SENSOR DE TEMPERATURA E PRESSÃO BMP180 O sensor de temperatura e pressão BMP180 também é uma evolução de um outro sensor, o BMP085, sendo totalmente compatível em termos de firmware, interface e software (pode utilizar inclusive a mesma biblioteca). A comunicação com o Arduino é feita por meio da interface I2C, e suporta alimentação de 1.8 à 3.6V, sendo portanto necessário tomar um certo cuidado ao ligar esse sensor ao Arduino. Apesar dessa limitação na alimentação do sensor, um regulador de tensão na placa permite que os pinos de dados (SCL e SDA) sejam utilizados normalmente em placas com nível de sinal de 5V, como o Arduino Uno. DISPLAY LCD NOKIA 5110 O display LCD Nokia 5110 que vamos utilizar no projeto é um display gráfico de 84×48 pixels, 1,6 polegadas e backlight (luz de fundo) azul, com tensão de alimentação de 5V. Sua conexão com o Arduino utiliza 5 fios, e a configuração dos pinos de ligação é feita via software, assim podemos utilizar praticamente qualquer pino do Arduino. Para o backlight (pino BL), a tensão máxima suportada é de 3.3V. No nosso projeto, vamos ligar esse display da seguinte maneira: Pino RST ligado ao pino 12 do Arduino Pino CE ligado ao pino 11 do Arduino Pino DC ligado ao pino 10 do Arduino Pino Din ligado ao pino 9 do Arduino Pino Clk ligado ao pino 8 do Arduino Pino Vcc ligado ao pino 5V do Arduino Pino BL ligado ao pino 3.3V do Arduino Pino GND ligado ao GND do Arduino Se você deseja montar esse projeto utilizando o display Nokia 5110 vermelho, consulte as especificações do fabricante, pois existem muitos modelos desse display que funcionam apenas com nível de sinal de 3.3V. CIRCUITO ESTAÇÃO METEOROLÓGICA Vamos apresentar duas opções de circuito, sendo uma com o Arduino Uno, para quem deseja apenas testar o projeto na protoboard, e outra com o Arduino Nano, ideal para montagens definitivas e que pode ser colocado em uma caixa plástica por exemplo. No Arduino Uno, utilizamos os pinos de 8 à 12 mencionados anteriormente para ligação do display, e o pino 3 como entrada de dados do DHT22 com um resistor de 10K funcionando como pull-up. O sensor BMP180 utiliza os pinos da interface I2C, que são os pinos analógicos A4 e A5: No Arduino Nano, são utilizados os mesmos pinos. Verifique na imagem abaixo a pinagem dessa placa e a conexão dos componentes: Para deixar o projeto mais compacto usamos uma case de modem para proteção e transporte mas você pode usar qualquer outra caixa para obter o mesmo resultado: BIBLIOTECAS E PROGRAMA Antes de carregar o programa faça o download das bibliotecas abaixo : Display – Bibliotecas Adafruit_GFX e Adafruit_PCD8544 DHT - Biblioteca DHT BMP180 – Biblioteca Adafruit_BMP085 Descompacte cada uma delas e copie para dentro da pasta LIBRARIES da IDE do Arduino. A Adafruit_GFX é a biblioteca gráfica, responsável pelas funções de desenho de retângulos, círculos, linhas, etc. A Adafruit_PCD8544 é a biblioteca utilizada para gerenciar a comunicação entre o Arduino e o display. A biblioteca BMP085 serve tanto para o sensor BMP085 como para o BMP180, utilizado neste projeto. O mesmo programa pode ser carregado no Arduino Uno ou no Arduino Nano. O programa desenha três retângulos com as bordas arredondadas, e dentro deles mostra as informações de temperatura, umidade e pressão, atualizando as informações à cada 5 segundos. 1 // Programa : Estacao Meteorologica com Arduino 2 // Autor : FILIPEFLOP 3 4 // Carrega bibliotecas graficas e sensores 5 #include <Adafruit_GFX.h> 6 #include <Adafruit_PCD8544.h> 7 #include <DHT.h> 8 #include <Adafruit_BMP085.h> 9 #include <Wire.h> 10 #include <SPI.h> 11 12 // Pinagem ligacao display Nokia 5110 13 // pin 8 - Serial clock out (SCLK) 14 // pin 9 - Serial data out (DIN) 15 // pin 10 - Data/Command select (D/C) 16 // pin 11 - LCD chip select (CS/CE) 17 // pin 12 - LCD reset (RST) 18 19 // Inicializa o display nos pinos acima 20 Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 11, 12); 21 22 // Define pino e tipo do sensor DHT 23 DHT dht(3, DHT22); 24 25 Adafruit_BMP085 bmp180; 26 27 void setup() 28 { 29 Serial.begin(9600); 30 // Informacoes iniciais no display 31 display.begin(); 32 // Ajusta o contraste do display 33 display.setContrast(48); 34 // Apaga o buffer e o display 35 display.clearDisplay(); 36 // Define tamanho do texto e cor 37 display.setTextSize(1); 38 display.setTextColor(BLACK); 39 40 // Retangulo temperatura 41 display.drawRoundRect(0,0, 44,24, 3, 2); 42 // Texto inicial temperatura 43 display.setCursor(11,3); // Seta a posição do cursor 44 display.println("TEMP"); 45 display.setCursor(5,14); 46 display.println("----"); 47 display.setCursor(29,14); 48 display.drawCircle(31, 15, 1,1); 49 display.println(" C"); 50 51 // Retangulo umidade 52 display.drawRoundRect(45,0, 39 ,24, 3, 2); 53 // Texto inicial Umidade 54 display.setCursor(52,3); 55 display.println("UMID"); 56 display.setCursor(50,14); 57 display.println("----"); 58 display.setCursor(75,14); 59 display.println("%"); 60 61 // Retangulo pressao 62 display.drawRoundRect(0,25, 84 ,23, 3, 2); 63 // Texto inicial Pressao 64 display.setCursor(22,28); 65 display.println("PRESSAO"); 66 display.setCursor(55,38); 67 display.println("hPa"); 68 display.setCursor(11,38); 69 display.println("------"); 70 display.display(); 71 72 delay(1000); 73 // Inicializa o sensor BMP180 74 if (!bmp180.begin()) 75 { 76 Serial.println("Sensor BMP180 nao encontrado !!"); 77 while (1) {} 78 } 79 // Inicializa o DHT22 80 dht.begin(); 81 } 82 83 void loop() 84 { 85 // Leitura temperatura, umidade e pressao 86 float h = dht.readHumidity(); 87 float t = dht.readTemperature(); 88 float p = bmp180.readPressure()/100.0; 89 90 // Atualiza valor da temperatura 91 display.fillRect(4,13, 25 , 10, 0); 92 display.setCursor(4,14); 93 display.println(t,1); 94 95 // Atualiza valor da umidade 96 display.fillRect(50,13, 23 , 10, 0); 97 display.setCursor(50,14); 98 display.println(h,1); 99 100 // Atualiza valor da pressao 101 display.fillRect(4, 37, 46 , 10, 0); 102 display.setCursor(11,38); 103 display.println(p,2); 104 105 display.display(); 106 // Aguarda 5 segundos para efetuar nova leitura 107 delay(5000); 108 } Você pode utilizar também o sensor de temperatura DHT11 no projeto, utilizando a mesma biblioteca DHT mostrada acima. Para isso, altere a linha DHT dht(3, DHT22), substituindo DHT22por DHT11. WWW.TECNOTRONICS.COM.BR