Si ce n’est pas encore fait, je vous propose de commencer par lire la présentation générale de ce projet ici
Sur le même modèle que la partie 2, nous allons réaliser un deuxième module météo, qui, en plus d’un capteur de température, apportera une mesure de l’hygrométrie et une mesure de la pression atmosphérique.
Si vous ne souhaitez qu’un module, vous pouvez si vous le souhaiter enrichir votre premier montage. Il faudra alors sans doute adapter le code de cette partie afin qu’il soit compatible avec les pins que vous avez choisi sur votre arduino.
Et comme toujours, exercez vous sur une platine d’essai avant de souder!
Matériel nécessaire
Pour les tests:
- Un arduino UNO (ou équivalent)
- Un module HC12
- Une platine d’essai
- Des fils
- Un capteur de température DS18B20
- Ce capteur existe au format sonde étanche, ou en boîtier. J’ai pris les sondes car elles sont déportables.
- Un capteur de pression BMP180
- Un hygromètre DHT22
- Ce dernier existe seul, ou sur un PCB qui pré traite son signal
- Prenez la version avec PCB 🙂
- Le DHT11 existe aussi, mais les mesures que j’ai pu obtenir avec étaient de mauvaise qualité
- Une résistance 4.7kOhm
En utilisation nominale :
- Un arduino nano ou équivalent
- Pour ce montage, j’ai un arduino pro micro, mais cela ne devrait pas avoir d’influence
- Des PCBs
- Si elles ne sont pas fournies avec vos modules radio, des antennes
- Si vous souhaitez créer une boite pour votre montage final, il vous sera utile de déporte le port USB : Voici ce dont vous aurez besoin
Présentation générale
Dans les grandes lignes, ce module est très similaire au précédent. Il est contacté par l’arduino maître, effectue ses mesures et les renvoie.
Il enverra cependant plus d’informations puisqu’en plus de la température, l’hygrométrie et la pression atmosphérique sont mesurées.
Trois librairies supplémentaires sont utilisées
- SFE_BMP180: pour la gestion du baromètre
- DHT: pour la gestion de l’hygromètre
- OneWire: Comme à la partie 2
Les librairies doivent être collés dans le répertoire libraries de l’IDE
Pour le DHT, de nombreuses informations sur son utilisation sont disponibles ici
Le montage
Et voilà le schéma!
Les points importants du montage:
- Le baromètre BMP180 communique avec l’arduino via les ports SDA et SCL.
- Sur l’arduino nano, ou sur l’arduino UNO, ils correspondent respectivement aux pins A4 et A5, comme explicité ici
- Ces pins diffèrent en fonction de l’arduino, faites attention dans le cas ou vous travaillez sur un autre arduino
- Les pins SCL et SDA sont inhérents aux bus I2C qui permet à plusieurs composants de communiquer à travers les même pins, comme pour le bus 1-Wire
- Pour le HC12, rien de neuf par rapport à la partie 2
- SET: 10
- TXD: 9
- RXD: 7
- Pour le DS18B20, rien de neuf non plus
- DATA: 5
- Une résistance de tirage entre le +5V et le pin DATA
- Le DHT22 se branche normalement sur un pin
- DATA: 3
Le code
Voila le code que je vous propose pour gérer l’ensemble de ces composants. N’hésitez pas à proposer des améliorations!
#include <OneWire.h>
#include <SFE_BMP180.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <DHT.h>
#define VW_MAX_MESSAGE_LEN 200
#define SET_PIN 10
#define ALTITUDE 68.0 // Altitude Appartement
#define DHTTYPE DHT22
#define DHTPIN 3
/* Broche du bus 1-Wire */
const byte BROCHE_ONEWIRE = 5;
boolean sendInfos = false;
SoftwareSerial hc12(9, 7);
DHT dht(DHTPIN, DHTTYPE);
SFE_BMP180 pressure;
char EOT[1];
char EOL[1];
/* Code de retour de la fonction getTemperature() */
enum DS18B20_RCODES {
READ_OK, // Lecture ok
NO_SENSOR_FOUND, // Pas de capteur
INVALID_ADDRESS, // Adresse re?ue invalide
INVALID_SENSOR // Capteur invalide (pas un DS18B20)
};
/* Cr?ation de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);
/**
* Fonction de lecture de la temp?rature via un capteur DS18B20.
*/
byte getTemperature(float *temperature, byte reset_search) {
byte data[9], addr[8];
// data[] : Donn?es lues depuis le scratchpad
// addr[] : Adresse du module 1-Wire d?tect?
/* Reset le bus 1-Wire ci n?cessaire (requis pour la lecture du premier capteur) */
if (reset_search) {
ds.reset_search();
}
/* Recherche le prochain capteur 1-Wire disponible */
if (!ds.search(addr)) {
// Pas de capteur
Serial.println("NO SENSOR");
return NO_SENSOR_FOUND;
}
/* V?rifie que l'adresse a ?t? correctement re?ue */
if (OneWire::crc8(addr, 7) != addr[7]) {
// Adresse invalide
Serial.println("INVALID_ADDRESS");
return INVALID_ADDRESS;
}
/* V?rifie qu'il s'agit bien d'un DS18B20 */
if (addr[0] != 0x28) {
// Mauvais type de capteur
Serial.println("INVALID_SENSOR");
return INVALID_SENSOR;
}
/* Reset le bus 1-Wire et s?lectionne le capteur */
ds.reset();
ds.select(addr);
/* Lance une prise de mesure de temp?rature et attend la fin de la mesure */
ds.write(0x44, 1);
delay(800);
/* Reset le bus 1-Wire, s?lectionne le capteur et envoie une demande de lecture du scratchpad */
ds.reset();
ds.select(addr);
ds.write(0xBE);
/* Lecture du scratchpad */
for (byte i = 0; i < 9; i++) {
data[i] = ds.read();
}
/* Calcul de la temp?rature en degr? Celsius */
*temperature = ((data[1] << 8) | data[0]) * 0.0625;
// Pas d'erreur
return READ_OK;
}
byte getPression(double *Pout, double *p0out){
char status;
double T,P,p0,a;
//Debut mesure temp
status = pressure.startTemperature();
if (status != 0)
{
delay(status);
status = pressure.getTemperature(T);
{
//Debut mesure Pression
status = pressure.startPressure(3);
if (status != 0)
{
delay(status);
status = pressure.getPressure(P,T);
if (status != 0)
{
*Pout = P;
p0 = pressure.sealevel(P,ALTITUDE);
*p0out = p0;
return 0;
}
}
}
}
return -1;
}
void readSerial(unsigned int MAXBUF, char* buffer){
buffer[0] = 0;
int i = 0;
while(hc12.available() && i < MAXBUF){
buffer[i++] = hc12.read();
delay(10);
}
}
/** Fonction setup() **/
void setup() {
/* Initialisation du port s?rie */
Serial.begin(2400);
int i = 0;
dht.begin();
pinMode(SET_PIN,OUTPUT);
digitalWrite(SET_PIN,LOW);
delay(300);
hc12.begin(2400);
hc12.print("AT+B2400");
delay(200);
hc12.print("AT+C093");
delay(200);
hc12.print("AT+P8");
delay(200);
digitalWrite(SET_PIN,HIGH);// enter transparent mode
if (pressure.begin())
Serial.println("BMP180 init success");
else
{
Serial.println("BMP180 init fail\n\n");
}
EOT[0] = 4;
EOL[0] = '\n';
}
void reinitBuf(char* buf, int bufsize)
{
for(int i = 0 ; i < bufsize; i++){
buf[i] = 0;
}
}
/** Fonction loop() **/
void loop() {
byte taille_messageRx = 8;
char messageRx[taille_messageRx];
readSerial(taille_messageRx, messageRx);
if (messageRx[0] != 0) {
Serial.println((char*)messageRx);
if(strncmp((char*)messageRx, "CALL QT", 7) == 0){
Serial.println((char*) "Appel recu"); // Affiche le message
sendInfos=true;
}
}
if(sendInfos){
delay(800);
//TEMPERATURE
float temperature = 0;
/* Lit la temp?rature ambiante ? ~1Hz */
if (getTemperature(&temperature, true) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur temp?rature"));
return;
}
//PRESSION
double P,p0;
boolean pressionOk = true;
if (getPression(&P, &p0) != 0) {
Serial.println(F("Erreur de lecture du capteur pression"));
pressionOk = false;
}
//HYGRO
float hum = dht.readHumidity();;
boolean hygroOk = true;
if (isnan(hum)) {
hygroOk = false;
Serial.println(F("Failed to read from DHT sensor!"));
}
char message[100] = "";
reinitBuf(message, 100);
char buf[10];
strcat(message, "RECE QT\n");
reinitBuf(buf, 10);;
strcat(message, "RECE T ");
dtostrf(temperature, 2, 2, buf);
strcat(message, buf);
strcat(message, "\n");
if(pressionOk){
reinitBuf(buf, 10);
strcat(message, "RECE AP ");
dtostrf(P, 4, 1, buf);
strcat(message, buf);
strcat(message, "\n");
reinitBuf(buf, 10);
strcat(message, "RECE RP ");
dtostrf(p0, 4, 1, buf);
strcat(message, buf);
strcat(message, "\n");
}
if(hygroOk){
reinitBuf(buf, 10);
strcat(message, "RECE HH ");
dtostrf(hum, 4, 2, buf);
strcat(message, buf);
}
strcat(message, EOT);
strcat(message, "\n");
Serial.print(message);
Serial.println("");
hc12.flush();
hc12.write(message);
sendInfos = false;
}
}
Les pins peuvent être paramétrés:
- Ligne 13
- Ligne 16
- Ligne 19
La pression relative que le code communique, celle que vous entendez à la météo, dépend de votre altitude. Il faut donc configurer votre altitude ligne 10.
Elle est calculée par rapport à la pression absolue, également communiquée par l’arduino
Par ailleurs, n’oubliez pas de configurer le HC12 dans la fonction setup pour qu’il soit compatible avec l’arduino maître
Une fois qu’une demande de mesure est reçue, les 3 mesures seront prises successivement, formatées, et envoyées à l’arduino maître!
Modification du programme Java
Maintenant que cette nouvelle station météo est prête, activez la dans le fichier de configuration
- mode.meteo1.activated=1
Conclusion
Voila! Vous avez maintenant deux stations météo, et une application qui les pilote! Les graphiques de votre site web devraient commencer à se remplir 🙂
Le chapitre suivant traitera d’un module permettant un contrôle automatique du chauffage
Commentaires