29 junho 2013

Ethernet shield Wiznet W5100 - Parte 2

Módulo Ethernet Shield Wiznet W5100

Parte 2 - Comunicação com o browser

Dando continuidade ao assunto módulo Arduino Ethernet Shield W5100 , hoje vamos montar um circuito composto por 2 botões e 2 leds, mais a placa ethernet, obviamente, e testar o envio de dados para o browser.

Recomendo a leitura da Parte 1 deste artigo, onde mostro os conceitos básicos para ligação do ethernet shield no Arduino e configuração do endereço IP.

Você vai precisar do seguinte material :

  • 2 Leds (sugestão : 1 vermelho e 1 verde)
  • 2 Push button
  • 2 resistores de 330 ohms
  • fios para ligação

Com o ethernet shield devidamente encaixado no Arduino, monte o circuito abaixo :

Ethernet Shield Arduino W5100
Carregue o seguinte programa no Arduino :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Programa : Webserver com aviso de acionamento de botoes
// Autor : Arduino e Cia
// Baseado no programa exemplo Webserver, de David Mellis e Tom Igoe

#include <SPI.h>
#include <Ethernet.h>

// A linha abaixo permite que voce defina o endereço fisico (MAC ADDRESS) 
// da placa de rede
byte mac[] = { 0xAB, 0xCD, 0x12, 0x34, 0xFF, 0xCA };

// Os valores abaixo definem o endereço IP, gateway e máscara. 
// Configure de acordo com a sua rede.
IPAddress ip(192,168,0,100);         //Define o endereço IP
IPAddress gateway(192,168,0,1);    //Define o gateway
IPAddress subnet(255, 255, 255, 0); //Define a máscara de rede

// Inicializa a biblioteca da placa ethernet com as 
// configurações de IP fornecidas
EthernetServer server(80);

int botao1 = 6;   //Botao que aciona o led vermelho
int botao2 = 7;   //Botao que aciona o led verde
int pinoled=8;    //Pino ligado ao led vermelho
int pinoled2=9;   //Pino ligado ao led verde
int leitura = 0;  //Armazena o valor de leitura do botao1
int leitura2 = 0; //Armazena o valor de leitura do botao2
char mensagem[20];   //Mensagem a ser apresentada para o botao1
char mensagem2[20];  //Mensagem a ser apresentada para o botao2

void setup()
{
  pinMode(pinoled, OUTPUT); //Led
  pinMode(pinoled2, OUTPUT); //Led
  pinMode(botao1, INPUT);
  digitalWrite(botao1, HIGH);
  pinMode(botao2, INPUT);
  digitalWrite(botao2, HIGH);
  //Inicializa a conexao ethernet e o servidor web na porta 80
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop()
{
   //Verifica o status do Botao1 e imprime mensagem no browser
   leitura=digitalRead(botao1);   
   if (leitura == 0)
     { 
       digitalWrite(pinoled,1);
       char mensagem[] = "Botao 1 acionado !!!";
       char mensagem2[] = "Aguardando...";
       apresentadados(mensagem,mensagem2);
       delay(5000);   //Mantem o led aceso por 5 segundos
       //Imprime mensagem padrao, aguardando novo acionamento
       apresentadados("Aguardando...", "Aguardando...");  
       digitalWrite(pinoled,0);
     }

   //Verifica o status do Botao2 e imprime mensagem no browser
   leitura2=digitalRead(botao2); 
   if (leitura2 == 0)
     { 
       digitalWrite(pinoled2,1);
       char mensagem[] = "Aguardando...";
       char mensagem2[] = "Botao 2 acionado !!!";
       apresentadados(mensagem,mensagem2);   
       delay(5000);  //Mantem o led aceso por 5 segundos
       //Imprime mensagem padrao, aguardando novo acionamento
       apresentadados("Aguardando...", "Aguardando...");  
       digitalWrite(pinoled2,0);   
     }
}

// Rotina que recebe os valores de Mensagem e Mensagem2, 
// imprimindo o resultado no browser

void apresentadados(char msg[], char msg2[])  
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          // the connection will be closed after completion of 
          // the response
          client.println("Connection: close");  

          // refresh the page automatically every 5 sec
          client.println("Refresh: 0");  
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          client.print("Estado Botao 1 : ");
          client.print(msg);
          client.println("<br />");
          client.print("Estado Botao 2 : ");
          client.print(msg2);
          client.println("<br />");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
 }

Para testar o programa, entre no browser (testei com o Firefox), e digite o endereço da placa de rede, que você configurou no programa, e pressione <ENTER>. Nesse momento o browser irá acessar o servidor Web interno da placa, e aguardará o pressionamento de um dos botões :

Browser aguardando conexao
Pressione um dos botoes do circuito e o led correspondente será aceso, indicando que o botão foi acionado. Ao mesmo tempo, será exibida na tela a mensagem abaixo, de acordo com o botão pressionado :

Browser - Botão 1 acionado
O led permanecerá aceso por 5 segundos, e depois disso o browser exibirá a mensagem de "Aguardando..." para os 2 botões, sinalizando a espera de um novo sinal :

Browser - Aguardando
Utilizei como base o programa de exemplo do Webserver, que acompanha a IDE do Arduino, tentando deixar o código o mais simples possível.

Voltarei a esse assunto futuramente, pois a comunicação via rede com o Arduino oferece inúmeras possibilidades de configuração.


24 junho 2013

Ethernet shield Wiznet W5100 - Parte 1

Módulo Ethernet Shield Wiznet W5100

Parte 1 - Montagem e configuração IP

Um módulo muito interessante que temos para o Arduíno é o módulo Arduino Ethernet W5100. Com ele podemos conectar o nosso Arduino à rede local e também à internet, possibilitando acesso remoto, transferência de dados, verificação remota de status de sensores, e muito mais.

Este assunto é complexo em alguns pontos e permite muitas possibilidades de programação, que serão temas de outros artigos. Vou dividir essa parte inicial em dois tópicos :

  • Parte 1 - Montagem e configuração IP
  • Parte 2 - Envio de dados do arduino para o browser, via ethernet

O módulo que eu vou usar é o ethernet shield com chipset Wiznet W5100, como esse da foto. Este módulo é compatível tanto com Arduino Uno como com o Arduino Mega, e possui também um leitor de cartões microSD :

ethernet shield w5100

Esse módulo é ligado ao Arduino Uno simplesmente encaixando o módulo na parte superior :

Ethernet Shield W5100 - Montado

Se você tem o Arduino Mega, o encaixe será feito desta maneira :

Arduino Ethernet Shield - Placas

A princípio o encaixe fica um pouco estranho, com o shield longe da placa do Arduino, isso ocorre porque os pinos do shield são longos, mas se você reparar na foto abaixo, verá que isso evita que o shield toque no conector USB :

Arduino Ethernet Shield - Detalhe

Com o shield ethernet devidamente encaixado na placa do Arduino, basta ligar o cabo de rede. Na parte superior, temos os leds de status, que mostram o funcionamento do módulo e o status de conexão à rede :

Arduino Ethernet Shield - Leds

Arduino Ethernet Shield W5100 - Funcionamento


Vamos testar o funcionamento da placa  utilizando um programa que simplesmente configura o endereço IP, utilizando os valores abaixo. Os valores apresentados são alguns dos mais comuns usados na comunicação IP. Talvez a sua rede use endereços diferentes. Se tiver dúvidas, verifique suas configurações de rede ou deixe um comentário para que eu possa ajudá-lo :

Arduino Ethernet Shield W5100 - IP

Carregue o seguinte programa no Arduino :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Programa : Ethernet Shield Wiznet W5100 - Define endereço IP
// Autor : Arduino e Cia

#include <SPI.h>
#include <Ethernet.h>

// A linha abaixo permite que voce defina o endereço 
// fisico (MAC ADDRESS) da placa de rede
byte mac[] = { 0xAB, 0xCD, 0x12, 0x34, 0xFF, 0xCA };

// Os valores abaixo definem o endereço IP, gateway e máscara. 
// Configure de acordo com a sua rede.
IPAddress ip(192,168,0,100);         //Define o endereço IP
IPAddress gateway(192,168,0,1);    //Define o gateway
IPAddress subnet(255, 255, 255, 0); //Define a máscara de rede

void setup() 
{
  Ethernet.begin(mac, ip, gateway, subnet); //Inicializa o Ethernet Shield
}

void loop() {}

Note que os endereços IP são separados por vírgula, ao invés de ponto, como é habitual. Para verificar o funcionamento da placa, abra um prompt de comando (janela DOS, para os mais antigos) no seu computador, e digite o seguinte comando, seguido de <ENTER> :

ping 192.168.0.100

Se tudo estiver ok, uma tela parecida com essa será apresentada, indicando que o módulo ethernet foi corretamente configurado e consegue enviar e receber dados pela rede :

Arduino Ethernet Shield W5100 - Ping

Isso encerra a parte básica de montagem e configuração IP do módulo ethernet. No próximo artigo, vamos ver como enviar dados do módulo para o browser.

Atualizado : Parte 2 nesse link : http://www.arduinoecia.com.br/2013/06/ethernet-shield-wiznet-w5100-parte-2.html

Até lá !

17 junho 2013

Sensor de temperatura e pressão BMP085 - Módulo GY-65

Hoje vou apresentar um outro módulo facilmente encontrado no mercado, que é o módulo de temperatura e pressão BMP085, como esse abaixo :

Módulo GY-65 com sensor BMP085

O nome BMP085 vem do nome dado ao sensor propriamente dito, conforme podemos ver no datasheet. No caso do módulo da foto acima, o código do módulo é GY-65.

O módulo funciona com uma tensão de 1.8 a 3.6v. Sua faixa de leitura de pressão é de 300 a 1100 hPa (hectoPascal), o que permite determinar altitudes desde 9000 metros acima do nível do mar, até -500m. A conexão com o controlador é feita por apenas 2 pinos, usando a interface I2C.

Vou utilizar uma biblioteca da Adafruit (www.adafruit.com), que você pode baixar nesse endereço.

Um parênteses a respeito dessa biblioteca é que, ao descompactar, o nome da pasta será "Adafruit-BMP085-Library-master". Infelizmente a IDE não aceita nome de pasta de bibliotecas com números e caracteres especiais, então renomeie a pasta apenas para "BMP085". Uso a versão 1.0.5 da IDE do Arduino, não sei se isso acontece nas outras versões.

Biblioteca baixada e instalada, vamos ao circuito :

Circuito BMP085 e Arduino Uno
 Tome cuidado para não inverter nenhuma conexão ao conectar os fios, pois geralmente a marcação dos pinos vem embaixo da placa, ficando escondida quando você a encaixa na protoboard.

O programa abaixo é baseado no programa de teste que vem junto com a biblioteca, com as devidas traduções para facilitar o entendimento :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//Programa : Teste módulo pressão BMP085
//Autor : Adafruit
//Traducoes e comentarios : Arduino e Cia


#include <Wire.h>
#include <Adafruit_BMP085.h>

// Conectar pino Vcc do BMP085 ao pino 3.3v do Arduino(NAO UTILIZAR 5.0V !)
// Conectar pino GND do módulo ao GND do Arduino
// Conectar o pino SCL do módulo ao pino analógico 5 do Arduino
// Conectar o pino SDA do módulo ao pino analógico 4 do Arduino
// Pino EOC (End of conversion) não utilizado
// Pino XCLR é um pino de reset, também não é utilizado

Adafruit_BMP085 bmp;

void setup() 
{
  Serial.begin(9600);
  if (!bmp.begin()) {
  Serial.println("Sensor BMP085 não encontrado, verifique as conexões !");
  while (1) {}
  }
}

void loop() 
{
    Serial.print("Temperatura = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressao = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");

    // Calcula a altitude utilizando a pressao barometrica padrao
    // de 1013.25 milibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" metros");

  // É possivel extrair uma medição mais precisa se você souber 
  // a pressão ao nível do mar, que varia com o tempo/clima. 
  // Se ela for de 1015 milibars ,é igual a 101500 Pascals.

    Serial.print("Altitude real = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" metros");
    Serial.println();

    delay(5000);
}

Rode o programa e abra o serial monitor. De 5 em 5 segundos será apresentada a temperatura em Celsius, a pressão em Pascal e a altitude, em metros :

Dados do BMP085 no Serial Monitor

08 junho 2013

Controlando um servo motor com Arduino

O grande barato de comprar as coisas pela internet, e no exterior, é a quase completa falta de manuais. Um exemplo disso é o servo motor abaixo, que chegou essa semana :

controlar servo motor Arduino

Chegou inteiro, mas desse jeito : o servo, os acessórios num plástico, e só. Uma etiqueta escrito "Micro Servo 9g" foi a maior pista que eu tive do modelo.

Aí começa a parte divertida da coisa, que é descobrir como o servo funciona, suas conexões, voltagens e tal. Vasculhando no Google, descobri um modelo muito parecido, chamado HXT900, e que sua voltagem de operação vai de 3 a 6v. Já é um começo. Mas e as conexões ?

Bom, o cabo tem 3 vias : Preto, vermelho e branco. Fácil, não ? Preto no GND, vermelho no 5V e branco para dados.

Testei o servo usando o exemplo que já vem na IDE do Arduino, que usa um potenciômetro para controlar a rotação do motor :

servo motor 9g Arduino
O programa abaixo você pode encontrar no menu Arquivo -> Exemplos -> Servo -> Knob :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Programa : Controlando a posicao de um servo usando potenciometro
// Traducao e comentarios : Arduino e Cia
//
// Controlling a servo position using a potentiometer (variable resistor) 
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott> 


#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

// Pino analgico do potenciometro
int potpin = 0;

// Variavel que armazena o valor lido do potenciometro
int val;     

void setup() 
{ 
  // Define que o servo esta ligado a porta 9
  myservo.attach(9);  
} 

void loop() 
{ 
  // Le o valor do potenciometro (valores entre 0 e 1023) 
  val = analogRead(potpin);            

  // Converte o valor pra ser usado no servo (valores entre 0 e 180) 
  val = map(val, 0, 1023, 0, 179);     

  // Move o eixo do servo, de acordo com o angulo
  myservo.write(val);                  

  // Aguarda o servo atingir a posição
  delay(15);                           
}

O programa lê as informações do potenciômetro ligado à entrada analógica (valores de 0 a 1023), converte esses valores para serem usados no servo (0 a 180), e move o servo motor para a posição correspondente. Gire o potenciômetro nos 2 sentidos, e o servo irá acompanhar o movimento do potenciômetro.

Também podemos controlar o servo usando posições pré-estabelecidas, o que é muito útil quando precisamos usar o motor para movimentos repetitivos. Como no exemplo abaixo, onde utilizei 3 chaves (push-button) :

Circuito Arduino - Servo motor - Push button
 e o seguinte programa :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Programa : Controlando o servo com 3 chaves
// Autor: Arduino e Cia

#include <Servo.h> 

Servo myservo;

int val; 
int ChaveEsquerda=3; //Pino a ser ligado na chave esquerda
int ChaveCentral=4;  //Pino a ser ligado na chave central
int ChaveDireita=5;  //Pino a ser ligado na chave direita

void setup() 
{ 
  // Pino de dados do servo conectado ao pino 9 do Arduino
  myservo.attach(9);   
  //Define o pino como entrada
  pinMode(ChaveEsquerda, INPUT);      
  //Aciona o resistor pull-up interno
  digitalWrite(ChaveEsquerda, HIGH);  
  pinMode(ChaveCentral, INPUT);
  digitalWrite(ChaveCentral, HIGH);
  pinMode(ChaveDireita, INPUT);
  digitalWrite(ChaveDireita, HIGH);
} 

void loop() 
{ 
 //Le o valor da Chave Esquerda (On/Off)
 val=digitalRead(ChaveEsquerda);  
   //Caso a chave seja pressionada, movimenta o servo
   if(val!=1) 
    {
       myservo.write(60);  //Move o servo para o angulo de 60 graus
       delay(15);          //Delay para o servo atingir a posiçao
    }

 val=digitalRead(ChaveCentral);
   if(val!=1)
    {
       myservo.write(90);  //Move o servo para o angulo de 90 graus
       delay(15);
    }

 val=digitalRead(ChaveDireita);
   if(val!=1)
    {
       myservo.write(120);  //Move o servo para o angulo de 120 graus
       delay(15);
    }
}

Ao pressionar o botão da esquerda, o servo se movimenta para a posição "60 graus", o botão central leva à posição 90 graus, e o botão da direita, à posição 120 graus.


04 junho 2013

Sons no Arduino usando buzzer

Você sabia que é possível gerar sons a partir do Arduino ?

Não só é possível, como é bem simples: basta usar a função "tone". Perfeito para quem, ao contrário deste que vos escreve, tem intimidade com a música.

A função tone tem o seguinte formato :

tone(pino, frequencia, duração)

onde a frequencia do tom é setada em hertz, e a duração, em milisegundos.

Para efeito de testes, usei um pequeno buzzer, desses que se usam em placa-mãe de computador, como esse abaixo :

sons no Arduino

A ligação é feita com o pino 10 do Arduino ligado ao "+" do buzzer/falante, e o outro pino do buzzer ligado ao GND :

Circuito Arduino e Buzzer
 Para testar, carregue o programa abaixo e ouça uma linda melodia :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//Programa : Som no Arduino - Do Re Mi
//Autor : Arduino e Cia

void setup() 
{
pinMode(10,OUTPUT); //Pino do buzzer
}

void loop()
{
    delay(2000);
    tone(10,262,200); //DO
    delay(200);
    tone(10,294,300); //RE
    delay(200);
    tone(10,330,300); //MI
    delay(200);
    tone(10,349,300); //FA
    delay(300);
    tone(10,349,300); //FA
    delay(300);
    tone(10,349,300); //FA
    delay(300);
    tone(10,262,100); //DO
    delay(200);
    tone(10,294,300); //RE
    delay(200);   
    tone(10,262,100); //DO
    delay(200);
    tone(10,294,300); //RE
    delay(300);
    tone(10,294,300); //RE
    delay(300);
    tone(10,294,300); //RE
    delay(300);
    tone(10,262,200); //DO
    delay(200);
    tone(10,392,200); //SOL
    delay(200);
    tone(10,349,200); //FA
    delay(200);
    tone(10,330,300); //MI
    delay(300);
    tone(10,330,300); //MI
    delay(300);
    tone(10,330,300); //MI
    delay(300);
    tone(10,262,200); //DO
    delay(200);
    tone(10,294,300); //RE
    delay(200);
    tone(10,330,300); //MI
    delay(200);
    tone(10,349,300); //FA
    delay(300);
    tone(10,349,300); //FA
    delay(300);
    tone(10,349,300); //FA
    delay(300);
}

Depois dessa aula de música, que tal uma sirene de policia ? Use este programa :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//Programa : Som no Arduino - Sirene
//Autor : Arduino e Cia

#define tempo 10
int frequencia = 0;
int Pinofalante = 10;

void setup()
{
  pinMode(Pinofalante,OUTPUT); //Pino do buzzer
}

void loop()
{
  for (frequencia = 150; frequencia < 1800; frequencia += 1) 
  {
    tone(Pinofalante, frequencia, tempo); 
    delay(1);
  }
  for (frequencia = 1800; frequencia > 150; frequencia -= 1) 
  {
    tone(Pinofalante, frequencia, tempo); 
    delay(1);
  }

}

Leia também o artigo NewTone - Alternativa à biblioteca Tone do Arduino, onde falo sobre problemas de conflito da biblioteca tone padrão do Arduino com outras bibliotecas, e como resolver esse problema.

Até a próxima !