Table des matières:

Comment faire un enregistreur de données pour la température, le pH et l'oxygène dissous : 11 étapes (avec photos)
Comment faire un enregistreur de données pour la température, le pH et l'oxygène dissous : 11 étapes (avec photos)

Vidéo: Comment faire un enregistreur de données pour la température, le pH et l'oxygène dissous : 11 étapes (avec photos)

Vidéo: Comment faire un enregistreur de données pour la température, le pH et l'oxygène dissous : 11 étapes (avec photos)
Vidéo: l'atterrissage en direct de la sonde Perseverance sur Mars 2024, Novembre
Anonim
Image
Image
Image
Image

Objectifs:

  • Fabriquez un enregistreur de données pour 500 $. Il stocke les données de température, de pH et d'oxygène dissous avec un horodatage et en utilisant la communication I2C.
  • Pourquoi I2C (Circuit Inter-Intégré) ? On peut empiler autant de capteurs sur une même ligne étant donné que chacun d'eux a une adresse unique.

Étape 1:

Étape 2: Achetez les pièces ci-dessous:

Achetez les pièces ci-dessous
Achetez les pièces ci-dessous
  1. Arduino MEGA 2560, 35 $,
  2. Adaptateur secteur pour carte Arduino, 5,98 $,
  3. Module LCD I2C (affichage), 8,99 $,
  4. Répartition de l'horloge en temps réel (RTC), 7,5 $,
  5. Carte de dérivation de carte MicroSD, 7,5 $,
  6. Carte SD de 4 Go, 6,98 $,
  7. Capteur numérique étanche DS18B20, 9,95 $,
  8. Sonde pH + Kits + Tampons standards, 149,15 $,
  9. Sonde DO + Kits + Tampons standard, 247,45 $,
  10. Planche à pain, câble de démarrage, 7,98 $,
  11. (Facultatif) Isolateur de tension, 24 $,

Total: 510,48 $

* Certaines pièces (comme la carte générique) pourraient être achetées auprès d'autres vendeurs (eBay, vendeur chinois) pour un prix inférieur. Les sondes pH et DO sont recommandées pour les obtenir auprès d'Atlas Scientific.

* Un multimètre est recommandé pour vérifier la conductivité et la tension. Cela coûte environ 10 à 15 $ (https://goo.gl/iAMDJo)

Étape 3: Câblage

Câblage
Câblage
  • Utilisez des câbles de démarrage/DuPont pour connecter les pièces comme indiqué dans le schéma ci-dessous.
  • Utilisez le multimètre pour vérifier la conduction.
  • Vérifiez l'alimentation en tension positive (VCC) et la terre (GND) (il est facile de confondre si vous n'êtes pas familier avec le circuit)
  • Branchez l'adaptateur secteur et vérifiez l'indicateur d'alimentation dans chaque partie. En cas de doute, utilisez le multimètre pour vérifier que la tension entre VCC et GND est (5V)

Étape 4: préparer les circuits PH, DO, carte SD

Préparer les circuits PH, DO, carte SD
Préparer les circuits PH, DO, carte SD
  1. Passer à I2C pour les circuits pH et DO
  2. Les dérivations pH et DO sont livrées avec une communication série comme mode par défaut de transmission/réception (TX/RX). Pour utiliser la ligne d'horloge en mode I2C (SCL) et la ligne de données (SDA), changez de mode en (1): débranchez les câbles VCC, TX, RX, (2): passez TX à la masse pour la sonde, PGND (pas GND), (3) branchez VCC au circuit, (4): attendez que la LED passe du vert au bleu. Plus de détails, consultez la page 39 (Fiche technique du circuit de pH,
  3. Faire la même étape avec le circuit DO
  4. (si vous savez comment télécharger l'exemple de code sur la carte, vous pouvez le faire via Serial Monitor)
  5. Formater la carte SD au format FAT

Étape 5: préparer le logiciel

Préparer le logiciel
Préparer le logiciel
Préparer le logiciel
Préparer le logiciel
Préparer le logiciel
Préparer le logiciel
Préparer le logiciel
Préparer le logiciel
  1. Téléchargez l'environnement de développement intégré (IDE) Arduino,
  2. Installer la bibliothèque sur Arduino IDE:
  3. La plupart d'entre eux sont livrés avec le logiciel Arduino. LiquidCrystal_I2C.h est disponible via GitHub
  4. Installez le pilote pour USB. Pour un Arduino authentique, vous n'aurez peut-être pas besoin d'en installer un. Pour un générique, vous devez installer le pilote CH340 (GitHub:
  5. Vérifiez si vous connectez correctement la carte en exécutant un test de LED clignotant
  6. Comment trouver l'adresse MAC de la température numérique 18B20. Utilisation du modèle de scanner I2C dans Arduino IDE avec la sonde branchée. Chaque appareil a une adresse MAC unique, vous pouvez donc utiliser autant de sondes de température avec une ligne partagée (#9). 18B20 utilise un I2C à un fil, il s'agit donc d'un cas particulier de méthode de communication I2C. Vous trouverez ci-dessous une méthode pour trouver MAC - Medical Access Control ("ROM" lorsque vous exécutez la procédure ci-dessous).

Étape 6: Commencez à coder

Commencer à coder
Commencer à coder
  • Copiez-collez le code ci-dessous dans Arduino IDE:
  • Ou téléchargez le code (.ino) et une nouvelle fenêtre devrait apparaître dans Arduino IDE.

/*

Tutoriels de référence:

1. Enregistreur de température, redox, pH:

2. Bouclier numérique sécurisé (SD):

Ce code produira des données sur le moniteur série Arduino. Tapez des commandes dans le moniteur série Arduino pour contrôler le circuit pH EZO en mode I2C.

Modifié à partir des tutoriels référencés ci-dessus, principalement à partir du code I2C par Atlas-Scientific

Dernière mise à jour: 26 juillet 2017 par Binh Nguyen

*/

#include //activer I2C.

#define pH_address 99 //Numéro d'identification I2C par défaut pour le circuit pH EZO.

#define DO_address 97 //Numéro d'identification I2C par défaut pour le circuit EZO DO.

#include "RTClib.h" // Fonctions date et heure utilisant un DS1307 RTC connecté via I2C et Wire lib

RTC_DS1307 rtc;

#include // Pour la bibliothèque SD

#include // Carte SD pour stocker les données

const int chipSelect = 53; // besoin de comprendre pour Adafruit SD breakout//https://learn.adafruit.com/adafruit-micro-sd-breakout-board-card-tutorial/wiring

//DO=MISO, DI=MOSI, sur la broche ATmega#: 50(MISO), 51(MOSI), 52(SCK), 53(SS)

char logFileName = "dataLT.txt"; // modifiez logFileName pour identifier votre expérience, par exemple PBR_01_02, datalog1

identifiant long = 1; //le numéro d'identification pour entrer l'ordre du journal

#comprendre

LiquidCrystal_I2C lcd (0x27, 20, 4);

#comprendre

#comprendre

#define ONE_WIRE_BUS 9 //définir la broche # pour la sonde de température

OneWire oneWire(ONE_WIRE_BUS);

DallasCapteurs de température (&oneWire);

DeviceAddress ProbeP = { 0x28, 0xC2, 0xE8, 0x37, 0x07, 0x00, 0x00, 0xBF }; //Adresse MAC, unique à chaque sonde

Chaîne dataString; // la variante principale pour stocker toutes les données

Chaîne dataString2; // une variante temporaire pour stocker la température/pH/DO pour l'impression

données informatiques de caractères[20]; //instruction d'Atlas Scientific: nous créons un tableau de caractères de 20 octets pour contenir les données entrantes d'un pc/mac/autre.

octet receive_from_computer=0; //nous avons besoin de savoir combien de caractères ont été reçus.

octet serial_event=0;//un indicateur pour signaler quand des données ont été reçues du pc/mac/autre.

code d'octet=0; //utilisé pour contenir le code de réponse I2C.

car pH_data[20]; //nous créons un tableau de caractères de 20 octets pour contenir les données entrantes du circuit de pH.

octet in_char=0; //utilisé comme tampon de 1 octet à stocker dans les octets liés du circuit pH.

octet i=0; //compteur utilisé pour le tableau ph_data.

int time_=1800; //utilisé pour modifier le délai nécessaire en fonction de la commande envoyée au circuit de pH de classe EZO.

float pH_float; //float var utilisé pour contenir la valeur flottante du pH.

car DO_data[20];

//float temp_C;

void setup() //initialisation matérielle.

{

Serial.begin(9600); //activer le port série.

Wire.begin(pH_address); //activer le port I2C pour la sonde de pH

Wire.begin(DO_address);

lcd.init();

lcd.begin (20, 4);

LCD rétro-éclairage();

lcd.home();

lcd.print("Bonjour PBR!");

lcd.setCursor(0, 1);

lcd.print("Initialisation…");

Serial.print("RTC is…");

si (! rtc.begin())

{

Serial.println("RTC: Horloge temps réel…NON TROUVÉE");

while (1);// (Serial.println("RTC: horloge temps réel…TROUVE"));

}

Serial.println("RUNNING");

Serial.print("Horloge en temps réel…");

si (! rtc.isrunning())

{rtc.adjust(DateTime(F(_DATE_), F(_TIME_)));

}

Serial.println("WORKING");

lcd.setCursor(0, 0);

lcd.println("RTC: OK");

Serial.print("Carte SD…"); // voir si la carte est présente et peut être initialisée:

si (!SD.begin(chipSelect))

{ Serial.println("Échec"); // ne fais plus rien:

revenir;

}

Serial.println("OK");

lcd.setCursor(0, 1);

lcd.println("Carte SD: OK");

Serial.print("Fichier journal: ");

Serial.print(logFileName);

Serial.print("…");

Fichier logFile = SD.open(logFileName, FILE_WRITE); // ouvre le fichier. "datalog" et imprimer l'en-tête

si (fichier journal)

{

logFile.println(",,, "); //indique qu'il y avait des données dans l'exécution précédente

En-tête de chaîne = "Date -Heure, Temp(C), pH, DO";

logFile.println(en-tête);

logFile.close();

Serial.println("READY");

//Serial.println(dataString); // imprime aussi sur le port série:

}

else { Serial.println("erreur d'ouverture du journal de données"); } // si le fichier n'est pas ouvert, affiche une erreur:

lcd.setCursor(0, 2);

lcd.print("Fichier journal:");

lcd.println(logFileName);

retard(1000);

capteurs.begin();

capteurs.setResolution(ProbeP, 10); //10 est la résolution (10 bits)

lcd.clear();

identifiant = 0;

}

boucle vide()

{ // la boucle principale.

dataString = String(id);

dataString = String(', ');

DateHeure maintenant = rtc.now();

dataString = String(now.year(), DEC);

dataString += String('/');

dataString += String(now.month(), DEC);

dataString += String('/');

dataString += String(now.day(), DEC);

dataString += String(' ');

dataString += String(now.hour(), DEC);

dataString += String(':');

dataString += String(now.minute(), DEC);

dataString += String(':');

dataString += String(now.second(), DEC);

lcd.home();

lcd.print(dataString);

capteurs.requestTemperatures();

afficherTempérature(SondeP);

Wire.beginTransmission(pH_address); // appelle le circuit par son numéro d'identification

Wire.write('r'); //code dur r pour lire en continu

Wire.endTransmission(); //fin de la transmission de données I2C.

temporisation_); // attend le temps nécessaire pour que le circuit termine son instruction.

Wire.requestFrom(pH_address, 20, 1); //Appelle le circuit et demande 20 octets (cela peut être plus que ce dont nous avons besoin)

while(Wire.available()) // y a-t-il des octets à recevoir

{

in_char = Wire.read(); //recevoir un octet.

if ((in_char > 31) && (in_char <127)) //vérifie si le caractère est utilisable (imprimable)

{

pH_data= in_char; //charge cet octet dans notre tableau.

i+=1;

}

if(in_char==0) //si nous voyons que nous avons reçu une commande nulle.

{

i=0; //remet le compteur i à 0.

Wire.endTransmission(); //fin de la transmission de données I2C.

Pause; // quitte la boucle while.

}

}

événement_série=0; //réinitialiser l'indicateur d'événement en série.

dataString2 += ", ";

dataString2 += String(pH_data);

Wire.beginTransmission(DO_address); // appelle le circuit par son numéro d'identification

Wire.write('r');

Wire.endTransmission(); //fin de la transmission de données I2C

temporisation_); // attendre le temps nécessaire pour que le circuit termine son instruction

Wire.requestFrom(DO_address, 20, 1); // appelle le circuit et demande 20 octets

while(Wire.available()) // y a-t-il des octets à recevoir.

{

in_char = Wire.read(); //recevoir un octet.

if ((in_char > 31) && (in_char <127)) //vérifie si le char est utilisable (imprimable), sinon le in_char contient un symbole au début dans le fichier.txt

{ DO_data= in_char; //charge cet octet dans notre tableau

i+=1; // engage le compteur pour l'élément du tableau

}

if(in_char==0)

{ // si nous voyons que nous avons reçu une commande nulle

i=0; //remet le compteur i à 0.

Wire.endTransmission(); //fin de la transmission de données I2C.

Pause; // quitte la boucle while.

}

}

événement_série=0; //réinitialiser l'indicateur d'événement en série

pH_float = atof (pH_data);

dataString2 += ", ";

dataString2 += String(DO_data);

lcd.setCursor(0, 1);

lcd.print("Température/ pH/ OD");

lcd.setCursor(0, 2);

lcd.print(dataString2);

chaîne de données += ', ';

dataString += dataString2;

Fichier dataFile = SD.open(logFileName, FILE_WRITE); // ouvre le fichier. notez qu'un seul fichier peut être ouvert à la fois, vous devez donc fermer celui-ci avant d'en ouvrir un autre.

if (dataFile) // si le fichier est disponible, écrivez-y:

{

dataFile.println(dataString);

dataFile.close();

Serial.println(dataString); // imprime aussi sur le port série:

}

else { Serial.println("erreur d'ouverture du fichier journal de données"); } // si le fichier n'est pas ouvert, affiche une erreur:

lcd.setCursor(0, 3);

lcd.print("Course(x5m):");

lcd.setCursor(15, 3);

lcd.print(id);

identifiant ++; // augmente d'un identifiant l'itération suivante

chaîne de données = "";

retard(300000); //retard 5 minutes = 5*60*1000 ms

lcd.clear();

} //fin de la boucle principale

void displayTemperature(DeviceAddress deviceAddress)

{

float tempC = capteurs.getTempC(deviceAddress);

if (tempC == -127,00) lcd.print("Erreur de température");

else dataString2 = String(tempC);

}//le code se termine ici

  • Choisissez le bon port COM via Arduino IDE sous Outils/Port
  • Choisissez la bonne carte Arduino. J'ai utilisé Mega 2560 car il a plus de mémoire interne. Arduino Nano ou Uno fonctionne bien avec cette configuration.
  • Vérifier et coder et télécharger le code

Étape 7: Résultats sur le câblage (peut être amélioré) et l'écran LCD

Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
Résultats sur le câblage (peut être amélioré) et l'affichage LCD
  • Avis: J'ai rencontré le bruit de la sonde DO à la sonde pH après 2-3 mois de fonctionnement continu. Selon Atlas Scientific, un isolateur de tension en ligne est recommandé lorsque les sondes de pH et de conductivité fonctionnent ensemble. Plus de détails à la page 9 (https://goo.gl/d62Rqv)
  • Les données enregistrées (la première a des caractères non imprimés avant les données pH et DO). J'ai filtré au code en n'autorisant que les caractères imprimables.

Étape 8: importer des données et créer un graphique

Importer des données et créer un graphique
Importer des données et créer un graphique
Importer des données et créer un graphique
Importer des données et créer un graphique
Importer des données et créer un graphique
Importer des données et créer un graphique
  1. Importer des données à partir du texte sous l'onglet DONNÉES (Excel 2013)
  2. Séparez les données par la virgule (c'est pourquoi il est utile d'avoir des virgules après chaque entrée de données)
  3. Tracez les données. Chaque donnée ci-dessous a environ 1700 points. L'intervalle de mesure est de 5 minutes (réglable). Le minimum pour les circuits DO et pH pour lire les données est de 1,8 s.

Étape 9: Étalonnage

Étalonnage
Étalonnage
  1. Le capteur de température numérique (18B20) peut être calibré en ajustant la différence directement sur le. Sinon, si la compensation et la pente nécessitaient un étalonnage, vous pouvez le faire en modifiant les valeurs sur la ligne #453, DallasTemperature.cpp dans le dossier \libraries\DallasTemperature.
  2. Pour les sondes pH et DO, vous pouvez étalonner les sondes avec les solutions d'accompagnement. Vous devez utiliser l'exemple de code d'Atlas Scientific et suivre les instructions de ce fichier.
  3. Veuillez suivre les pages 26 et 50 pour la sonde pH (https://goo.gl/d62Rqv) pour l'étalonnage et la compensation de température, ainsi que les pages 7-8 et 50 pour la sonde DO (https://goo.gl/mA32mp). Tout d'abord, veuillez télécharger à nouveau le code générique fourni par Atlas, ouvrez le moniteur série et saisissez une commande appropriée.

Étape 10: Trop de câblage ?

  1. Vous pouvez éliminer la carte SD et le module d'horloge temps réel en utilisant Dragino Yun Shield pour les cartes Arduino (https://goo.gl/J9PBTH). Le code devait être modifié pour fonctionner avec Yun Shield. Voici un bon point de départ (https://goo.gl/c1x8Dm)
  2. Encore trop de câblage: Atlas Scientific a fait un guide pour leurs circuits EZO (https://goo.gl/dGyb12) et leur carte sans soudure (https://goo.gl/uWF51n). L'intégration de la température numérique 18B20 est ici (https://goo.gl/ATcnGd). Vous devez être familiarisé avec les commandes sur Raspbian (une version de Debian Linux) fonctionnant sur Raspberry Pi (https://goo.gl/549xvk)

Étape 11: Reconnaissance:

C'est mon projet parallèle lors de mes recherches postdoctorales où j'ai travaillé sur un photobioréacteur avancé pour cultiver des microalgues. J'ai donc pensé qu'il était nécessaire de créditer les parties d'avoir fourni des conditions pour que cela se produise. Premièrement, la subvention DE-EE0007093: « Enrichissement et livraison de CO2 atmosphérique (ACED) » du département américain de l'Énergie, Office of Energy Efficiency and Renewable Energy Targeted Algal Biofuels and Bioproducts. Je remercie le Dr Bruce E. Rittmann du Biodesign Swette Center for Environmental Biotechnology, Arizona State Univesity pour m'avoir donné l'opportunité de bricoler avec l'électronique et Arduino. J'ai été formé en génie de l'environnement, principalement en chimie, un peu en microbiologie.

Conseillé: