Balances connectées via Sigfox pour peser les ruches:

De HackerLab
Aller à : navigation, rechercher

Objectifs du projet

Les électroniciens amateurs du Hacker Lab' se sont lancés au printemps 2021, le défis de construire des balances pour peser les ruches de la MLC et observer l'évolution à distance de leur poids. Le poids indique quelle est la production de miel et l'importance en nombre de la colonie.

Notre groupe a réussi la construction de plusieurs systèmes qui ont fonctionné l'été 2021 et 2022. L'apiculteur peut donc, sur son smartphone contrôler le poids de ses ruches pour savoir s'il est temps de se déplacer sur le rucher et inspecter les hausses afin de commencer la récolte.

Description globale

Le système de pesée est constitué d'une centrale, de 4 balances et de capteurs externes de température et d'humidité.

La centrale est composée d'un boîtier contenant

  • une platine à trous métallisés pour y souder les composants électroniques et les connecteurs des balances et des capteurs de température et d'humidité. Ces derniers, selon leur emplacement, peuvent mesurer avec précision la météo au niveau du rucher ou bien être placés au sein de la colonie pour observer la température de la grappe d'abeilles en hiver par exemple pour voir son niveau de santé.
  • Le cœur du système est un microprocesseur ATMEL 328 sur une platine pro mini Arduino programmé en langage C++ pour lui permettre d'analyser les données des capteurs de poids, de température, d'humidité et de tension de batterie.
  • 4 convertisseurs analogiques / digitaux HX711 captent les mesures des jauges de contrainte des balances. Un module radio transmet les données sur un réseau publique. Un panneau solaire et son chargeur miniature garde la batterie à un bon niveau.
  • 1 sonde de température / humidité DHT22 qui peut être laissée libre hors de la centrale ou glissée dans la ruche au sein de la colonie.
  • 1 module chargeur solaire pour entretenir la charge d'un accumulateur 3,4V LIPO
  • 1 petit panneau solaire
  • 1 module radio Sigfox.
  • 1 antenne externe 868Mhz.
  • 4 balances "type pèse personne" en verre trempé.

Les composants

le microcontrôleur: platine arduino Pro-Mini

Microcontrôleur arduino pro mini.jpg
Promini schema gpio.png
Arduino promini schema.png

La platine se programme avec une interface FTDI en positionnant le cavalier sur 3,3V

Interface FTDI FT232RL USB.jpg

Les convertisseurs analogiques / digitaux HX711:

Exemple de câblage avec des jauges de contrainte de 50kg observées dans les pèses personnes
Convertisseur HX711 et son cablage.jpg

Les balances:

Nous avons opté pour des pèses personne vendus chez Décathlon à 12€.

Ces balances électroniques ont 4 jauges. On a enlevé son électronique et relié ses jauges aux HX711 via des câbles 4 brins.

Les câbles transportent une information analogique qui correspond aux fluctuations de résistance des jauges.

Pour l'instant, les câbles ne semblent pas être sensibles à des perturbations électromagnétiques qui pourraient fausser les mesures.

Pese-personne-scale-100-verre.jpg

Le module chargeur solaire

Chargeur solaire.jpg

Le module radio de transmission sur le réseau Sigfox que l'on trouve ici

Bien choisir la fréquence européenne de 868Mhz.

Le module est vendu avec un abonnement Sigfox d'un an pour une capacité de 140 messages par jour

Vous pouvez l'activer à tout moment pour commencer la période d'abonnement

Module radio sigfox et l'antenne.jpg

La sonde de température / humidité DHT22

Elle montée ici sur une petite platine qui intègre une résistance entre DATA et le positif. Elle n'a besoin de rien d'autre.

Si l'on veut l'intégrer dans une ruche, il serait préférable de la glisser par exemple dans une mini cagette à reine pour la protéger (non expérimenté encore)

Sonde DHT22 sur sa platine.jpg

Programmation du microcontrôleur

Les outils de programmation

Nous utilisons l'éditeur Visual Studio Code

Accueil visual studio code.png

L'édition, la compilation et la visualisation de la sortie USB du PC se fait avec l'intégration de l’extension Platmormio

L'extension est intégrée à partir de Visual Studio Code via le menu

Exemple de capture d'écran de l'éditeur platformio

PlatformIO.png

La logique de fonctionnement du programme

Pour ne pas consommer durant la mise en sommeil du microcontrôleur, le périphériques: la sonde DHT22, les convertisseurs A/D HX711, sont alimentés par des ports GPIO mis à 1 ou 0.

Le module radio consomme trop pour être alimenté par les GPIO, il est donc mis en sommeil avec ses propres fonctionnalités.

L'alimentation générale du microcontrôleur se fait par la broche VCC qui doit être à 3V3. Les GPIO fonctionnent aussi sous 3V3.

La tension batterie est mesurée en utilisant les bornes de A0 et A1

Extrait des commentaires du code
//on met une résistance CMS de 47K entre A0 et A1 coté supérieur du processeur

//on met une résistance CMS de 10K entre A0 et le plan de masse en parallele à un condensateur de 1,1 nano soudés l'un sur l'autre

Modifications à faire sur la platine arduino pro mini:

  • Les composants CMS sont minuscules. La résistance de 47K peut se souder sans problème entre A0 et A1 au dessus du contrôleur
  • la résistance de 10K entre A0 et la masse se soude en dessous de la platine. Rayer le vernis du plan de masse à proximité et étamer le cuivre qui apparaît. souder le CMS.
  • par dessus le CMS de 10K, poser le condensateur CMS de 1n1 environ et le souder en parallèle avec la résistance de 10K.
  • dessouder le régulateur et la LED qui le suit pour encore moins consommer.
  • il faut savoir que la broche VCC de la platine est directement câblée sur le VCC du contrôleur et se trouve après le régulateur. Comme on utilise un accumulateur de 3V3, le contrôleur ne risque rien et le régulateur ne sert plus à rien ainsi que la LED.
  • on n'utilise pas l'entrée RAW située avant le régulateur. C'est pour cette raison que l'on peut supprimer ce régulateur.

Le code source

Il est suffisamment commenté pour pouvoir comprendre les fonctionnalités et faire le câblage.

Il se place dans le sous répertoire src du projet que vous aurez créé avec platformio
  1 #include <Arduino.h>
  2 #include <avr/sleep.h>
  3 #include <avr/power.h>
  4 
  5 //consignes pour programmation du minipro arduino qui n'a pas de schip USB via TX RX pour baisser la consommation
  6 //utiliser un FTDI externe qui adaptera le TX RX à l'USB
  7 //utiliser la position 3V3
  8 //déconnecter le TX RX de sigfox pour ne pas perturber le TX RX du promini
  9 //mettre la valeur **** boolean AUTODETECT_HX711_N34 = 0**** ; à UN pour observer sur le terminal les valeurs données par les capteurs
 10 //mettre la valeur ****const unsigned int MAX_COUNTER_POWER_DOWN_WAKE_UP = 116 ;**** à 2 ou 3 pour ne pas attendre un cycle de 15mn entre chaque mesure
 11 //ne rien mettre sur les balances avant chaque RESET et voir l'évolution des valeurs selon les poids posés
 12 //si tout semble bon, remettre les valeurs à ZERO pour ne pas débugger et à 116 pour avoir un cycle de 15mn entre chque envoi de trame sigfox
 13 
 14 
 15 #include <DHT_U.h>
 16 #include "DHT.h"
 17 #define DHT_POWER_SUPPLY_PIN 12 // l'alimentation de la DHT22 se fait via un GPIO qui sera mis à zéro pour couper l'alimentation
 18 #define DHTPIN A3// connexion au DATA de la DHT22
 19 #define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321  utilisation d'une DHT22 sur platine ayant déjà la résistance entre le DATA et le PLUS
 20 
 21 DHT dht(DHTPIN, DHTTYPE);  //initailisation de la DHT22
 22 
 23 #include "HX711.h"
 24 HX711 Hx711_N1;   
 25 HX711 Hx711_N2;
 26 HX711 Hx711_N3;
 27 HX711 Hx711_N4;
 28 
 29 #define POWER_PIN_HX711_N1_DATA_OUT 3//chaque HX711 a une alimentation commune sur un même GPIO mis à zéro pour couper l'alimentation
 30 #define PIN_HX711_N1_DATA_OUT 4 // connexion auDATA
 31 #define PIN_HX711_N1_SCK_AND_POWER_DOWN 8// connexion à l'horloge SCK
 32 
 33 float offset_HX711_N1_ChannelA;// pour Patrick et Sébastien on utilisera que le canal A+-
 34 float offset_HX711_N1_ChannelB;//Sylvain utilise les 2 canaux pour mettre une barre de pesée par canal
 35 
 36 boolean AUTODETECT_HX711_N2 = 1 ; // 0 = No 2nd HX711, autodetection of a 2nd HX711 is in Setup sequence will toggle to 1 if detected 
 37 
 38 #define POWER_PIN_HX711_N2_DATA_OUT 3
 39 #define PIN_HX711_N2_DATA_OUT 5
 40 #define PIN_HX711_N2_SCK_AND_POWER_DOWN 9
 41 
 42 float offset_HX711_N2_ChannelA;
 43 float offset_HX711_N2_ChannelB;
 44 
 45 
 46 boolean AUTODETECT_HX711_N34 = 0 ; // 0 = No 3rd&4th  HX711, autodetection of a 3rd & 4th  HX711 is in Setup sequence will toggle to 1 if detected 
 47 
 48 #define POWER_PIN_HX711_N3_DATA_OUT 3
 49 #define PIN_HX711_N3_DATA_OUT 6
 50 #define PIN_HX711_N3_SCK_AND_POWER_DOWN 10
 51 
 52 
 53 #define POWER_PIN_HX711_N4_DATA_OUT 3
 54 #define PIN_HX711_N4_DATA_OUT 7
 55 #define PIN_HX711_N4_SCK_AND_POWER_DOWN 11
 56 
 57 float offset_HX711_N3_ChannelA;
 58 float offset_HX711_N4_ChannelA;
 59 
 60 #include <avr/interrupt.h> 
 61 //mesure de la tension batterie appliquée sur VCC
 62 //on met une résistance CMS de 47K entre A0 et A1 coté supérieur du processeur
 63 //on met une résistance CMS de 10K entre A0 et le plan de masse en parallele à un condensateur de 1,1 nano soudés l'un sur l'autre
 64 #define MICROPROCESOR_VOLTAGE_CAN_MEASUREMENT A0 
 65 #define MICROPROCESOR_VOLTAGE_CAN_PULL_UP_PIN A1
 66 
 67 #define SOLAR_PANEL_VOLTAGE_CAN_MEASUREMENT A2//dispositif en prévision de la mesure du panneau solaire pour déterminer les cycles jour nuit mais non cablé
 68 
 69 #define RESET_SIGFOX_MODULE 2//on utilise le RESET du module sigfox
 70 
 71 const unsigned int Weight_sensitivity = 4 ;
 72 
 73 const unsigned int MAX_COUNTER_POWER_DOWN_WAKE_UP = 116 ; // MUST BE >=2 , 116 for 15mnsNumber of WATCH DOG before starting the main software  
 74 unsigned int counter_power_down_wake_up; // 
 75 
 76 //  Header byte = 1st Byte transmitted int he Sigox Tram ( SIGFOX #01 )
 77 // Bit 7 = Sigfog Debug Mode, =1 for SIGFOX DEBUG MODE
 78 // Bit 6 = Solar Panel Luminosity, measured during software excution ( =0 Voltage solar panel < Voltage Battery, =1 > 
 79 // Bit 5 = FUll Charging Battery status , measured during software excution
 80 // Bit 4 = Charging on going, measured during software excution
 81 // Bit 0 to 3 = Software version : 0000 = Debug Software, then 0001 = V1 ...
 82 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 83 byte header_byte = B00000000;
 84 
 85 boolean DEBUG_MODE =  0; // =1 for debbug , then ALLOW BLINKING LED and statement on Serial Monitor throught SERIAL RX/TX UART0  
 86 
 87 
 88 // put your setup code here, to run once:
 89 void setup() {
 90 
 91     pinMode(RESET_SIGFOX_MODULE,OUTPUT);
 92 
 93     digitalWrite(RESET_SIGFOX_MODULE,LOW);
 94     delay (100);
 95     digitalWrite(RESET_SIGFOX_MODULE,HIGH);
 96     // delay (100);
 97 
 98 
 99 Serial.begin(9600);
100 
101 if (DEBUG_MODE) {   
102                         Serial.print("SETUP DONE");
103                         Serial.println();
104                         pinMode (LED_BUILTIN,OUTPUT); 
105                         digitalWrite(LED_BUILTIN,HIGH);
106                         delay(2000);
107                         digitalWrite(LED_BUILTIN,LOW);
108                         // delay(5000);
109                 }
110 
111 
112 pinMode(POWER_PIN_HX711_N1_DATA_OUT,OUTPUT);
113 digitalWrite(POWER_PIN_HX711_N1_DATA_OUT,HIGH);
114 
115 pinMode(POWER_PIN_HX711_N2_DATA_OUT,OUTPUT);
116 digitalWrite(POWER_PIN_HX711_N2_DATA_OUT,HIGH);
117 
118 pinMode(POWER_PIN_HX711_N3_DATA_OUT,OUTPUT);
119 digitalWrite(POWER_PIN_HX711_N3_DATA_OUT,HIGH);
120 
121 pinMode(POWER_PIN_HX711_N4_DATA_OUT,OUTPUT);
122 digitalWrite(POWER_PIN_HX711_N4_DATA_OUT,HIGH);
123 
124 delay(1000);
125 
126 float Sample_weight;
127 
128 Hx711_N1.begin(PIN_HX711_N1_DATA_OUT,PIN_HX711_N1_SCK_AND_POWER_DOWN,64 );
129 Sample_weight = Hx711_N1.get_units();
130 offset_HX711_N1_ChannelA = Hx711_N1.get_units();
131 
132 Hx711_N1.begin(PIN_HX711_N1_DATA_OUT,PIN_HX711_N1_SCK_AND_POWER_DOWN,32 );
133 Sample_weight = Hx711_N1.get_units();
134 offset_HX711_N1_ChannelB = Hx711_N1.get_units();
135 
136 Hx711_N2.begin(PIN_HX711_N2_DATA_OUT,PIN_HX711_N2_SCK_AND_POWER_DOWN,64 );
137 Sample_weight = Hx711_N2.get_units();
138 offset_HX711_N2_ChannelA = Hx711_N2.get_units();
139 
140 Hx711_N2.begin(PIN_HX711_N2_DATA_OUT,PIN_HX711_N2_SCK_AND_POWER_DOWN,32 );
141 Sample_weight = Hx711_N2.get_units();
142 offset_HX711_N2_ChannelB = Hx711_N2.get_units();
143 
144 if ((offset_HX711_N2_ChannelA!=0) & (offset_HX711_N2_ChannelA!=0)) { AUTODETECT_HX711_N2 = 1 ;}
145 
146 
147 
148 Hx711_N3.begin(PIN_HX711_N3_DATA_OUT,PIN_HX711_N3_SCK_AND_POWER_DOWN,64 );
149 Sample_weight = Hx711_N3.get_units();
150 offset_HX711_N3_ChannelA = Hx711_N3.get_units();
151 
152 Hx711_N4.begin(PIN_HX711_N4_DATA_OUT,PIN_HX711_N4_SCK_AND_POWER_DOWN,64 );
153 Sample_weight = Hx711_N4.get_units();
154 offset_HX711_N4_ChannelA = Hx711_N4.get_units();
155 
156 if ((offset_HX711_N3_ChannelA!=0) & (offset_HX711_N4_ChannelA!=0)) { AUTODETECT_HX711_N34 = 1 ;}
157 
158 
159 
160 
161 if (DEBUG_MODE) {  
162                         Serial.print("Offset N1 Channel A : ");
163                         Serial.print(offset_HX711_N1_ChannelA);
164 
165                         Serial.print(" Offset N1 Channel B : ");
166                         Serial.print(offset_HX711_N1_ChannelB);
167 
168                         Serial.println();
169                         
170 
171                         
172                         Serial.print("Offset N2 Channel A : ");
173                         Serial.print(offset_HX711_N2_ChannelA);
174 
175                         Serial.print(" Offset N2 Channel B : ");
176                         Serial.print(offset_HX711_N2_ChannelB);
177 
178                         Serial.print(" AUTO DETECT N2 : ");
179                         Serial.print(AUTODETECT_HX711_N2);
180 
181                         Serial.println();              
182 
183                         
184                         
185                         Serial.print("Offset N3 Channel A : ");
186                         Serial.print(offset_HX711_N3_ChannelA);
187 
188                         Serial.print(" Offset N4 Channel A : ");
189                         Serial.print(offset_HX711_N4_ChannelA);
190 
191                         Serial.print(" AUTO DETECT N3&N4 : ");
192                         Serial.print(AUTODETECT_HX711_N34);
193 
194                         Serial.println();
195                         
196                         Serial.flush() ;
197 
198 
199 
200                 }
201 
202 //1er message pour voir bon fonctionnement sigfox à l'allumage système
203 Serial.println("AT$SF=12345678");
204 
205 
206 
207 counter_power_down_wake_up = MAX_COUNTER_POWER_DOWN_WAKE_UP;
208 
209 
210 
211 
212 // Message AT popur Sigfox - 
213 Serial.println("AT");  // Test after wake up from sleep mode
214 Serial.flush() ;
215 delay(100);
216 
217 // char Sigfox_message[34] = {0};  // 26 or 34 bytes max ( 1 or 2 HX711)
218 
219 //sprintf(Sigfox_message,"AT$SF=%02x%02x%02x%02x%04x%04x",header_byte,power_supply_voltage_Arduino,t_byte,h_byte,Weight_HX711_N1_Channel_A,Weight_HX711_N1_Channel_B);
220 //Serial.println(Sigfox_message);
221 // Serial.flush() ;
222 Serial.println("AT$SF=SETUP DONE");
223 
224 Serial.println("AT$P=2"); // SLeep mode
225 Serial.flush() ;
226 
227 
228 // Save Power by writing all Digital IO to LOW EXCLUDING SPECIAL PORT
229 
230 //pinMode(0,INPUT);
231 //pinMode(1,INPUT);
232 
233 for(int i=2; i<19; i++) {
234     if (i != RESET_SIGFOX_MODULE) {
235         pinMode(i,OUTPUT);
236         digitalWrite(i,LOW);
237         }
238     //else {
239     //    digitalWrite(i,HIGH);
240     //    }
241     }
242 
243   digitalWrite(RESET_SIGFOX_MODULE,HIGH);
244 
245 
246 
247 
248 //SETUP WATCHDOG TIMER
249 WDTCSR = B00011000; // (24 = B00011000);//change enable and WDE − also resets
250 WDTCSR = B00100001; // (33 =  B00100001);//prescalers only − get rid of the WDE and WDCE bit
251 WDTCSR = (1<<6);
252 
253 // SETUP WATCHDOG TIMER 
254 //WDTCSR = (24); // Change enable and WDE - Also resets
255 //WDTCSR = (33); /// prescalers only -get ride of the WDE and WDCE bit
256 //WDTCSR |=(1<<6);// enable interrupt modue
257 
258 // SET UP CAN ANALOGU REFERENCE @ 1,1V INTERNAL
259 analogReference(INTERNAL);
260 
261 
262 // DISABLE ADC ( ADEN bit set to 0 in ADCSRA REGISTER ) 
263 // ADCSRA = 0;
264 ADCSRA &= B01111111;
265 
266 
267 //noInterrupts (); // timed sequence follows
268 cli();  // Interrupts impossible
269 
270 // ENABLE SLEEP 
271 //set_sleep_mode (SLEEP_MODE_PWR_DOWN);
272 SMCR |= (1<<2); //SET UP  SLEEP MODE = Power Down Mode
273 //sleep_enable();
274 SMCR |= 1; //Enable Sleep
275 
276                                       
277 //interrupts (); // guarantees next instruction executed
278 sei();
279 
280 }
281 
282 
283 
284 
285 // ------------------------------------------------------------------------------------------------------------------------------------------------------
286 
287 
288 
289 
290 // put your main code here, to run repeatedly:
291 void loop() {
292 
293 
294 
295 if (DEBUG_MODE) { 
296                         Serial.begin(9600);
297                         digitalWrite(LED_BUILTIN,HIGH);
298                         delay(100);
299                         digitalWrite(LED_BUILTIN,LOW);
300                         // delay(500);
301 
302 
303                         Serial.print("LOOP CNT = ");
304                         Serial.println (counter_power_down_wake_up);
305                         Serial.flush() ;
306                 }
307 
308 
309 
310 if (counter_power_down_wake_up == 0) {
311     
312     counter_power_down_wake_up  = MAX_COUNTER_POWER_DOWN_WAKE_UP;
313     
314     // PUT HERE THE CODE TO BE EXECUTED 
315 
316     Serial.begin(9600);
317 
318    
319     pinMode(RESET_SIGFOX_MODULE,OUTPUT);
320 
321     digitalWrite(RESET_SIGFOX_MODULE,LOW);
322     delay (100);
323     digitalWrite(RESET_SIGFOX_MODULE,HIGH);
324     // delay (100);
325 
326 
327     if (DEBUG_MODE) { 
328                         Serial.println("CODE TO BE EXCUTED");
329                     }
330     
331     
332     pinMode(POWER_PIN_HX711_N1_DATA_OUT,OUTPUT);
333     digitalWrite(POWER_PIN_HX711_N1_DATA_OUT,HIGH);
334     
335     if (AUTODETECT_HX711_N2) {
336         pinMode(POWER_PIN_HX711_N2_DATA_OUT,OUTPUT);
337         digitalWrite(POWER_PIN_HX711_N2_DATA_OUT,HIGH);                   
338     }
339 
340     if (AUTODETECT_HX711_N34) {
341         pinMode(POWER_PIN_HX711_N3_DATA_OUT,OUTPUT);
342         digitalWrite(POWER_PIN_HX711_N3_DATA_OUT,HIGH); 
343 
344         pinMode(POWER_PIN_HX711_N4_DATA_OUT,OUTPUT);
345         digitalWrite(POWER_PIN_HX711_N4_DATA_OUT,HIGH);     
346 
347     }
348 
349 
350     
351     pinMode(DHT_POWER_SUPPLY_PIN,OUTPUT);
352     digitalWrite(DHT_POWER_SUPPLY_PIN,HIGH);
353 
354     pinMode(MICROPROCESOR_VOLTAGE_CAN_PULL_UP_PIN,OUTPUT);
355     digitalWrite(MICROPROCESOR_VOLTAGE_CAN_PULL_UP_PIN,HIGH);
356     pinMode(MICROPROCESOR_VOLTAGE_CAN_MEASUREMENT,INPUT); 
357     pinMode(SOLAR_PANEL_VOLTAGE_CAN_MEASUREMENT,INPUT);
358 
359 
360     //delay(2000);
361 
362 
363 
364 
365     dht.begin();
366     delay(1000);    // MADATORY 1000 or put code in between
367 
368 
369 
370   
371     
372     
373     // Reading temperature or humidity takes about 250 milliseconds!
374     // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
375     float h = dht.readHumidity();
376 
377     // Read temperature as Celsius
378     float t = dht.readTemperature();
379 
380 
381     digitalWrite(DHT_POWER_SUPPLY_PIN,LOW);
382 
383     
384 
385     int8_t  t_byte = (t + 35 )*2;
386     uint8_t h_byte = h*2;
387 
388     if (DEBUG_MODE) { 
389                         Serial.print("Temperature: "); 
390 
391                         Serial.print(t);
392                         Serial.print(" *C SIGFOX #03: ");
393                         Serial.print(t_byte,HEX);
394                         Serial.print(" Byte   ");
395 
396                         Serial.print("Humidity : "); 
397                         Serial.print(h);
398                         Serial.print(" %\t SIGFOX #04: ");
399                         Serial.print(h_byte,HEX);
400                         Serial.println(" Byte   ");
401                     }
402 
403 
404     // analogReference(INTERNAL);  dans set up 
405 
406     ADCSRA |= B10000000;
407     
408     int  test = analogRead(MICROPROCESOR_VOLTAGE_CAN_MEASUREMENT); // Une mesure pour rien pour eviter les erreurs ( 3F delta contaté), a voir si mettre une fois dans le setup
409     
410     uint8_t power_supply_voltage_Arduino= (analogRead(MICROPROCESOR_VOLTAGE_CAN_MEASUREMENT)>>2);
411 
412     test = analogRead(SOLAR_PANEL_VOLTAGE_CAN_MEASUREMENT); // Une mesure pour rien pour eviter les erreurs ( 3F delta contaté), a voir si mettre une fois dans le setup
413     
414     uint8_t power_supply_voltage_Solar_panel= (analogRead(SOLAR_PANEL_VOLTAGE_CAN_MEASUREMENT)>>2);
415     
416     digitalWrite(MICROPROCESOR_VOLTAGE_CAN_PULL_UP_PIN,LOW); 
417     
418     ADCSRA &= B01111111;
419 
420 
421 
422 
423     if (DEBUG_MODE) { 
424                         Serial.print("ADMUX: ");
425                         Serial.print(ADMUX,BIN);
426 
427                         Serial.print("  ARDUINO VOLTAGE : ");
428                         Serial.print(power_supply_voltage_Arduino,BIN);
429 
430 
431                         Serial.print("  SIGFOX #02: ");
432                         Serial.print(power_supply_voltage_Arduino,HEX);
433 
434                         Serial.print("  SOLAR PANEL VOLTAGE: ");
435                         Serial.print(power_supply_voltage_Solar_panel,BIN);
436 
437                         Serial.println();
438 
439                     }
440 
441 
442 
443     float Sample_weight;
444     
445     Hx711_N1.begin(PIN_HX711_N1_DATA_OUT,PIN_HX711_N1_SCK_AND_POWER_DOWN,64 );
446     Sample_weight = Hx711_N1.get_units();                                          // For nothing library problem...
447     Sample_weight = (offset_HX711_N1_ChannelA - Hx711_N1.get_units())/256*Weight_sensitivity;
448 
449     if (Sample_weight < 0) { 
450         Sample_weight =0; 
451         }
452     else { 
453        if (Sample_weight > 65535) { 
454            Sample_weight = 65535; 
455            }
456        }
457 
458     unsigned int Weight_HX711_N1_Channel_A = Sample_weight;
459  
460     Hx711_N1.begin(PIN_HX711_N1_DATA_OUT,PIN_HX711_N1_SCK_AND_POWER_DOWN,32 );
461     Sample_weight = Hx711_N1.get_units();                                          // For nothing library problem...
462     Sample_weight = (offset_HX711_N1_ChannelB - Hx711_N1.get_units())/128*Weight_sensitivity;
463 
464     if (Sample_weight < 0) {
465         Sample_weight =0; 
466         }
467         else { 
468         if (Sample_weight > 65535) { 
469             Sample_weight = 65535; 
470             }
471         }
472     
473     unsigned int Weight_HX711_N1_Channel_B = Sample_weight;
474 
475 
476     
477 
478     unsigned int Weight_HX711_N2_Channel_A;
479     unsigned int Weight_HX711_N2_Channel_B;
480 
481     if (AUTODETECT_HX711_N2) {
482                                 Hx711_N2.begin(PIN_HX711_N2_DATA_OUT,PIN_HX711_N2_SCK_AND_POWER_DOWN,64 );
483                                 Sample_weight = Hx711_N2.get_units();                                          // For nothing library problem...
484                                 Sample_weight = (offset_HX711_N2_ChannelA - Hx711_N2.get_units())/256*Weight_sensitivity;
485 
486                                 if (Sample_weight < 0) { 
487                                     Sample_weight =0; 
488                                     }
489                                 else { 
490                                     if (Sample_weight > 65535) { 
491                                                             Sample_weight = 65535; 
492                                                             }
493                                     }
494 
495                                 Weight_HX711_N2_Channel_A = Sample_weight;
496 
497                                 Hx711_N2.begin(PIN_HX711_N2_DATA_OUT,PIN_HX711_N2_SCK_AND_POWER_DOWN,32 );
498                                 Sample_weight = Hx711_N2.get_units();                                          // For nothing library problem...
499                                 Sample_weight = (offset_HX711_N2_ChannelB - Hx711_N2.get_units())/128*Weight_sensitivity;
500 
501                                 if (Sample_weight < 0) {
502                                     Sample_weight =0; 
503                                     }
504                                     else { 
505                                     if (Sample_weight > 65535) { 
506                                                                 Sample_weight = 65535; 
507                                                                 }
508                                     }
509                                 
510                                 Weight_HX711_N2_Channel_B = Sample_weight;
511                                 
512                                 
513                             }
514 
515     
516 
517 
518 
519 
520     unsigned int Weight_HX711_N3_Channel_A;
521     unsigned int Weight_HX711_N4_Channel_A;
522 
523 
524     if (AUTODETECT_HX711_N34) {
525                                 Hx711_N3.begin(PIN_HX711_N3_DATA_OUT,PIN_HX711_N3_SCK_AND_POWER_DOWN,64 );
526                                 Sample_weight = Hx711_N3.get_units();                                          // For nothing library problem...
527                                 Sample_weight = (offset_HX711_N3_ChannelA - Hx711_N3.get_units())/256*Weight_sensitivity;
528 
529                                 if (Sample_weight < 0) { 
530                                     Sample_weight =0; 
531                                     }
532                                 else { 
533                                     if (Sample_weight > 65535) { 
534                                                             Sample_weight = 65535; 
535                                                             }
536                                     }
537 
538                                 Weight_HX711_N3_Channel_A = Sample_weight;
539 
540                                 
541 
542                                 Hx711_N4.begin(PIN_HX711_N4_DATA_OUT,PIN_HX711_N4_SCK_AND_POWER_DOWN,64 );
543                                 Sample_weight = Hx711_N4.get_units();                                          // For nothing library problem...
544                                 Sample_weight = (offset_HX711_N4_ChannelA - Hx711_N4.get_units())/256*Weight_sensitivity;
545 
546                                 if (Sample_weight < 0) {
547                                     Sample_weight =0; 
548                                     }
549                                     else { 
550                                     if (Sample_weight > 65535) { 
551                                                                 Sample_weight = 65535; 
552                                                                 }
553                                     }
554                                 
555                                 Weight_HX711_N4_Channel_A = Sample_weight;
556 
557                                 digitalWrite(POWER_PIN_HX711_N3_DATA_OUT,LOW);
558                                 digitalWrite(POWER_PIN_HX711_N4_DATA_OUT,LOW);
559 
560                             }
561 
562 
563     digitalWrite(POWER_PIN_HX711_N1_DATA_OUT,LOW);
564        if (AUTODETECT_HX711_N2) { digitalWrite(POWER_PIN_HX711_N2_DATA_OUT,LOW); }
565 
566 
567     if (DEBUG_MODE) {  
568                         Serial.print("Weight N1 Channel A : ");
569    
570                         Serial.print(Weight_HX711_N1_Channel_A,DEC);
571                         Serial.print(" "); 
572                         Serial.print(Weight_HX711_N1_Channel_A,HEX);
573                         Serial.print(" "); 
574                         Serial.print(Weight_HX711_N1_Channel_A,BIN);
575                         Serial.print(" "); 
576 
577                         Serial.print("Weight N1 Channel B : ");
578 
579                         Serial.print(Weight_HX711_N1_Channel_B,DEC);
580                         Serial.print(" "); 
581                         Serial.print(Weight_HX711_N1_Channel_B,HEX);
582                         Serial.print(" "); 
583                         Serial.print(Weight_HX711_N1_Channel_B,BIN);
584                         Serial.print(" ");
585    
586                         Serial.println();
587 
588                         if (AUTODETECT_HX711_N2) {
589                                                     Serial.print("Weight N2 Channel A : ");
590    
591                                                     Serial.print(Weight_HX711_N2_Channel_A,DEC);
592                                                     Serial.print(" "); 
593                                                     Serial.print(Weight_HX711_N2_Channel_A,HEX);
594                                                     Serial.print(" "); 
595                                                     Serial.print(Weight_HX711_N2_Channel_A,BIN);
596                                                     Serial.print(" "); 
597 
598                                                     Serial.print("Weight N2 Channel B : ");
599 
600                                                     Serial.print(Weight_HX711_N2_Channel_B,DEC);
601                                                     Serial.print(" "); 
602                                                     Serial.print(Weight_HX711_N2_Channel_B,HEX);
603                                                     Serial.print(" "); 
604                                                     Serial.print(Weight_HX711_N2_Channel_B,BIN);
605                                                     Serial.print(" ");
606                             
607                                                     Serial.println();
608 
609                                                     }
610 
611                         if (AUTODETECT_HX711_N34) {
612                                                     Serial.print("Weight N3 Channel A : ");
613    
614                                                     Serial.print(Weight_HX711_N3_Channel_A,DEC);
615                                                     Serial.print(" "); 
616                                                     Serial.print(Weight_HX711_N3_Channel_A,HEX);
617                                                     Serial.print(" "); 
618                                                     Serial.print(Weight_HX711_N3_Channel_A,BIN);
619                                                     Serial.print(" "); 
620 
621                                                     Serial.print("Weight N4 Channel A : ");
622 
623                                                     Serial.print(Weight_HX711_N4_Channel_A,DEC);
624                                                     Serial.print(" "); 
625                                                     Serial.print(Weight_HX711_N4_Channel_A,HEX);
626                                                     Serial.print(" "); 
627                                                     Serial.print(Weight_HX711_N4_Channel_A,BIN);
628                                                     Serial.print(" ");
629                             
630                                                     Serial.println();
631 
632                                                     }
633 
634 
635                     }
636 
637 
638 
639     
640 
641 
642 // Message AT popur Sigfox - 
643 Serial.println("AT");  // Test after wake up from sleep mode 
644 Serial.flush() ;
645 delay(100);
646 char Sigfox_message[34] = {0};  // 26 or 34 bytes max ( 1 or 2 HX711)
647 
648 
649 if (AUTODETECT_HX711_N34) {
650                         sprintf(Sigfox_message,"AT$SF=%02x%02x%02x%02x%04x%04x%04x%04x",header_byte,power_supply_voltage_Arduino,t_byte,h_byte,Weight_HX711_N1_Channel_A,Weight_HX711_N2_Channel_A,Weight_HX711_N3_Channel_A,Weight_HX711_N4_Channel_A);
651                         }
652                         else {
653 
654 
655                         if (AUTODETECT_HX711_N2) {
656                             sprintf(Sigfox_message,"AT$SF=%02x%02x%02x%02x%04x%04x%04x%04x",header_byte,power_supply_voltage_Arduino,t_byte,h_byte,Weight_HX711_N1_Channel_A,Weight_HX711_N1_Channel_B,Weight_HX711_N2_Channel_A,Weight_HX711_N2_Channel_B);
657                             }
658 
659                             else{
660                                 sprintf(Sigfox_message,"AT$SF=%02x%02x%02x%02x%04x%04x",header_byte,power_supply_voltage_Arduino,t_byte,h_byte,Weight_HX711_N1_Channel_A,Weight_HX711_N1_Channel_B);
661                                 }
662                         }
663 
664 
665 Serial.println(Sigfox_message);
666 Serial.flush() ;
667 
668 Serial.println("AT$P=2");   // SLeep mode
669 Serial.flush() ;
670 
671 
672 }   
673 
674 else {   
675 // Decrementaiton counter WDT
676 counter_power_down_wake_up  =  counter_power_down_wake_up-1 ;
677 
678 }
679 
680 
681 
682 
683 
684 // Save Power by writing all Digital IO to LOW EXCLUDING SPECIAL PORT
685 
686 //pinMode(0,INPUT);
687 
688 //pinMode(1,INPUT);
689 
690 
691 for(int i=2; i<19; i++) {
692     if (i != RESET_SIGFOX_MODULE) {
693         pinMode(i,OUTPUT);
694         digitalWrite(i,LOW);
695         }
696     //else {
697     //    digitalWrite(i,HIGH);
698     //    }
699     }
700 
701 // EXEPTION POWER DOWN PIN
702 
703 /////Hx711_N1.power_down();                                          // put the HX711 ADC in sleep mode
704 /////if (CONNECTION_HX711_N2 !=0) { Hx711_N2.power_down();           // put the HX711 ADC in sleep mode  
705 /////}
706 
707 
708 // Brown-out Detector DISABLE , − this must be called right before the __asm__ sleep instruction
709 MCUCR = bit (BODS) | bit (BODSE)  ; // | bit(PUD) ;  // Do not forget to diseable ALL IO Pull up by >Turn PUD bit in the MCUCR // TBCHECK ???
710 MCUCR = bit (BODS);
711 // MCUCR |=(3<<5); // Set both BODS and BODSE  at the same time
712 // MCUCR = (MCUCR & ~(1 <<5)) | (1<<6); // then set the BODS bit and clear the BODSE at the same time
713         
714 //sleep_cpu (); // sleep within 3 clock cycles of above
715 __asm__ __volatile__("sleep");
716 
717 
718 }
719 
720 
721 
722 
723 
724 
725 
726 
727 
728 //needed for the digital input interrupt
729 //void digitalInterrupt() {
730 // }
731 
732 
733 // watchdog interrupt
734 //DON'T FORGET THIS!  Needed for the watch dog timer.  This is called after a watch dog timer timeout - this is the interrupt function called after waking up
735 ISR(WDT_vect) {
736 
737 if (DEBUG_MODE) {      
738                     Serial.println("ISR_WDT VECTOR");
739                     Serial.flush() ;
740                 }
741 }

Le fichier platformio.ini

Il est important car il donne tous les éléments au compilateur pour fonctionner: type de microcontrôleur, librairies à utiliser

Il faut vraiment se plonger dans platformio pour exploiter le sujet à fond.
 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:pro8MHzatmega328]
12 
13 [env:nanoatmega328]
14 
15 platform = atmelavr
16 board = pro8MHzatmega328
17 ;board = nanoatmega328
18 framework = arduino
19 build_flags = -std=c++11
20 monitor_speed = 9600
21 ;upload_speed = 9600
22 lib_deps = 
23 	adafruit/DHT sensor library@^1.4.3
24 	bogde/HX711@^0.7.5

Les consignes de programmation et d'utilisation du système

  • Extrait du code source
//consignes pour programmation du minipro arduino qui n'a pas de schip USB via TX RX pour baisser la consommation

//utiliser un FTDI externe qui adaptera le TX RX à l'USB

//utiliser la position 3V3

//déconnecter le TX RX de sigfox pour ne pas perturber le TX RX du promini

//mettre la valeur **** boolean AUTODETECT_HX711_N34 = 0**** ; à UN pour observer sur le terminal les valeurs données par les capteurs

//mettre la valeur ****const unsigned int MAX_COUNTER_POWER_DOWN_WAKE_UP = 116 ;**** à 2 ou 3 pour ne pas attendre un cycle de 15mn entre chaque mesure

//ne rien mettre sur les balances avant chaque RESET et voir l'évolution des valeurs selon les poids posés

//si tout semble bon, remettre les valeurs à ZERO pour ne pas débugger et à 116 pour avoir un cycle de 15mn entre chque envoi de trame sigfox
Pour compléter les commentaires,
  • il faut savoir que l'arduino pro-mini possède qu'un seul duo TX RX pour transmettre et recevoir des informations. Le module radio Sigfox utilise TX RX. Avant de programmer avec le FTDI, il faut déconnecter physiquement le TX RX du module Sygfox.
  • le FTDI doit utiliser la tension 3,3V via son cavalier de sélection 5V ou 3V3
  • pour observer ce qui se passe durant le déroulement du programme, il faut envoyer des informations de débogage.
    • Il ne faut pas brancher encore le TX RX du module radio
    • il faut mettre zéro sur la ligne boolean DEBUG_MODE = 0; // =1 for debbug ,
    • il faut mettre 3 sur la ligne const unsigned int MAX_COUNTER_POWER_DOWN_WAKE_UP = 116 ; // MUST BE >=2
  • le système s'initialise au moment de sa mise sous tension. Il calcule sa tare, c'est à dire qu'il garde en mémoire la valeur à vide des balances. Il ne faut donc pas poser de poids au moment de l'initialisation.
  • quelques secondes plus tard, le système est prêt à recevoir un poids. Toutes les mesures apparaissent sur le terminal de platformio.
  • si tout est conforme,
    • on enlève les poids,
    • on débranche le FTDI,
    • on reconnecte le TX RX du module radio
    • on branche l'alimentation autonome du système