Go Down

Topic: Servidor domotico con ethernet shield (Read 19062 times) previous topic - next topic

Maverik

DRicote:

mira ese es solo una demo, en realidad mi servidor esta en casa y si prendido las 24Hs es un pentium III de 600mhz con 256Mb de ram sin teclados sin pantalla ni nada mas solo la torre conectada al router y listo, si te preocupa el consumo te digo q es muy muy poco.

pero si quieres tener un servidor externo lo puedes hacer perfectamente, si te fijas en mi pagina yo lo que hago es pasar un parametro por medio de GET o POST a la IP del arduino por ejemplo al seleccionar una zona se carga la IP y los botones tienen parametros genericos asi si precionas el boton de TV en la zona sala lo que haces es enviar un parametro a la IP 192.168.1.15/?acc1ON

si quieren se puede armar un topic para hacer un sistema domotico donde todos aportemos algo que les parece.

dejo algunos links donde e sacado info.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1278347111/0

http://es.opendomo.org/

http://www.instructables.com/id/Connecting-a-12V-Relay-to-Arduino/

ami este tema me interesa mucho, no solo prender y apagar las cosas, sino tmb recibir datos y poder programar las acciones.

cualquier cosa estoy por aqui  ::)

y mi pagina yo la puedo ver bien, el servidor es medio lento pero anda  ;D

http://domotica23.260mb.com/

Usuario: user
Password: pass

venomio

#31
Sep 23, 2010, 01:22 am Last Edit: Sep 23, 2010, 01:25 am by venomio Reason: 1
Otra opción si quieres prescindir del uso de un PC entero para la tarea y poder montar un interface medio en condiciones es esta:
http://real2electronics.blogspot.com/2009/11/rapid-prototyping-hardware.html

Mirate todos los enlaces de la izquierda que hacen referencia a LINKDUINO que es engancharle un Router por por puerto serie al arduino. Asi el router gestiona el servidor web desde una SD y el arduino solo se encarga de lo que se tiene que encargar.

El mas importante de todos es el ultimo
+LINKDUINO:DD-WRT + OPTWARE

DRicote

pacojarcia:
Pues no se hasta donde se podría subir realmente el buffer, lo que si sé es que yo para hacer funcionar los 6 botones con dos "switch" como te comenté, tuve que subir el buffer a 1700, no funcionaba ni con mas ni con menos y por supuesto tuve que ir subiéndolo según fuí aumentando botones cuando empecé con ello.


Maverik:
Hola, no es por el consumo que pueda generar el ordenador las 24h, es que ya tuve uno hace tiempo como servidor de domótica por x10, camaras y alguna cosa mas, pero lo que pretendía con arduino es tener un sistema standalone y no preocuparme de nada mas que de alimentarlo y por supuesto que el tamaño reducido ayuda ;)

Próbe a hacer una prueba en una html externa enviando por get al arduino y funcionó pero me devuelve la página del arduino, quiere decirse que si no funciona la del arduino no haría caso, supongo :-/ no?, bueno fue una prueba nada mas.


venomio:
Buenos enlaces, ya vi la página algun día, es del amigo Igor que también transita este foro, es una máquina el tio.

Maverik

DRicote:
si el tamaño del arduino es algo q ayuda muxo.
no entiendo q pruebas hicistes, puedes explicar mejor? :-/

Maverik

#34
Sep 26, 2010, 01:43 am Last Edit: Sep 26, 2010, 01:46 am by Maverik Reason: 1
ok eso es lo q hace. prueba en poner este codigo en la pagina del arduino. lo que hace es regresart a la ultima pagina visitada.

Code: [Select]
client.println("HTTP/1.1 200 OK");
         client.println("Content-Type: text/html");
         client.println("<head>");
         client.println("<meta http-equiv=Content-Type content=text/html; charset=utf-8 />");
         client.println("<title>Titulo de tu web</title>");
         client.println("</head>");
         client.println("<body>");
         client.println("<input type=button value=Atras onClick=javascript:history.back();>");
         client.println("</body>");



o tmb puedes cambiar el meta por este codigo que hace lo mismo pero automatico
Code: [Select]
<META HTTP-EQUIV= "Refresh"CONTENT=\"1;URL=javascript:history.back() ">

DRicote

#35
Sep 26, 2010, 10:31 pm Last Edit: Feb 11, 2011, 09:54 pm by DRicote Reason: 1
Pues le he borrado la web entera al arduino y le he puesto solo la redireccion con el meta que me has comentado y ya llevo 26 botones (on+off=52 en total) en servidor externo funcionando de maravilla, se puede hacer la web al gusto y sin problemas de saturar el buffer del enc28j60.

Por lo que tengo entendido, éste tiene un buffer de 8K, si la web con solo unos botones le ocupaba de 2 a 4K y la misma programación ya le metía mas, por eso se saturaba tan rápido...

Gracias tambien a pacojarcia que si no descubre lo de las letras hubiera sido imposible ;)


Todo esto por el metodo get, alguien a probado con post?

Y otra cosa, antes cuando estaba la web en el arduino, se podía ver el estado de cada salida, como se podría visualizar esto en un servidor externo?

Lo que voy haciendo yo es una mera prueba en html, supongo que en php se le podría preguntar lo que tiene en memoria el arduino verdad?

DRicote

También he conseguido meter en la eeprom el estado de encendido o apagado, así desde cualquier otro interface, ya sea un lcd, etc, se puede saber el estado real en cada momento.

Una buena forma que se me ha ocurrido es que el arduino con la shield de ethernet enviara esa info a una base de datos tipo mysql y así desde fuera (servidor externo) se pueden hace estadísticas y todo tipo de cosas.

Alguien ha conseguido conectar o sabe como se podría ,la shield basada en el enc28j60 a una base de datos tipo mysql?

maurogamer

Hola, la verdad es que soy nuevo en el tema arduino.. y me ha encantado como han llevado acabo este proyecto.. me parece espectacular.. solo que me queda una inquietud, sería posible montar esto en una placa Arduino Mega??, así para tener más puntos de control

DRicote

Claro que es posible!, la nueva shield de ethernet con chip wiznet (la que lleva slot micro sd) ya es compatible con el mega, la anterior había que hacerla alguna modificación pero también he visto que la usaban.

maurogamer

#39
Oct 23, 2010, 05:53 pm Last Edit: Oct 23, 2010, 06:57 pm by maurogamer Reason: 1
Hola Dricote, muchas gracias por responder, sabes, estoy con algunas dudas frente a este proyecto..

Tengo clara la configuración de la página, para el envío de la información a la Arduino, pero no tengo muy claro como realizar la configuración en el arduino para que recepcione la información de la web. Hice un intento pero no me funciono  :-[ :-[ :-[

lo que sucede es que yo solo quiero abrir unas puertas, solo ON, y luego darle un tiempo para cerrar, como las puertas magnéticas...

pero me confundí un poco, revisé el código de pacojarcia y vi como funcionaba.. y esta de maravillas con 6 botones, pero también realicé una web para comunicarla con el arduino ocupando datos por la URL..

maurogamer

estimado Dricote, hice una prueba tratanto de tomar los datos de la Web, pero no me es posible que funcione, por lo que lei, lograste realizar esa opción, para mi es la mejor, porque no cargas el código en el arduino, si no que puedes ocupar un web que sería ideal,

el código que revisé es para la wiznet, y tu tenias la ethernet con el enc28J60, que es lo que tengo en este minuto, una duemilanove y  una ethernet shield con el enc28j60.. podria ver la perte de tu código donde recopilas la información de la web ???

yo envío los valores de la web vía GET action,

Muchas Gracias

DRicote

Si te revisas el post desde el principio hallarás la respuesta (ya lo han mencionado varios compañeros), para enviar info a la shield de ethernet por GET no hace falta que sea un modelo u otro, funciona con las dos.

Y no he quitado el código si no, no haría nada, sólo he quitado la parte de html.


Saludos

gonchi

hola. he adquirido hace un tiempo una ethernet shield. y la aplicacion sobre la que estais debatiendo es la que mas me interesa y apasiona como aplicacion.
Estais a años luz mia. Podriais indicarme ejemplos o paginas para ir adquiriendo conocimientos. porque los codigos que  poneis no estan completos no.

gracias.

maurogamer

si, hice un ejemplo de web como la siguiente:
Quote

<head>
   <title>sin título</title>
   <meta http-equiv="content-type" content="text/html;charset=utf-8" />
   <meta name="generator" content="Geany 0.18" />
</head>

<body>

<form method="GET" action="192.168.0.15">
   <input type="submit" name="Puerta1" value ="1"><br>
   <input type="submit" name="Puerta2" value ="1"><br>
   <input type="submit" name="Puerta3" value ="1"><br>
   <input type="submit" name="Puerta4" value ="1"><br>
</form>    

</body>
</html>


pero el código que cargo en la arduino no me funciona, ahora estoy en la Universidad, llegando a casa postiaré en código que cargo en la arduino. Si es posible me indiquen donde está el problema,

Muchas Gracias

maurogamer

Muchas Gracias Dricote, logré enviar los datos vía web con los ejemplos del foro, lo que si intente colocar un delay bajo el primer switch, funciona pero se tarda 14 seg aprox. en apagar y además la web se torna lenta.. a que se puede deber eso...????

dejo mi codigo

Code: [Select]
#include "etherShield.h"

static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t myip[4] = {192,168,0,15};
static char baseurl[]="http://192.168.0.15/";
static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254)

// Relay status. Start Off.
byte on_off1;
byte on_off2;
byte on_off3;
byte on_off4;
byte on_off5;
byte on_off6;

#define BUFFER_SIZE 1500
static uint8_t buf[BUFFER_SIZE+1];
#define STR_BUFFER_SIZE 22
static char strbuf[STR_BUFFER_SIZE+1];

EtherShield es=EtherShield();

// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf, byte on_off1, byte on_off2, byte on_off3, byte on_off4, byte on_off5, byte on_off6);
int8_t analyse_cmd(char *str);

// 6 relays connected to output
#define SW1  2
#define SW2  3
#define SW3  4
#define SW4  5
#define SW5  6
#define SW6  7

void setup(){
Serial.begin(9600); //PACO para depurar el programa
 /*initialize enc28j60*/
  es.ES_enc28j60Init(mymac);
  es.ES_enc28j60clkout(2);
  delay(10);
       es.ES_enc28j60PhyWrite(PHLCON,0x880);
     delay(250);
     es.ES_enc28j60PhyWrite(PHLCON,0x990);
     delay(250);
     es.ES_enc28j60PhyWrite(PHLCON,0x880);
     delay(250);
     es.ES_enc28j60PhyWrite(PHLCON,0x990);
     delay(250);
       delay(100);
 //init the ethernet/ip layer:
 es.ES_init_ip_arp_udp_tcp(mymac,myip,mywwwport);
 // Init outputs
      pinMode(SW1, OUTPUT);
      digitalWrite(SW1, LOW);  // switch off LED
      pinMode(SW2, OUTPUT);
      digitalWrite(SW2, LOW);  // switch off LED
       pinMode(SW3, OUTPUT);
      digitalWrite(SW3, LOW);  // switch off LED
       pinMode(SW4, OUTPUT);
      digitalWrite(SW4, LOW);  // switch off LED
       pinMode(SW5, OUTPUT);
      digitalWrite(SW5, LOW);  // switch off LED
       pinMode(SW6, OUTPUT);
      digitalWrite(SW6, LOW);  // switch off LED
}

void loop(){
 uint16_t plen, dat_p;
 int8_t cmd;

// Ethernet Mode
 plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);

 if(plen!=0){  /*plen will ne unequal to zero if there is a valid packet (without crc error) */
             // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address.
           if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){
             es.ES_make_arp_answer_from_request(buf);
             return;    }
           // check if ip packets are for us:
           if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){return;}
           if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
                   es.ES_make_echo_reply_from_request(buf,plen);
                   return;    }
           
           // tcp port www start, compare only the lower byte
     if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport){
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
                    es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack
                    return;}
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
                   es.ES_init_len_info(buf); // init some data structures
                   dat_p=es.ES_get_tcp_data_pointer();
                   if (dat_p==0){ // we can possibly have no data, just ack:
                           if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){es.ES_make_tcp_ack_from_any(buf);}
                           return;}
                   if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
                           // head, post and other methods for possible status codes see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                           plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                           goto SENDTCP;}
                   // If "get /" without parameters
                      if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
                           plen=print_webpage(buf, on_off1, on_off2, on_off3, on_off4, on_off5, on_off6);
                           goto SENDTCP;}
                   cmd=analyse_cmd((char *)&(buf[dat_p+5]));
                   
                   // Process commands
                   switch (cmd) {
                   case 'A':      //PACO: cambio los números por letras
                           on_off1=1;
                             digitalWrite(SW1, HIGH); // switch on LED1
                           delay(7000);
                           digitalWrite(SW1, LOW);
                           break;
                   case 'B':
                           on_off1=0;
                                digitalWrite(SW1, LOW);  // switch off LED1
                           break;
                   case 'C':
                           on_off2=1;
                             digitalWrite(SW2, HIGH);  // switch on LED2
                           break;
                   case 'D':
                           on_off2=0;
                             digitalWrite(SW2, LOW);  // switch off LED2
                           break;
                   case 'E':
                           on_off3=1;
                             digitalWrite(SW3, HIGH);  // switch on LED3
                           break;
                   case 'F':
                           on_off3=0;
                             digitalWrite(SW3, LOW);  // switch off LED3
                           break;
                   case 'G':
                           on_off4=1;
                             digitalWrite(SW4, HIGH);  // switch on LED4
                           break;
                   case 'H':
                           on_off4=0;
                             digitalWrite(SW4, LOW);  // switch off LED4
                           break;
                   case 'I':
                           on_off5=1;
                             digitalWrite(SW5, HIGH);  // switch on LED5
                           break;
                   case 'J':
                           on_off5=0;
                             digitalWrite(SW5, LOW);  // switch off LED5
                           break;
                   case 'K':
                           on_off6=1;
                             digitalWrite(SW6, HIGH);  // switch on LED6
                           break;
                   case 'L':
                           on_off6=0;
                             digitalWrite(SW6, LOW);  // switch off LED6
                           break;                
                       }
                   plen=print_webpage(buf, on_off1, on_off2, on_off3, on_off4, on_off5, on_off6);
                   
         SENDTCP:  es.ES_make_tcp_ack_from_any(buf); // send ack for http get
                   es.ES_make_tcp_ack_with_data(buf,plen); // send data      
   } } } }


// The returned value is stored in the global var strbuf
   uint8_t find_key_val(char *str,char *key)
   {
           uint8_t found=0;
           uint8_t i=0;
           char *kp;
           kp=key;
           while(*str &&  *str!=' ' && found==0){
                   if (*str == *kp){
                           kp++;
                           if (*kp == '\0'){
                                   str++;
                                   kp=key;
                                   if (*str == '='){ found=1;}
                           }
                   }else{kp=key;}
                   str++;
           }
           if (found==1){
                   // copy the value to a buffer and terminate it with '\0'
                   while(*str &&  *str!=' ' && *str!='&' && i<STR_BUFFER_SIZE){
                           strbuf[i]=*str;
                           i++;
                           str++;}
                   strbuf[i]='\0';
           }
           return(found);
}


int8_t analyse_cmd(char *str)
{      int8_t r=-1;
        if (find_key_val(str,"cmd")){
               if (*strbuf < 0x4f && *strbuf > 0x40){   //PACO antes era:   if (*strbuf < 0x3a && *strbuf > 0x2f) ahora permito de la 'A' a la 'N'
                       // is a ASCII number, return it
                       r=*strbuf;               // PACO antes era:   r=(*strbuf-0x30);  ahora esto 40 A->0 ; B -> 1 ; ....
               }
       }
       return r;
}


uint16_t print_webpage(uint8_t *buf, byte on_off1, byte on_off2, byte on_off3, byte on_off4, byte on_off5, byte on_off6)
{       int i=0;
       uint16_t plen;
       plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
       return(plen);
}  

Go Up