Arduino Uno con Ethernet Shield W5100

Continuando la discusión desde ChipKIT Max32 con Digilent WiFi Shield:

Buen día @Frank1985,

Aunque en éste momento no tenemos éste hardware exacto para hacer las pruebas, vamos a sugerirte un ensayo, así:

Una trama HTTP POST tiene normalmente éstos campos

POST /api/v1.6/variables/{id_variable}/values HTTP/1.1
Content-Type: application/json
X-Auth-Token: {token}
Host: things.ubidots.com

{"value":44}

Mirando la teoría, un pequeño detalle: debe haber un espacio entre el comando “POST” y la URL “/api/v1.6…”

client.println("POST /api/v1.6/variables/"+idvariable+"/values HTTP/1.1");
client.println("Content-Type: application/json");
client.println("Content-Length: "+String(num));
client.println("X-Auth-Token: "+token);
client.println("Host: things.ubidots.com\n");
client.print(var);

Cuéntanos cómo te va. Saludos

Efectivamente. Ya se puede enviar el dato. Muchas gracias por su respuesta.

Hasta pronto.

1 Like

Buenas tardes.

Siguiendo con el tema de enviar regularmente los datos al DashBoard desde un Arduino Uno con Ethernet Shield W5100 tengo para comentar:

  1. El envío del dato en el primer ciclo se efectúa sin problemas.

    if (client.connect(“things.ubidots.com”, 80))
    {
    // int dato = client.connect(“things.ubidots.com”, 80);
    // Serial.println(dato);
    Serial.println(“connected”);
    //Linea de código original.
    client.println(“POST /api/v1.6/variables/” + idvariable + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num) + "\nX-Auth-Token: " + token + “\nHost: things.ubidots.com\n”);
    Serial.println(“POST /api/v1.6/variables/” + idvariable + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num) + "\nX-Auth-Token: " + token + “\nHost: things.ubidots.com\n”);
    // En el codigo original fala agregar el valor de la variable.
    client.print(var + “\n”);
    Serial.print(var + “\n”);
    // client.connect(“things.ubidots.com”, 80);
    }

  2. Al momento de repetir el ciclo, se toma el cliente como no disponible ( Toma la condicion falsa “else” al no poder tomar como verdadero la condición. if (client.connect(“things.ubidots.com”, 80)). Por tanto pasa a “Connection Failed”.

    else
    {
    // if you didn’t get a connection to the server:
    Serial.println(“connection failed”);

    }
    
  3. Se repite durante varios ciclos. Una veces toma de nuevo la condición verdadera. Otras veces no la vuelve a tomar hasta el que se cumple la condición para desconectar el Arduino.

    if (!client.connected())
    {
    Serial.println();
    Serial.println(“disconnecting.”);
    client.stop();
    // do nothing forevermore:
    for (;;);

    }
    

Mi pregunta es:

Después Post hacia Ubidots. hay que esperar un tiempo para enviar el siguiente POST?, o es necesario un paso adicional, como un GET de confirmación para saber que ya se puede enviar otro dato?.

Muchas Gracias por su atención. Hasta Pronto.

Hola @Frank1985,

En realidad no es necesario esperar para enviar el siguiente post (por lo menos no desde el punto de vista de la API). Se nos ocurren dos posibilidades en cuanto al hardware:

1- En algunos sistemas embebidos hemos observado algo similar debido al manejo de Strings y su concatenación. Tal vez el Arduino no maneja bien la memoria internamente y llena el “heap memory”, causando problemas para el manejo de nuevos strings. Ésto se puede resolver usando chars y el comando “sprintf” en lugar de Strings y concatenación con signos “+”.

2- En algunos sistemas es necesario cerrar el socket de lo contrario el sistema comienza a crear un socket para cada conexión hasta que se queda sin memoria. Que tal hacer un “client.flush();” al final de cada envío? Aquí unos links:

http://www.arduino.cc/en/Reference/ClientFlush
http://forum.freetronics.com/viewtopic.php?t=176&start=30

Hola, buenos días.

Efectivamente, al parecer el Arduino UNO tiene algún problema al enviar muy frecuentemente los datos a ubidots. Por tanto tuve que poner una linea client.stop una vez se ha enviado el dato. Pues intente con la linea client.flush pero seguía teniendo el mismo problema.

Aun así, después de unos 4 minutos, el Arduino se desconecta.

Para reiniciar una vez mas la conexión, quité la linea for(;:wink: para que el programa vuelva a conectarse automáticamente.

Detallo a continuación el código completo.

/*
Web client

This sketch connects to a website using an Arduino Wiznet Ethernet shield.

Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13

created 18 Dec 2009
modified 9 Apr 2012
by David A. Mellis
modified 15 Jan 2015
by Mateo Velez for Ubidots, Inc.
modified 11 Jun 2015
by Francisco Valderrama for Electrotics, Inc. */ 
  #include <SPI.h>
  #include <Ethernet.h>


   // Enter a MAC address for your controller below.
   // Newer Ethernet shields have a MAC address printed on a sticker on the shield
     byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
     byte ip[]={192, 168, 1, 2};
     byte gw [] = {192, 168, 1, 254};
     byte dns_[] = {200, 13, 249, 101};
     byte subnet_[] = {255, 255, 255, 0};
  // Initialize the Ethernet client library
  // with the IP address and port of the server
  // that you want to connect to (port 80 is default for HTTP):
      EthernetClient client;

      String idvariable_1 = "55565d0d7625423f7d3b7d5a";
      String idvariable_2 = "5579c01c762542309af36bef";
      String token = "D7wHWtSAwAi3cSp5RVoFecZXAZzm7ylO7ytx1YqOHWeTzgEpwWofMVlmd3uy";
            void setup() {
                     // Open serial communications and wait for port to open:
                      Serial.begin(9600);
                       while (!Serial) {
                                     ; // wait for serial port to connect. Needed for Leonardo only
                       }

     // start the Ethernet connection:
     // Ethernet.begin(mac, ip, dns_, gw, subnet_);
    if (Ethernet.begin(mac)==0) {
       Serial.println("Failed to configure Ethernet using DHCP");
       // Si Falla la configuracion por DHCP se realiza una Configuaración de red manual. 
       Serial.println("Configuring manually network parameters");
       Ethernet.begin(mac, ip, dns_, gw, subnet_);
       }
     // give the Ethernet shield a second to initialize:
     delay(1000);
     Serial.println("connecting...");
     }

   void loop()
   {
	   
	   int value = analogRead(A0);            // Lectura canal analogo 0
	   int value_2 = analogRead(A1);          // Lectura canal analogo 1
     float volt = float(value)*5/1023;      // conversion a Voltios segun rango del Arduino UNO
     float temp = (float(value_2)*5/1023)*500/5;  
	   save_value(String(volt), String(temp));              // Funcion para enviar a Ubidots. 
     client.flush();                        // Se descartan bytes que no han sido leidos por el cliente. 
	   client.stop();                         // Se desconecta del cliente para permitir envio frecuente de datos. 
	   delay(2000);
    }

   void save_value(String value, String value_2)
   {
	   // if you get a connection, report back via serial:
	   int num_1, num_2 = 0;
	   String var = "{\"value\":" + String(value) + "}";
     String var_2 = "{\"value\":" + String(value_2) + "}";
	   num_1 = var.length();
     num_2 = var_2.length();
	   if (client.connect("things.ubidots.com", 80))
	   {
		   Serial.println("connected");
		   //Linea de código original. 
		   client.println("POST /api/v1.6/variables/" + idvariable_1 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_1) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
		   Serial.println("POST /api/v1.6/variables/" + idvariable_1 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_1) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
		   // En el codigo original fala agregar el valor de la variable. 
		   client.print(var + "\n");
		   Serial.print(var + "\n");
       
		   client.flush();
       // Header se al segunda variable. 
       client.println("POST /api/v1.6/variables/" + idvariable_2 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_2) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
       Serial.println("POST /api/v1.6/variables/" + idvariable_2 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_2) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
       // En el codigo original fala agregar el valor de la variable. 
       client.print(var_2 + "\n");
       Serial.print(var_2 + "\n");
       
	   }
	   else
	   {
		   // if you didn't get a connection to the server:
		   Serial.println("connection failed");
	   }
	   if (!client.connected())
	   {
		   Serial.println();
		   Serial.println("disconnecting.");
		   client.stop();
		   // do nothing forevermore:
		   
                   // for (;;);                         
	   }

	   if (client.available())
	   {
		   char c = client.read();
		   Serial.print(c);
	   }
         }

Gracias Frank1985, vamos a proceder a hacer la anotación en el tutorial para advertir sobre éste problema del Arduino.