Olduvaï
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment :
LEGO Icons 10331 – Le martin-pêcheur
Voir le deal
35 €

Arduino, programmation, résilience et librairie Olduvaï

5 participants

Page 2 sur 2 Précédent  1, 2

Aller en bas

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Empty Re: Arduino, programmation, résilience et librairie Olduvaï

Message par tarsonis Lun 17 Avr 2023 - 14:54

Salut à tous,
Aujourd'hui on va parler horloge et conservation du temps, de pile, accu, batterie, d'optimisation du code et d'erreurs assez graves dans les notices techniques ainsi que la plupart des tutoriels d'internet clind'oeil

Je souhaitais évoquer ce module au détour d'un autre post, mais il me semble qu'il mérite son article à part entière.

Sommairement, j'ai besoin d'ajouter une horloge à certains de mes montages. A moins de conserver la carte Arduino alimentée en permanence, la moindre extinction fait perdre toute notion temporelle.
Pour le suivi et les logs de mon compteur geiger/dosimètre, il me faut à la fois la date et l'heure d'enregistrement. D'une manière générale, dans de nombreux montages touchant à la résilience, on peut être amené à vérifier l'heure et la date à un instant T (déclenchement nocturne, aux heures creuses, clôture, contrôle, poulailler, monitoring, etc.) et la préserver même en cas de panne.

C'est la tâche qui est proposée par les petits modules de type DS1307 pour une poignée d'euros. Le fonctionnement est "relativement" simple puisque cela utilise le protocole I2C -que l'on a déjà vu pour interagir avec les EEPROMs externes plus haut- et peut se faire avec des librairies disponibles un peu partout.
Cependant, il convient de détailler un peu l'utilisation car les notices techniques sont vraiment floues, voire trompeuses.

Le module

La plupart des modules DS1307 proposent en fait beaucoup plus de fonctions que la simple horloge. Ici le HW-111 permet d'avoir :

- Evidemment l'heure et la date via les broches I2C; on reconnaît SCL et SDA, en bleu. Le circuit intégré DS1307Z, en violet.
- Dans la zone verte on peut souder U1, le capteur de température DS18B20. On récupère le signal analogique sur la broche DS. Il sert en général de facteur correctif pour la déviation de l'heure selon la température. Mais on peut sans souci l'utiliser pour un autre usage.
- une mémoire externe EEPROM (en rouge) 24C32N de 32kb (donc 4ko), via les autres proches SDA et SCL (en orange). Voir un peu plus haut dans le topic pour plus de détails sur son fonctionnement.

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1104




Code
Au niveau du code, on peut faire extrêmement simple en utilisant une librairie ad hoc type uRTCLib. On n'a pas à se soucier de quoi que ce soit :

Code:
#include "Arduino.h"
#include "uRTCLib.h"

// uRTCLib rtc;
uRTCLib rtc(0x68);

void setup() {
  Serial.begin(9600);
  delay(3000); // wait for console opening

  URTCLIB_WIRE.begin();

  // Comment out below line once you set the date & time.
  // Following line sets the RTC with an explicit date & time
  // for example to set January 13 2022 at 12:56 you would call:
   //  rtc.set(0, 27, 10, 2, 7, 3, 23);
  // rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year)

}

void loop() {
  rtc.refresh();

  Serial.print(rtc.year());
  Serial.print(rtc.month());
  Serial.print(rtc.day());



  Serial.print(rtc.hour());
  Serial.print(rtc.minute());
  Serial.println(rtc.second());
  
  delay(1000);
}

Il y a plusieurs bons tutos à ce sujet :
https://arduino-france.site/rtc-arduino/
https://tutoduino.fr/blog-rtc/
et celui de l'exemple, très complet :
https://lastminuteengineers.com/ds1307-rtc-arduino-tutorial/

Soit on essaye de décortiquer le fonctionnement du module via Wire.h, on peut optimiser la consommation des ressources Arduino :

Code:
/**
 * Exemple de code de lecture et d'ajustement de l'heure avec un module RTC DS1307.
 * Compatible Arduino 0023 et Arduino 1.x (et supérieur).
 */

/* Dépendances */
#include <Wire.h>
#include "DS1307.h"


/* Rétro-compatibilité avec Arduino 1.x et antérieur
#if ARDUINO >= 100
#define Wire.write(x) Wire.write(x)
#define Wire.read() Wire.read()
#else
#define Wire.write(x) Wire.send(x)
#define Wire.read() Wire.receive()
#endif*/


/** Fonction de conversion BCD -> decimal */
byte bcd_to_decimal(byte bcd) {
  return (bcd / 16 * 10) + (bcd % 16);
}

/** Fonction de conversion decimal -> BCD */
byte decimal_to_bcd(byte decimal) {
  return (decimal / 10 * 16) + (decimal % 10);
}


/**
 * Fonction récupérant l'heure et la date courante à partir du module RTC.
 * Place les valeurs lues dans la structure passée en argument (par pointeur).
 * N.B. Retourne 1 si le module RTC est arrêté (plus de batterie, horloge arrêtée manuellement, etc.), 0 le reste du temps.
 */
byte read_current_DateHeure(DateHeure_t *DateHeure) {
  
  /* Début de la transaction I2C */
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write((byte) 0); // Lecture mémoire à l'adresse 0x00
  Wire.endTransmission(); // Fin de la transaction I2C
 
  /* Lit 7 octets depuis la mémoire du module RTC */
  Wire.requestFrom(DS1307_ADDRESS, (byte) 7);
  byte raw_secondes = Wire.read();
  DateHeure->secondes = bcd_to_decimal(raw_secondes);
  DateHeure->minutes = bcd_to_decimal(Wire.read());
  byte raw_heures = Wire.read();
  if (raw_heures & 64) { // Format 12h
    DateHeure->heures = bcd_to_decimal(raw_heures & 31);
    DateHeure->am_pm = raw_heures & 32;
  } else { // Format 24h
    DateHeure->heures = bcd_to_decimal(raw_heures & 63);
    DateHeure->am_pm = 0;
  }
  DateHeure->joursemaine = bcd_to_decimal(Wire.read());
  DateHeure->jour = bcd_to_decimal(Wire.read());
  DateHeure->mois = bcd_to_decimal(Wire.read());
  DateHeure->annee = bcd_to_decimal(Wire.read());
  
  /* Si le bit 7 des secondes == 1 : le module RTC est arrêté */
  return raw_secondes & 128;
}


/**
 * Fonction ajustant l'heure et la date courante du module RTC à partir des informations fournies.
 * N.B. Redémarre l'horloge du module RTC si nécessaire.
 */
 
void adjust_current_DateHeure(DateHeure_t *DateHeure) {
  
  /* Début de la transaction I2C */
  /*
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write((byte) 0); // Ecriture mémoire à l'adresse 0x00
  Wire.write(decimal_to_bcd(DateHeure->secondes) & 127); // CH = 0
  Wire.write(decimal_to_bcd(DateHeure->minutes));
  Wire.write(decimal_to_bcd(DateHeure->heures) & 63); // Mode 24h
  Wire.write(decimal_to_bcd(DateHeure->joursemaine));
  Wire.write(decimal_to_bcd(DateHeure->jour));
  Wire.write(decimal_to_bcd(DateHeure->mois));
  Wire.write(decimal_to_bcd(DateHeure->annee));
  Wire.endTransmission(); // Fin de transaction I2C*/
}


/** Fonction setup() */
void setup() {
  
  /* Initialise le port série */
  Serial.begin(9600);
  
  /* Initialise le port I2C */
  Wire.begin();
  
  /* Vérifie si le module RTC est initialisé */
  DateHeure_t now;
  if (read_current_DateHeure(&now)) {
   // Serial.println(F("L'horloge du module RTC n'est pas active !"));

  }
  /*
    // Reconfiguration avec une date et heure en dure (pour l'exemple)
    now.seconds = 0;
    now.minutes = 0;
    now.hours = 12; // 12h 0min 0sec
    now.is_pm = 0;
    now.day_of_week = 4;
    now.days = 1;
    now.months = 12;
    now.year = 16; // 1 dec 2016
    adjust_current_DateHeure(&now);
  }*/
}


/** Fonction loop() */
void loop() {
  //  Serial.println("Test");
  /* Lit la date et heure courante */
  DateHeure_t now;
  if (read_current_DateHeure(&now)) {
//    Serial.println(F("L'horloge du module RTC n'est pas active !"));
  }

  /* Affiche la date et heure courante */

  Serial.print(now.jour);

  Serial.print(now.mois);

  Serial.print(now.annee + 2000);

  Serial.print(now.heures);

   Serial.print(now.minutes);

  Serial.println(now.secondes);
  
  /* Rafraichissement une fois par seconde */
  delay(1000);
}

Source et tuto complet :
https://www.carnetdumaker.net/articles/utiliser-un-module-horloge-temps-reel-ds1307-avec-une-carte-arduino-genuino/

La différence entre les deux :

Le code tout fait utilise 5262 octets (16%) de l'espace de stockage de programmes. Les variables globales utilisent 431 octets (21%) de mémoire dynamique.
Le code optimisé utilise 4440 octets (13%) de l'espace de stockage de programmes. Les variables globales utilisent 404 octets (19%) de mémoire dynamique.

On économie presque 1ko de stockage (3%) et 27 octets de RAM (un peu moins de 2%). Cela peut paraître dérisoire, mais il s'agit ici juste d'ajouter une horloge au circuit, donc parmi tout le reste du code.


Je commence à modifier petit à petit mes codes pour remplacer l'écran LCD1602, vraiment encombrant et limité, par un Oled 128x64.
A nouveau, on peut procéder exactement de la même manière :

Soit avec un code "tout en un" avec une lib type Adafruit_SSD1306.

Code:
/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <Wire.h>
#include "DS1307.h"

#include "Arduino.h"
#include "uRTCLib.h"

// uRTCLib rtc;
uRTCLib rtc(0x68);

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);


#include <Wire.h>
#include "DS1307.h"






void setup() {

 Serial.begin(9600);
  delay(3000); // wait for console opening

  URTCLIB_WIRE.begin();

  /* Initialise le port série */
  
  /* Initialise le port I2C */
  Wire.begin();
  display.clearDisplay();
  display.println(String(rtc.year())+" " +(String(rtc.month()))+" "+String(rtc.day()));
  


 
}


/** Fonction loop() */
void loop() {
  rtc.refresh();


  delay(1000);
  String Horloge = "";


  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);
  // Display static text
 //display.println(Horloge);

display.println(String(rtc.hour())+"h " +(String(rtc.minute())+"m "+String(rtc.second())+"s"));
  
  display.display();
 
  delay(100);
}


Le croquis utilise 14362 octets (44%) de l'espace de stockage de programmes. Les variables globales utilisent 557 octets (27%) de mémoire dynamique

Ou utiliser des librairies un peu plus optimisées comme SSD1306Ascii :

Code:
/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <Wire.h>

#include "DS1307.h"


#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiWire oled;



/** Fonction de conversion BCD -> decimal */
byte bcd_to_decimal(byte bcd) {
  return (bcd / 16 * 10) + (bcd % 16);
}

/** Fonction de conversion decimal -> BCD */
byte decimal_to_bcd(byte decimal) {
  return (decimal / 10 * 16) + (decimal % 10);
}


/**
 * Fonction récupérant l'heure et la date courante à partir du module RTC.
 * Place les valeurs lues dans la structure passée en argument (par pointeur).
 * N.B. Retourne 1 si le module RTC est arrêté (plus de batterie, horloge arrêtée manuellement, etc.), 0 le reste du temps.
 */
byte read_current_DateHeure(DateHeure_t *DateHeure) {
  
  /* Début de la transaction I2C */
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write((byte) 0); // Lecture mémoire à l'adresse 0x00
  Wire.endTransmission(); // Fin de la transaction I2C
 
  /* Lit 7 octets depuis la mémoire du module RTC */
  Wire.requestFrom(DS1307_ADDRESS, (byte) 7);
  byte raw_secondes = Wire.read();
  DateHeure->secondes = bcd_to_decimal(raw_secondes);
  DateHeure->minutes = bcd_to_decimal(Wire.read());
  byte raw_heures = Wire.read();
  if (raw_heures & 64) { // Format 12h
    DateHeure->heures = bcd_to_decimal(raw_heures & 31);
    DateHeure->am_pm = raw_heures & 32;
  } else { // Format 24h
    DateHeure->heures = bcd_to_decimal(raw_heures & 63);
    DateHeure->am_pm = 0;
  }
  DateHeure->joursemaine = bcd_to_decimal(Wire.read());
  DateHeure->jour = bcd_to_decimal(Wire.read());
  DateHeure->mois = bcd_to_decimal(Wire.read());
  DateHeure->annee = bcd_to_decimal(Wire.read());
  
  /* Si le bit 7 des secondes == 1 : le module RTC est arrêté */
  return raw_secondes & 128;
}


void setup() {



  /* Initialise le port série */
  Serial.begin(9600);
  
  /* Initialise le port I2C */
  Wire.begin();

  
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  oled.setFont(Adafruit5x7);
  
  /* Vérifie si le module RTC est initialisé */
  DateHeure_t now;
 if (read_current_DateHeure(&now)) {
   http://Serial.println(F("L'horloge du module RTC n'est pas active !"));
  
  }
  



oled.clear();
  oled.print(String(now.annee)+" " +(String(now.mois))+" "+String(now.jour));
  
  
  delay(1000);
}


/** Fonction loop() */
void loop() {
  
  /* Lit la date et heure courante */
  DateHeure_t now;
  if (read_current_DateHeure(&now)) {
   // Serial.println(F("L'horloge du module RTC n'est pas active !"));
  }

  String Horloge = "";


 oled.setCursor(0, 0);
  oled.print(String(now.heures)+"h " +(String(now.minutes))+"m "+String(now.secondes)+"s");
  

  
  /* Rafraichissement une fois par seconde */
  delay(100);
}

Le fonctionnement est strictement identique, mais niveau ressources, Le croquis utilise 8270 octets (25%) de l'espace de stockage de programmes. Les variables globales utilisent 452 octets (22%) de mémoire dynamique.
On économise 6ko de mémoire de stockage Arduino (presque moitié moins) et 100 octets de RAM (20% en moins). Pour deux fonctions - l'heure et l'affichage- ça commence à être pas mal pour laisser de la place pour le reste du code.

Tests et sauvegarde :

Test avec affichage de la date sur un Oled, après deux semaines Arduino éteint.... ici on remarque le délai qu'il y a entre le brouillon et la publication clind'oeil


Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1087
puis de l'heure
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1088


Au niveau des problèmes de conception électronique, notices techniques et turoriels

Au démarrage du projet, le module avait fonctionné sans trop de soucis puis, au bout de quelques heures Arduino éteint, il perdait l'heure et rebootait sur la date d'initialisation. Bizarre, vu qu'il avait une pile CR2032 neuve, comme demandé sur la technote. Test de la tension de la pile : 2,65V. C'est bas, mais au dessus de la tension de rétention.
Puis, truc assez fou : en relançant l'Arduino, la tension aux bornes de la pile remonte à 4,2V !

Bon ben la notice est fausse :
Backup Supply Input for Any Standard 3V Lithium Cell or Other Energy Source.


Certains sur le net ont recréé le schéma à partir du circuit, effectivement....il y a bien un circuit de recharge :
https://www.codrey.com/arduino-projects/how-to-play-with-rtc-modules/
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Tiny-r10

Ce qui n'a évidemment rien à voir avec le schéma de la documentation fournie avec :
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1091

Du coup, la pile CR2023 n'a pas vraiment aimé la recharge et s'est mise en défaut rapidement, le module a perdu sa base de temps puis au rallumage cela a "rechargé" la pile pour lui faire remonter sa tension au dessus du seuil nécessaire.
J'ai lui quelques retours sur le forum Arduino dans lesquels la pile a carrément claqué.

Donc, lors de l'utilisation d'un DS1307 comme le mien (la quasi-totalité sur le marché), il ne faut surtout pas utiliser de pile mais un accumulateur, donc une LIR2032 (lithium ion rechargeable). Sans quoi, au mieux, le module est défectueux et ne garde pas la date ou, au pire, claque avec tous les risques de mettre une pile au lithium en recharge.

En gros, confusion usuelle entre pile, accumulateur et batterie qui s'est perdue dans la technote, les tutos et même tous les sites de vente en ligne.
Mon hypothèse reste que le circuit originel - type Adafruit, Seeed- était restreint à l'unique DS1307 sans les artifices autour, avec juste la pile reliée à VBatt, mais que les clones qui ont suivi proposaient la recharge... sans mettre à jour la notice technique.


Ici, plusieurs modèles, à part celle du bas (LIR, accumulateur), ce sont toutes des piles.
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1089

Notez à la 2e ligne à gauche la pile improprement nommée "Battery". En fait il y a plusieurs interprétations en français et en anglais. La batterie désigne à la base la mise en série d'éléments, qui peuvent être des piles (bien que ce soit rare), comme une batterie au plomb de voiture où l'on colle 6 accus en série.


Même ce qui ressemble à un accumulateur de sauvegarde de laptop est une pile BR2032 (au monofluoride polycarbone)

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1090


L'autre solution, si on souhaite utiliser une pile sans tout claquer est de simplement retirer D1 et R4. Retirer les parties rouges : D1 pour éviter la recharge de la pile, R4 pour éviter de drainer quelques µA à la pile, donc prolonge l'autonomie qui est théoriquement de plusieurs années.
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1105

Vue version avec l'accu de sauvegarde :
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1094

Voili voilou, c'est très simple à utiliser, avec de nombreuses fonctions.... mais il me paraissait important de relever ces quelques points dans le cadre de ce topic orienté résilience et frugalité clind'oeil

________________________________________________________
L'expérience est une lumière qui n'éclaire que ceux qu'elle a déjà brûlés. Cédric Dassas

Récapitulatif des projets électroniques - [Chroniques du Bunker de L'Apocalypse] - Projet Geiger - Culture ethnobotanique en France - 甩葱歌 - 古箏 - Distant Pulsar - Un Mauvais Fils - 25 Years of Zelda - Machinarium
tarsonis
tarsonis
Administrateur

Masculin Nombre de messages : 10770
Age : 38
Localisation : Grand Est
Loisirs : Trek, ethnobotanique, électronique DIY, nucléaire, médecine, post apo.
Date d'inscription : 21/05/2008

Revenir en haut Aller en bas

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Empty Re: Arduino, programmation, résilience et librairie Olduvaï

Message par tarsonis Jeu 30 Nov 2023 - 23:03

Salut à tous,
un court post pour mentionner les petits modules HC12 que l'on peut trouver dans certains kits. C'est toujours de l'UART, donc se pilote avec RxTx comme l'horloge et l'Oled au dessus.
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1148

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1149

Il s'agit des modules émetteur-récepteur sur 433-473MHz sur 100 canaux. Alors il y a des tonnes de subtilités, perso je voulais évoquer la principale : la transmission d'infos (texte, fichiers, etc) sur une distance un peu plus grande que les modules Wifi et Bluetooth, mais en gardant l'ensemble très simple et bon marché. Avec le bon mode (FU4), on peut taper dans les 1,8km. Avec le mode par défaut (FU3), j'ai atteint 450m en environnement urbain assez dense sans vue directe (plusieurs murs en béton). Je pense qu'il est possible de tirer plus loin avec une meilleure antenne que celle fournie avec le module, quitte à perdre en discrétion.

D'abord deux précautions :
- l'émission sur cette bande radio est limitée à 10mW en France en usage libre (voir LPD433). Il faut bien faire attention à ce que vous faites avec et limiter cette puissance avec le bridage ad hoc, ou alors avoir une licence Radioamateur.
Datasheet à cet effet.
https://statics3.seeedstudio.com/assets/file/bazaar/product/HC-12_english_datasheets.pdf

- Ces modules sont normalement des émetteurs 100mW par défaut, mais on trouve pas mal de sujets où les utilisateurs n'arrivaient pas au dessus de 10mW, même avec les bonnes commandes. Cela pousse à croire que soit il y a un bridage avec les modèles récents, soit les copies n'atteignent pas les specs de base. Exemple ici :
http://paulfjujo.free.fr/_Transceivers_HC12/Test_Modules_HC12_transceivers.htm

Les modules que j'ai sont issus d'un ancien kit, donc dans le doute, j'aurais tendance à acheter d'occaz.
J'ai eu des résultats parfois moins bons avant de remarquer que cela dépendait de la powerbank qui alimentait l'émetteur. Le montage est à la fois sensible à la tension et au courant max dispo. Il faut donc absolument 5V (pas du 4,90V dégueu qui crépite) et brancher un condensateur 100µF en parallèle pour les salves d'envoi qui pompent 100mA en longue distance FU4.
Les modules sont bidirectionnels, chacun peut devenir un émetteur et un récepteur.

Afin de tester rapidement les distances selon différents environnements, j'ai codé un truc vite fait pour donner un pourcentage de réception :

Code:
#include <SoftwareSerial.h>
SoftwareSerial HC12(2, 3); // HC-12 TX Pin, HC-12 RX Pin

byte t=0;

void setup() {
  Serial.begin(9600);            
  HC12.begin(9600);          
}

void loop() {
 
  
    HC12.write(t);
    t++;
    if (t==100)
    {

      t=1;
    }
    delay(10);
  
}

En gros, on émet la valeur de t toutes les 10ms. Donc on a 100 paquets par seconde. Il ne faudrait pas descendre en dessous de 5ms par salve car le module a besoin de quelques ms entre chaque salve. Et dans le cadre FU4 avec émission longue distance, les specs parlent d'à peu près 2s entre deux salves.

Balise émettrice, résumée à un nano, un module HC et un condo.

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1150

Côté récepteur, pour ne pas me balader avec un moniteur série sur ordi, j'ai sorti l'affichage sur l'écran Oled. Si on choppe toute la salve, on affiche 100%, s'il en manque, on affiche le nombre de paquets reçus, donc un pourcentage.
Si on perd le signal plus d'une seconde, on affiche le temps en ms depuis lequel on n'a plus rien reçu.
Ce dernier point permet de s'orienter en environnement urbain très dense (escaliers, portes blindées, etc), où bouger le montage de quelques cm améliore beaucoup la réception, ce que l'on voit avec le nombre de ms qui reste bas. On peut ainsi voir à quelques dizaines de cm près où on perd le signal.

C'est codé avec le c*l comme certains diraient, et mériterait beaucoup d'optimisation, mais ça reste suffisant pour tester la qualité du signal.

Code:


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

SoftwareSerial HC12(2, 3); // HC-12 TX Pin, HC-12 RX Pin

byte recep=0;
byte stat=0;
long temps;

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {          
  HC12.begin(9600);      
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
 //   Serial.println(F("SSD1306 allocation failed"));
//    for(;;);
  }
  temps=millis();
  delay(2000);
  display.clearDisplay();

  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);

  display.println("Waiting DATA");
  display.display();
  display.clearDisplay();
}

void loop() {
  

    while (HC12.available()) {
      recep=(byte)HC12.read();
      temps=millis();
      
      if ((recep<stat)|| (recep==100))// on a loupé le paquet 100 ou on le reçoit;
      { stat++;
        display.clearDisplay();
        display.setCursor(0, 10);
        display.print(String(stat)+"%");
        display.display();
        stat=0;
      }
      if (recep<100)
      {
        stat++;
      }
  }

  if ((millis()-temps)>1000)
  {
         display.clearDisplay();
   display.setCursor(0, 40);
  
    display.print(String(millis()-temps)+"ms");
    display.display();
  }
}

Le récepteur, avec un Uno (les autres nano sont sur les projets du petit...), un HC12 et un Oled.

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1151


En tests, dans un parking sur plusieurs niveaux béton.
Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1152

Avec 4 étages de différence, commence à perdre le signal.

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1153

On pousse la balise de quelques dizaines de cm et on perd quasiment tous les paquets.

Arduino, programmation, résilience et librairie Olduvaï - Page 2 Capt1154

Bon évidemment, il est sans doute possible d'améliorer la réception en diminuant le taux de transfert et en limitant le nombre de salves. Peut être qu'avec quelques octets toutes les 100ms ça passerait mieux.



Sinon, le programme bien connu ci-dessous permet de faire communiquer via le moniteur série deux ordinateurs et chacun leur Arduino-HC12 avec ce programme. C'est à dire que tout caractère entré sur le PC1 sera affiché sur le moniteur du PC2 et réciproquement. En gros, on a un système de chat sur 433MHz clind'oeil

Code:
#include <SoftwareSerial.h>

SoftwareSerial HC12(2, 3); // HC-12 TX Pin, HC-12 RX Pin

void setup() {
  Serial.begin(9600);            
  HC12.begin(9600);          
}

void loop() {
  while (HC12.available()) {
    Serial.println((int)HC12.read());
  }
  while (Serial.available()) {
    HC12.write(Serial.read());
  }
}


On peut évidemment imaginer bien plus avec des possibilité des transferts de fichiers sur carte SD vers un ordi voire une balise web.

Perso, je creusais pour le projet Compteur Geiger sur Arduino, avec une balise autonomie extérieure qui émet périodiquement ses stats.

Et sur un projet avec 4 modules qui permettraient de faire un chaînage type A <-> B <->C <-> D avec des trucs simples type "Ici A, qui m'entend ?", "B Reçu, parlez", etc.. et un D qui va tout collationner et le retour jusqu'à A.

En gros, un protocole primitif, mais de quoi porter plusieurs km avec quelques balises.
Je manque de temps pour avancer dans tous les brouillons, mais espère que ça suscitera de l'intérêt parmi les bidouilleurs. fumeur

________________________________________________________
L'expérience est une lumière qui n'éclaire que ceux qu'elle a déjà brûlés. Cédric Dassas

Récapitulatif des projets électroniques - [Chroniques du Bunker de L'Apocalypse] - Projet Geiger - Culture ethnobotanique en France - 甩葱歌 - 古箏 - Distant Pulsar - Un Mauvais Fils - 25 Years of Zelda - Machinarium
tarsonis
tarsonis
Administrateur

Masculin Nombre de messages : 10770
Age : 38
Localisation : Grand Est
Loisirs : Trek, ethnobotanique, électronique DIY, nucléaire, médecine, post apo.
Date d'inscription : 21/05/2008

Canis Lupus et victor81 aiment ce message

Revenir en haut Aller en bas

Page 2 sur 2 Précédent  1, 2

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum