Bonjour!
J'ai à ma disposition une carte arduino UNO, une carte GPS LoRa GPS/Shield, un détecteur de particules PM laser dust sensor et un module SD MicroSD Card Adapter muni d'une carte SD de 1Giga.
J'ai écrit un code qui récupère les données de la carte GPS (latitude, longitude, date et heure) et celles du détecteur de particules (concentrations PM1.0, PM2.5 et PM10) dans un fichier de la carte SD.
Voilà le code:
/**
* Exemple de code Arduino pour un datalogger basique avec stockage sur carte SD.
*/
/* Dépendances */
#include <SPI.h> // Pour la communication SPI
#include <SD.h> // Pour la communication avec la carte SD
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <Arduino.h>
#define LENG 31 //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];
float flat, flon;
char sz[32];
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
//Le PIN SS de la carte GPS est relié à D5 et le pin SS de la carte GPS au pin D2
int GPS_SS=5;
int SD_SS=6;
/** Broche CS de la carte SD */
const byte SDCARD_CS_PIN = 6; // A remplacer suivant votre shield SD
/** Nom du fichier de sortie */
const char* OUTPUT_FILENAME = "gpspm4.csv";
/** Delai entre deux prise de mesures */
const unsigned long DELAY_BETWEEN_MEASURES = 1000;
int PM01Value=0; //define PM1.0 value of the air detector module
int PM2_5Value=0; //define PM2.5 value of the air detector module
int PM10Value=0; //define PM10 value of the air detector module
/** Fichier de sortie avec les mesures */
File file;
TinyGPS gps;
SoftwareSerial ss(3, 4); // Arduino TX, RX ,
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
/** Fonction setup() */
void setup() {
Serial.setTimeout(1500);
pinMode(SD_SS, OUTPUT);
pinMode(GPS_SS,OUTPUT);
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
Serial.begin(9600); // start serial for output
ss.begin(9600); // SoftSerial port to get GPS data.
while (!Serial) {
;
};
/* Initialisation du port SPI */
//Le module SD écoute et le module GPS est comme sourd et muet
digitalWrite(SD_SS,LOW);
digitalWrite(GPS_SS,HIGH);
/* Initialisation de la carte SD */
Serial.println(F("Initialisation de la carte SD ... "));
if (!SD.begin(SDCARD_CS_PIN)) {
Serial.println(F("Erreur : Impossible d'initialiser la carte SD"));
Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
for (;;); // Attend appui sur bouton RESET
}
/* Ouvre le fichier de sortie en ecriture */
Serial.println(F("Ouverture du fichier de sortie ... "));
file = SD.open(OUTPUT_FILENAME, FILE_WRITE);
if (!file) {
Serial.println(F("Erreur : Impossible d'ouvrir le fichier de sortie"));
Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
for (;;); // Attend appui sur bouton RESET
}
/* Ajoute l'entete CSV si le fichier est vide */
if (file.size() == 0) {
Serial.println(F("Ecriture de l'entete CSV ..."));
file.println(F("PM1.0- PM2.5- PM10 " "-Long - Lat - Date et Heure "));
file.flush();
}
}
/** Fonction loop() */
void loop() {
/*Le module GPS écoute et le module SD est comme sourd et muet*/
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
gps.f_get_position(&flat, &flon, &age);
print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
print_date(gps);
gps.stats(&chars, &sentences, &failed);
Serial.println();
smartdelay(1000);
//delay(1000);
digitalWrite(SD_SS,LOW);
digitalWrite(GPS_SS,HIGH);
// Temps de la precedente mesure et de la mesure actuelle
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
/* Realise une prise de mesure toutes les DELAY_BETWEEN_MEASURES millisecondes */
if (currentMillis - previousMillis >= DELAY_BETWEEN_MEASURES) {
previousMillis = currentMillis;
measure();
}
if(Serial.find(0x42)){ //start to read when detect 0x42
Serial.readBytes(buf,LENG);
if(buf[0] == 0x4d){
if(checkValue(buf,LENG)){
PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
}
}
}
}
static void smartdelay(unsigned long ms)
{
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
unsigned long start = millis();
do
{
while (ss.available())
{
//ss.print(Serial.read());
gps.encode(ss.read());
}
} while (millis() - start < ms);
}
static void print_float(float val, float invalid, int len, int prec)
{
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len)
{
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
if (val == invalid)
strcpy(sz, "*******");
else
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartdelay(0);
}
static void print_date(TinyGPS &gps)
{
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
int year;
byte month, day, hour, minute, second, hundredths;
unsigned long age;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
if (age == TinyGPS::GPS_INVALID_AGE)
Serial.print("********** ******** ");
else
{
sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
day, month, year, hour, minute, second);
//Serial.print(sz);
}
smartdelay(0);
}
static void print_str(const char *str, int len)
{
digitalWrite(SD_SS,HIGH);
digitalWrite(GPS_SS,LOW);
int slen = strlen(str);
for (int i=0; i<len; ++i)
Serial.print(i<slen ? str[i] : ' ');
smartdelay(0);
}
char checkValue(unsigned char *thebuf, char leng)
{
char receiveflag=0;
int receiveSum=0;
for(int i=0; i<(leng-2); i++){
receiveSum=receiveSum+thebuf[i];
}
receiveSum=receiveSum + 0x42;
if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1])) //check the serial data
{
receiveSum = 0;
receiveflag = 1;
}
return receiveflag;
}
int transmitPM01(unsigned char *thebuf)
{
int PM01Val;
PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
return PM01Val;
}
//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
int PM2_5Val;
PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
return PM2_5Val;
}
//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
int PM10Val;
PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module
return PM10Val;
}
/** Fonction de recuperation des donnees du GPS */
void measure() {
digitalWrite(SD_SS,LOW);
digitalWrite(GPS_SS,HIGH);
/* Recupere les valeurs */
float lon=flon;
float lat=flat;
float PM01 = PM01Value;
float PM25 = PM2_5Value;
float PM10 = PM10Value;
/* Affiche les donnees sur le port serie pour tester si les valeurs sont bien recuperees */
Serial.print(PM01);
Serial.print(F("- "));
Serial.print(PM25);
Serial.print(F("- "));
Serial.print(PM10);
Serial.print(lon);
Serial.print(F("- "));
Serial.print(lat);
Serial.print(F("- "));
Serial.println(sz);
/* Enregistre les donnees sur la carte SD */
file.print(PM01);
file.print(F("- "));
file.print(PM25);
file.print(F("- "));
file.print(PM10);
file.flush();
file.print(lon);
file.print(F("- "));
file.print(lat);
file.print(F("- "));
file.println(sz);
file.flush();
}
La capture du résultat du moniteur est joint à ce message.
Maintenant je veux que chaque jour il soit créé un fichier ayant comme nom la date actuelle (par exemple 11/07/2018.csv). Je ne suis pas très forte en programmation, j'attends vos suggestions excusez moi pour la longueur.