Balances connectées via Sigfox pour peser les ruches:
Sommaire
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
La platine se programme avec une interface FTDI en positionnant le cavalier sur 3,3V
Les convertisseurs analogiques / digitaux HX711:
Exemple de câblage avec des jauges de contrainte de 50kg observées dans les pèses personnesLes 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.
Le module chargeur solaire
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
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)
Programmation du microcontrôleur
Les outils de programmation
Nous utilisons l'éditeur Visual Studio Code
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
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
- 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