×

ARDUINO

Control d’accés amb contrasenya. Orgue de llums. Comparativa de editors Arduino. Projecte bon Nadal. Sensor de gas i de fums. Control de la qualitat del aire interior (CO2) amb semàfor LED.

NodeMCU

NodeMCU-ThingSpeak. ThingSpeak. NodeMCU com AccessPoint. Control de la llum de casa per web. Control de un led per el mòbil. Sistema de fitxers en ESP8266. Altura del nivell d'aigua. Avis d’alarma a Telegram. Control de la llum de casa des de Telegram. Control de la intensitat de llum de un LED per Internet. Magatzematge de temperatura i humitat en Thinger. Publicar temperatura i humitat en Google Sheets. ESP8266 i Firebase. ESP8266-BME280 Firebase. La bàscula. ESP8266 NodeMCU amb cèl·lula de càrrega..

ESP32

ESP32-CAM, exemple de prova. Esp32-Cam captura fotos per ser vistes en la WEB. Pujar fotos a un servidor FTP amb ESP32-CAM. Foto amb ESP32-CAM i Telegram. Alarma amb avis a Telegram, utilitzant la placa ESP32-CAM.

PROGRAMACIÓ

Matemàtiques. App Inventor tutorial. MicroPython en ESP8266. Visual Estudio Code per Arduino

Intel·ligència artificial

Classificador d’imatges.

SERVIDORS

Instal·lar i configurar Apache en Ubuntu. Accés a un servidor Linux remotament. Client i Servidor FTP.

MÀQUINES VIRTUALS

Màquina virtual UBUNTU. WindowsXP en Virtualbox.

ELECTRÒNICA

Simulador Multisim. Simulador Proteus.

BASE DE DADES

MySQL. Instal·lació. MySQL. Aplicacions.

JAVA

Netbeans Maven MySQL. Java+Netbeans+Maven+EclipseLink+MySQL Aplicació d’escriptori JavaFX App JavaFX amb SceneBuilder App Java-Swing
favicon
logo

Tresavis

Benvinguts al blog de tresavis de noves tecnologies i més.

Correu : tresavis3@gmail.com

facebook   Instagram   youtube   x   tiktok

☰ Pràctiques   ☰ Articles

Descripció:

Es vol mesurar a quina altura es troba el aigua de un recipient, per extrapolar després a una piscina i poder observar la pèrdua d’aigua per evaporació o altres causes. Per aquest projecte fem servir la memòria FLASH del chip ESP8266, per emmagatzemar les dades rebudes del sensor de distancia HC-SR04. Des de un navegador WEB en mode client i connectat al servidor NodeMCU, volem iniciar una sèrie de mesures d’altures indicant la data d’inici i el interval entre mesures. Les dades es guarden en format CSV i posteriorment ser exportades a una fulla de càlcul.

Componets:

Placa NodeMCU que te WiFi integrat.

Sensor de ultrasons HC-SR04.

Dues resistències de 330 Ω.

IDE de Arduino.

Llibreria FS.h File System per la gestió del sistema d’arxius.

Bibliografia:

https://www.youtube.com/watch?v=eCe9A9wq4Go

https://www.esploradores.com/uso-memoria-flash-para-almacenamiento-de-datos/

Circuit: Gràcies a la aplicació de https://www.circuito.io

circuit

El microcontrolador ESP8266 conté SPIFFS, Serial Peripheral Interface Flsh File System . SPIFFS es un sistema de fitxers lleuger en el chip de la memòria flash que incorpora el ESP8266. Per carregar els fitxers a la memòria flash es fa servir un plugin per el IDE de Arduino. SPIFFS dona accés als fitxers de la memòria flash de la mateixa manera que ho fem en el nostre ordinador, però mes simple i mes limitat. Es pot llegir, escriure, eliminar fitxers. No suporta directoris, tots els fitxers tenen que estar en el mateix nivell, en la carpeta data.

Llegir mes de SPIFFS >>

Funcionament de la pràctica.

Volem mesurar les altures del aigua en un recipient, volem guardar suficients dades, per poder crear un fitxer CSV i exportar-lo a una fulla de càlcul. Les dades les guardem en la memòria FLASH del microcontrolador ESP8266.

Configurem el ESP8266 com a servidor AccesPoint. El client des d’un navegador al connectar amb el AccesPoint, rep un formulari al escriure la URL: 192.168.4.1

En el formulari tenim la data i hora actual i dos camps a emplenar, el interval entre diferents mesures i si es vol buidar la memòria FLASH o no. El formulari al enviar-lo, envia al servidor la data hora, el interval i si o no es buida la memòria i també comença a mesurar les altures, cada interval de temps. Les mesures es guarden en un fitxer de la memòria.

El client amb la URL: 192.168.4.1/altura, don la ordre al servidor de servir en el navegador la lectura del fitxer on es guarden les mesures preses.

Copiem les dades del navegador en un fitxer de text .csv. Importem el fitxer des el EXCEL o LibreOffice i ja podem fer gràfics.

Explicació sobre el codi.

El formulari ha de mostrar la data hora actual. La data hora actual es la data inicial per prendre les mesures, que es un String, la passem al tipus time_t, que son els segons que han pasat des de 1970. Amb aquest numero podem sumar-li el interval entre trets del sensor. Per guardar la data en el fitxer tenim que tornar passar de time_t a String.

Sensor de ultrasons:

Emissor Trigger, envia la ona de ultrasons.

Receptor Echo, rep la ona de tornada.

circuit

Podem saber la distancia, saben la duració de la ona de anada i tornada, aplicant la formula:

Distancia= velocitat del so * duració

Velocitat del so=340 m/s= 0.034 cm/µs

La duració es d’anada i tornada, tenim que dividir-la per 2

Distancia=(0.034 cm/µs*duració µs)/2

En el nostre codi, posem:

long duracio = pulseIn(EchoPin, HIGH);
// convertim la altura, en cm   
long alturaCm = duracio * 10 / 292/ 2;
// 10/292=0.0342465
 
          

El codi esta força comentat, esperem que s’entengui.

Hardware.

Hardware

Codi.

AlturaPiscina.ino
            
/*
 * Es vol mesurar els milimetres de aigua que perd la piscina per evaporació 
 * Fem servir http per visualitzar les dades
 * Placa NodeMCU, sensor ultasonic  HC-SR04
 * magazamatge de dades en format CSV per exportar a un full de calcul
 * SPIFFS Serial Peripheral Interface Flash File System
 */
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
//llibreria file system per gestionar els fitxers en memoria FLASH
#include <FS.h>
#include <TimeLib.h>

#define EchoPin D0
#define TriggerPin D1
#define LedPin D4

///// variables globals ///////
//temps (ms) del procesador encès
static unsigned long tempsMicroActiu;                       
File fitxer;
int interval;
long  alturaCm;
String dataHora;
String iniciar = "no";
//el objecte time_t guarda els segons de la data actual a 1970
time_t tempsSegons;
const char *ssid_AP = "AlturaAP";
const char *password_AP = "12345678";

ESP8266WebServer server(80);
//guardem la pagina web en memoria flach
//formulari amb la data actual
//checkBox per formatajar la flash
//interval de lectures
//data inicial es: Sat Jan 30 2021 11:14:38 GMT+0100 (hora estándar de Europa central)
//la formatejem a 30/01/2021 11:14
static const char INDEX_HTML[] PROGMEM = R"(
  <html>
  <body>
  <form action='/formulari'>
      Data:                    <input type='datetime-local' name='dateTime' id='idData'><br>
      Formatear memoria Flash:  <input type='checkbox' name='format' value='si'><br>
      Interval de Mesures (s): <input type="number" name="interval" min="10" step="10" value="30"><br><br>
                                <input type="submit" value="Enviar">
  </form>
  
  <script>
      var dataActual = new Date();
      var yyyy = dataActual.getFullYear();
      var mm = dataActual.getMonth()+1;         if(mm<10) {mm='0'+mm};
      var dd = dataActual.getDate();            if(dd<10) {dd='0'+dd};
      var hh = dataActual.getHours();           if(hh<10) {hh='0'+hh}; 
      var mn = dataActual.getMinutes();         if(mn<10) {mn='0'+mn}; 
  
      var dataActualFormat =  dd+'-'+mm+'-'+yyyy+'H'+hh+'-'+mn;
      document.getElementById('idData').value = dataActualFormat;
  </script>
  </body>
  </html>
)";

//El servidor agafa la data actual que envia el formulari en mode GET
//converteix el String dataActual a time_t  i el retorna
time_t convertirStringATime(String dataActual){
    //String dataActual = server.arg("dateTime");
    // el format de dataActual es: dd+'-'+mm+'-'+yyyy+'H'+hh+'-'+mn;
    tmElements_t tm;
       tm.Year = dataActual.substring(6,10).toInt()-1970;                         
       tm.Month = dataActual.substring(3,5).toInt();      //6 ????
       tm.Day = dataActual.substring(0,2).toInt();                                
       tm.Hour = dataActual.substring(11,13).toInt();                             
       tm.Minute = dataActual.substring(14,16).toInt();                            
       time_t tempsSegons=makeTime(tm);
       Serial.print("Temps segons->: ");
       Serial.println(String(tempsSegons));//1612092824
    return tempsSegons;                                                              
}
//converteix el tipus time_t a String i el retorna
String convertirTimeAString(time_t temps){
    String dd = day(temps)<10? String("0")+String(day(temps)):String(day(temps));                    //26
    String mm = month(temps)<11? String("0")+String(month(temps)):String (month(temps));         //06
    String yyyy=String(year(temps));
    String hh = hour(temps)<10? String("0")+String(hour(temps)):String(hour(temps));                 //23
    String mn = minute(temps)<10? String("0")+String(minute(temps)):String(minute(temps));           //54
    String dataHora = (dd+"/"+mm+"/"+yyyy+";"+hh+":"+mn+";");                      //26/06/2018;23:54;
    Serial.print("Data Hora->: ");
    Serial.println(dataHora);
    return dataHora;
}

//Funció per formatejar la memoria flash SPIFFS
void format_SPIFFS(){                               
   if (server.arg("format") == "si"){
      Serial.println("Formateix iniciat...");
      digitalWrite(LedPin, LOW); 
      SPIFFS.format();
      Serial.println("Formateix finalizat!");
      digitalWrite(LedPin, HIGH);
   }
}
//llegeix el fitxer global
void llegir_SPIFFS(){
    fitxer = SPIFFS.open("/altura.txt", "r");
    server.streamFile(fitxer, "text/plain");
    fitxer.close();
}

long obtenirAltura() {
   digitalWrite(LedPin, LOW);

   //per generar un tret net posem a LOW 4us
   digitalWrite(TriggerPin, LOW);         
   delayMicroseconds(4);
   //generamos Trigger (tret) de 10us
   digitalWrite(TriggerPin, HIGH);        
   delayMicroseconds(10);
   digitalWrite(TriggerPin, LOW);
   //mesurem el temps entre trets, en microsegons
   long duracio = pulseIn(EchoPin, HIGH);
   //convertim la altura, en cm      
   //alturaCm=(velocitat so * duracio)/2
   // velocitat del so = 0.034cm/microseg 
   // 10/292=0.03424
   long alturaCm = duracio * 10 / 292/ 2;    
   Serial.print("Altura: ");
   Serial.println(alturaCm);
   
   digitalWrite(LedPin, HIGH);
   return alturaCm; 
}


void setup() {
  Serial.begin(115200);
     
  pinMode(LedPin, OUTPUT);
  digitalWrite(LedPin, HIGH); 
  pinMode(TriggerPin, OUTPUT);
  pinMode(EchoPin, INPUT);
  
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid_AP, password_AP); 
  Serial.println("WiFi inicializada."); 
  Serial.print("La adreça del AccesPoint es IP: ");
  Serial.println(WiFi.softAPIP()); 
  Serial.println();
  
  SPIFFS.begin();

  //el servidor envia el formulari si el GET es "/"
  server.on("/", []() {                               
      server.send_P(200, "text/html", INDEX_HTML);
  });
  //Si s'envia el formulari, el servidor inicia el proces
  server.on("/formulari", [](){
    //envia el texte inicialitzat
    server.send(200, "text/plain", "Inicializat!");
    //posa la variable global iniciar a si  
    iniciar = "si";
    //obté el inteval de lectures enviat del formulari
    interval = server.arg("interval").toInt();
    Serial.print("interval: ");
    Serial.println(interval);
    //comença a contar el temps en que el micro esta actiu
    tempsMicroActiu = millis();
    //obtenim la variable global dataHora del formulari
    String dataForm=server.arg("dateTime");
    Serial.print("Data hora formulari: ");
    Serial.println(dataForm);
    //la converim al tipus time_t i el guardem com a variable global 
    tempsSegons= convertirStringATime(dataForm);
    //la converim String a time_t i el guardem com a variable global 
    //dataHora=convertirTimeAString(tempsSegons); NO ES NECESARI, PODEM FER SERVIR EL ARGUMENT DEL FORMULARI
    dataHora=dataForm;
    //formateja si en el formulari se clicat formateix, altrament res 
    format_SPIFFS();
    //Si el fitxer altura.txt no existeix el crea de nou i afegeix al final
    fitxer = SPIFFS.open("/altura.txt", "a+");
    //escriu la capçalera del fitxer
    fitxer.println("data;Hora;Altura (cm)");
    fitxer.close();
  });
  //si el GET es /altura llegeix el fitxer altura.txt  
  server.on("/altura", [](){
  llegir_SPIFFS();
  });
  
  server.begin();
  Serial.println("Servidor inicializat.");
}

void loop() {
  server.handleClient();
  //Cada interval s'executa
  if (iniciar == "si" && abs(millis()-tempsMicroActiu) > interval*1000) {     
    tempsSegons = tempsSegons + interval;
    dataHora=convertirTimeAString(tempsSegons);
    alturaCm=obtenirAltura();
    fitxer = SPIFFS.open("/altura.txt", "a+");
    fitxer.print(dataHora);
    fitxer.println(alturaCm);
    fitxer.close();
    tempsMicroActiu = millis(); 
  }
  //Si porta 15 minuts sense incializarse ho fa automáticament
  if (iniciar == "no" && millis()> 900*1000){   
    iniciar="si";
    tempsSegons = 0;
    interval = 60;
    fitxer = SPIFFS.open("/altura.txt", "a+");
    fitxer.println("Data;Hora;Altura (cm)");
    fitxer.close();
  }
}

Posada en marxa.

Pas 1.

Obrir el monitor serial a 115200 baudis on es mostra la adreça del servidor que sempre es:

192.168.4.1/

nivell

Pas 2.

Connectar-se a la WiFi de nom AlturaAP amb al contrasenya 12345678. Una vegada estem en la mateixa xarxa, des del navegador, escrivim la url 192.168.4.1, el servidor respon amb el següent formulari:

nivell

Pas 3.

Emplenem els camps, interval i format. Enviem el formulari. Si mirem que es el que enviem. Enviem la url, on en el comando GET hi ha la data, el format i el interval. El servidor al rebre les dades del formulari, inicia les mesures i le guarda en el fitxer altura.txt de la memòria FLASH.

nivell
nivell

Pas 4.

Per llegir el fitxer guardat en memòria FLASH i obtenir les mesures d’altura, escrivim en el navegador la url:

192.168.4.1/altura

El servidor respon amb la llista de data - altura, separat en “;”, per poder exportar en format CVS.

nivell

Pas 5.

Copiem del navegador la llista en un fitxer de text en extensió .cvs i el guardem en el nostre ordinador, anomenat nivells.csv.

nivell

Pas 6.

Obrim el EXCEL o el CALC de OpenOffice, en el nostre cas fem servir el EXCEL. En el menú “datos” anem a “Desde el texto/CSV” i busquem el nostre fitxer guardat en el pas anterior, nivells.csv. Emergeix una nova finestra amb les dades i nomes tenim que carregar a la nostra fulla de càlcul. Cliquem el botó “CARGAR”.

nivell

Pas 6.

Gràfics.

En la fulla de càlcul seleccionem la llista amb les dades i en el menú “Insertar”, en el apartat de gràfics, escollim el tipus de gràfic que mes ens agrada.

nivell
nivell

Contingut.


Nosaltres

actuals
actuals
actuals
actuals
actuals
actuals
actuals
actuals
actuals

Tags

Noves tecnologies WEB Arduino Domótica MycroPython NodeMCU IoT Java ESP8266 Lora C++ Programació Server-Client