Yahoo refuse tous les emails du site. Si vous avez une adresse chez un autre prestataire, c'est le moment de l'utiliser
En cas de soucis, n'hésitez pas à aller faire un tour sur la page de contact en bas de page.
Topic "Fabriquer un système d'acquisition de mesures (datalogger) avec une carte Arduino / Genuino"
Flux RSS des posts récents dans ce topic ( Flux Atom)
Dans ce tutoriel, nous allons fabriquer un système d'acquisition de mesures autonome (aka "datalogger"). Celui-ci stockera les mesures sur une carte SD dans un format textuel facilement utilisable avec un logiciel de type tableur (Excel, Libre Calc, etc.). Nous étudierons deux versions du code : une version basique sans horodatage pour comprendre les bases du fonctionnement et une version plus complexe avec horodatage pour obtenir des mesures utilisables par la suite.
Lire la suite de l'article sur le site
Derniére modification le
#467 |
Petit oubli dans l'article :
Dans la partie "Le code avec horodatage", tu écris :
Le reste du code de la fonction setup() reste inchangé.
Mais ce n'est pas exactement vrai : il faut également rajouter la colonne "Horodatage" dans l'entête du fichier.
#472 |
Mais ce n'est pas exactement vrai : il faut également rajouter la colonne "Horodatage" dans l'entête du fichier.
par BugsByte
Modification faite, merci pour la remarque
#814 |
Bonjour, Merci pour l'article.Après avoir testé le code, j'ai essayé de le modifier pour intégrer des mesures avec un DHT22. Je n'ai pas de problème de compilation, mais lors de l’exécution, les données s'affichent sur le moniteur série mais rien ne s'enregistre sur la carte SD (ni les data ni l'entête). Avec le code d'origine de l'article je n'ai pas ce problème avec la carte SD. Pouvez m'aider car je ne sais pas où je dois regarder dans mon code (problème de boucle ou autre)? Merci
Derniére modification le
#819 |
Sans le code ça va être difficile de dire où est le probléme
#826 |
Sans le code ça va être difficile de dire où est le probléme
par skywodd![]()
Voici mon code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | /**
* datalogger avec horodatage : stockage temperature et humidité (DHT22) sur carte SD.
*/
/* Dépendances */
#include <Wire.h> // Pour la communication I2C
#include <SPI.h> // Pour la communication SPI
#include <SD.h> // Pour la communication avec la carte SD
#include "DS1307.h" // Pour le module DS1307
/* Rétro-compatibilité avec Arduino 1.x et antérieur */
#if ARDUINO >= 100
#define Wire_write(x) Wire.write(x)
#define Wire_read() Wire.read()
#else
#define Wire_write(x) Wire.send(x)
#define Wire_read() Wire.receive()
#endif
/** Broche CS de la carte SD */
const byte SDCARD_CS_PIN = 10; // A remplacer suivant votre shield SD
/** Broche "DATA" du capteur */
const byte BROCHE_CAPTEUR = 5;
/** Nom du fichier de sortie */
const char* OUTPUT_FILENAME = "data.csv";
/** Delai entre deux prises de mesures */
const unsigned long DELAY_BETWEEN_MEASURES = 5000;
/* Code d'erreur de la fonction readDHT11() et readDHT22() */
const byte DHT_SUCCESS = 0; // Pas d'erreur
const byte DHT_TIMEOUT_ERROR = 1; // Temps d'attente dépassé
const byte DHT_CHECKSUM_ERROR = 2; // Données reçues erronées
/** Fonction de conversion BCD -> decimal */
byte bcd_to_decimal(byte bcd) {
return (bcd / 16 * 10) + (bcd % 16);
}
/**
* Fonction récupérant l'heure et la date courante à partir du module RTC.
* Place les valeurs lues dans la structure passée en argument (par pointeur).
* N.B. Retourne 1 si le module RTC est arrêté (plus de batterie, horloge arrêtée manuellement, etc.), 0 le reste du temps.
*/
byte read_current_datetime(DateTime_t *datetime) {
/* Début de la transaction I2C */
Wire.beginTransmission(DS1307_ADDRESS);
Wire_write((byte) 0); // Lecture mémoire à l'adresse 0x00
Wire.endTransmission(); // Fin de la transaction I2C
/* Lit 7 octets depuis la mémoire du module RTC */
Wire.requestFrom(DS1307_ADDRESS, (byte) 7);
byte raw_seconds = Wire_read();
datetime->seconds = bcd_to_decimal(raw_seconds);
datetime->minutes = bcd_to_decimal(Wire_read());
byte raw_hours = Wire_read();
if (raw_hours & 64) { // Format 12h
datetime->hours = bcd_to_decimal(raw_hours & 31);
datetime->is_pm = raw_hours & 32;
} else { // Format 24h
datetime->hours = bcd_to_decimal(raw_hours & 63);
datetime->is_pm = 0;
}
datetime->day_of_week = bcd_to_decimal(Wire_read());
datetime->days = bcd_to_decimal(Wire_read());
datetime->months = bcd_to_decimal(Wire_read());
datetime->year = bcd_to_decimal(Wire_read());
/* Si le bit 7 des secondes == 1 : le module RTC est arrêté */
return raw_seconds & 128;
}
/** Fichier de sortie avec les mesures */
File file;
/** Fonction setup() */
void setup() {
/* Initialise le port I2C */
Wire.begin();
/* Initialisation du port série (debug) */
Serial.begin(115200);
Serial.println(F("Demo DHT22"));
/* Vérifie si le module RTC est initialisé */
DateTime_t now;
if (read_current_datetime(&now)) {
Serial.println(F("Erreur : L'horloge du module RTC n'est pas active"));
Serial.println(F("Configurer le module RTC avant d'utiliser ce programme"));
for (;;); // Attend appui sur bouton RESET
}
/* Initialisation du port SPI */
pinMode(10, OUTPUT); // Arduino UNO
//pinMode(53, OUTPUT); // Arduino Mega
/* 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 écriture */
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'entête CSV si le fichier est vide */
if (file.size() == 0) {
Serial.println(F("Ecriture de l'entete CSV ..."));
file.println(F("Horodatage; humidite; température"));
file.flush();
}
/* Place la broche du capteur en entrée avec pull-up */
pinMode(BROCHE_CAPTEUR, INPUT_PULLUP);
}
/** Fonction loop() */
void loop() {
// Temps de la précédente mesure et actuel
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
/* Réalise une prise de mesure toutes les DELAY_BETWEEN_MEASURES millisecondes */
if (currentMillis - previousMillis >= DELAY_BETWEEN_MEASURES) {
previousMillis = currentMillis;
measure();
}
}
/** Fonction de mesure - à personnaliser selon ses besoins */
void measure() {
float temperature, humidity;
/* Lit la date et heure courante */
DateTime_t now;
read_current_datetime(&now);
/* Réalise la mesure */
/* Lecture de la température et de l'humidité, avec gestion des erreurs */
// N.B. Remplacer readDHT11 par readDHT22 en fonction du capteur utilisé !
switch (readDHT22(BROCHE_CAPTEUR, &temperature, &humidity)) {
case DHT_SUCCESS:
/* Affichage de la température et du taux d'humidité */
Serial.print(F("Humidite (%): "));
Serial.print(humidity, 2);
Serial.print(F(" Temperature (°C): "));
Serial.println(temperature, 2);
break;
case DHT_TIMEOUT_ERROR:
Serial.println(F("Pas de reponse !"));
break;
case DHT_CHECKSUM_ERROR:
Serial.println(F("Pb de communication !"));
break;
}
/* Enregistre les données sur la carte SD */
// Horodatage
file.print(now.days);
file.print(F("/"));
file.print(now.months);
file.print(F("/"));
file.print(now.year + 2000);
file.print(F(" "));
file.print(now.hours);
file.print(F(":"));
file.print(now.minutes);
file.print(F(":"));
file.print(now.seconds);
file.print(F("; "));
// Données brutes
file.print(humidity,2);
file.println(temperature,2);
file.flush();
}
byte readDHT22(byte pin, float* temperature, float* humidity) {
/* Lit le capteur */
byte data[5];
byte ret = readDHT22(pin, data, 1, 1000);
/* Détecte et retourne les erreurs de communication */
if (ret != DHT_SUCCESS)
return ret;
/* Calcul la vraie valeur de la température et de l'humidité */
float fh = data[0];
fh *= 256;
fh += data[1];
fh *= 0.1;
*humidity = fh;
float ft = data[2] & 0x7f;
ft *= 256;
ft += data[3];
ft *= 0.1;
if (data[2] & 0x80) {
ft *= -1;
}
*temperature = ft;
/* Ok */
return DHT_SUCCESS;
}
/**
* Fonction bas niveau permettant de lire la température et le taux d'humidité (en valeurs brutes) mesuré par un capteur DHTxx.
*/
byte readDHT22(byte pin, byte* data, unsigned long start_time, unsigned long timeout) {
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// start_time est en millisecondes
// timeout est en microsecondes
/* Conversion du numéro de broche Arduino en ports / masque binaire "bas niveau" */
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *ddr = portModeRegister(port); // Registre MODE (INPUT / OUTPUT)
volatile uint8_t *out = portOutputRegister(port); // Registre OUT (écriture)
volatile uint8_t *in = portInputRegister(port); // Registre IN (lecture)
/* Conversion du temps de timeout en nombre de cycles processeur */
unsigned long max_cycles = microsecondsToClockCycles(timeout);
/* Evite les problèmes de pull-up */
*out |= bit; // PULLUP
*ddr &= ~bit; // INPUT
delay(100); // Laisse le temps à la résistance de pullup de mettre la ligne de données à HIGH
/* Réveil du capteur */
*ddr |= bit; // OUTPUT
*out &= ~bit; // LOW
delay(start_time); // Temps d'attente à LOW causant le réveil du capteur
// N.B. Il est impossible d'utilise delayMicroseconds() ici car un délai
// de plus de 16 millisecondes ne donne pas un timing assez précis.
/* Portion de code critique - pas d'interruptions possibles */
noInterrupts();
/* Passage en écoute */
*out |= bit; // PULLUP
delayMicroseconds(40);
*ddr &= ~bit; // INPUT
/* Attente de la réponse du capteur */
timeout = 0;
while(!(*in & bit)) { /* Attente d'un état LOW */
if (++timeout == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
timeout = 0;
while(*in & bit) { /* Attente d'un état HIGH */
if (++timeout == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
/* Lecture des données du capteur (40 bits) */
for (byte i = 0; i < 40; ++i) {
/* Attente d'un état LOW */
unsigned long cycles_low = 0;
while(!(*in & bit)) {
if (++cycles_low == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
/* Attente d'un état HIGH */
unsigned long cycles_high = 0;
while(*in & bit) {
if (++cycles_high == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
/* Si le temps haut est supérieur au temps bas c'est un "1", sinon c'est un "0" */
data[i / 8] <<= 1;
if (cycles_high > cycles_low) {
data[i / 8] |= 1;
}
}
/* Fin de la portion de code critique */
interrupts();
/*
* Format des données :
* [1, 0] = humidité en %
* [3, 2] = température en degrés Celsius
* [4] = checksum (humidité + température)
*/
/* Vérifie la checksum */
byte checksum = (data[0] + data[1] + data[2] + data[3]) & 0xff;
if (data[4] != checksum)
return DHT_CHECKSUM_ERROR; /* Erreur de checksum */
else
return DHT_SUCCESS; /* Pas d'erreur */
}
|
Merci pour l'aide et le temps passé dans les tuto et à répondre aux "commentaires"-questions.
Derniére modification le
#856 |
Je ne vois pas d'erreur dans le code …
Il faudra essayer avec une autre carte SD et/ou un autre lecteur de carte si possible.
Est-ce qu'un code simple de démo qui écrit sur la carte SD fonctionne (Exemples > SD > ReadWrite par exemple) ?
#1050 |
Bonjour,
J'ai un problème au niveau de la compilation avec un message d'erreur qui m'indique : "error: 'DateTime_t' was not declared in this scope byte read_current_datetime(DateTime_t *datetime) { ^ /tmp/072077767/sketch_dec1b/sketch_dec1b.ino:54:40: error: 'datetime' was not declared in this scope byte read_current_datetime(DateTime_t *datetime) { ^ /tmp/072077767/sketch_dec1b/sketch_dec1b.ino:54:28: error: redefinition of 'byte read_current_datetime' byte read_current_datetime(DateTime_t *datetime) { ^ /tmp/072077767/sketch_dec1b/sketch_dec1b.ino:54:6: error: 'byte read_current_datetime' previously defined here byte read_current_datetime(DateTime_t *datetime) { ^ /tmp/072077767/sketch_dec1b/sketch_dec1b.ino:54:28: error: 'DateTime_t' was not declared in this scope byte read_current_datetime(DateTime_t *datetime) { ^ /tmp/072077767/sketch_dec1b/sketch_dec1b.ino:54:40: error: 'datetime' was not declared in this scope byte read_current_datetime(DateTime_t *datetime) { ^ exit status 1"
Auriez vous une idée de quoi faire ? Merci d'avance