[SOLUCIONADO] Lectura de dht11 en thingspeak usando Arduino y SIM900

Saludes a todos, os tengo una duda acerca de como podría leer la info de un dht11 en la plataforma de thingspeak. He logrado enviar un valor constante haciendo uso de esta sentencia

char direccion[] = "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field1=9 HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n";

el valor constante llega sin problemas, pero ahora he tratado de enviar la lectura del dht11 y no me llega nada a la plataforma.

Este es el código el cual estoy usando.

#include <SoftwareSerial.h>
#include "DHT.h"

SoftwareSerial SIM900(10, 11); // Configura el puerto serial para el SIM900. Para el Arduino MEGA utilizar pines 10 y 11
#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

int respuesta;
char aux_str[80];

char direccion[] = "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field1=float(humedad) HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n";

void setup()
{
  SIM900.begin(19200); //Configura velocidad del puerto serie para el SIM900
  Serial.begin(19200); //Configura velocidad del puerto serie del Arduino
  dht.begin();
  delay(1000);
  Serial.println("Iniciando..."); 
  iniciar();
    
}


void loop() 
{ 
}


int enviarAT(String ATcommand, char* resp_correcta, unsigned int tiempo)
{

  int x = 0;
  bool correcto = 0;
  char respuesta[100];
  unsigned long anterior;

  memset(respuesta, '\0', 100); // Inicializa el string
  delay(100);
  while ( SIM900.available() > 0) SIM900.read(); // Limpia el buffer de entrada
  SIM900.println(ATcommand); // Envia el comando AT
  x = 0;
  anterior = millis();
  // Espera una respuesta
  do {
    // si hay datos el buffer de entrada del UART lee y comprueba la respuesta
    if (SIM900.available() != 0)
    {
      respuesta[x] = SIM900.read();
      x++;
      // Comprueba si la respuesta es correcta
      if (strstr(respuesta, resp_correcta) != NULL)
      {
        correcto = 1;
      }
    }
  }
  // Espera hasta tener una respuesta
  while ((correcto == 0) && ((millis() - anterior) < tiempo));
  Serial.println(respuesta);

  return correcto;
}



//////////////////////////////////////////////////////////////////////////////
void iniciar()
{
  enviarAT("AT+CPIN?", "OK", 6000);
  Serial.println("Conectando a la red...");
  delay (5000);

  //Espera hasta estar conectado a la red movil
  enviarAT("AT+CSQ", "OK", 3000);   // Medir la calidad de la senal, 15 a mas, es muy buena.
  while ( enviarAT("AT+CREG?", "+CREG: 0,1", 1000) == 0 )
  {
  }
  Serial.println("Conectado a la red.");
  enviarAT("AT+CGATT?", "OK", 2000); //Iniciamos la conexión GPRS
  enviarAT("AT+CGATT=1\r", "OK", 2000); //Iniciamos la conexión GPRS
  enviarAT("AT+CGCLASS?", "OK", 10000); //Iniciamos la conexión GPRS
  enviarAT("AT+CSTT=\"web.emovil\",\"webemovil\",\"webemovil\"", "OK", 3000);
  enviarAT("AT+CSTT=\"CMNET\"", "OK", 3000);
  enviarAT("AT+CIICR", "OK", 3000); //Activamos la conexion inalambrica
  enviarAT("AT+CIFSR", "", 4000);   //Se obitene la direccion IP local
  PeticionHttp();
}



//////////////////////////////////////////////////////////////////////////////
void PeticionHttp()
{

float humedad = dht.readHumidity();

  {
  if (enviarAT("AT+CREG?", "+CREG: 0,1", 6000) == 1) //Comprueba la conexion a la red
  {
    enviarAT("AT+CIPSTART=\"TCP\",\"184.106.153.149\",\"80\"", "CONNECT OK", 5000); //Inicia una conexión TCP
    // Envíamos datos a través del TCP
    sprintf(aux_str, "AT+CIPSEND=%d", strlen(direccion));
    if (enviarAT(aux_str, ">", 20000) == 1)
    {
      enviarAT(direccion, "OK", 10000);
      enviarAT("AT+CIPCLOSE", "OK", 10000);
      enviarAT("AT+CIPSHUT\r", "OK", 10000);
      delay(5000);
      Serial.println("Concluido");
      delay(5000);
    }
  }
  else
  {
    Serial.println("Error en el envio");
  }
}
}

Toda sugerencia es bienvenida y de antemano agradezco vuestra atención.

Saludes y quedo atento a vuestras observaciones....

Dudas a la sección Software o Hardware.
Esto es Proyectos, es algo que lleva tiempo desarrollar. No una simple consulta.
Lee las normas del foro por favor, 1er hilo de cada Sección.
Hilo movido a Software

Mis sinceras disculpas Surbyte, como es un proyecto que estoy desarrollando lo catalogue como tal.! Pero tenéis razón y gracias por haberlo colocado en la sección adecuada. Saludes.

Hola,
Mira este hilo

Hola Rodri, gracias por vuestro comentario. Lo he colocado de esta manera

char direccion[] = "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field1= + String(humedad) HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n";

al compilar y actualizar la plataforma de Thingspeak, la plataforma detecta algo pero no lo muestra.
Solo dice que se actualizo pero no con que.

No se si el problema radica en el tipo de la variable que estoy usando y la que estoy enviando.

Ya que obtengo la temperatura asi

float humedad = dht.readHumidity();

con float, pero ahi en la direccion del GET la coloco como string, asi que no se si deba hacer algo en intermedio para prepararla para el envío.

Te falta cerrar comillas antes del + otro + después del String (variable) y abrir de nuevo comillas.
Ejemplo="cadena" + String (variable) + " sigue la cadena";

Lo he colocado a como me has aconsejado rodripelto.

char direccion[] = "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field1= " + String(humedad) + "HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n";

pero no me compila en el IDE, me advierte que "humedad" no esta declarada! Cuando en realidad ya la tengo en el ciclo de la funcion "void PeticionHttp()"

Prueba esto... todo esta en la rutina PeticionHttp()

#include <SoftwareSerial.h>
#include "DHT.h"

SoftwareSerial SIM900(10, 11); // Configura el puerto serial para el SIM900. Para el Arduino MEGA utilizar pines 10 y 11
#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

int respuesta;
char aux_str[80];


void setup() {
  SIM900.begin(19200); //Configura velocidad del puerto serie para el SIM900
  Serial.begin(19200); //Configura velocidad del puerto serie del Arduino
  dht.begin();
  delay(1000);
  Serial.println("Iniciando..."); 
  iniciar();   
}

void loop() { 
}


int enviarAT(String ATcommand, char* resp_correcta, unsigned int tiempo) {

  int x = 0;
  bool correcto = 0;
  char respuesta[100];
  unsigned long anterior;

  memset(respuesta, '\0', 100); // Inicializa el string
  delay(100);
  while ( SIM900.available() > 0) SIM900.read(); // Limpia el buffer de entrada
  SIM900.println(ATcommand); // Envia el comando AT
  x = 0;
  anterior = millis();
  // Espera una respuesta
  do {
    // si hay datos el buffer de entrada del UART lee y comprueba la respuesta
    if (SIM900.available() != 0)  {
      respuesta[x] = SIM900.read();
      x++;
      // Comprueba si la respuesta es correcta
      if (strstr(respuesta, resp_correcta) != NULL)  {
        correcto = 1;
      }
    }
  }
  // Espera hasta tener una respuesta
  while ((correcto == 0) && ((millis() - anterior) < tiempo));
  Serial.println(respuesta);

  return correcto;
}

//////////////////////////////////////////////////////////////////////////////
void iniciar() {

  enviarAT("AT+CPIN?", "OK", 6000);
  Serial.println("Conectando a la red...");
  delay (5000);

  //Espera hasta estar conectado a la red movil
  enviarAT("AT+CSQ", "OK", 3000);   // Medir la calidad de la senal, 15 a mas, es muy buena.
  while ( enviarAT("AT+CREG?", "+CREG: 0,1", 1000) == 0 ) {
  }

  Serial.println("Conectado a la red.");
  enviarAT("AT+CGATT?", "OK", 2000); //Iniciamos la conexión GPRS
  enviarAT("AT+CGATT=1\r", "OK", 2000); //Iniciamos la conexión GPRS
  enviarAT("AT+CGCLASS?", "OK", 10000); //Iniciamos la conexión GPRS
  enviarAT("AT+CSTT=\"web.emovil\",\"webemovil\",\"webemovil\"", "OK", 3000);
  enviarAT("AT+CSTT=\"CMNET\"", "OK", 3000);
  enviarAT("AT+CIICR", "OK", 3000); //Activamos la conexion inalambrica
  enviarAT("AT+CIFSR", "", 4000);   //Se obitene la direccion IP local
  PeticionHttp();
}

//////////////////////////////////////////////////////////////////////////////
void PeticionHttp() {
  float humedad = dht.readHumidity();

  char str[6];
  char direccion[46];
  dtostrf(humedad, 5, 2, str);
  sprintf(direccion, "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field1=%s HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n", str);
 
  if (enviarAT("AT+CREG?", "+CREG: 0,1", 6000) == 1)  { //Comprueba la conexion a la red 
      enviarAT("AT+CIPSTART=\"TCP\",\"184.106.153.149\",\"80\"", "CONNECT OK", 5000); //Inicia una conexión TCP
      // Envíamos datos a través del TCP

      sprintf(aux_str, "AT+CIPSEND=%d", strlen(direccion));
      if (enviarAT(aux_str, ">", 20000) == 1) {
          enviarAT(direccion, "OK", 10000);
          enviarAT("AT+CIPCLOSE", "OK", 10000);
          enviarAT("AT+CIPSHUT\r", "OK", 10000);
          delay(5000);
          Serial.println("Concluido");
          delay(5000);
      }
  }
  else  {
      Serial.println("Error en el envio");
  }
}

Muchisimas gracias Surbyte el arreglo ha quedado de maravilla.

Pero ahora, me podria explicar como funciona esa parte

char str[6];
  char direccion[46];
  dtostrf(humedad, 5, 2, str);
  sprintf(direccion, "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field1=%s HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n", str);

no entendi esa parte de dtostrf. Lei acerca de esa funcion pero no entiendo porque el 5 (Disculpad mi duda al respecto, quizas es algo tonto) y el porque str tiene 6.

si quiero agregar temperatura, solo agregaria otra direccion con field2, algo asi?

sprintf(direccion, "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field2=%s HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n", str);

oh en el mismo lo podria hacer?

Porque hice otra funcion donde se recolectara la info de la otra variable y se envia de forma independiente, asi:

void Sensor2()
{
  float temp = dht.readTemperature();
  char str[6];
  char direccion[46];
  dtostrf(temp, 5, 2, str);
  sprintf(direccion, "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field2=%s HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n", str);
  
  if (enviarAT("AT+CREG?", "+CREG: 0,1", 6000) == 1)  { //Comprueba la conexion a la red 
      enviarAT("AT+CIPSTART=\"TCP\",\"184.106.153.149\",\"80\"", "CONNECT OK", 5000); //Inicia una conexión TCP
      // Envíamos datos a través del TCP

      sprintf(aux_str, "AT+CIPSEND=%d", strlen(direccion));
      if (enviarAT(aux_str, ">", 20000) == 1) {
          enviarAT(direccion, "OK", 10000);
          enviarAT("AT+CIPCLOSE", "OK", 10000);
          enviarAT("AT+CIPSHUT\r", "OK", 10000);
          delay(5000);
      }
      
  }
  else  {
      Serial.println("Error en el envio");
  }
}

Pero no se si lo podria hacer en la misma funcion, para reducir codigo.

De antemano mis agradecimientos. Saludes.

Tengo un código por ahi y no se porque tienes que usar esa forma de enviarlo pero debe ser por el SIM900.

El dtostrf(humedad, 5, 2, str); es una función que convierte un float a string
5 es la cantidad de digitos involucrados y 2 la cantidad de decimales.
Si cambias 5 debes incrementar el tamaño de str que sera 5+1
debes dejar un espacion para indicar fin de string o \0

si quiero agregar temperatura, solo agregaria otra direccion con field2, algo asi?

Code: [Select]

sprintf(direccion, "GET /update?api_key=P4W9GZ5VKKQ3KQQW&field2=%s HTTP/1.1\r\nHost: api.thingspeak.com\r\nConnection: close\r\n\r\n", str);

oh en el mismo lo podria hacer?

Si con el mismo puede ser... es la ventaja de sprintf.
Ya definido el tamaño de la cadena que en nuestro caso será direccion mientras no aumentemos el tamaño porque recuerda que dice 46 lugares... si lo cambias entonces riesgos de que haga cualquier cosa.
Ahi hay que ser estricto.

Usala N veces siempre y cuando no aumentes el tamaño maximo de direccion, claro que no lo harás pero quiero decir... dentro de extremo a extremo debemos mantenernos en el rango de 46 y si no sirve tendras que hacer otra cadena.

Oh venga vale.! Lo he probado ya, y ha quedado de maravilla.!!!

Se os agradece la ayuda brindada y la explicación detallada.

Saludes y termino el post con SOLUCIONADO.

Gracias.