Skip to content

ATMOS-14

#include      "RAK13010_SDI12.h"

#define       TX_PIN              WB_IO6      // Broche TX du bus de données SDI-12
#define       RX_PIN              WB_IO5      // Broche RX du bus de données SDI-12
#define       OE                  WB_IO4      // Broche pour autoriser la sortie
#define       POWER               WB_IO2      // Broche pour l'alimenttion du capteur
#define       PIN_VBAT            WB_A0       // Broche pour lire la tension de batterie

RAK_SDI12     mySDI12(RX_PIN, TX_PIN, OE);
int           sensor_address  =   0; 
String        raw_data        =   ""; 
float         temperature;
float         humidite;
float         pression_vapeur;
float         pression_atmos;
float         battery_voltage;

// Fonction d'initialisation
void setup() {
  pinMode(POWER, OUTPUT);
  Serial.begin(115200, RAK_AT_MODE);
  delay(2000);
  Serial.println("Demo SDI12 sensor");
  delay(1000);
}

// Boucle principale
void loop() {
  battery_voltage = readVBAT();                   // Lecture de la tension de la batterie
  raw_data = readFromSensor(sensor_address);      // Lecture du capteur SDI-12 à l'adresse 0
  Serial.println();
  Serial.println(raw_data);
  parseResponse(raw_data);
  Serial.println("Temperature : " + String(temperature)+" °C"); 
  Serial.println("Humidite : " + String(humidite*100)+" %");
  Serial.println("pression vapeur : " + String(pression_vapeur)+" kPa");
  Serial.println("pression atmos : " + String(pression_atmos)+" kPa");
  Serial.println("Tension de la batterie : " + String(battery_voltage) + " V");
  delay(1000);
}

// Fonction pour la lecture des données sur le capteur SDI-12
String readFromSensor(int sensor_address) {
  String sdiResponse = "";
  digitalWrite(POWER, HIGH);
  delay(500);
  mySDI12.begin();
  delay(50); 
  mySDI12.clearBuffer();
  delay(50);  
  mySDI12.sendCommand(String(sensor_address) + "M!");
  delay(700); 
  mySDI12.clearBuffer();
  mySDI12.sendCommand(String(sensor_address) + "D0!");
  delay(500);
  sdiResponse = mySDI12.readStringUntil('\n');
  mySDI12.end();
  digitalWrite(POWER, LOW);
  return sdiResponse;
}

// Fonction pour "parser" les données brutes
void parseResponse(String response) {
  int pos1 = response.indexOf('+');
  int pos2 = response.indexOf('+', pos1 + 1);
  int pos3 = response.indexOf('+', pos2 + 1);
  int pos4 = response.indexOf('+', pos3 + 1);
  pression_vapeur = response.substring(pos1 + 1, pos2).toFloat();
  temperature = response.substring(pos2 + 1, pos3).toFloat();
  humidite = response.substring(pos3 + 1, pos4).toFloat();
  pression_atmos = response.substring(pos4 + 1).toFloat();
}

// Fonction pour lire la tension de la batterie
float readVBAT(void){
  analogReference(AR_INTERNAL_3_0);
  analogReadResolution(12);
  delay(1);
  float raw = analogRead(PIN_VBAT);
  return raw * (3.0/4096)*1.73;
}
  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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/**
Programmation noeud SDI12 

Capteurs : RTC EM3028 + ATMOS14 (pression atmospherique, température, humidité, pression de vapeur)

**/



#include <lib.h>
#include <Arduino.h>
#include <Wire.h>
#include "RAK13010_SDI12.h"
#include "Melopero_RV3028.h"  //http://librarymanager/All#Melopero_RV3028  bibliothèque pour le RTC
#include <time.h>             /* time_t, struct tm, time, mktime */
#include "timestamp32bits.h"

// Comment la ligne ci-dessous pour debug (print des mesures)
#define MAX_SAVE

//define time interval measurement
#define SDI12_sensor_PERIOD (600000)  //timer 600000 (10min)



#define TX_PIN WB_IO6  // The pin of the SDI-12 data bus.
#define RX_PIN WB_IO5  // The pin of the SDI-12 data bus.
#define OE WB_IO4      // Output enable pin, active low.


#define PIN_VBAT WB_A0  //  // The pin of the ADC.
uint32_t vbat_pin = PIN_VBAT;

#define PIN_LORA_DIO_1 47  // DIO1 GPIO pin for RAK4631

/* variables de chaque capteur */
typedef struct __attribute__((__packed__)) {

  float pressure_vapor;
  float temperature;
  float humidity;
  float pressure;
  float batteryVoltage;
  uint8_t time_sep[8];
} SensorDataStruct;  // sensor_data_t

SensorDataStruct sensor;  // creation of the payload structure

uint8_t time_sep[8];


timestamp32bits stamp = timestamp32bits();  // time en format timestamp


int sensor_address = 0;  // Adresse du capteur SDI12

Melopero_RV3028 rtc;


RAK_SDI12 mySDI12(RX_PIN, TX_PIN, OE);

String sdiResponse = "";  //variable String : réponse du capteur SDI12
//int sdiCommandIndex = 1;
String sdiCommand = "M!";    // commande SDI12 de lecture des capteurs (voir protocole SDI12)
String sdiCommand1 = "D0!";  // commande SDI12 de lecture des capteurs (voir protocole SDI12)

//Declaration des fonctions
void readFromSensor(int sensor_address);
void uplink_routine();
void parseResponse(String response, int sensor_address);


//PARTIE LORAWAN
/**************************************************************************************************************************

   LoRaWAN band setting:
     RAK_REGION_EU433
     RAK_REGION_CN470
     RAK_REGION_RU864
     RAK_REGION_IN865
     RAK_REGION_EU868
     RAK_REGION_US915
     RAK_REGION_AU915
     RAK_REGION_KR920
     RAK_REGION_AS923

 *************************************/
#define PROJET_NODE_BAND (RAK_REGION_EU868)
#define PROJET_NODE_DEVEUI \
  { 0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x0C, 0xC1, 0x37 }  //Déclaration du DEVEUI
#define PROJET_NODE_APPEUI \
  { 0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x0C, 0xC1, 0x37 }  // Non utilisé
#define PROJET_NODE_APPKEY \
  { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3E }  // Declaration de l'APPEUI



/** Packet buffer for sending */
uint8_t collected_data[64] = { 0 };

void recvCallback(SERVICE_LORA_RECEIVE_T *data) {
  if (data->BufferSize > 0) {
    Serial.println("Something received!");
    for (int i = 0; i < data->BufferSize; i++) {
      Serial.printf("%x", data->Buffer[i]);
    }
    Serial.print("\r\n");
  }
}

void joinCallback(int32_t status) {
  Serial.printf("Join status: %d\r\n", status);
}

void sendCallback(int32_t status) {
  if (status == 0) {
    Serial.println("Successfully sent");
  } else {
    Serial.println("Sending failed");
  }
}

/*****************************************************************************************************************************/

void setup() {
  Serial.begin(115200, RAK_AT_MODE);
  delay(2000);

  Wire.begin();  //I2C RTC

  rtc.initI2C();  // First initialize and create the rtc device
  rtc.writeToRegister(0x35, 0x00);
  rtc.writeToRegister(0x37, 0xB4);
  rtc.set24HourMode();  // Set the device to use the 24hour format (default) instead of the 12 hour format
  rtc.setTime(2024, 1, 10, 30, 18, 50, 00);


  Serial.println("RAKwireless SDI12 sensor");
  Serial.println("------------------------------------------------------");



  // OTAA Device EUI MSB first
  uint8_t node_device_eui[8] = PROJET_NODE_DEVEUI;
  // OTAA Application EUI MSB first
  uint8_t node_app_eui[8] = PROJET_NODE_APPEUI;
  // OTAA Application Key MSB first
  uint8_t node_app_key[16] = PROJET_NODE_APPKEY;

  if (!api.system.lpm.set(1)) {
    Serial.printf("LoRaWan SDI12 sensor - set low power mode is incorrect! \r\n");
    return;
  }

  if (!api.lorawan.nwm.set(1)) {
    Serial.printf("LoRaWan SDI12 sensor - set network working mode is incorrect! \r\n");
    return;
  }

  if (!api.lorawan.appeui.set(node_app_eui, 8)) {
    Serial.printf("LoRaWan SDI12 sensor - set application EUI is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.appkey.set(node_app_key, 16)) {
    Serial.printf("LoRaWan SDI12 sensor - set application key is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deui.set(node_device_eui, 8)) {
    Serial.printf("LoRaWan SDI12 sensor - set device EUI is incorrect! \r\n");
    return;
  }

  if (!api.lorawan.band.set(PROJET_NODE_BAND)) {
    Serial.printf("LoRaWan SDI12 sensor - set band is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
    Serial.printf("LoRaWan SDI12 sensor - set device class is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.njm.set(RAK_LORA_OTAA))  // Set the network join mode to OTAA
  {
    Serial.printf("LoRaWan SDI12 sensor - set network join mode is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.join())  // Join to Gateway
  {
    Serial.printf("LoRaWan SDI12 sensor - join fail! \r\n");
    return;
  }

  Serial.println("++++++++++++++++++++++++++");
  Serial.println("SDI12 sensor");
  Serial.println("++++++++++++++++++++++++++");


  /** Wait for Join success */
  while (api.lorawan.njs.get() == 0) {
    Serial.print("Wait for LoRaWAN join...");
    api.lorawan.join();
    delay(10000);  //10000
  }

  if (!api.lorawan.adr.set(true)) {
    Serial.printf("LoRaWan SDI12 sensor - set adaptive data rate is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.rety.set(1)) {
    Serial.printf("LoRaWan SDI12 sensor - set retry times is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.cfm.set(1)) {
    Serial.printf("LoRaWan SDI12 sensor - set confirm mode is incorrect! \r\n");
    return;
  }

  /** Check LoRaWan Status*/
  Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get() ? "ON" : "OFF");             // Check Duty Cycle status
  Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get() ? "CONFIRMED" : "UNCONFIRMED");  // Check Confirm status
  uint8_t assigned_dev_addr[4] = { 0 };
  api.lorawan.daddr.get(assigned_dev_addr, 4);
  Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);  // Check Device Address
  Serial.printf("Uplink period is %ums\r\n", SDI12_sensor_PERIOD);
  Serial.println("");
  api.lorawan.registerRecvCallback(recvCallback);
  api.lorawan.registerJoinCallback(joinCallback);
  api.lorawan.registerSendCallback(sendCallback);
  if (api.system.timer.create(RAK_TIMER_0, (RAK_TIMER_HANDLER)uplink_routine, RAK_TIMER_PERIODIC) != true) {
    Serial.printf("LoRaWan SDI12 sensor - Creating timer failed.\r\n");
    return;
  }
  if (api.system.timer.start(RAK_TIMER_0, SDI12_sensor_PERIOD, NULL) != true) {
    Serial.printf("LoRaWan SDI12 sensor - Starting timer failed.\r\n");
    return;
  }
}


//Fonction de transfert des data en Lorawan + appel des fonctions de lecture des capteurs
void uplink_routine() {

  uint32_t time_sensor = (uint32_t)(stamp.timestamp((rtc.getYear() - 2000), rtc.getMonth(), rtc.getDate(), rtc.getHour(), rtc.getMinute(), rtc.getSecond()));  //Formatage au format TimeStamp

#ifndef MAX_SAVE
  Serial.println(String(time_sensor));
#endif

  for (int8_t j = 0; j < 4; j++) {
    sensor.time_sep[j] = ((time_sensor >> j * 8) & 0xFF);
  }

#ifndef MAX_SAVE
  Serial.println(sensor.time_sep[0], HEX);
  Serial.println(sensor.time_sep[1], HEX);
  Serial.println(sensor.time_sep[2], HEX);
  Serial.println(sensor.time_sep[3], HEX);
  uint32_t test = sensor.time_sep[0] | sensor.time_sep[1] << 8 | sensor.time_sep[2] << 16 | sensor.time_sep[3] << 24;
  Serial.println(String(test));
#endif

  //Lecture du capteur SDI12
  readFromSensor(sensor_address);  //read sensor  SDI_adress=0

  //Lecture de la valeur de la batterie
  sensor.batteryVoltage = (int)(readVBAT() * 100);

  /*Payload */
  uint8_t data_len = 0;

  collected_data[data_len++] = highByte((int)sensor.pressure_vapor);
  collected_data[data_len++] = lowByte((int)sensor.pressure_vapor);
  collected_data[data_len++] = highByte((int)sensor.temperature);
  collected_data[data_len++] = lowByte((int)sensor.temperature);
  collected_data[data_len++] = highByte((int)sensor.humidity);
  collected_data[data_len++] = lowByte((int)sensor.humidity);
  collected_data[data_len++] = highByte((int)sensor.pressure);
  collected_data[data_len++] = lowByte((int)sensor.pressure);
  collected_data[data_len++] = highByte((int)sensor.batteryVoltage);
  collected_data[data_len++] = lowByte((int)sensor.batteryVoltage);

  collected_data[data_len++] = sensor.time_sep[0];
  collected_data[data_len++] = sensor.time_sep[1];
  collected_data[data_len++] = sensor.time_sep[2];
  collected_data[data_len++] = sensor.time_sep[3];


  Serial.println("Data Packet:");
  for (int i = 0; i < data_len; i++) {
    Serial.printf("0x%02X ", collected_data[i]);
  }
  Serial.println("");


  /** Send the data package */
  if (api.lorawan.send(data_len, (uint8_t *)&collected_data, 2, true, 1)) {
    Serial.println("Sending is requested");
  } else {
    Serial.println("Sending failed");
  }
}
/***********************************************************************************************/
//Mesure du niveau de batterie
float readVBAT(void) {
  // Set the analog reference to 3.0V (default = 3.6V)
  analogReference(AR_INTERNAL_3_0);
  // Set the resolution to 12-bit (0..4095)
  analogReadResolution(12);  // Can be 8, 10, 12 or 14
  // Let the ADC settle
  delay(1);
  float raw;
  // Get the raw 12-bit, 0..3000mV ADC value
  raw = analogRead(vbat_pin);
  //return raw * REAL_VBAT_MV_PER_LSB;
  return raw * (3.0 / 4096) * 1.73;
}

/************************************************************************************************/
//Mesure des capteurs SDI12
void readFromSensor(int sensor_address) {
  // Power the sensor.
  pinMode(WB_IO2, OUTPUT);
  digitalWrite(WB_IO2, HIGH);
  delay(500);  //1500


  mySDI12.begin();
  delay(50);  //500

  sdiResponse = "";

  mySDI12.clearBuffer();
  delay(50);  //500
  mySDI12.sendCommand(String(sensor_address) + sdiCommand);


  delay(700);  //700 pour ATMOS14 ECH20 GS3


  mySDI12.clearBuffer();

  mySDI12.sendCommand(String(sensor_address) + sdiCommand1);

  delay(500);



  sdiResponse = mySDI12.readStringUntil('\n');

#ifndef MAX_SAVE
  Serial.println("D:" + sdiResponse);
#endif

  parseResponse(sdiResponse, sensor_address);

  mySDI12.end();

  digitalWrite(WB_IO2, LOW);
}
/*******************************************************************************************/
//Formatage de la data SDI12 avant transfert en LoraWan
void parseResponse(String response, int sensor_address) {

  int index = 0;
  int nextIndex = 0;
  int counter = 0;
  String value = "";
  while (index < response.length()) {
    nextIndex = response.indexOf('+', index);

    // If no other "+" sign is found, get the rest of the string.
    if (nextIndex == -1) {
      nextIndex = response.length();
    }

    value = response.substring(index, nextIndex);
    //Serial.println(value);

    switch (sensor_address) {

      case 0:

        switch (counter) {
          case 0:
            // Address of the sensor
            break;
          case 1:
            sensor.pressure_vapor = (value.toFloat() * 100);
#ifndef MAX_SAVE
            Serial.print(String(value.toFloat()) + ",");
#endif
            break;
          case 2:
            sensor.temperature = (value.toFloat() * 10);
#ifndef MAX_SAVE
            Serial.print(String(value.toFloat()) + ",");
#endif
            break;
          case 3:
            sensor.humidity = (value.toFloat() * 100);
#ifndef MAX_SAVE
            Serial.print(String(value.toFloat()) + ",");
#endif
            break;
          case 4:
            sensor.pressure = (value.toFloat() * 100);
#ifndef MAX_SAVE
            Serial.println(String(value.toFloat()));
#endif
            break;

          default:
            break;
        }
        break;
    }

    index = nextIndex + 1;
    counter = counter + 1;
  }
#ifndef MAX_SAVE
  Serial.println(sensor.batteryVoltage);
#endif
}

void loop() {
  /* Destroy this busy loop and use timer to do what you want instead,
     * so that the system thread can auto enter low power mode by api.system.lpm.set(1); */
  api.system.scheduler.task.destroy();
}
#include      "RAK13010_SDI12.h"

#define       SDI12_sensor_PERIOD   30000               // Timer 60000 ms (1 min)
#define       TX_PIN                WB_IO6              // Broche TX du bus de données SDI-12
#define       RX_PIN                WB_IO5              // Broche RX du bus de données SDI-12
#define       OE                    WB_IO4              // Broche pour autoriser la sortie
#define       POWER                 WB_IO2              // Broche pour l'alimenttion du capteur
#define       PIN_VBAT              WB_A0               // Broche pour lire la tension de batterie
#define       PIN_LORA_DIO_1        47                  // DIO1 GPIO pin for RAK4631
#define       PROJET_NODE_BAND      RAK_REGION_EU868    // Choix de la fréquence LoRa
#define       PROJET_NODE_DEVEUI    { 0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x18, 0x3A, 0xBD }  // DevEUI, à changer pour chaque noeud
#define       PROJET_NODE_APPEUI    { 0xDE, 0xAD, 0x42, 0xDE, 0xAD, 0x42, 0xDE, 0xAD }  // AppEUI, définie sur le serveur
#define       PROJET_NODE_APPKEY    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF } // AppKEY, définie sur le serveur

RAK_SDI12     mySDI12(RX_PIN, TX_PIN, OE);
int           sensor_address  =   0; 
String        site_name       =   "fra";
String        raw_data        =   ""; 
float         temperature;
float         humidite;
float         pression_vapeur;
float         pression_atmos;
float         battery_voltage;

/* Fonction d'initialisation */
void setup() {
  pinMode(POWER, OUTPUT);
  Serial.begin(115200, RAK_AT_MODE);
  delay(2000);
  Serial.println("Demo SDI12 sensor");
  init_LoRaWAN();
}

/* Boucle principale */
void loop() {
  api.system.scheduler.task.destroy();
}

/* Cycle de mesure et de transfert des données */
void uplink_routine() {
  battery_voltage = readVBAT();                   // Lecture de la tension de la batterie
  raw_data = readFromSensor(sensor_address);      // Lecture du capteur SDI-12 à l'adresse 0
  Serial.println(raw_data);
  parseResponse(raw_data);
  displaySensorData();
  String data_string = "{\"pv\":" + String(pression_vapeur) 
                      + ",\"h\":" + String(humidite*100) 
                      + ",\"t\":" + String(temperature) 
                      + ",\"pa\":" + String(pression_atmos) 
                      + ",\"v\":" + String(battery_voltage) 
                      + ",\"l\":\"" + site_name + "\"}";
  /* Afficher la chaîne de caractères JSON */
  Serial.print("Paquet de données :");
  Serial.println(data_string);
  /* Envoi du paquet de données */
  if (api.lorawan.send(data_string.length(), (uint8_t *)data_string.c_str(), 2, true, 1)) {
    Serial.println("Demande d'envoi");
  } else {
    Serial.println("La demande d'envoi a échoué");
  }
}

/* Fonction pour la lecture des données sur le capteur SDI-12 */
String readFromSensor(int sensor_address) {
  String sdiResponse = "";
  digitalWrite(POWER, HIGH);
  delay(500);
  mySDI12.begin();
  delay(50); 
  mySDI12.clearBuffer();
  delay(50);  
  mySDI12.sendCommand(String(sensor_address) + "M!");
  delay(700); 
  mySDI12.clearBuffer();
  mySDI12.sendCommand(String(sensor_address) + "D0!");
  delay(500);
  sdiResponse = mySDI12.readStringUntil('\n');
  mySDI12.end();
  digitalWrite(POWER, LOW);
  return sdiResponse;
}

/* Fonction pour "parser" les données brutes */
void parseResponse(String response) {
  int pos1 = response.indexOf('+');
  int pos2 = response.indexOf('+', pos1 + 1);
  int pos3 = response.indexOf('+', pos2 + 1);
  int pos4 = response.indexOf('+', pos3 + 1);
  pression_vapeur = response.substring(pos1 + 1, pos2).toFloat();
  temperature = response.substring(pos2 + 1, pos3).toFloat();
  humidite = response.substring(pos3 + 1, pos4).toFloat();
  pression_atmos = response.substring(pos4 + 1).toFloat();

}

/* Fonction pour afficher les données du capteur dans le moniteur série */
void displaySensorData(void) {
  Serial.println();
  Serial.println("Temperature : " + String(temperature) + " °C"); 
  Serial.println("Humidite : " + String(humidite*100) + " %");
  Serial.println("pression vapeur : " + String(pression_vapeur) + " kPa");
  Serial.println("pression atmos : " + String(pression_atmos) + " kPa");
  Serial.println("Tension de la batterie : " + String(battery_voltage) + " V");
}

/* Fonction pour lire la tension de la batterie */
float readVBAT(void){
  analogReference(AR_INTERNAL_3_0);
  analogReadResolution(12);
  delay(1);
  float raw = analogRead(PIN_VBAT);
  return raw * (3.0/4096)*1.73;
}

/****************************************/
/* Fonctions additionnelles LoRaWAN
/****************************************/

void init_LoRaWAN() {
  uint8_t node_device_eui[8] = PROJET_NODE_DEVEUI;
  uint8_t node_app_eui[8] = PROJET_NODE_APPEUI;
  uint8_t node_app_key[16] = PROJET_NODE_APPKEY;
  if (!api.system.lpm.set(1)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage du mode basse consommation est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.nwm.set(1)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage du mode de fonctionnement du réseau est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.appeui.set(node_app_eui, 8)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage de l'AppEUI est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.appkey.set(node_app_key, 16)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage de l'AppKEY est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.deui.set(node_device_eui, 8)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage du devEUI de l'appareil est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.band.set(PROJET_NODE_BAND)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage de la bande est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage de la classe de l'appareil est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.njm.set(RAK_LORA_OTAA))  // Réglage en mode OTAA
  {
    Serial.printf("Erreur LoRaWAN - le paramétrage du mode de connexion au réseau est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.join())  // Connexion à la gateway
  {
    Serial.printf("Erreur LoRaWAN - échec de la connexion ! \r\n");
    return;
  }
  /* Attente de la connexion */
  while (api.lorawan.njs.get() == 0) {
    Serial.print("En attente de la connexion LoRaWAN...");
    api.lorawan.join();
    delay(10000); // 10000
  }
  if (!api.lorawan.adr.set(true)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage du débit de données adaptatif est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.rety.set(1)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage des temps de réessai est incorrect ! \r\n");
    return;
  }
  if (!api.lorawan.cfm.set(1)) {
    Serial.printf("Erreur LoRaWAN - le paramétrage du mode de confirmation est incorrect ! \r\n");
    return;
  }
  /* Check LoRaWan Status */
  Serial.printf("Le duty cycle est %s\r\n", api.lorawan.dcs.get() ? "ON" : "OFF");             // Obtention du statut du Duty Cycle
  Serial.printf("Le statut des paquets est %s\r\n", api.lorawan.cfm.get() ? "CONFIRMÉ" : "NON CONFIRMÉ");  // Obtention du statut de confirmation
  uint8_t assigned_dev_addr[4] = { 0 };
  api.lorawan.daddr.get(assigned_dev_addr, 4);
  Serial.printf("L'adresse du noeud est %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);  // Obtention de l'adresse du noeud 
  Serial.printf("La période d'uplink est de %u sec.\r\n", SDI12_sensor_PERIOD/1000);
  Serial.println("");
  api.lorawan.registerRecvCallback(recvCallback);
  api.lorawan.registerJoinCallback(joinCallback);
  api.lorawan.registerSendCallback(sendCallback);
  if (api.system.timer.create(RAK_TIMER_0, (RAK_TIMER_HANDLER)uplink_routine, RAK_TIMER_PERIODIC) != true) {
    Serial.printf("Erreur LoRaWAN - Echec de la création du timer\r\n");
    return;
  }
  if (api.system.timer.start(RAK_TIMER_0, SDI12_sensor_PERIOD, NULL) != true) {
    Serial.printf("Erreur LoRaWAN - Echec du démarrage du timer\r\n");
    return;
  }
}

void recvCallback(SERVICE_LORA_RECEIVE_T *data) {
  if (data->BufferSize > 0) {
    Serial.println("Données reçues par LoRaWAN !");
    for (int i = 0; i < data->BufferSize; i++) {
      Serial.printf("%x", data->Buffer[i]);
    }
    Serial.print("\r\n");
  }
}

void joinCallback(int32_t status) {
  Serial.printf("Statut de la connexion: %d\r\n", status);
}

void sendCallback(int32_t status) {
  if (status == 0) {
    Serial.println("Envoi réussi");
  } else {
    Serial.println("Echec de l'envoi");
  }
}