Datalogger de bajo coste autónomo y bajo consumo con ATmega1284p-pu

Registrador de datos de bajo coste autónomo para monitorización de sistemas fotovoltaicos híbridos(es más parecido a una estación meteorológica, con lo cual se utiliza para medir el ambiente en cualquier sitio que se desee, pero en este trabajo se ha utilizado para tal fin).

Este registrador de datos se ha programado en C++ mediante el IDE de Arduino y consta de varios shields como GPRS, lector de tarjetas microSD, reloj RTC DS3231, conversor analógico digital, sensores de temperatura y humedad relativa, pluviómetro y anemómetro y por último el ATmega1284p-pu.

Está diseñado para medir el ambiente en campos solares, por lo que su alimentación estará sustentada por una batería que se carga a través de un módulo solar independiente. Esta batería se calcula en función del consumo total en el ciclo de medidas del registrador, y en función de esto según las necesidades que tengamos. Este presente proyecto se calcula para que la batería sea capaz de alimentarlo durante 7 días de ausencia solar. Otro aspecto importante es el regulador de carga solar, pues será el encargado de tener los márgenes para iniciar el proceso de carga y evitar que reduzca su carga por debajo del 80% de su voltaje nominal y con esto lograr un mayor periodo de vida útil de la misma.

Para realizar la medida del consumo del proyecto se ha utilizado el sensor de corriente digital INA219B.

Este trabajo se apoya de unas aplicaciones en php que son las encargadas de recibir los datos mediante peticiones GET, y son almacenados en un fichero CSV para después ser reenviados a la web de gestión de contenido emonCMS, para su posterior visionado en gráficas. Cabe decir que se podría haber evitado el diseño de estas aplicaciones de recogida de datos, pero se hace para tener una programación más sencilla en registrador y además tener un backup de los datos en el servidor web, ya que en primera instancia se almacenan en la tarjeta microSD. El servidor también aloja aplicaciones que comprueban la existencia del fichero para actuar en consecuencia y otra app que devuelve la hora a nuestro datalogger y con ello fijarla en el RTC, consiguiendo con esto no necesitar de usar una pila para guardar la hora del reloj en caso de quedarse sin alimentación nuestro ATmega, ya que sincroniza la hora cada vez que se inicia de una forma tipo al protocolo NTP(Network time protocol) utilizado por cualquier PC, smartphone, tablet, etc para sincronizar la hora automáticamente desde internet.

El microcontrolador tiene grabado el bootloader optiboot, ya que hace uso del watchdog para evitar un posible cuelgue del mismo, debido a que su emplazamiento teóricamente estaría en un lugar lejos de nuestra vivienda.

Este proyecto ha intentado minimizar los gastos de todo el hardware y reducir el consumo al máximo para optimizar la autonomía del mismo, ya que un menor consumo, reduce los gastos en los componentes de mayor valor, que en este caso serán la batería y el módulo solar.

Indico un enlace a GitHub donde se encuentras las fotos de los diagramas de flujo de los programas, los diseños en fritzing y el código de todo. Responderé dudas o preguntas cuando pueda.

Enlace GitHub: Archivos y código GitHub

Enlace a una web sencilla que además muestra el dashboard con las gráficas de emonCMS. No se muestran resultados por que hace meses que termine el proyecto, pero si en las gráficas pulsais el botón Y(year) podréis ver los datos que pude recopilar durante el desarrollo del mismo: Web del proyecto con gráficas emonCMS

Gracias a todos y si alguien reutiliza este trabajo, solo pido que se mencione al autor.

Nota: si alguien se atreve a traducir a inglés la explicación del proyecto de Github se lo agradecería, ya que ahora no dispongo de los conocimientos suficientes para hacerlo por mí mismo.(es una vergüenza lo se…)

2 Me gusta

Exelente proyecto. No se si me pudieras ayudar con el mio. Estoy haciendo un datalogger pero solo temperaratura y humedad con DHT11 y SIM800L. Quiero subir los datos a un servidor. Me marca errores.

Este es mi correo [email protected]

Espero y me puedas ayudar.

Gracias.

Saludos.

Amigo:
Gracias por acercarte al HackLab de Almería.
Por favor, pon tus dudas por aqui, lo mismo hay más gente que te puede ayudar y lo más importante… aprendemos todos. Para eso es la comunidad ¿no?

Muchas gracias y un saludo

Perfecto. Muchas gracias.

este es el programa que quiero poner en marcha pero me manda este error.

#define BLYNK_PRINT Serial// Comment this out to disable prints and save space

// Default heartbeat interval for GSM is 60
// If you want override this value, uncomment and set this option:
#define BLYNK_HEARTBEAT 30
#define TINY_GSM_MODEM_SIM800
#include <TinyGsmClient.h>
#include <BlynkSimpleSIM800.h>
#include "DHT.h"
#define DHTTYPE DHT11 

const int DHTPin = 8;
DHT dht(DHTPin, DHTTYPE);

// Temporary variables
static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "d47cc91e02b1455384b2d06ffacbc5d9";

// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[]  = "internet.itelcel.com"; //APN of your service provider
char user[] = "webgprs";
char pass[] = "webgprs2003";

// Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1

// or Software Serial on Uno, Nano
#include <SoftwareSerial.h>
SoftwareSerial SerialAT(2, 3); // RX, TX

TinyGsm modem(SerialAT);

void setup()
{
  // Set console baud rate
  Serial.begin(19200);
  delay(10);

  // Set GSM module baud rate
  SerialAT.begin(19200);
  delay(3000);

  // Restart takes quite some time
//  To skip it, call init() instead of restart()
  modem.restart();

  // Unlock your SIM card with a PIN
  modem.simUnlock("1234");

  Blynk.begin(auth, modem, apn, user, pass);
}

void loop()
{
  Blynk.run();
  float h = dht.readHumidity();
            // Read temperature as Celsius (the default)
            float t = dht.readTemperature();
            // Read temperature as Fahrenheit (isFahrenheit = true)
            float f = dht.readTemperature(true);
            // Check if any reads failed and exit early (to try again).
            if (isnan(h) || isnan(t) || isnan(f)) {
              Serial.println("Failed to read from DHT sensor!");
              strcpy(celsiusTemp,"Failed");
              strcpy(fahrenheitTemp, "Failed");
              strcpy(humidityTemp, "Failed");         
            }
            else{
              // Computes temperature values in Celsius + Fahrenheit and Humidity
              float hic = dht.computeHeatIndex(t, h, false);       
              dtostrf(hic, 6, 2, celsiusTemp);             
              float hif = dht.computeHeatIndex(f, h);
              dtostrf(hif, 6, 2, fahrenheitTemp);         
              dtostrf(h, 6, 2, humidityTemp);
              // You can delete the following Serial.print's, it's just for debugging purposes
              Serial.print("Humidity: ");
              Serial.print(h);
              Serial.print(" %\t Temperature: ");
              Serial.print(t);
              Serial.print(" *C ");
              Serial.print(f);
              Serial.print(" *F\t Heat index: ");
              Serial.print(hic);
              Serial.print(" *C ");
              Serial.print(hif);
              Serial.print(" *F");
              Serial.print("Humidity: ");
              Serial.print(h);
              Serial.print(" %\t Temperature: ");
              Serial.print(t);
              Serial.print(" *C ");
              Serial.print(f);
              Serial.print(" *F\t Heat index: ");
              Serial.print(hic);
              Serial.print(" *C ");
              Serial.print(hif);
              Serial.println(" *F");
                  Blynk.virtualWrite(V1,t);
                    Blynk.virtualWrite(V2,h);
                       if(t>30) //set temperatur level for notification
                       {
                        Blynk.email("[email protected]", "ESP8266 Alert", "Temperature Increased over limit");
                        Blynk.notify("Temperature Increased over limit");
            }
        
            }

Creo que el código tienes que ponerlo entre las macas de “texto preformateado” que es el boton </>
Y no veo el error. Ademas dices que te tira muchls errores… ¿cuales y en donde? A la hora de compilar, por el puerto serie?
Pone que es para un esp8266, pero parece codigo de arduino. ¿le has subido el boot de arduino? Es que creo que el esp viene con Lua.

Desde hace mucho se puede compilar para los ESP con «código arduino» sin tener que hacer nada, se ocupa de todo el IDE. Lo único necesario es instalar los paquetes en Arduino IDE y seleccionar la placa correspondiente.

1 me gusta

Gracias Miguel Angel. No lo sabía y no lo había intentado. Solo le puse el micropython y el resto los voy a utilizar directamente con Lua.

Hola @Edena87,
No conozco muchas de de las librerías que estás usando en el sketch, ni he usado el SIM800L, pero por lo pronto con respeco al DHT11 y su librería veo que te falta inicializar el sensor en el setup, algo así como:

dht.begin();

De todas formas, creo que deberías de empezar con sketshs más sencillos, haciendo programas individuales para cada una de las cosas que quieres realizar y luego montar un sketch definitivo con todas las funcionalidades, cuando ya lo controles de forma individualizada.

Un saludo
Javier

1 me gusta

Muchas gracias @JavierNo. Intentare hacer de uno en uno y despues juntarlos. Gracias por tu opinion. No se si tu me puedas ayudar? En que parte del programa tengo que hacer esto?

Gracias @josemar1992. Si. Como respondio @MiguelAngelLV. Se hacen con los mismos codigos que Arduino. Este proyecto ya lo tengo sencillo(Temperatura/Humedad) pero ahora lo requiero hacer como un Datalogger con el modulo SIM800L pero no se como conectarme a la red de datos (Telcel).

Saludos.

Vamos a ver, en el hilo de la publicación hay un enlace a GitHub donde se puede descargar el .ino y tiene funciones totalmente separadas para leer temperatura y humedad relativa con dht11, ds18b20, conversor analógico/digital, etc. Te podemos ayudar pero no hacerte el código. Si te da error pública el error que lo vea la comunidad y se te echa una :raised_hand:.

Saludos @JavierNo

Obviamente, como lo tienes que hacer sólo una vez, lo suyo es que sea en el setup().
Yo suelo poner primero los “includes” y luego los “define”. Seguro que no importa el orden, pero yo es que soy así de picajoso. Ya te digo, aunque lo ordenes no se te va a quitar el error.
Por favor, publica los errores que te dan, y en donde te dan y que haces justo antes de que te den.

Tienes mucha razón, hace varios mensajes que pregunté por el error que le daba.

Hola @Edena87,
Como te comentaba lo tienes que inicializar en el setup. Si te fijas en el ejemplo que viene con la libría DHT (ejemplo DHTtester) verás que aparece en el setup como:

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
} 

Como te decía más arriba @robitibillo ayudarte te podemos ayudar, más bien guiarte en las dudas y problemas que te surjan, pero al igual que con @robitibillo, el acuerdo debe de ser que después cuelges en el foro el desarrollo que has realizado para que otras personas se puedan beneficiar del mismo, al igual que tu ahora te beneficias del desarrollo que han realizado otros anteriormente.

Hola @robitibillo, me alegra de saber de tí. No te lo había dicho, pero gracias por cumplir tu parte del acuerdo de colgar en el foro tu proyecto una vez finalizado, a pesar de las reticencias de tu profesor. Te quedó muy bien, y la verdad con un montón de librerías y detalles que desconocía. No sé si escribistes una memoría del proyecto, si es así y si es de acceso libre, estaría bien que tambien la cologaras en Github para complementar la información y que los interesados se hagan una ida más clara.

Por cierto tengo un amigo (@edosantillana) está interesado en el módulo SIM800L (a mí también me gustaría aprender más sobre el mismo), podéis comentar dónde lo habeís conseguido, y si conocéis algún otro con prestaciones similares/mejores y buena relación calidad/precio.

Saludos
Javier

Hola @JavierNo

Mejor en cuanto a funcionalidades/precio(6 € en Ebay) no lo hay. Supongo que mejor lo habrá, pero con el SIM800L he mandado SMS, le coloqué un micrófono de pc y unos auriculares y pude hacer una llamada y además se pueden mandar datos por conexiones http. Creo que por ese precio es imbatible. Ya tengo el proyecto técnico colgado en GitHub pero quiero poner un vínculo directo en el post pero no me deja editarlo.

Saludos

Casi siempre da igual, CASI siempre. Sin embargo, hay algunas veces, que los includes hacen algo según lo que tengas definido o no. Creo recordar que algunas bibliotecas del DHT necesitan que primero definas que modelo estás usando para cargar unos datos u otros.

1 me gusta

El orden de un include es totalmente indiferente, da igual que lo pongas al principio que al final del código puesto que el orden de ejecución SIEMPRE en Arduino es setup y siguiente y de forma infinita el loop, el resto que serían variables globales, define, volátiles, funciones, includes da igual donde se coloquen. Evidentemente si una librería incluye varios modelos es lógico que al instanciarla creando un objeto, le digas el modelo que quieres cargar para saber a qué tipo de hardware deben atacar sus métodos o lo que tenga esa librería.

Saludos y gracias por reavivar este trabajo.

Ua! Pues claro. He dado muchas, pero que muchas vueltas para que el código que me generara Visualino con los bloques que he definido para el robot Evolution de BQ quedara todo en orden. Que funcione no significa que se puede poner desordenado. Y si, en muchos casos, no funciona.

Será por el Visualino, pero el orden del código son buenas prácticas para evitar un código ininteligible (el denominado spaghetti). Evidentemente en un código que se interpreta de forma secuencial se debe hacer de forma ordenada, pero los includes, definición de variables de ámbito global, donde ubicar las funciones, las constantes, etc se pueden colocar donde a uno le plazca.

Saludos

No. Eso podría pasar en Java, en C no da igual para nada.

Prueba este código:

Servo servo;

#include <Servo.h>

Verás como falla, pues no puedes instanciar servo antes de incluir su librería.

2 Me gusta