arduino day 2015 image

Material necessario

  • Arduino; ;-)
  • Ethernet Shield (Wiznet-+`5100);
  • Arduino IDE (Ultima versao v1.6.1) ou
  • Conta no codebender.cc;
  • Um computador com saida USB;
  • Cabo USB (computador x Arduino);
  • Cabo Ethernet (Arduino x Rede);

Sobre o que vamos falar

  • Um pouco sobre redes;
    • Como funcionam as redes;
    • O que eh um servidor web;
    • Porque os enderecos iniciam por http;
  • Arduino!
    • Shields e placas Ethernet;
    • Codigo!

Redes

As camadas da sua rede

  • A sua aplicacao (hello world, por exemplo);
  • O protocolo de comunicacao (http, neste caso);
  • Um protocolo de transporte (TCP);
  • Um protocolo de internet ou "inter-redes" (IP);
  • Uma ligacao logica da rede (Ethernet);
  • Uma ligacao fisica da rede (fios e cabos);

Redes

As camadas da sua rede

Fios e cabos

  • Conexao fisica entre dispositivos;
  • Os cabos sao geralmente Cat5, Cat6 ou Cat7, com 4 pares de fios (coloridos);
  • Os conectores possuem 8 pinos e sao do tipo RJ-45;
  • A transmissao e a recepcao de dados ocorre pelos pares de fios;
  • Conhecida como "par-trancado";
cabo Cat5e cabo Cat7 ligacoes t568

Redes

As camadas da sua rede

Ethernet

  • Conexao logica entre dispositivos;
  • Cada dispositivo possui um endereco unico (MAC);
  • Os computadores sao conectados diretamente um ao outro ou a hub/switches;

Redes

As camadas da sua rede

TCP

  • Permite que multiplos programas se comuniquem com um unico dispositivo, atraves da ideia de "portas";
  • A porta 80 eh utilizada pelo servidores web (nosso caso);
  • Mais portas em IANA;

Redes

As camadas da sua rede

IPv4

  • Computadores sao identificados por enderecos IP;
  • Cada endereco IP possui 4 Bytes (32bits);
  • Exemplo: 192.168.0.1;
  • Cada rede possui uma "mascara de rede";
  • Exemplo: 255.255.255.0;
  • A mascara limita a quantidade de dispositivos na rede;

Redes

As camadas da sua rede

IPv4

  • Existem enderecos reservados;
  • Exemplo: 127.0.0.1 (localhost);
  • Para se comunicar de uma rede local para a internet, eh necessario utilizar NAT;
  • NAT(Network Address Translator) mapeia um endereco da rede interna e utiliza um unico IP externo valido para todos os computadores da rede;

Redes

As camadas da sua rede

IPv4

Como obter um endereco IP:

  • Endereco estatico (conf. geralmente manual):
  • DNS servers;
  • Mascara de subrede;
  • Endereco IP;
  • Gateway;
  • ...

Redes

As camadas da sua rede

IPv6

Como obter um endereco IP:

  • Endereco dinamico (conf. automatica):
  • Pronto!

Redes

As camadas da sua rede

HTTP

  • Funciona a partir da arquitetura cliente-servidor;
  • Um cliente solicita uma pagina ao servidor (request);
  • O servidor responde com um codigo + mensagem (response);
request-response request-response1

Redes

As camadas da sua rede

HTTP

Requisicao GET

				GET /sobre.html HTTP/1.1
Host: matehackers.org
...... outras informacoes ........
...... linha em branco ............

Redes

As camadas da sua rede

HTTP

Requisicao POST

				POST /login.php HTTP/1.1
Host: matehackers.org
...... outras informacoes .........
...... linha em branco ............
...... conteudo "encoded" .........

Redes

As camadas da sua rede

HTTP

Resposta do servidor

				200 OK
Content-Type: text/html
...... outras informacoes .........
...... linha em branco ............
...... conteudo (da pagina) .........

Arduino

Os equipamentos

Arduinos

Baseados nos chips Atmel

  • Yun
  • Mega
  • Duemilanove / Uno / Due
  • Leonardo
  • Mini / Micro / Nano
  • Lillypad
  • ...
arduino family

Arduino

Os equipamentos

Tipos de Ethernet chips

  • ENC28J60
  • Wiznet5100

Arduino

Os equipamentos

ENC28J60

  • Biblioteca propria;
  • Permite usar IPv6 (eh necessario codificar a pilha...);
  • Maioria nao eh um shield!
modulo enc28j60 modulo enc28j60 shield

Arduino

Os equipamentos

Wiznet5100

  • Biblioteca oficial;
  • Nao permite usar IPv6 (IPv4 em hardware);
  • Eh um shield!
modulo enc28j60

A aplicacao

Hands on

OK. Mas o que vamos precisar de verdade?

  • Ligacoes fisicas;
  • Configurar endereco MAC;
  • Configurar parametros da rede (ou DHCP);
  • Codificar a saida HTTP;
  • Fazer uma leitura em loop dos sensores e mostrar os valores;
  • Fim;

A aplicacao

Ligacoes fisicas

  • Use o esquema do fritzing para as ligacoes;
  • Lembre-se: tudo em 5V! (alguma placas requerem 3,3V. Fique atento.)
esquema de ligacoes no fritzing

A aplicacao

Configurar endereco MAC

Lets code!

	#include <LiquidCrystal.h>
	#include <SPI.h>
	#include <Ethernet.h>
	byte MAC_ADDRESS[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x__ };
	byte IP_ADDRESS[]={192,168,0, _ _ _};
	byte DNS_SERVER[] = { 192,168,1,1 };
	byte DEFAULT_GATEWAY[]={192,168,1,1};
	byte SUBNET_MASK[]={255,255,255,0};
	LiquidCrystal lcd(9,8,5,4,3,2); // pinos para o LCD
	EthernetServer server(80);

A aplicacao

Configurar os parametros minimos de rede:

Lets code!

  • Voce deve conhecer a rede na qual pretende ligar o servidor Arduino!;
  • Use o seu IP !;
	#include <LiquidCrystal.h>
	#include <SPI.h>
	#include <Ethernet.h>
	byte MAC_ADDRESS[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x__ };
 	byte IP_ADDRESS[]={192,168,0,_ _ _ };
	byte DNS_SERVER[] = { 192,168,1,1 };
	byte DEFAULT_GATEWAY[]={192,168,1,1};
	byte SUBNET_MASK[]={255,255,255,0};
	LiquidCrystal lcd(9,8,5,4,3,2); // pinos para o LCD
	EthernetServer server(80);

A aplicacao

Configurar os parametros do LCD (opcional)

Lets code!

  • Voce deve observar que a biblioteca LCD solicita usar os pinos 11 e 12;
  • Mas o Ethernet Shield ja usa os pinos 11 e 12! Trocaremos para 8 e 9 no LCD;
	#include <LiquidCrystal.h>
	#include <SPI.h>
	#include <Ethernet.h>
	byte MAC_ADDRESS[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x__ };
	byte IP_ADDRESS[]={192,168,0,_ _ _};
	byte DNS_SERVER[] = { 192,168,1,1 };
	byte DEFAULT_GATEWAY[]={192,168,1,1};
	byte SUBNET_MASK[]={255,255,255,0};
	LiquidCrystal lcd(9,8,5,4,3,2); // pinos para o LCD
	EthernetServer server(80);

A aplicacao

Configurar a porta do servidor Arduino

Lets code!

  • Essa eh barbada;
	#include <LiquidCrystal.h>
	#include <SPI.h>
	#include <Ethernet.h>
	byte MAC_ADDRESS[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x__ };
	byte IP_ADDRESS[]={192,168,0,_ _ _};
	byte DNS_SERVER[] = { 192,168,1,1 };
	byte DEFAULT_GATEWAY[]={192,168,1,1};
	byte SUBNET_MASK[]={255,255,255,0};
	LiquidCrystal lcd(9,8,5,4,3,2); // pinos para o LCD
	EthernetServer server(80);

A aplicacao

Setup

void setup() {
  Serial.begin(9600); // Inicializa comunicacao serial com o computador
  lcd.begin(16,2);    // Especifica o tamanho do lcd
  lcd.setCursor(0,0); // Linha inicial do LCD (co X li)
  int dhcpip = 0;
  dhcpip = Ethernet.begin(MAC_ADDRESS);  // Tenta conf. via DHCP
   if (dhcpip == 0) { // Se nao conseguiu
      delay(1000);    // Aguarda o shield reinicializar
      Serial.println("IP manual sendo configurado...");
      Ethernet.begin(MAC_ADDRESS, IP_ADDRESS, DNS_SERVER, DEFAULT_GATEWAY, SUBNET_MASK); // IP na marra!
      Serial.println(Ethernet.localIP());
      lcd.print(Ethernet.localIP());
    }
    else{
      Serial.println("Meu IP via DHCP eh: ");
      Serial.println(Ethernet.localIP());
      lcd.print(Ethernet.localIP());
    }
  server.begin();	 // Inicializa o servidor para "ouvir" requisicoes dos clientes
}

A aplicacao

Loop


void loop() {
   EthernetClient client = server.available(); // Se cliente conectado, valor = verdadeiro
  if (client) {
    Serial.println("novo cliente conectado...");
    boolean currentLineIsBlank = true; // Uma requisicao HTTP acaba com uma linha em branco
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) { // Se chegou uma linha em branco, o cliente parou de transmitir
          client.println("HTTP/1.1 200 OK");   // Hora de trabalhar, Arduino! Transmitindo a resposta....
          client.println("Content-Type: text/html"); // Tipo de dado que sera transmitido
          client.println("Connection: close");  // A conexao encerra quando parar de responder
          //client.println("Refresh: 5");  // Rele automaticamente a pagina a cada 5s
          client.println(); // final do cabecalho (header) HTTP

A aplicacao

Loop

  • Continua o loop...
  • Cabecalho HTML...
    client.println("<!DOCTYPE html>");
    client.println("<head>");
    client.println("<title>Arduino Ports -  List Page</title>");
    client.println("<meta charset="UTF-8" />");
    client.println("<link href="//maxcdn.bootstrapcdn.com/bootstrap/
    3.3.2/css/bootstrap.min.css" type="text/css" rel="stylesheet" />");
    client.println("</head>");
    client.println("<body> <div class="row" > <div class="span3 well" > <p></p></div>");
    client.println("<div class="span9" style="margin:20px 20px 20px 20px; " >");
    client.println("<h3>Sinais dos pinos do Arduino</h3>");

A aplicacao

Loop

  • Continua o loop...
  • Inicio da tabela e primeiro loop dos sensores analogicos
    client.println("<table class="table table-striped table-bordered" >");
    client.println("<thead><tr> <th>Pino</th><th>Valor atual</th> </tr></thead>");
    client.println("<tbody>");
    for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
      int sensorReading = analogRead(analogChannel);
      client.print("<tr><td>Analog");
      client.print(analogChannel); 
      client.print("</td><td>");
      client.print(sensorReading);
      client.print("</td></tr>");
    }

A aplicacao

Loop

  • Continua o loop...
  • Loops dos sensores digitais
for (int digitalChannel = 0; digitalChannel <= 7; digitalChannel++) {
  int pinReading = bitRead(PORTD,digitalChannel);
  client.print("    <tr><td>Digital");
  client.print(digitalChannel); 
  client.print("    </td><td>");
  client.print(pinReading);
  client.println("  </td></tr>");
}
for (int digitalChannel = 8; digitalChannel <= 13; digitalChannel++) {
  int pinReading = bitRead(PORTB,digitalChannel);
  client.print("    <tr><td>Digital");
  client.print(digitalChannel); 
  client.print("    </td><td>");
  client.print(pinReading);
  client.println("  </td></tr>");
}

A aplicacao

Loop

  • Continua o loop...
  • Finalizando a tabela e o IF da resposta...
  client.println("</tbody></table></div></div>");
  client.println("<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/
  bootstrap/3.3.2/js/bootstrap.min.js" ></script>");
  client.println("<script type="text/javascript" src="https://ajax.googleapis.com/
  ajax/libs/jquery/2.1.3/jquery.min.js" ></script>");
  client.println("</body>");
  client.println("</html>");
  break;
}   // finaliza a resposta

A aplicacao

Loop

  • Continua o loop...
  • Finalizando o loop principal
        if (c == '\n') {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }
      } // encerra rotina de cliente disponivel 
    }   // encerra rotina de cliente conectado 
    delay(1); // espera o buffer de envio ser esvaziado pelo navegador
    client.stop(); // encerra a conexao com o cliente
    Serial.println("Cliente desconectado.");
  }     // encerra cliente conectado
}       // encerra loop

Resultado em forma de tabela

Description

Resultado em formato JSON

Description

Links

Programas utilizados na apresentacao/oficina:

  • Programa com saida em formato tabela no codebender.cc
  • Programa com saida em formato JSON no codebender.cc
  • MateHackers;

Obrigado!

MateHackers - www.matehackers.org