Balances connectées via Lora: programme et traitement des données:

De HackerLab
Aller à : navigation, rechercher

La programmation

Le programme pour intégrer 1 balance, une sonde DHT22 et une sonde DS18b20

le programme principal
  1 /*
  2 ceci est basé sur le programme master de sylvain
  3 le module est en mode OTAA
  4 il est configuré pour émettre avec 20dbm
  5 
  6 la lecture des capteur est demandée une fois au setup pour les balances puis dans le loop selon uint32_t appTxDutyCycle = 15000;
  7 elle appelée avec prepareTxFrame( appPort );
  8 puis les données sont envoyées avec LoRaWAN.send();
  9 le format est l'octet dont le nombre est non limité à priori
 10 des exemples sont disponibles via l'IDE arduino quand on a installé la bibliothèque de la carte cubcell HTCC-AB02 plus 
 11 
 12 la balance et les sondes
 13 largement commenté dans static void prepareTxFrame( uint8_t port )
 14 
 15 alimentation des capteurs
 16 on utilise la sortie VEXT : HIGH pas de tension     LOW tension sur VEXT
 17  */
 18 #include "LoRaWan_APP.h" //https://github.com/mcci-catena/arduino-lorawan/
 19 #include <Arduino.h>
 20 #include <Adafruit_Sensor.h>
 21 
 22 //les température humidité
 23 #include <DHT.h>
 24 #include <DHT_U.h>
 25 #define DHTPIN GPIO5    // Changer le pin sur lequel est branché le DHT
 26 #define DHTTYPE DHT22 
 27 DHT dht(DHTPIN, DHTTYPE); 
 28 
 29 float humidite;
 30 float temperature;
 31 
 32 //les températures sonde DS18B20    EXterne au boitier
 33 #include "OneWire.h"
 34 #include "DallasTemperature.h"
 35 OneWire oneWire(ADC3);
 36 DallasTemperature ds(&oneWire);
 37 
 38 
 39 //la balance.
 40 //le module LORA a une sortie Vext sur laquelle on peut mettre l'alimentation des capteurs
 41 //on met Vext à LOW pour alimenter et à HIGH pour couper l'alimentation
 42 //par rapport au master de Sylvain, j'ai donc effacé la gestion de l'alimentation via une PIN spécialement dédiée
 43 #include "HX711.h"
 44 HX711 Hx711_N1;  
 45 
 46 #define PIN_HX711_N1_DATA_OUT GPIO6 // connexion au DATA
 47 #define PIN_HX711_N1_SCK_AND_POWER_DOWN GPIO7// connexion à l'horloge SCK
 48 
 49 float offset_HX711_N1_ChannelA;// pour Patrick et Sébastien on utilisera que le canal A+-
 50 
 51 const unsigned int Weight_sensitivity = 4 ;
 52 
 53 //  Header byte = 1st Byte transmitted int he Sigox Tram ( SIGFOX #01 )
 54 // Bit 7 = Sigfog Debug Mode, =1 for SIGFOX DEBUG MODE
 55 // Bit 6 = Solar Panel Luminosity, measured during software excution ( =0 Voltage solar panel < Voltage Battery, =1 > 
 56 // Bit 5 = FUll Charging Battery status , measured during software excution
 57 // Bit 4 = Charging on going, measured during software excution
 58 // Bit 0 to 3 = Software version : 0000 = Debug Software, then 0001 = V1 ...
 59 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 60 
 61 // DEBUG_MODE  mettre à zéro en mode normal pour moins consommer*************************
 62 boolean DEBUG_MODE =1; // =1 or debug , then ALLOW BLINKING LED and statement on Serial Monitor throught SERIAL RX/TX UART0  
 63 /*
 64 //ceci est la partie qui règle les conditions d'émission radio du module. J'ai augmenté à 20db la puissance
 65 //////////////////////////////////////Radio.SetTxConfig  dans le SETUP////////////
 66 #define TX_OUTPUT_POWER                             20 ///14        // pour 20dBm
 67 
 68 #define LORA_BANDWIDTH                              0         // [0: 125 kHz,
 69                                                               //  1: 250 kHz,
 70                                                               //  2: 500 kHz,
 71                                                               //  3: Reserved]
 72 #define LORA_SPREADING_FACTOR                       9         // [SF7..SF12]
 73 #define LORA_CODINGRATE                             1         // [1: 4/5,
 74                                                               //  2: 4/6,
 75                                                               //  3: 4/7,
 76                                                               //  4: 4/8]
 77 #define LORA_PREAMBLE_LENGTH                      8         // Same for Tx and Rx
 78 #define LORA_SYMBOL_TIMEOUT                         0         // Symbols
 79 #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
 80 #define LORA_IQ_INVERSION_ON                        false
 81 /////////////////////////////////////////////////////////////////////////////////
 82 */
 83 /* OTAA para c'est ce OTAA paramêtre qui est utilisé */
 84 
 85 uint8_t appEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 86 
 87 /*décommenter les modules à programmer */
 88 
 89 //lora-01
 90 //uint8_t devEui[] = { 0x70, 0xB3, xxxxxxx }; 
 91 //uint8_t appKey[] = { 0x43, 0x26, xxxxxxxx };
 92 
 93 
 94 
 95 /* ABP para*/
 96 uint8_t nwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 };
 97 uint8_t appSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 };
 98 uint32_t devAddr =  ( uint32_t )0x260B37FC;
 99 
100 /*LoraWan channelsmask, default channels 0-7*/ 
101 uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };
102 
103 /*LoraWan region, select in arduino IDE tools*/
104 LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;//jjjjjjj essai git
105 
106 /*LoraWan Class, Class A and Class C are supported*/
107 DeviceClass_t  loraWanClass = LORAWAN_CLASS;
108 
109 /*the application data transmission duty cycle.  value in [ms].*//////////////////////////////////////
110 uint32_t appTxDutyCycle = 60000;  //15000 donc 15sec;  900000 donc 15mn
111 
112 /*OTAA or ABP*/
113 bool overTheAirActivation = LORAWAN_NETMODE;
114 
115 /*ADR enable*/
116 bool loraWanAdr = LORAWAN_ADR;
117 
118 /* set LORAWAN_Net_Reserve ON, the node could save the network info to flash, when node reset not need to join again */
119 bool keepNet = LORAWAN_NET_RESERVE;
120 
121 /* Indicates if the node is sending confirmed or unconfirmed messages */
122 bool isTxConfirmed = LORAWAN_UPLINKMODE;
123 
124 /* Application port */
125 uint8_t appPort = 2;
126 /*!
127 * Number of trials to transmit the frame, if the LoRaMAC layer did not
128 * receive an acknowledgment. The MAC performs a datarate adaptation,
129 * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
130 * to the following table:
131 *
132 * Transmission nb | Data Rate
133 * ----------------|-----------
134 * 1 (first)       | DR
135 * 2               | DR
136 * 3               | max(DR-1,0)
137 * 4               | max(DR-1,0)
138 * 5               | max(DR-2,0)
139 * 6               | max(DR-2,0)
140 * 7               | max(DR-3,0)
141 * 8               | max(DR-3,0)
142 *
143 * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
144 * the datarate, in case the LoRaMAC layer did not receive an acknowledgment
145 */
146 uint8_t confirmedNbTrials = 4;
147 
148 //*****************************
149 static void prepareTxFrame( uint8_t port )
150 {
151   pinMode(Vext, OUTPUT);
152   digitalWrite(Vext, LOW);//LOW pour alimenter la sortie Vext 3V3 pour les capteur. Sur l'établi, j'alimente pour l'instant en continu pour les essais
153   
154   if (DEBUG_MODE) { 
155                         Serial.println("CODE prepareTxFrame s'exécute  ");
156                     }
157   
158   //on traite d'abord la tension batterie
159   uint16_t batteryVoltage = getBatteryVoltage();
160   batteryVoltage = batteryVoltage;//  la tension est mesurée en miliVolts
161   
162   if (DEBUG_MODE) {
163                       Serial.print("tension batterie en mili voltes ");
164                       Serial.println(batteryVoltage);
165                   }
166   /*
167   température sur sur node red on fait le calcul inverse
168 
169   var temp_octet0 = msg.payload.uplink_message.decoded_payload.bytes[2];
170   var temp_octet1 = msg.payload.uplink_message.decoded_payload.bytes[3];
171   var temp = ((temp_octet0 * 256 + temp_octet1)) / 2 -35;
172   var newMsg = { payload: temp };
173   return newMsg;
174 
175   on reçoit le payload en HEX
176   on multiplie le poids fort (octet 0) par 256 et on ajoute le poids faible (octet 1) 
177   qui n'a pas besoin d'être converti puisque l'HEX est égal au DEC
178   **************************************
179   humidité sur node red
180 
181   var hum_octet0 = msg.payload.uplink_message.decoded_payload.bytes[4];
182   var hum_octet1 = msg.payload.uplink_message.decoded_payload.bytes[5];
183   var hum = (hum_octet0 * 256 + hum_octet1) / 2;
184   var newMsg = { payload: hum };
185   return newMsg;
186   **************************************
187   1ère balance sur node red
188 
189   var balance_octet0 = msg.payload.uplink_message.decoded_payload.bytes[6];
190   var balance_octet1 = msg.payload.uplink_message.decoded_payload.bytes[7];
191   var balance = (balance_octet0 * 256 + balance_octet1) * 11.6;  
192 
193   var newMsg = { payload: balance };
194   return newMsg;
195 
196   */
197   // Reading temperature or humidity takes about 250 milliseconds!
198   // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
199   
200   
201   Serial.println("DHTxx test!");
202 
203   delay(1000);
204   dht.begin(); 
205   
206   delay(1000);//pour laisser le temps de montée de la sonde
207   float h = dht.readHumidity();  
208   delay(1000);
209   // Read temperature as Celsius
210   float t = dht.readTemperature();
211   int8_t  t_byte = (t + 35 )*2;      //  à mieux commenter
212   uint8_t h_byte = h*2;              // à mieux commenter
213 
214   if (DEBUG_MODE) { 
215                       Serial.print("Temperature: "); 
216                       Serial.print(t);
217                       Serial.print(" *C lora #03: ");
218                       Serial.print(t_byte,HEX);
219                       Serial.print(" Byte   ");
220                       Serial.print("Humidity : "); 
221                       Serial.print(h);
222                       Serial.print(" %\t lora #04: ");
223                       Serial.print(h_byte,HEX);
224                       Serial.println(" Byte   ");
225                   }
226 
227  //sonde dc18b20 en externe******************************
228   
229   Serial.println("ds18b20 test!");
230 
231   delay(1000);
232   ds.begin();          // sonde activée
233 
234   delay(1000);
235   ds.requestTemperatures();
236   int tDs = ds.getTempCByIndex(0);
237   int8_t  tDs_byte = (tDs + 35 )*2;
238 
239   if (DEBUG_MODE){
240         Serial.print(tDs);
241         Serial.println( " C");
242         Serial.print(tDs_byte,HEX);
243         Serial.println(" Byte   ");
244 
245   }
246 
247   //les balances*******************************************************
248   
249     
250   float Sample_weight;
251   
252   Hx711_N1.begin(PIN_HX711_N1_DATA_OUT,PIN_HX711_N1_SCK_AND_POWER_DOWN,64 );
253   Sample_weight = Hx711_N1.get_units();                                          // For nothing library problem...
254   Sample_weight = (offset_HX711_N1_ChannelA - Hx711_N1.get_units())/256*Weight_sensitivity;
255 
256   if (Sample_weight < 0) { 
257       Sample_weight =0; 
258       }
259   else { 
260       if (Sample_weight > 65535) { 
261           Sample_weight = 65535; 
262           }
263       }
264 
265   unsigned int Weight_HX711_N1_Channel_A = Sample_weight;
266 
267   if (DEBUG_MODE) {  
268                       Serial.print("Weight N1 Channel A : ");
269                       Serial.print(Weight_HX711_N1_Channel_A,DEC);
270                       Serial.print(" "); 
271                       Serial.print(Weight_HX711_N1_Channel_A,HEX);
272                       Serial.print(" "); 
273                       Serial.print(Weight_HX711_N1_Channel_A,BIN);
274                       Serial.print(" "); 
275                       Serial.println();
276                   }
277 
278 
279 
280   //en miliVolts
281 
282   //appData[0] = (uint8_t)(batteryVoltage >> 8);//décalage de 8 bit vers la droite, 
283   //4803  donne 0001001011000011 sur 16bit donc reste les 8 1ers bits 00010010  soit 12 hex
284   //Serial.println(appData[4]);
285   
286   //appData[1] = (uint8_t)batteryVoltage;
287   //4803  donne 0001001011000011 donc si uint_8  on prend donc 8bit de droite 11000011 soit C3 hex
288   // quand on concatène 12C3 hex dans un convertisseur hexa vers décimal, cela donne 4803 mV au décodage de la trame LORA
289   //Serial.println(appData[5]);
290 
291   //calcul pour la température
292   //sur lorawan on obtient 00 74 hex
293   //on concatène 00 et 74 , on convertit hexa vers décimal et on obtient 116 décimal
294   //on reprend la formule de Sylvain  t_byte = (t + 35 )*2  donc partie entière de t=116/2 moins 35 degrés soit 23 degrés
295 
296   //calcul pour l'humidité
297   //sur lorawan on obtient 00 7F hex
298   //on concatène 00 et 7F , on convertit hexa vers décimal et on obtient 127 décimal
299   //on reprend la formule de Sylvain h_byte = h*2 donc partie entière de h=127/2 soit 63%
300 
301   //calcul pour la pesée 
302   //sur lorawan on obtient 04 9B hex  pour une donnée de 1179 correspondant à un poids de 13800gr
303   //ou 1C E0 pour 7392  correspondant à 85700gr
304   //le rapport entre 85700gr et 7392 est un multiplicateur de 11,6
305   //quand on multiplie par 11,6 une mesure convertie en décimal, on obtient le poids réel en grammes
306 
307   appDataSize = 10;// nombre total d'octets de la trame envoyée
308   //et à changer selon le nombre de balances et capteurs
309 
310   appData[0] = (uint8_t)(batteryVoltage>>8);
311   appData[1] = (uint8_t)batteryVoltage;
312 
313 
314   appData[2] = (uint8_t)(t_byte>>8);
315   appData[3] = (uint8_t)t_byte;
316 
317 
318   appData[4] = (uint8_t)(h_byte>>8);
319   appData[5] = (uint8_t)h_byte;
320 
321   appData[6] = (uint8_t)(tDs_byte>>8);
322   appData[7] = (uint8_t)tDs_byte;
323 
324 
325   appData[8] = (uint8_t)(Weight_HX711_N1_Channel_A>>8);
326   appData[9] = (uint8_t)Weight_HX711_N1_Channel_A;
327 
328   digitalWrite(Vext, HIGH);//HIGH une fois les mesures faites, couper alimentation sortie Vext 3V3 par économie de mA
329 
330 }
331 
332 void setup()
333 {
334 
335   Serial.begin(9600);
336 
337   pinMode(Vext, OUTPUT);
338   digitalWrite(Vext, LOW);//alimentation de la sonde est valide pour permettre initialisation de la sonde
339   delay(1000);//on laisse un temps de montée pour la sonde
340 
341 
342   if (DEBUG_MODE) {   
343                         Serial.print("SETUP DONE");
344                         Serial.println();
345                         
346                 }
347   Serial.print("cycle d'envoi des données en ms  ");
348   Serial.print(appTxDutyCycle);
349   Serial.println();
350   Serial.print("LORA master 1bal dht22 et ds18b20.cpp  ");
351   Serial.println();
352 
353   #if(AT_SUPPORT)//ne pas oublier ce module???
354   enableAt();
355   #endif
356   deviceState = DEVICE_STATE_INIT;
357   LoRaWAN.ifskipjoin();
358   
359   
360   
361   //initialisation et détection des balances
362 
363   //////////dans le SETUP on calcule une bonne fois l'offset en mesurant la balance à VIDE après un RESET
364 
365   //pinMode(PIN_HX711_N1_DATA_OUT, OUTPUT); // connexion au DATA
366   //pinMode(PIN_HX711_N1_SCK_AND_POWER_DOWN, OUTPUT);// connexion à l'horloge SCK
367 
368   delay(1000);
369 
370   float Sample_weight;
371 
372   Hx711_N1.begin(PIN_HX711_N1_DATA_OUT,PIN_HX711_N1_SCK_AND_POWER_DOWN,64 );
373   Sample_weight = Hx711_N1.get_units();
374   offset_HX711_N1_ChannelA = Hx711_N1.get_units();
375 
376   if (DEBUG_MODE) {  
377                           Serial.print("Offset N1 Channel A : ");
378                           Serial.print(offset_HX711_N1_ChannelA);
379                           Serial.println();
380                           Serial.flush() ;
381                   }
382 
383   ////////////////////////////////////////////////////////////////////////////////////
384   /*
385    paramêtres de puissance émission à 20db PW maxi 110mA via constructeur voir #define TX_OUTPUT_POWER 
386  
387   
388   Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
389                                    LORA_SPREADING_FACTOR, LORA_CODINGRATE,
390                                    LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
391                                    true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); 
392                                    
393   /////////////////////////////////////////////////////////////////////////////////////
394   */
395   Serial.print("attente 10 secondes pour mise en place d'un poids éventuel   ");
396   delay(10000);
397   Serial.println();
398   Serial.flush() ;
399 
400   prepareTxFrame( appPort );
401 
402   digitalWrite(Vext, HIGH);
403 }
404 
405 void loop()
406 {
407 
408 switch( deviceState )
409   {
410     case DEVICE_STATE_INIT:
411     {
412 #if(LORAWAN_DEVEUI_AUTO)
413       LoRaWAN.generateDeveuiByChipID();
414 #endif
415 #if(AT_SUPPORT)
416       getDevParam();
417 #endif
418       printDevParam();
419       LoRaWAN.init(loraWanClass,loraWanRegion);
420       deviceState = DEVICE_STATE_JOIN;
421       break;
422     }
423     case DEVICE_STATE_JOIN:
424     {
425       LoRaWAN.join();
426       break;
427     }
428     case DEVICE_STATE_SEND:
429     {
430       prepareTxFrame( appPort );
431       LoRaWAN.send();
432       
433       deviceState = DEVICE_STATE_CYCLE;
434       break;
435     }
436     case DEVICE_STATE_CYCLE:
437     {
438       // Schedule next packet transmission
439       txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
440       LoRaWAN.cycle(txDutyCycleTime);
441       deviceState = DEVICE_STATE_SLEEP;
442       break;
443     }
444     case DEVICE_STATE_SLEEP:
445     {
446       LoRaWAN.sleep();
447       break;
448     }
449     default:
450     {
451       deviceState = DEVICE_STATE_INIT;
452       break;
453     }
454   }
455 
456 
457 
458   
459 }
le fichier platmormio.ini
 1 ; PlatformIO Project Configuration File
 2 ;
 3 ;   Build options: build flags, source filter
 4 ;   Upload options: custom upload port, speed and extra flags
 5 ;   Library options: dependencies, extra library storages
 6 ;   Advanced options: extra scripting
 7 ;
 8 ; Please visit documentation for the other options and examples
 9 ; https://docs.platformio.org/page/projectconf.html
10 
11 [env:cubecell_board_plus]
12 platform = asrmicro650x
13 board = cubecell_board_plus
14 framework = arduino
15 
16 build_flags = -std=c++11
17 monitor_speed = 9600
18 lib_deps = 
19 	adafruit/DHT sensor library@^1.4.4
20 	bogde/HX711@^0.7.5
21 board_build.arduino.lorawan.region = EU868
22 board_build.arduino.lorawan.class = CLASS_A
23 board_build.arduino.lorawan.netmode = OTAA
24 board_build.arduino.lorawan.adr = ON
25 board_build.arduino.lorawan.uplinkmode = UNCONFIRMED
26 board_build.arduino.lorawan.net_reserve = ON
27 board_build.arduino.lorawan.at_support = ON
28 board_build.arduino.lorawan.rgb = DEACTIVE
29 board_build.arduino.lorawan.debug_level = NONE