Omet navegació

Guardat de dades en la targeta SD

Anem a provar la targeta SD amb un sensor de temperatura DHT22 que ja hem provat abans en una altra secció.

Fes el muntatge:

SD_Card + DHT22 + Wemos

Primer de tot, comprova que la targeta està formatejada en format FAT32 si vols poder escriure amb WemosD1R32 i la targeta lectora/escriptora SD.

Posa el programa següent:

/*
  Autor: Rui Santos
  Font: https://RandomNerdTutorials.com/esp32-microsd-card-arduino/
   
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
   
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
 
  Modificat el 9 / 11 / 2023 a l'IES Gabriel Ciscar d'Oliva

*/
 
// Libraries for SD card
#include "FS.h"
#include "SD.h"
#include <SPI.h>
 
// Es pot modificar per posar un sensor diferent 
//Libraries DHT sensor 
#include "DHT.h"
#define DHTPIN 25     // Digital pin connected to the DHT sensor
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
 
// Libraries to get time from NTP Server
#include <WiFi.h>
#include "time.h"
 
// Replace with your network credentials
const char* ssid     = "Usuari_WIFI"; // Es pot modificar per posar la SSID
const char* password = "Contrasenya_WIFI"; // Es pot modificar per posar la Contrasenya de la wifi
 
// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
 
// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);
 
// Variables to hold sensor readings // Variables on guardarem les dades
float temp;
float hum;
String dataMessage;
 
// NTP server to request epoch time
const char* ntpServer = "pool.ntp.org";
 
// Variable to save current epoch time
unsigned long epochTime; 
 
// Function that gets current epoch time
unsigned long getTime() {
  time_t now;
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    //Serial.println("Failed to obtain time");
    return(0);
  }
  time(&now);
  return now;
}
 
// Initialize WiFi
void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
}
 

 
// Initialize SD card
void initSDCard(){
   if (!SD.begin()) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
 
  if(cardType == CARD_NONE){
    Serial.println("No SD card attached");
    return;
  }
  Serial.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }
  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);
}
 
// Write to the SD card
void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);
 
  File file = fs.open(path, FILE_WRITE);
  if(!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if(file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}
 
// Append data to the SD card
void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);
 
  File file = fs.open(path, FILE_APPEND);
  if(!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if(file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}
 
void setup() {
  Serial.begin(115200);

  Serial.println(F("DHTxx test!")); 
  dht.begin(); // Iniciem el DHT22

  initWiFi();
  initSDCard();
  configTime(0, 0, ntpServer);
   
  // If the data.txt file doesn't exist
  // Create a file on the SD card and write the data labels
  File file = SD.open("/data.txt");
  if(!file) {
    Serial.println("File doesn't exist");
    Serial.println("Creating file...");
    writeFile(SD, "/data.txt", "Epoch Time, Temperature, Humidity \r\n");
// La linia anterior Es pot modificar per canviar tipus de dades a guardar  }  else {    Serial.println("File already exists");    }  file.close(); } void loop() {  if ((millis() - lastTime) > timerDelay) {    //Get epoch time    epochTime = getTime();         //Get sensor readings         Llegim el sensor d DHT22    temp = dht.readTemperature();    hum = dht.readHumidity();        //Concatenate all info separated by commas    dataMessage = String(epochTime) + "," + String(temp) + "," + String(hum) + "\r\n";    Serial.print("Saving data: ");    Serial.println(dataMessage);    //Append the data to file    appendFile(SD, "/data.txt", dataMessage.c_str());    lastTime = millis();  } }// final de programa

El programa té molts comentaris mostrant on cal modificar les seccions per canviar el sensor o el tipus de dades a guardar

a la targeta SD com he comprovat.

La eixida del terminal serie és:

Dades terminal serie

Si parem el programa, traiem la targeta del SD_card i la posem a l'ordinador i obrim el fitxer data.txt, veurem quelcom com:

Dades guardades SD_card

El valor Epoch Time és una forma compacta de posar la data, la podem definir com  l'hora actual mesurada en nombre de segons des del Epoch Unix.

Epoch 0 és el 1 de gener  1970 00.00:00 GMT (ISO 8601: 1970-01-01T00:00:00Z). No s'usen segons de traspàs (d'anys «bisiestos») en el temps Unix.

Per pasar un valor  de Temps Epoch a l'actual anem a la pàgina aquesta i usem un convertidor.

Epoch conversor

El fitxer data.txt el podem passar a csv, obrir amb Libreoffice Calc i convertir les dades Epoch a Data/hora modernes de forma molt fàcil.

Data.csv to calc

Eixes dades ja es poden representar de forma molt fàcil, i també podem fer càlculs amb elles.

Creat amb eXeLearning (Finestra nova)