Si ce n’est pas encore fait, je vous propose de commencer par lire la présentation générale de ce projet ici
Nous avons un arduino capable d’interroger, mais nous n’avons personne à interroger. Qu’à cela ne tienne, développons notre première station météo, qui pourra être contactée par l’arduino maître du chapitre précédent.
Comme précédemment, testez d’abord ce module à l’aide de votre platine d’essais. Quand vous serez sur de vous, vous figerez tout ça!
Matériel nécessaire
Si vous avez décidé d’utiliser un module de communication autre que le HC12 précédemment, pensez à prendre quelque-chose de compatible avec ce que vous avez choisi ici!
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.
- Une résistance 4.7kOhm
En utilisation nominale :
- Un arduino nano
- 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
Ce deuxième montage a pour but de recevoir les instructions de l’arduino maître, effectuer une mesure de température, et communiquer le résultat obtenu. Il utilise un capteur de température DS18B20.
Vous pourrez trouvez d’excellentes informations sur l’utilisation de ce capteur sur cette page
La librairie OneWire est utilisée. Il vous faudra la télécharger et l’installer
Le montage
Voila le schéma du montage que nous souhaitons réaliser
- Pour le module HC12, les pins sont différents de la partie 1, mais le principe est le même.
- SET: pin 7
- TXD: pin 3
- RXD: pin 5
- La nouveauté réside dans le capteur de température DS18B20, représenté au format boitier sur le schéma.
- Pour le format sonde étanche, le fil jaune correspond à la pâte du milieu. Les fils rouge et noir correspondent respectivement au +5V et au GND
- La pate du milieu est reliée au pin 9 de l’arduino
- Une résistance relie le pin 9 au +5V
Voici quelques précisions supplémentaires sur ce montage:
Le bus 1-Wire
Notre capteur de température DS18B20 est un capteur 1-Wire. Plusieurs capteurs de ce type peuvent être branchés sur le même pin (le 9 dans notre cas). Ils possèdent une adresse unique, et sont utilisable indépendamment les uns des autres. Dans notre cas, c’est la libraire OneWire que vous avez dû télécharger qui se chargera de ces opérations.
La résistance de tirage
La résistance qui relie le pin 9 au +5V est appelée résistance de tirage. Elle permet de ne pas laisser “flottante” l’entrée 9. Plus de détails ici.
Le code
Si l’envie vous en dit, n’hésitez pas à proposer des améliorations sur le code ci dessous, qui en a bien besoin!
#include <OneWire.h>
#include <SoftwareSerial.h>
#define VW_MAX_MES
#define SET_PIN 7
/* Broche du bus 1-Wire */
const byte BROCHE_ONEWIRE = 9;
boolean sendInfos = false;
SoftwareSerial hc12(5, 3);
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;
}
void readSerial(unsigned int MAXBUF, char* buffer){
buffer[0] = 0;
int i = 0;
while(hc12.available() && i < MAXBUF){
char curCar[1];
curCar[0] = hc12.read();
buffer[i++] = curCar[0];
delay(2);
}
}
void reinitBuf(char* buf, int bufsize)
{
for(int i = 0 ; i < bufsize; i++){
buf[i] = 0;
}
}
/** Fonction setup() **/
void setup() {
Serial.begin(2400);
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
EOT[0] = 4;
EOL[0] = '\n';
}
/** Fonction loop() **/
void loop() {
//while(1){
//hc12.print(1);
//delay(30);
//if (hc12.available())
//{
// Serial.write(hc12.read());
//}
//}
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 N", 6) == 0){
Serial.println((char*) "Appel recu"); // Affiche le message
sendInfos=true;
}
}
if(sendInfos){
delay(800);
//TEMPERATURE
float temperature;
/* Lit la temp?rature ambiante ? ~1Hz */
if (getTemperature(&temperature, true) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur temperature"));
return;
}
char message[22] = "";
reinitBuf(message, 22);
char buf[10];
strcat(message, "RECE N\n");
reinitBuf(buf, 10);;
strcat(message, "RECE T2 ");
dtostrf(temperature, 2, 2, buf);
strcat(message, buf);
strcat(message, "\n");
strcat(message, EOT);
strcat(message, EOL);
Serial.println(message);
Serial.println("");
hc12.flush();
//Send bytes to trigger reception
//for(int i = 0; i <10; i++){
hc12.write(message);
//}
sendInfos = false;
}
}
Tout d’abord, les librairie SoftwareSerial, pour le module HC12, et OneWire, pour le capteur de température, sont utilisées. N’oubliez pas de les importer.
Les pins à configurer sont:
- Pin SET HC12: Ligne 5
- Pin RXD/TXD HC12: Ligne 10
- Pin 1-Wire : Ligne 8
La fonction setup configure le port HC12 comme dans la partie 1. Les paramètres doivent correspondre pour le canal et le débit
La fonction loop surveille le module HC12, qui est susceptible de recevoir des commandes de la part du maître. Dans le cas ou la chaîne de caractère “CALL N” est reçue, alors l’esclave se reconnaît et déclenche une mesure de température via la fonction getTemperature.
La fonction getTemperature est récupérée de ce tutorial
Si la mesure réussit, elle est formatée et envoyée par le module HC12. C’est alors une nouvelle fois au tour du maître de la réceptionner et de la traiter
Chaque esclave est identifié par une chaîne de caractère, et attends l’instruction “CALL X” ou X est la chaîne de caractère qui l’identifie. “N” est l’identifiant de ce module météo.
Conclusion
Si tout va bien, vous pouvez normalement faire contacter le maître et l’esclave. Envoyez “METEO2” sur le port série de l’arduino maître:
- Il enverra “CALL N” via le module radio HC12
- “CALL N” va être reçu par l’esclave, qui va se reconnaître et effectuer une mesure de température.
- Une fois la mesure faite, elle est formatée et envoyée
- Elle est alors reçue et affichée par l’arduino maître
Maintenant que nos arduinos communiquent, il est temps de mettre en place le programme qui permettra de commander tout ça automatiquement! C’est par là!
Commentaires