Les logiciels Windows de Tiercelin
Montage pour enregistrer les données d'un port série sur une carte SD
Ce montage est optimisé pour enregistrer les données du Livre de Bord (version 8 )
Si on arrête le journal de bord, et que l'on précise que l'on veut utiliser un data logger, un dossier utilisant la date est créé, ainsi qu'un sous dossier utilisant l'heure.
Par exemple ..........\10122015\15H
L'équipage, le départ, l'arrivée seront envoyés dans le fichier INIT.txt et les trames NMEA seront envoyées dans le fichier NMEA.txt
Pour utiliser ce programme, il faut au moins une carte Méga ( ne fonctionne pas avec la carte UNO )
On peut utiliser
un module SD et un module RTC ou un shield SD
Le montage avec le shield : j'ai du faire des modifications car les shield sont pratiques, mais souvent prévus pour la carte UNO.
La communication entre la carte Arduino et la carte mémoire SD utilise la communication SPI, laquelle utilise les broches 11, 12 et 13 de la plupart des cartes Arduino,
ou les broches 51, 50 et 52 sur la carte Arduino Mega
En plus, une autre broche est utilisée pour sélectionner la carte SD. Cette broche peut être la broche matérielle SS (broche 10 sur la plupart des cartes Arduino et broche 53 sur la Mega)
Il faut donc déporter les broches 10,11,12,13 du shield vers les broches 53,51,50,52 de la carte Méga.
Le module RTC a aussi une connection différente :
-
SDA --> pin A4 Data (pin 20 sur Mega)
-
SCL -->pin A5 Clock (pin 21 sur Mega)
Il faut donc déporter les broches 4 et 5 du shield vers les broches 20 et 21 de la carte Méga.
Le programme :
#include <Wire.h>
#include "RTClib.h"
#include <SD.h>
RTC_DS1307 rtc;
const int chipSelect = 53;//10 pour uno
char pathfile[22]; //longueur réelle plus 1
char _phrase[90];
int n;
int _w; // numero du traitement sur le caractere
int _checksum; // somme de controle calculée
int _check;// checksum inclus avec la phrase
int l;
String mastring ;
int charlu;
boolean findeligne;
boolean demlecture;
boolean fini;
char dossier[13];
File myFile;
unsigned long debutchrono ;
byte demarrer;
byte foiss=0;
DateTime maintenant;
//fonctions
int lecture(char c)
{// si LF et CR : _w=0 ----->case 0
if ((c == 10) || (c == 13)) {
_w = 0;
}
if (c == '$')
{
_checksum = 0;
_phrase[0] = c;
n = 1;
_w = 1;
return 0;//valeur de retour FALSE
}
// ajout des caractères pour fabriquer la phrase
switch(_w)
{
case 0:
// attente du caractère '$'
break;
case 1:
_phrase[n++] = c;
switch (c)
{
case '*': // si fin de phrase ( avant checksum)
_w = 2; // il faut lire le 1er caractère du checksum en case 2
break;
default: // ce n' est pas la fin de la phrase
_checksum = _checksum ^ c;
_w = 1;
break;
}
break;
case 2:
_phrase[n++] = c; // on lit le 1er caractère du checksum
_check = (16 * _convert_hex(c));
_w = 3; // il faut lire le 2eme caractère du checksum en case 3
break;
case 3:
_phrase[n++] = c; // lecture 2eme caractere checksum
_phrase[n++] = 13; // retour chariot
_phrase[n++] = 10; // retour ligne
_phrase[n++] = 0 ;
_check = _check + _convert_hex(c);
if (_checksum == _check) {
_w = 0;
return 1;
}// phrase acceptée , valeur de retour TRUE pour 1
else
{
return 0; // valeur de retour FALSE pour 0
_w=0;
}
default:
break;
}
return 0;
}
char* phrase() {
// retoune la phrase valide
return _phrase;
}
int _convert_hex(char a) {
// retourne la valeur en base 16 des caractères
if (int(a) >= 65) {
return int(a)-55;
}
else {
return int(a)-48;
}
}
void ecoutelitenvoie()
{
int i;
charlu=0;
char c;
mastring="";
findeligne=false;
//debutdeligne=false;
while ((Serial.available()>0)&&(findeligne==false) &&(millis() - debutchrono < 30000 ) )
{
charlu=Serial.read();
delay(1);
c=char(charlu);
switch (c)
{
case '!':
fini=true;
break;
case '>':
findeligne=true;
break;
default:
mastring+=c;
}
}
if (findeligne==true)
{
int i=0;
int par1;
String morceau;
String reste;
myFile = SD.open(pathfile, FILE_WRITE);
reste=mastring;
while (reste!=""){
par1=reste.indexOf(')');
morceau=reste.substring(0,par1);
reste=reste.substring(par1+1);
myFile.print(morceau);
myFile.println();
}
myFile .close();
}
}
void setup()
{
unsigned int heure ;
unsigned int minutes;
unsigned int secondes;
int annee;
unsigned int mois;
unsigned int jour;
char datafile[13];
int test;
Wire .begin();
rtc.begin();
// rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.begin(9600);
Serial1.begin(9600);
Serial2.begin(4800);
Serial.println("serial1 a 9600, serial2 a 4800");
Serial.print("Initialisation de la carte SD...");
pinMode(53, OUTPUT);
if (!SD.begin(53)) {
Serial.println("L'initialisation a echoue!");
return;
}
else
{
Serial.println("Initialisation reussie.");
delay(100);
}
maintenant = rtc.now();
annee = maintenant.year();
jour = maintenant.day();
mois = maintenant.month();
heure = maintenant.hour();
minutes = maintenant.minute();
//secondes = maintenant.second();
sprintf(datafile,"%02d%02dA%02dH.TXT",jour,mois,heure); // %d pour un int
sprintf(dossier,"%02d%02d%04d/%02dH",jour,mois,annee,heure);
sprintf(pathfile,"%12s/NMEA.TXT",dossier);
Serial.print("Le dossier du jour :");
Serial.println(dossier);
Serial.print("L'heure : ");
Serial.print(heure);
Serial.print("h");
Serial.println(minutes);
delay(500);
test = SD.exists(dossier);
if (test != true)
{
Serial.print("Le dossier ");
Serial.print(dossier);
Serial.println(" n'existe pas ");
SD.mkdir(dossier);
delay(500);
}
SD.remove(pathfile);
myFile = SD.open(pathfile, FILE_WRITE);
myFile.close();
n = 0;
_w = 0;
_checksum = 0;
demlecture=false;
fini=false;
mastring="";
Serial.println("Vous pouvez taper h pour mettre à l'heure");
Serial.println("Attendre 30 secondes ou rentrer l'initialisation $ pour commencer ! pour finir ");
delay(500);
debutchrono=millis();
demarrer=0;
//while (Serial.available()) Serial.read();
}
void loop()
{
if ((millis() - debutchrono < 30000) && (fini==false))
{
//recevoir les fichiers de livre de bord
while ((demlecture==false)&& (millis() - debutchrono < 30000) )
{
if (Serial.available()) charlu=Serial.read();
if ((demlecture==false)&&(charlu=='h'))
rtc.adjust(DateTime(__DATE__, __TIME__));
if (charlu=='$')
{
sprintf(pathfile,"%12s/INIT.TXT",dossier);
SD.remove(pathfile);
myFile = SD.open(pathfile, FILE_WRITE);
myFile.close();
demlecture=true;
}
}
while ((demlecture==true) && (fini==false) && (millis() - debutchrono < 30000))
ecoutelitenvoie();
}
if ((fini==true) || (millis() - debutchrono >= 30000))
{
if (demarrer==0)
{
Serial.println("(pret)");
delay(500);
if (fini==true)
sprintf(pathfile,"%12s/NMEA.TXT",dossier);
demarrer=1;
}
if (demarrer==1)
{
char car = 0; //variable contenant le caractère à lire GPS
// il y a un caractere à lire ?
if (Serial1.available())
{
maintenant = rtc.now();
car = Serial1.read(); // lect caractere
delay(1);
l=lecture(car);
if (l)
{
Serial.print(phrase());
File myFile;
myFile = SD.open(pathfile, FILE_WRITE);
myFile.print(maintenant.hour());
myFile.print(':');
myFile.print(maintenant.minute());
myFile.print(':');
myFile.print(maintenant.second());
myFile.print(' ');
myFile.print(phrase());
myFile .close();
Serial1.flush();
if (foiss==0){
Serial2.end();
foiss++;
}
}
}
if (Serial2.available())
{
maintenant = rtc.now();
car = Serial2.read(); // lect caractere
l=lecture(car);
if (l)
{
Serial.print(phrase());
File myFile;
myFile = SD.open(pathfile, FILE_WRITE);
myFile.print(maintenant.hour());
myFile.print(':');
myFile.print(maintenant.minute());
myFile.print(':');
myFile.print(maintenant.second());
myFile.print(' ');
myFile.print(phrase());
myFile .close();
if (foiss==0){
Serial1.end();
foiss++;
}
}
}
}
}
}