Open top menu
terça-feira, 10 de fevereiro de 2015
Automation Shield - Automação com Android e Bluetooth


Hoje vamos apresentar um projeto de automação com o Automation Shield, Bluetooh JY-MCU / HC-06 e um aplicativo de exemplo Android para acionamento das saídas.

Aplicativo Android para acionamento da placa
A nova versão do aplicativo mostra o estado das saídas da placa. A melhoria do código fonte do arduino é armazenar na EEPROM os últimos comandos do usuário, dessa forma, quando  a placa for reiniciada, ela será reestabelicida com os últimos comandos enviados pelo usuário.

A placa JY-MCU ou HC-06 Bluetooth pode ser encontrada com barra de terminais para conexão e faixa de tensão de alimentação entre 3.6 e 6V. Essa versão pode ser alimentada através do pino OUT + 5V do Shield.








Ou em uma versão sem barra de terminais e tensão de alimentação em 3.3V. Essa versão só pode ser alimentada através do pino 3V3 do Shield e deve ser utilizado um divisor de tensão entre os pinos TX (Arduino) e RX (módulo)




Lista de componentes
1 - Arduino NANO V3.0
1 - Placa Nano Automation Shield, a venda em nossa loja virtual.
1 - Fonte 12V x 3A.
1 - Placa JY-MCU ou HC-06 Bluetooth.
4 - Fios com conectores MODU para conexão do projeto.
1- Fita RGB
1 -  Resistor de 10K.
1 - Resistor de 20K.

Preparação da placa Bluetooh sem terminais.

Soldagem dos pinos.


Placa pronta com termo retrátil para isolamento das conexões.



GND - Preto
3,3V - Vermelho 
TX- Verde 
RX - Marrom 


Conexões do projeto

A conexão deve ser feita TX <-> RX entre o shield de Automação e a placa Bluetooh  JY-MCU. Se o módulo bluetooth trabalhar apenas com nível de sinal de 3,3 V será necessário utilizar um divisor de tensão no pino RX para não danificar o módulo. Conecte o pino TX do arduino com o pino RX do módulo com um resistor de 10K e o pino RX do módulo com um resistor de 20K ao GND.

Conexões das saídas

Código fonte do projeto
O código fonte do projeto é bem simples, dentro do loop do programa, ficamos esperando algum comando que venha pela porta serial, o caracter "|" define o início e fim do protocolo de envio de comandos. Durante o desenvolvimento, podemos testar nosso programa através do console serial do Arduino, e enviar os comandos, conforme exemplo abaixo:

|D11| Envia comando: Digital - Saida 1 - Sinal 1 -> Ligar Saida 1
|D10| Envia comando: Digital - Saida 1 - Sinal 0 -> Desligar Saida 1

|D21| Envia comando: Digital - Saida 2 - Sinal 1 -> Ligar Saida 2
|D20| Envia comando: Digital - Saida 2 - Sinal 0 -> Desligar Saida 2

|D31|
Envia comando: Digital - Saida 3 - Sinal 1 -> Ligar Saida 3
|D30|
Envia comando: Digital - Saida 3 - Sinal 0 -> Desligar Saida  3

|D41|
Envia comando: Digital - Saida 4 - Sinal 1 -> Ligar Saida 4
|D40|
Envia comando: Digital - Saida 4 - Sinal 0 -> Desligar Saida 4

|A60|
Envia comando: LED Vermelho - 0 (Desligado) -> Desligar Led Vermelho
|A69|
Envia comando: LED Vermelho - 9 (Maximo) -> Maxima pontencia Led Vermelho

O nível de potencia pode ser variado entre 0 (desligado) e 9 (máximo)
Led Verde
|A50|  ate |A59| 
Led Azul
|A30| até |A39|

Para evitar falhas no processo de upload, desconecte o Arduino do Shield ou remova as conexões com o Bluetooth. 

Código fonte Arduino

/*
  Software serial multple serial test

    https://drive.google.com/file/d/0B0t-Nu1Eo1b8OFdOWkg5QkMwMVE/view?usp=sharing

  VCC 3V
  GND  GND
  TX  RX
  RX  TX

  Protocolo
  |D21|
  |D20|

  |A64|

  Versão 1.1 -> Incluido persitencia de comandos na EEPROM e WACHTDOG

  */


#include <EEPROM.h>
#include <avr/wdt.h>

#define PIN_RED 6
#define PIN_GREEN 5
#define PIN_BLUE 3

int MemSaveSaida1 = 1;
int MemSaveSaida2 = 2;
int MemSaveSaida3 = 3;
int MemSaveSaida4 = 4;
int MemSaveRed    = 5;
int MemSaveBlue   = 6;
int MemSaveGreen  = 7;

int ValueSaveSaida1 = 0;
int ValueSaveSaida2 = 0;
int ValueSaveSaida3 = 0;
int ValueSaveSaida4 = 0;
int ValueSaveRed    = 0;
int ValueSaveBlue   = 0;
int ValueSaveGreen  = 0;

int inicioucomando;
String comando = "";

void setup()
{

  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);

  inicioucomando = 0;
  comando = "";

  Serial.begin(9600);

  ValueSaveSaida1 = EEPROM.read(MemSaveSaida1);
  ValueSaveSaida2 = EEPROM.read(MemSaveSaida2);
  ValueSaveSaida3 = EEPROM.read(MemSaveSaida3);
  ValueSaveSaida4 = EEPROM.read(MemSaveSaida4);
  ValueSaveRed = EEPROM.read(MemSaveRed);
  ValueSaveBlue = EEPROM.read(MemSaveBlue);
  ValueSaveGreen = EEPROM.read(MemSaveGreen);

  digitalWrite(A0, ValueSaveSaida1);
  digitalWrite(A1, ValueSaveSaida2);
  digitalWrite(A2, ValueSaveSaida3);
  digitalWrite(A3, ValueSaveSaida4);

  analogWrite(5, ValueSaveRed);
  analogWrite(6, ValueSaveGreen);
  analogWrite(3, ValueSaveBlue);

  wdt_enable(WDTO_8S); //Watchdog 8 Segundos
}

void loop()
{
  aguardacomandos();
  wdt_reset(); //Reset WatchDog
  RetornaComandos();

}

void aguardacomandos()
{
  char ch;
  while (Serial.available()) {
    ch = Serial.read();
    if (ch == '|')
    {
      if (inicioucomando == 1)
      {
        inicioucomando = 0;
        disparacomando();
      }
      else
      {
        inicioucomando = 1;
      }
    }
    else
    {
      comando.concat(ch);
    }
  }
}

void disparacomando()
{

  Serial.println(comando);
  if (comando[0] == 'D')
  {
    int port = (comando[1] - '0');
    int value = (comando[2] - '0');

    if (port == 1)
    {
      ValueSaveSaida1 = value;
      EEPROM.write(MemSaveSaida1, ValueSaveSaida1);
      digitalWrite(A0, ValueSaveSaida1);
    }
    else if (port == 2)
    {
      ValueSaveSaida2 = value;
      EEPROM.write(MemSaveSaida2, ValueSaveSaida2);
      digitalWrite(A1, ValueSaveSaida2);
    }
    else if (port == 3)
    {
      ValueSaveSaida3 = value;
      EEPROM.write(MemSaveSaida3, ValueSaveSaida3);
      digitalWrite(A2, ValueSaveSaida3);
    }
    else if (port == 4)
    {
      ValueSaveSaida4 = value;
      EEPROM.write(MemSaveSaida4, ValueSaveSaida4);
      digitalWrite(A3, ValueSaveSaida4);
    }
  }
  else if (comando[0] == 'A')
  {
    int port = (comando[1] - '0');
    int value = (comando[2] - '0');
    value = value * 28;

    if ( port == 6 )
    {
      ValueSaveRed = value;
      EEPROM.write(MemSaveRed, ValueSaveRed);
      analogWrite(port, value);
    }
    else if ( port == 5 )
    {
      ValueSaveGreen = value;
      EEPROM.write(MemSaveGreen, ValueSaveGreen);
      analogWrite(port, value);
    }
    else if ( port == 3 )
    {
      ValueSaveBlue = value;
      EEPROM.write(MemSaveBlue, ValueSaveBlue);
      analogWrite(port, value);
    }
  }
  else
  {
    Serial.println("Error");
  }
  comando = "";
}

void RetornaComandos()
{
  String retorno = "|COMANDOS#";
  retorno.concat(ValueSaveSaida1);
  retorno.concat("#");
  retorno.concat(ValueSaveSaida2);
  retorno.concat("#");
  retorno.concat(ValueSaveSaida3);
  retorno.concat("#");
  retorno.concat(ValueSaveSaida4);
  retorno.concat("#");
  retorno.concat(ValueSaveRed);
  retorno.concat("#");
  retorno.concat(ValueSaveGreen);
  retorno.concat("#");
  retorno.concat(ValueSaveBlue);
  retorno.concat("#");

  Serial.println(retorno);
}



Código fonte Android

Não foi criada uma tela para seleção do dispositivo pareado para conexão. O programa busca pelo nome default (Linvor) ou (HC-06)  da placa JY-MCU para conexão. Se o dispositivo for renomeado ou estiver com nome diferente de Linvor ou HC-06, não ocorrerá a conexão, sendo então necessário renomear o dispositivo para um dos dois nome antes dos testes no aplicativo de exemplo.





O código fonte está disponível no github em: https://github.com/sergiomokshin/AutomationShield/tree/master/Bluetooth
  
A senha padrão do bluetooth é 1234, 123 ou 0000. Ele precisa ser pareado com o celular antes da abertura e utilização do aplicativo.

No vídeo abaixo podemos ver todo o processo de pareamento e acesso da placa pelo aplicativo.


A placa JY-MCU Bluetooth não é compatível com alguns dispositivos IPhone e IPad, o exemplo de hardware e software desse projeto é compatível apenas com dispositivos com sistema operacional Android.
Read more
sábado, 7 de fevereiro de 2015
Automation Shield - WebServer com W5100


O artigo de hoje é um dos projetos mais interessantes que podemos desenvolver com o Arduino, dando sequencia com os artigos de “Internet das coisas”, é um projeto para acionamento da placa de automação remotamente. O arduino Nano será configurado como WebServer disponibilizando uma página html para visualização e acionamento dos IOs da placa.

Versão do projeto com Mini EthernetShield
Versão do projeto com Ethernet Shield para Arduino

O chip WS5100 tem algumas vantagens em relação ao enc28j60, ele é suportado pelas bibliotecas oficiais do Arduino e como a pilha TCP/IP é executada no próprio shield, o arduino fica responsável apenas em executar o programa do projeto.

Mini Shield

Shield para Arduino

Os dois shields são 100% compatíveis com o projeto e código fonte, vamos ver em detalhes as conexões com o Automation Shield.

Pagina html para acionamento dos comandos e visualização dos status das chaves.


Lista de componentes
1 - Arduino NANO V3.0
1 - Placa Nano Automation Shield, a venda em nossa loja virtual.
1 - Fonte 12V
1 - Shield W5100 - MiniShield ou Ethernet Shield
3 - Chaves liga/desliga
3 - Resistores 10K
16 - Fios com conectores MODU para conexão do projeto

Conexões do projeto com mini Shield
Conexões do projeto com Ethernet Shield
A conexões com o EthernetShield foram realizadas pela parte traseira do shield.

Conexões das Saídas

Alimentação do W5100
Verifique o modelo do shield W5100. As novas versões possuem um regulador de tensão para 5V, nesse caso, podemos ligar direto na saída 5V da placa. algumas versões são alimentadas com 3,3V e deverão ser alimentadas através do pino 3v3 ou pelo conector ICSP,



Código Fonte
O código fonte do projeto é 100% compatível com os dois Shields de Ethernet. Recomendo usar a função F() para montagem do html para optimização da memória usada pelo scketch. A função F(), permite acessar as variáveis strings sem carregar na memória SRAM, o conteúdo da string é armazenado na memoria FLASH do Arduino.

/*
Sergio Mokshin
Automação Live - Jan /2015

*/

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

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

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0D, 0xA6, 0x09 }; //physical mac address
byte ip[] = {
  192, 168, 0, 177 }; // ip in lan
byte gateway[] = {
  192, 168, 0, 1 }; // internet access via router
byte subnet[] = {
  255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port


#define CHAVE_1 2
#define CHAVE_2 4
#define CHAVE_3 7

#define PIN_RED 3
#define PIN_GREEN 6
#define PIN_BLUE 5

String readString;

void setup(){


  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.begin(9600);

  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);

}

void loop(){

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {

          Serial.println(readString);
       
          if(readString.indexOf("?S1Ligado") >0) {
            digitalWrite(A0, HIGH);
          }
          if(readString.indexOf("?S1Desligado") >0) {
            digitalWrite(A0, LOW);
          }

          if(readString.indexOf("?S2Ligado") >0) {
            digitalWrite(A1, HIGH);
          }
          if(readString.indexOf("?S2Desligado") >0) {
            digitalWrite(A1, LOW);
          }

          if(readString.indexOf("?S3Ligado") >0) {
            digitalWrite(A2, HIGH);
          }
          if(readString.indexOf("?S3Desligado") >0) {
            digitalWrite(A2, LOW);
          }

          if(readString.indexOf("?S4Ligado") >0) {
            digitalWrite(A3, HIGH);
          }
          if(readString.indexOf("?S4Desligado") >0) {
            digitalWrite(A3, LOW);
          }

          if(readString.indexOf("?red") >0) {
            analogWrite(PIN_RED, 255);
            analogWrite(PIN_GREEN, 0);            
            analogWrite(PIN_BLUE, 0);
          }

          if(readString.indexOf("?green") >0) {
            analogWrite(PIN_RED, 0);
            analogWrite(PIN_GREEN, 255);            
            analogWrite(PIN_BLUE, 0);
          }

          if(readString.indexOf("?blue") >0) {
            analogWrite(PIN_RED, 0);
            analogWrite(PIN_GREEN, 0);            
            analogWrite(PIN_BLUE, 255);
          }

          if(readString.indexOf("?white") >0) {
            analogWrite(PIN_RED, 255);
            analogWrite(PIN_GREEN, 255);            
            analogWrite(PIN_BLUE, 255);
          }


          if(readString.indexOf("?rgboff") >0) {
            analogWrite(PIN_RED, 0);
            analogWrite(PIN_GREEN, 0);            
            analogWrite(PIN_BLUE, 0);
          }

          int S1 = digitalRead(A0);
          int S2 = digitalRead(A1);
          int S3 = digitalRead(A2);
          int S4 = digitalRead(A3);

          int Chave1 = digitalRead(CHAVE_1);
          int Chave2 = digitalRead(CHAVE_2);
          int Chave3 = digitalRead(CHAVE_3);

          int LedR = analogRead(6);
          int LedG = analogRead(5);
          int LedB = analogRead(3);

          client.println(F("HTTP/1.1 200 OK")); //send new page
          client.println(F("Content-Type: text/html"));
          client.println();

          client.println(F("<HTML>"));
          client.println(F("<HEAD>"));
          client.println(F("<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css' rel='stylesheet'></link>"));
          client.println(F("</head>"));
          client.println(F("<body>"));
          client.println(F("<div class='jumbotron'>"));
          client.println(F("<h2>Interface de comando</h2>"));
          client.println(F("<div class='row'>"));
          client.println(F("<div class='col-md-10'>"));
          client.println(F("<table class='table table-bordered'>"));
          client.println(F("<tbody>"));
          //S 1
          client.println(F("<tr><td width=130px>S 1 - "));
          if(S1 == HIGH)
          {
            client.println(F("Ligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-danger btn-lg' href='?S1Desligado'>Desligar</buttLigado>"));
          }
          else
          {
            client.println(F("Desligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-success btn-lg' href='?S1Ligado'>Ligar</buttLigado>"));      
          }      
          client.println(F("</td></tr>"));


          //S 2
          client.println(F("<tr><td width=130px>S 2 - "));
          if(S2 == HIGH)
          {
            client.println(F("Ligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-danger btn-lg' href='?S2Desligado'>Desligar</buttLigado>"));
          }
          else
          {
            client.println(F("Desligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-success btn-lg' href='?S2Ligado'>Ligar</buttLigado>"));      
          }      
          client.println(F("</td></tr>"));


          //S 3
          client.println(F("<tr><td width=130px>S 3 - "));
          if(S3 == HIGH)
          {
            client.println(F("Ligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-danger btn-lg' href='?S3Desligado'>Desligar</buttLigado>"));
          }
          else
          {
            client.println(F("Desligado"));
            client.println(F("</b></td><td>"));
            client.println(F("<a class='btn btn-success btn-lg' href='?S3Ligado'>Ligar</buttLigado>"));      
          }      
          client.println(F("</td></tr>"));


          //S 4
          client.println(F("<tr><td width=130px>S 4 - "));
          if(S4 == HIGH)
          {
            client.println(F("Ligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-danger btn-lg' href='?S4Desligado'>Desligar</buttLigado>"));
          }
          else
          {
            client.println(F("Desligado"));
            client.println(F("</td><td>"));
            client.println(F("<a class='btn btn-success btn-lg' href='?S4Ligado'>Ligar</buttLigado>"));      
          }      
          client.println(F("</td></tr>"));


          //RGB
          client.println(F("<tr><td>RGB</td><td>"));
          client.println(F("<a class='btn btn-primary btn-lg' href='?blue' >Azul</a>&nbsp;"));
          client.println(F("<a class='btn btn-danger btn-lg' href='?red' >Vermelho</a>&nbsp;"));      
          client.println(F("<a class='btn btn-success btn-lg' href='?green' >Verde</a>&nbsp;"));      
          client.println(F("<a class='btn btn-default btn-lg' href='?white' >Branco</a>&nbsp;"));                  
          client.println(F("<a class='btn btn-link' href='?rgboff' >Desligar</a>&nbsp;"));                                                          
          client.println(F("</td></tr>"));




          client.println(F("<tr><td colspan=2>Chave 1 - "));
          if(Chave1 == HIGH)
          {
            client.println(F("<span class='glyphicon glyphicon-ok-circle' aria-hidden='true'></span>"));  
          }
          else
          {
            client.println(F("<span class='glyphicon glyphicon-ban-circle' aria-hidden='true'></span>"));  
          }

          client.println(F("<br>"));    

          client.println(F("Chave 2 - "));
          if(Chave2 == HIGH)
          {
            client.println(F("<span class='glyphicon glyphicon-ok-circle' aria-hidden='true'></span>"));  
          }
          else
          {
            client.println(F("<span class='glyphicon glyphicon-ban-circle' aria-hidden='true'></span>"));  
          }


          client.println(F("<br>"));    
          client.println(F("Chave 3 - "));

          if(Chave3 == HIGH)
          {
            client.println(F("<span class='glyphicon glyphicon-ok-circle' aria-hidden='true'></span>"));  
          }
          else
          {
            client.println(F("<span class='glyphicon glyphicon-ban-circle' aria-hidden='true'></span>"));  
          }

          client.println(F("<br>"));    
          client.println(F("<a class='btn btn-link' href='/'>Verificar status chaves</a>"));                                                          
       
       
          client.println(F("</td></tr>"));
       

          client.println(F("</tbody>"));
          client.println(F("</table>"));
          client.println(F("</div>"));

          client.println(F("</body>"));
          client.println(F("</html>"));

          delay(1);
          //stopping client
          client.stop();

          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

Vamos ver um vídeo do projeto com a versão mini Shield W5100


E com a versão Ethernet Shield para Arduino Uno


Projeto com WebServer e W5100 que automatiza um aquário, em breve será publicado no site.









Read more
Automation Shield - WebServer com Enc28j60


Hoje vamos apresentar um projeto básico de automação remota com o ethernet shield Enc28j60.  O arduino Nano será configurado como WebServer disponibilizando uma página html para visualização e acionamento dos IOs da placa.
Pagina html para acionamento dos comandos e visualização dos status das chaves.
Antes de começar a apresentação do projeto vamos ressaltar algumas limitações do Enc28j60.

Buffer para resposta do html
A cada request, apenas uma variável de buffer para o response pode ser retornada, o Arduino Uno e Nano possuem apenas 2Kb de memória para utilização por todo o programa, dessa forma, limitamos em 1Kb a variável para criação do html de resposta, se excedermos 1Kb, o Arduino irá travar. É importante durante o desenvolvimento do projeto com Enc28j60 verificar a quantidade de caracteres que está sendo atribuída e nunca exceder 1Kb. A pagina html do projeto possui 900 caracteres, está no limite para montagem de um html de resposta. Como alternativa, podemos montar apenas a resposta no formato Json com os status dos IOs, e criar uma página html que realiza o acesso via Javascript e Ajax, dessa forma não teremos restrição para montagem do html de apresentação dos dados, mas teremos que manter e abrir o arquivo html para acessarmos a placa de automação.

Instabilidade
Verificamos alguns problemas de instabilidade e travamento do Arduino quando usamos em um mesmo projeto com outras comunicações, principalmente seriais ou com RTC, A principal diferença entre o Enc28j60 e o W5100 é que o Enc28j60 executa a a pilha TCP/IP no Arduino, enquanto que o W5100 isola em seu próprio shield, permitindo que o Arduino execute apenas o código implementado para o projeto. Existem inúmeras bibliotecas criadas para o Enc28j60 que podem ser avaliadas e testadas, mas a recomendação é usar um shield com o W5100 para criação de projetos complexos e com múltiplos dispositivos.

Mesmo com as limitações acima, o Enc28j601 pode ser usado para desenvolvimento projetos de WebServer com acionamento de saídas e leitura de sinais analógicos e digitais.

Lista de componentes
1 - Arduino NANO V3.0
1 - Placa Nano Automation Shield, a venda em nossa loja virtual.
1 - Fonte 12V
1 - Shield Enc28j60, a venda em nossa loja virtual.
3 - Chaves liga/desliga
3 - Resistores 10K
10 - Fios com conectores MODU para conexão do projeto

Conexões do projeto


Esquema elétrico de ligações



Alimentação do Enc38j60
Verifique o modelo do shield Enc28j60. As novas versões vem com  12 pinos, e possui um regulador de tensão para 5V, nesse caso, podemos ligar direto na saída 5V da placa. algumas versões do Enc28j60 são alimentadas com 3,3V e não podem ser alimentadas com 5V. A recomendação para essas versões é utilizar um LM1115 3,3V para alimentação. Algumas versões clone do Arduino não conseguem fornecer a corrente necessária para o funcionamento do módulo, ocasionando mal funcionamento e travamentos.

Esquema de ligação das chaves


Watchdog e EEPROM 
Um projeto de automação, é fundamental que seja persistido em memória não volátil os comandos enviados pelo usuário, se o Arduino travar ou ocorrer interrupção da alimentação, o Arduino deve preservar nas saídas as últimos comandos enviados pelo usuário. No nosso projeto usamos o método EEPROM.write para gravar o ultimo comando para cada saída e o método EEPROM.read no setup para ler o último comando e iniciar a placa em um eventual travamento ou interrupção por falta de energia.

O projeto implementa um watchdog time com um timer de 8 segundos. Um watchdog timer é um dispositivo eletrônico temporizado que dispara um reset ao sistema se o programa principal, deixar de fazer reset no watchdog timer.


Código fonte do projeto
#include <EtherCard.h>
#include <EEPROM.h>
#include <avr/wdt.h>

#define PIN_RED 6 
#define PIN_GREEN 5
#define PIN_BLUE 3
#define PIN_ALARM 3

#define CHAVE_1 2
#define CHAVE_2 4
#define CHAVE_3 7

int MemSaveSaida1 = 1;
int MemSaveSaida2 = 2;
int MemSaveSaida3 = 3;
int MemSaveSaida4 = 4;

int ValueSaveSaida1 = 0;
int ValueSaveSaida2 = 0;
int ValueSaveSaida3 = 0;
int ValueSaveSaida4 = 0;

// Ip address
static byte myip[] = { 192,168,1,200 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };


static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
byte Ethernet::buffer[1000]; // tcp/ip send and receive buffer
BufferFiller bfill;

void setup(){ 
   wdt_enable(WDTO_8S); //Watchdog 8 Segundos
 

  //Setup Inicial / descomentar build / comentar
  //EEPROM.write(MemSaveSaida1, 0); 
  //EEPROM.write(MemSaveSaida2, 0);
  //EEPROM.write(MemSaveSaida3, 0);         
  //EEPROM.write(MemSaveSaida4, 0); 
 
  Serial.begin(57600);
  Serial.println("Iniciando Setup");     

  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(PIN_ALARM, OUTPUT);

   
  ValueSaveSaida1 = EEPROM.read(MemSaveSaida1);
  ValueSaveSaida2 = EEPROM.read(MemSaveSaida2);
  ValueSaveSaida3 = EEPROM.read(MemSaveSaida3);
  ValueSaveSaida4 = EEPROM.read(MemSaveSaida4);
 
  digitalWrite(A0, ValueSaveSaida1);
  digitalWrite(A1, ValueSaveSaida2);
  digitalWrite(A2, ValueSaveSaida3);
  digitalWrite(A3, ValueSaveSaida4); 

 
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
  {
    Serial.println( "Failed to access Ethernet controller");
  }


  ether.staticSetup(myip, gwip);
  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip); 
  ether.printIp("DNS: ", ether.dnsip); 

  analogWrite(6, 0); 
  analogWrite(5, 0);   
  analogWrite(3, 0); 

  Serial.println("Finalizando Setup");     
}



static word homePage() {

  Serial.println("Gerando Home Page"); 

  int S1 = digitalRead(A0);
  int S2 = digitalRead(A1);
  int S3 = digitalRead(A2);
  int S4 = digitalRead(A3); 
  int Chave1 = digitalRead(CHAVE_1); 
  int Chave2 = digitalRead(CHAVE_2); 
  int Chave3 = digitalRead(CHAVE_3); 

  int LedR = analogRead(6); 
  int LedG = analogRead(5); 
  int LedB = analogRead(3); 

 
  int AL = digitalRead(PIN_ALARM); 
         

  bfill = ether.tcpOffset();
 
  bfill.emit_p(PSTR("<html><head>"));
  bfill.emit_p(PSTR("<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css' rel='stylesheet'></link>"));

  bfill.emit_p(PSTR("</head>"));
  bfill.emit_p(PSTR("<body>"));
  bfill.emit_p(PSTR("<div class='jumbotron'>"));
  bfill.emit_p(PSTR("<h2>Interface de comando</h2>"));
  bfill.emit_p(PSTR("<div class='row'>"));
  bfill.emit_p(PSTR("<div class='col-md-6'>"));
  bfill.emit_p(PSTR("<table class='table table-bordered'>"));
  bfill.emit_p(PSTR("<tbody>"));

  //SAIDA 1

  bfill.emit_p(PSTR("<tr><td width=200px>Saida 1 - "));
  if(S1 == HIGH)
  {
    bfill.emit_p(PSTR("On"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S1/OFF' type='button'>Desligar</button>"));
  }
  else
  {
    bfill.emit_p(PSTR("Off"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S1/ON' type='button'>Ligar</button>"));       
  }       
  bfill.emit_p(PSTR("</td></tr>"));


  //SAIDA 2
  bfill.emit_p(PSTR("<tr><td width=200px>Saida 2 - "));
  if(S2 == HIGH)
  {
    bfill.emit_p(PSTR("On"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S2/OFF' type='button'>Desligar</button>"));
  }
  else
  {
    bfill.emit_p(PSTR("Desligado"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S2/ON' type='button'>Ligar</button>"));       
  }       
  bfill.emit_p(PSTR("</td></tr>"));

  //SAIDA 3
  bfill.emit_p(PSTR("<tr><td width=200px>Saida 3 - "));
  if(S3 == HIGH)
  {
    bfill.emit_p(PSTR("Off"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S3/OFF' type='button'>Desligar</button>"));
  }
  else
  {
    bfill.emit_p(PSTR("Desligado"));
    bfill.emit_p(PSTR("</b></td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S3/ON' type='button'>Ligar</button>"));       
  }       
  bfill.emit_p(PSTR("</td></tr>"));

  //SAIDA 4
  bfill.emit_p(PSTR("<tr><td width=200px>Saida 4 - "));
  if(S4 == HIGH)
  {
    bfill.emit_p(PSTR("Ligado"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S4/OFF' type='button'>Desligar</button>"));
  }
  else
  {
    bfill.emit_p(PSTR("Desligado"));
    bfill.emit_p(PSTR("</td><td>"));
    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S4/ON' type='button'>Ligar</button>"));       
  }       
  bfill.emit_p(PSTR("</td></tr>"));

  bfill.emit_p(PSTR("<tr><td colspan=2>Chave 1 - "));
  if(Chave1 == HIGH)
  {
    bfill.emit_p(PSTR("On"));   
  }
  else
  {
    bfill.emit_p(PSTR("Off"));       
  }

  bfill.emit_p(PSTR("<br>"));     
  bfill.emit_p(PSTR("Chave 2 - "));
  if(Chave2 == HIGH)
  {
    bfill.emit_p(PSTR("On"));   
  }
  else
  {
    bfill.emit_p(PSTR("Off"));       
  }
 
  bfill.emit_p(PSTR("<br>"));     
  bfill.emit_p(PSTR("Chave 3 - "));
  if(Chave3 == HIGH)
  {
    bfill.emit_p(PSTR("On"));   
  }
  else
  {
    bfill.emit_p(PSTR("Off"));       
  }

  bfill.emit_p(PSTR("</td></tr>"));   
  bfill.emit_p(PSTR("</tbody>"));
  bfill.emit_p(PSTR("</table>"));
  bfill.emit_p(PSTR("</div>"));
  bfill.emit_p(PSTR("</body>"));
  bfill.emit_p(PSTR("</html>"));
    
  return bfill.position();
}

void loop(){   
  WebServer();
  wdt_reset(); //diReset WatchDog
}

void WebServer()
{

  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

 
 // char* dados =(char *)Ethernet::buffer + pos; 
 // if(pos >0)
 // {
 //    Serial.println(dados); 
 // }
 
    if(strstr((char *)Ethernet::buffer + pos, "GET /S1/ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(A0, HIGH);
      EEPROM.write(MemSaveSaida1, 1);
    }
    if(strstr((char *)Ethernet::buffer + pos, "GET /S1/OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(A0, LOW);
      EEPROM.write(MemSaveSaida1, 0);
    }
   
  if(strstr((char *)Ethernet::buffer + pos, "GET /S2/ON") != 0) {
      Serial.println("Received ON command");
       digitalWrite(A1, HIGH);
       EEPROM.write(MemSaveSaida2, 1);
    }
    if(strstr((char *)Ethernet::buffer + pos, "GET /S2/OFF") != 0) {
      Serial.println("Received OFF command");
       digitalWrite(A1, LOW);
       EEPROM.write(MemSaveSaida2, 0);  
    }

  if(strstr((char *)Ethernet::buffer + pos, "GET /S3/ON") != 0) {
      Serial.println("Received ON command");
       digitalWrite(A2, HIGH);
       EEPROM.write(MemSaveSaida3, 1);
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /S3/OFF") != 0) {
      Serial.println("Received OFF command");
       digitalWrite(A2, LOW);
       EEPROM.write(MemSaveSaida3, 0);    
    }


  if(strstr((char *)Ethernet::buffer + pos, "GET /S4/ON") != 0) {
      Serial.println("Received ON command");
       digitalWrite(A3, HIGH);
       EEPROM.write(MemSaveSaida4, 1);      
    }
  if(strstr((char *)Ethernet::buffer + pos, "GET /S4/OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(A3, LOW);
      EEPROM.write(MemSaveSaida4, 0);
   }    

 
  if(strstr((char *)Ethernet::buffer + pos, "GET /R/ON") != 0) {
      Serial.println("Received OFF command");
      analogWrite(5, 255); 
   }

 
   if(strstr((char *)Ethernet::buffer + pos, "GET /R/OFF") != 0) {
      Serial.println("Received OFF command");
      analogWrite(5, 0);
   }

 
   if(strstr((char *)Ethernet::buffer + pos, "GET /G/ON") != 0) {
      Serial.println("Received OFF command");
      analogWrite(6, 255); 
   }

 
   if(strstr((char *)Ethernet::buffer + pos, "GET /G/OFF") != 0) {
      Serial.println("Received OFF command");
      analogWrite(6, 0); 
   }

 
   if(strstr((char *)Ethernet::buffer + pos, "GET /B/ON") != 0) {
      Serial.println("Received OFF command");
      analogWrite(3, 255); 
   }

   if(strstr((char *)Ethernet::buffer + pos, "GET /B/OFF") != 0) {
      Serial.println("Received OFF command");
      analogWrite(3, 0); 
   }

   if (pos)
   {
    ether.httpServerReply(homePage());  
   }  
}


Acessando pelo browser com o ip http://192.168.1.200 configurado no projeto a página de monitoramento é aberta.


Vídeo de funcionamento do projeto



Clique aqui para download da biblioteca EtherCad utilizada no projeto;

Atualização:

O código fonte abaixo adiciona na interface o comando de led RGB.


/*

Sergio Mokshin

Automação Livre

Fev/2015



*/



#include <EtherCard.h>

#include <EEPROM.h>

#include <avr/wdt.h>



#define PIN_RED 6 

#define PIN_GREEN 5

#define PIN_BLUE 3

#define PIN_ALARM 3



#define CHAVE_1 2

#define CHAVE_2 4

#define CHAVE_3 7



int MemSaveSaida1 = 1;

int MemSaveSaida2 = 2;

int MemSaveSaida3 = 3;

int MemSaveSaida4 = 4;

int MemSaveRed    = 5;

int MemSaveBlue   = 6;

int MemSaveGreen  = 7;



int ValueSaveSaida1 = 0;

int ValueSaveSaida2 = 0;

int ValueSaveSaida3 = 0;

int ValueSaveSaida4 = 0;

int ValueSaveRed    = 0;

int ValueSaveBlue   = 0;

int ValueSaveGreen  = 0;







// ethernet interface ip address

static byte myip[] = { 192, 168, 1, 200 };

// gateway ip address

static byte gwip[] = { 192, 168, 1, 1 };



// ethernet mac address - must be unique on your network

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[1100]; // tcp/ip send and receive buffer

BufferFiller bfill;



void setup(){ 

 

   wdt_enable(WDTO_8S); //Watchdog 8 Segundos

  

  //Setup Inicial / descomentar build / comentar

  //EEPROM.write(MemSaveSaida1, 0); 

  //EEPROM.write(MemSaveSaida2, 0);

  //EEPROM.write(MemSaveSaida3, 0);         

  //EEPROM.write(MemSaveSaida4, 0); 

 

 

  Serial.begin(38400);

  Serial.println("Iniciando Setup");     

 

  pinMode(A0, OUTPUT);

  pinMode(A1, OUTPUT);

  pinMode(A2, OUTPUT);

  pinMode(A3, OUTPUT);

  pinMode(PIN_ALARM, OUTPUT);

   

  ValueSaveSaida1 = EEPROM.read(MemSaveSaida1);

  ValueSaveSaida2 = EEPROM.read(MemSaveSaida2);

  ValueSaveSaida3 = EEPROM.read(MemSaveSaida3);

  ValueSaveSaida4 = EEPROM.read(MemSaveSaida4);

  ValueSaveRed = EEPROM.read(MemSaveRed);

  ValueSaveBlue = EEPROM.read(MemSaveBlue);

  ValueSaveGreen = EEPROM.read(MemSaveGreen);

   

  digitalWrite(A0, ValueSaveSaida1);

  digitalWrite(A1, ValueSaveSaida2);

  digitalWrite(A2, ValueSaveSaida3);

  digitalWrite(A3, ValueSaveSaida4);





    

 

   analogWrite(5, ValueSaveRed); 

   analogWrite(6, ValueSaveGreen); 

   analogWrite(3, ValueSaveBlue);    

 

 

 

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)

  {

    Serial.println( "Failed to access Ethernet controller");

  }



  ether.staticSetup(myip, gwip);

  ether.printIp("IP:  ", ether.myip);

  ether.printIp("GW:  ", ether.gwip); 

  ether.printIp("DNS: ", ether.dnsip);   

  

  Serial.println("Finalizando Setup");     

}



static word homePage() {

 

  Serial.println("Gerando Home Page"); 



  int S1 = digitalRead(A0);

  int S2 = digitalRead(A1);

  int S3 = digitalRead(A2);

  int S4 = digitalRead(A3); 

 

  int Chave1 = digitalRead(CHAVE_1); 

  int Chave2 = digitalRead(CHAVE_2); 

  int Chave3 = digitalRead(CHAVE_3); 

 

  int LedR = analogRead(6); 

  int LedG = analogRead(5); 

  int LedB = analogRead(3); 

 

  int AL = digitalRead(PIN_ALARM); 

           

  bfill = ether.tcpOffset();

 

  bfill.emit_p(PSTR("<html><head>"));

  bfill.emit_p(PSTR("<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css' rel='stylesheet'></link>"));

  bfill.emit_p(PSTR("</head>"));

  bfill.emit_p(PSTR("<body>"));

  bfill.emit_p(PSTR("<div class='jumbotron'>"));

  bfill.emit_p(PSTR("<h2>Interface de comando</h2>"));

  bfill.emit_p(PSTR("<div class='row'>"));

  bfill.emit_p(PSTR("<div class='col-md-6'>"));

 

  //SAIDA 1

  if(S1 == HIGH)

  {

    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S1/OFF' type='button'>S1 - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S1/ON' type='button'>S1 - OFF -> Ligar</button></a>"));       

  }       

  bfill.emit_p(PSTR("<br><br>"));

 

   //SAIDA 2

  if(S2 == HIGH)

  {

    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S2/OFF' type='button'>S2 - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S2/ON' type='button'>S2 - OFF -> Ligar</button></a>"));       

  }       

  bfill.emit_p(PSTR("<br><br>"));

 

   //SAIDA 3

  if(S3 == HIGH)

  {

    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S3/OFF' type='button'>S3 - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S3/ON' type='button'>S3 - OFF -> Ligar</button></a>"));       

  }       

  bfill.emit_p(PSTR("<br><br>"));

 

   //SAIDA 4

  if(S4 == HIGH)

  {

    bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/S4/OFF' type='button'>S4 - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/S4/ON' type='button'>S4 - OFF -> Ligar</button></a>"));       

  }       

  bfill.emit_p(PSTR("<br><br>"));



 

  //RGB Red

  if(ValueSaveRed == 255)

  {

     bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/R/OFF' type='button'>Red - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/R/ON' type='button'>Red - OFF -> Ligar</button></a>"));           

  }       

  bfill.emit_p(PSTR("<br><br>")); 

 

    //RGB Green

  if(ValueSaveGreen == 255)

  {

     bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/G/OFF' type='button'>Green - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/G/ON' type='button'>Green - OFF -> Ligar</button></a>"));           

  }       

  bfill.emit_p(PSTR("<br><br>")); 

 

 

    //RGB Blue

  if(ValueSaveBlue == 255)

  {

     bfill.emit_p(PSTR("<a class='btn btn-success btn-lg' href='/B/OFF' type='button'>Blue - ON -> Desligar</button></a>"));       

  }

  else

  {

    bfill.emit_p(PSTR("<a class='btn btn-danger btn-lg' href='/B/ON' type='button'>Blue - OFF -> Ligar</button></a>"));           

  }       

 

  bfill.emit_p(PSTR("<br><br>"));

 

  bfill.emit_p(PSTR("Chave 1 - "));

  if(Chave1 == HIGH)

  {

    bfill.emit_p(PSTR("On"));   

  }

  else

  {

    bfill.emit_p(PSTR("Off"));       

  }



  bfill.emit_p(PSTR("<br>"));     

  bfill.emit_p(PSTR("Chave 2 - "));

  if(Chave2 == HIGH)

  {

    bfill.emit_p(PSTR("On"));   

  }

  else

  {

    bfill.emit_p(PSTR("Off"));       

  }

 

  bfill.emit_p(PSTR("<br>"));     

  bfill.emit_p(PSTR("Chave 3 - "));

  if(Chave3 == HIGH)

  {

    bfill.emit_p(PSTR("On"));   

  }

  else

  {

    bfill.emit_p(PSTR("Off"));       

  }





  bfill.emit_p(PSTR("</div>"));

  bfill.emit_p(PSTR("</body>"));

  bfill.emit_p(PSTR("</html>"));

     

  return bfill.position();

}





void loop(){   

 

  WebServer();

  wdt_reset(); //diReset WatchDog

}

void WebServer()

{

 word len = ether.packetReceive();

  word pos = ether.packetLoop(len);

 

 // char* dados =(char *)Ethernet::buffer + pos; 

 // if(pos >0)

 // {

 //    Serial.println(dados); 

 // }

 

    if(strstr((char *)Ethernet::buffer + pos, "GET /S1/ON") != 0) {

      Serial.println("Received ON command");

      digitalWrite(A0, HIGH);

      EEPROM.write(MemSaveSaida1, 1);

    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /S1/OFF") != 0) {

      Serial.println("Received OFF command");

      digitalWrite(A0, LOW);

      EEPROM.write(MemSaveSaida1, 0);

    }

   

  if(strstr((char *)Ethernet::buffer + pos, "GET /S2/ON") != 0) {

      Serial.println("Received ON command");

       digitalWrite(A1, HIGH);

       EEPROM.write(MemSaveSaida2, 1);

    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /S2/OFF") != 0) {

      Serial.println("Received OFF command");

       digitalWrite(A1, LOW);

       EEPROM.write(MemSaveSaida2, 0);  

    }



  if(strstr((char *)Ethernet::buffer + pos, "GET /S3/ON") != 0) {

      Serial.println("Received ON command");

       digitalWrite(A2, HIGH);

       EEPROM.write(MemSaveSaida3, 1);

    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /S3/OFF") != 0) {

      Serial.println("Received OFF command");

       digitalWrite(A2, LOW);

       EEPROM.write(MemSaveSaida3, 0);

      

    }



  if(strstr((char *)Ethernet::buffer + pos, "GET /S4/ON") != 0) {

      Serial.println("Received ON command");

       digitalWrite(A3, HIGH);

       EEPROM.write(MemSaveSaida4, 1);      

    }

  if(strstr((char *)Ethernet::buffer + pos, "GET /S4/OFF") != 0) {

      Serial.println("Received OFF command");

      digitalWrite(A3, LOW);

      EEPROM.write(MemSaveSaida4, 0);

   }    

  

  if(strstr((char *)Ethernet::buffer + pos, "GET /R/ON") != 0) {

      Serial.println("Received OFF command");

      analogWrite(5, 255); 

      EEPROM.write(MemSaveRed, 255);

      ValueSaveRed = 255;

   }

  

   if(strstr((char *)Ethernet::buffer + pos, "GET /R/OFF") != 0) {

      Serial.println("Received OFF command");

      analogWrite(5, 0); 

      EEPROM.write(MemSaveRed, 0);

      ValueSaveRed = 0;

   }

  

   if(strstr((char *)Ethernet::buffer + pos, "GET /G/ON") != 0) {

      Serial.println("Received OFF command");

      analogWrite(6, 255); 

      EEPROM.write(MemSaveGreen, 255);     

      ValueSaveGreen = 255;

   }

  

   if(strstr((char *)Ethernet::buffer + pos, "GET /G/OFF") != 0) {

      Serial.println("Received OFF command");

      analogWrite(6, 0); 

      EEPROM.write(MemSaveGreen, 0);           

      ValueSaveGreen = 0;

   }

  

   if(strstr((char *)Ethernet::buffer + pos, "GET /B/ON") != 0) {

      Serial.println("Received OFF command");

      analogWrite(3, 255); 

      EEPROM.write(MemSaveBlue, 255);      

      ValueSaveBlue = 255;    

   }

  

   if(strstr((char *)Ethernet::buffer + pos, "GET /B/OFF") != 0) {

      Serial.println("Received OFF command");

      analogWrite(3, 0); 

      EEPROM.write(MemSaveBlue, 0);                       

      ValueSaveBlue = 0;     

   }

  

  

   if (pos)

   {

    ether.httpServerReply(homePage());  

   }  

}


Guias de referência / apoio
http://www.tweaking4all.com/hardware/arduino/arduino-enc28j60-ethernet/
http://nathanhein.com/2013/02/getting-arduino-online-with-an-enc28j60/
https://github.com/jcw/ethercard/blob/master/README.md
Read more
Automation Shield - Temporizador com RTC DS1307 e LCD


No projeto de hoje, vamos montar um temporizador para acionamento dos relés e saídas de potência em horários pré-determinados. O horário atual será mostrado no LCD.





Lista de componentes
1 - Arduino NANO V3.0
1 - Placa Nano Automation Shield, a venda em nossa loja virtual.
1 - Fonte industrial 12V x 5A
1 - RTC DS1307
1 - Fita de Leds RGB
1- LCD 16x02


Conexões do projeto

Existe uma diferença entre os RTCs DS1302 e DS1307. O DS1302 usa o protocolo SPI, enquanto o DS1307 usa o procolo I2C através dos pinos 4 e 5. Nosso projeto está compatível apenas com o RTC DS1307.


Código fonte
Para ajuste inicial do horário do RTC, siga os passos:
  1. Conforme exemplo abaixo, atribua o horário e data atual nas variáveis.
  2. Descomente (remova da linha //) o método setDateDs1307.
  3. Realize o upload para o Arduino.
  4. Comente (insira // no começo da linha) setDateDs1307.
  5. Faça novamente o upload para o Arduino. 

second = 00;
minute = 8;
hour = 22;
dayOfWeek = 1;
dayOfMonth = 1;
month = 2;
year = 15;

Esse último passo é necessário para não ajustar o horário quando o Arduino for reinicializado, a hora será ajustada novamente com os parâmetros que já não correspondem mais ao horário atual.

Os saídas foram programadas da seguinte forma:
Saída S1: Ligada entre 00:00 e 11:59 todos os dias
Saída S2: Ligada entre 12:00 e 23:59 todos os dias
Saída S3: Ligada entre 08:00 e 17:00 de segunda a sexta
Saída S4: Ligada entre 08:00 e 17:00 sábado e domingo

RGB Branco: Ligado entre 18:00 e 22:00 todos os dias
RGB Azul: Ligado entre 22:00 e 23:59 todos os dias

/*
Sergio Mokshin
Automação Livre
Fev/2015
*/

//Referencia de apoio http://www.glacialwanderer.com/hobbyrobotics

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
#include <LiquidCrystal.h>


//Inicializando LCD
LiquidCrystal lcd(12, 11, 8, 9, 10, 7);

//Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

//Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.write(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}


void setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);
  
  lcd.begin(16, 2);
  
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
    
  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  second = 00;
  minute = 8;
  hour = 22;
  dayOfWeek = 1;
  dayOfMonth = 1;
  month = 2;
  year = 15;
 // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  MostraData();
  AtualizaSaidas();
  delay(1000);
}


void MostraData(){
    
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    
  lcd.setCursor(0, 1);   
  if (hour < 10){
  lcd.print("0");       
  }
  lcd.print(hour,DEC);   
  lcd.setCursor(2, 1); 
  lcd.print(":");
  lcd.setCursor(3, 1); 
  if (minute < 10){
  lcd.print("0");       
  }
  lcd.print(minute,DEC); 
  lcd.setCursor(5, 1); 
  lcd.print(":");             
  lcd.setCursor(6, 1); 
  if (second < 10){
  lcd.print("0");       
  }
  lcd.print(second,DEC);

  lcd.setCursor(8, 1); 
  lcd.print("  ");
  lcd.setCursor(10, 1);
  if (dayOfMonth < 10){
  lcd.print("0");         
  }
  lcd.print(dayOfMonth,DEC);
  lcd.setCursor(12, 1);
  lcd.print("/"); 
  lcd.setCursor(13, 1);
  if (month < 10){
  lcd.print("0");       
  }
  lcd.print(month,DEC);
  lcd.setCursor(15, 1);


  Serial.print(hour, DEC);
  Serial.print(":");
  Serial.print(minute, DEC);
  Serial.print(":");
  Serial.print(second, DEC);
  Serial.print("  ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.println(year, DEC);
  Serial.print("Day of week ");
  Serial.println(dayOfWeek, DEC);
}


void AtualizaSaidas(){
    
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);  
  //Saída S1: Ligada entre 00:00 e 11:59 todos os dias
  if (hour <= 11)  
  {
    Serial.println("S1 Off");
    digitalWrite(A0, HIGH);    
  }
  else
  {
    Serial.println("S1 On");    
    digitalWrite(A0, LOW);            
  }
    
  //Saída S2: Ligada entre 12:00 e 23:59 todos os dias
  if (hour >=12 )  
  {
    Serial.println("S2 On");
    digitalWrite(A1, HIGH);    
  }
  else
  {
    Serial.println("S2 Off");    
    digitalWrite(A1, LOW);            
  }

  //Saída S3: Ligada entre 08:00 e 17:00 de segunda a sexta
  if (hour >=8 && hour <=17 && dayOfWeek >= 2  && dayOfWeek <= 6)  
  {
    Serial.println("S3 On");
    digitalWrite(A2, HIGH);    
  }
  else
  {
    Serial.println("S3 Off");
    digitalWrite(A2, LOW);            
  }
  
  //Saída S4: Ligada entre 08:00 e 17:00 sábado e domingo
  if (hour >=8 && hour <=17  && (dayOfWeek == 1 || dayOfWeek == 7))  
  {
    Serial.println("S4 On");
    digitalWrite(A3, HIGH);    
  }
  else
  {
    Serial.println("S4 Off");    
    digitalWrite(A4, LOW);            
  }  
          
  //RGB Branco:  Ligado entre 18:00 e 22:00 todos os dias
  //RGB Azul:    Ligado entre 22:00 e 23:59 todos os dias
  if (hour <18 )  
  {
     Serial.println("RG Off");    
     analogWrite(5, 0);
     analogWrite(6, 0);
     analogWrite(3, 0);     
  }
  else if (hour >=18 && hour < 22 )  
  {
     Serial.println("RGB Branco");        
     analogWrite(5, 255);
     analogWrite(6, 255);
     analogWrite(3, 255);     
  }
  else if (hour >=22)  
  {
     Serial.println("RGB Azul");            
     analogWrite(5, 255);
     analogWrite(6, 0);
     analogWrite(3, 0);     
  }

}

Vídeo do projeto






Read more
Automation Shield


Hoje vamos apresentar o Automation Shield, ele foi desenvolvido com o objetivo de simplificar a criação de projetos de automação. É compatível com o Arduino Nano V3 e pode ser usada em diversos projetos de automação, monitoramento, temporizadores, entre outros. 


Os IOs da placa possuem Jumpers que permitem a inativação ou troca do pino utilizado no Arduino, permitindo expansão ou troca de funcionalidades.

Especificações técnicas
-Microcontrolador Arduino Nano.
-Alimentação 12V, possui regulador de tensão 9V para alimentação do Arduino Nano.
-Saída regulada 5V para alimentação de sensores, LCDs, Shields, entre outros.
-4 saídas de relés 120V 10A / 220V 10A;
-3 saídas de potência com TIP 120 - 5A PWM para RGB ou outro tipo de carga.
-Dimensões: 97 x 150 x 40 mm (Largura x Comprimeto x Altura)
-Jumpers que permitem inativação ou troca do pino utilizado no Arduino, permitindo expansão ou troca de funcionalidades.

Pinos utilizados 
  • A0, A1, A2 e A3: utilizados para saídas com relés *.
  • D3, D5 e D6: utilizados para saídas PWM de potência *.
*Os pinos possuem jumpers que permitem a inativação ou troca do pino do Arduino nano utilizado.

Exemplos 

WebServer de automação com enc28j60

WebServer de automação com WS5100

Temporizador de saídas

Automação de Aquário

Esquema elétrico de ligação

Cada projeto tem características individuais, que exigem recursos diferenciados de processamento, memória, comunicação serial, leituras digitais, analógicas, PWM entre outros. Quando usamos a plataforma Arduino, devemos avaliar entre as versões disponíveis, qual atende os requisitos funcionais do nosso projeto.

Vamos publicar uma série de artigos de projetos úteis, com código fonte aberto, integrando com LCD, RTC, BlueTooth, WiFi, Ethernet, WebServer, WebCliente, Android, entre outros.

Teste Básico de acionamento das saídas do Shield

/*
Sergio Mokshin
Automação Livre
Jan/2015
 
*/


#define PIN_RED 6
#define PIN_GREEN 5
#define PIN_BLUE 3

 void setup()  
{

  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
 

  Serial.begin(9600);  
  analogWrite(6, 0);  
  analogWrite(5, 0);    
  analogWrite(3, 0);  
  
}

 void loop() 
{    
   digitalWrite(A0, HIGH);    
   delay(500);
   digitalWrite(A0, LOW);     
   digitalWrite(A1, HIGH);       
   delay(500); 
   digitalWrite(A1, LOW);     
   digitalWrite(A2, HIGH);       
   delay(500);
   digitalWrite(A2, LOW);    
   digitalWrite(A3, HIGH);      
   delay(500); 
   digitalWrite(A3, LOW);    
   analogWrite(PIN_RED, 255); 
   delay(500);
   digitalWrite(PIN_RED, 0);    
   analogWrite(PIN_GREEN, 255); 
   delay(500);
   digitalWrite(PIN_GREEN, 0);    
   analogWrite(PIN_BLUE, 255); 
   delay(500);
   analogWrite(PIN_BLUE, 255);    
   analogWrite(PIN_RED, 255);    
   analogWrite(PIN_GREEN, 255);      
   delay(500);
   analogWrite(PIN_BLUE, 0);    
   analogWrite(PIN_RED, 0);    
   analogWrite(PIN_GREEN, 0);      

}


Teste de bancada do Aquadroid 2.0 com o AutomationShield



Conectando com outras versões do Arduino.
A placa Automation Shield permite a conexão com outras versões do Arduino. O diagrama abaixo mostra a conexão com um Arduino Mega.

Conexão “Arduino Mega – Automation Shield”. 
D3-P1 
D5-P2 
D6-P3 
A0-S1 
A1-S2 
A2-S3 
A3-S4 
GND-GND 
Vin– 9V 

Componentes


Conexão com o Arduino Mega


Vídeo de testes



A substituição do Arduino Nano pelo Arduino Mega permite a criação de projetos que necessitam de mais recursos de Software e Hardware. A placa Automation Shield incorpora funcionalidades úteis como alimentação regulada 9V para o Arduino, barra de terminais para alimentação 5V de outros Shields, saídas com relés, potência DC entre outros.

Projeto com Automation Shield e Arduino Mega




Read more