Sonde température + Horloge/Chronométre

Portrait de Walter

Bonjour,
Bien que projet, soit un bien grand mots, pour mon petit montage, c'est je pense le meilleur endroit pour le poster.

Il s'agit donc d'un montage pour afficher la température ambiante, ainsi qu'une horloge(hh:mm) ou un chronomètre.
En fonction du mode, la température et l'heure/chrono est affiché alternativement toutes les 5s.

Il y a donc un afficheur composé de 4 afficheur 7 segments, une horloge temps réel, 3 boutons, une sonde dht11.
Le premier bouton permet de passer entre les 4 modes (°C/horloge, °C/chrono, changer heures, changer minutes).
Le deuxième bouton permet de démarrer le chrono, d'incrémenter les heures, d'incrémenter les minute suivant le mode.
Le troisième bouton permet de décrémenter les heures ou les minutes suivant le mode.

Le schéma:
chronos_bb.png

Portrait de Ortalain

Intéressant Walter.

Portrait de Anonyme

Bonjour à quoi servent les cellules RC sur les BP ?

Puis j'ai essayé de compiler le code et je ne comprends pas pourquoi il y a au moins une dizaine de problèmes

  • #include <ds3231.h> pose problème il faut remplacer cette ligne par #include <DS3231.h>
  • les structures "  struct ts heure;" ne sont pas définies
  • idem pour "struct ts chronoStop;"
  • etc...

Tu n'as aucun problème de compilation chez toi ?

Et pour finir pourquoi autant de complications pour un code qui pourrait être somme toute être beaucoup plus simple ?

Si tu pouvais expliquer la logique que tu as utilisée se serait vraiment intéressant.

Portrait de Walter

Ce n'est pas a proprement parler des cellules RC, car il n'y a pas de signal fréquentiel.
La résistance est là pour polariser l'entrée numérique associée au bouton et le condo pour éviter les rebonds.

Non je n'ai aucune erreur, uniquement des warnings pour m'avertir que l'ESP8266 gére les timer en milli-seconde et non en micro-seconde.

Si tu est obligé de changer la casse, c'est que ce n'est pas le bon fichier.
C'est un truc chiant avec Arduino, il y a tellement de librairie différente, qu'il faut préciser celle que l'on utiilisent.
j'utilise la librairie ds3231FS, uTimerLib, TM1637.
ts est définie dans ds3231.h, donc si tu n'utilise pas le même, cela peut expliquer que celui que tu utilise n'ai pas la bonne déclaration.

SI il y a des points a optimiser, je suis ouvert à toutes propositions.

Je ne sais pas trop par ou commencer.
Dans les deux premiers mode, je veux afficher en alternance la température et l'horloge, avec un changement toutes les 5s.
Pour la température rien de spécial, pour l'horloge je veux que le séparateur clignote toutes les secondes.
J'ai donc un timer répétitif qui se déclenche toutes les 500ms, cela pourrait du coup être 1000ms, mais au début, j'avais une LED à 2Hz.

Comme il s'agit d'une interruption, je me contente de mettre à jour les variables concernée, pour passer le moins de temps possible dans la fonction(blink).

Dans les deux autres modes, j'affiche l'horloge et fait clignoter les heures ou les minutes en fonction du mode, toujours avec le même timer, donc en plus du séparateur.

Les trois boutons sont gérés par une intérruption et une fonction dédiée.
Quand l'un des boutons est relaché la fonction dédié est appelée, comme pour la fonction blink, uniquement la variable associé est modifiée, toujours pour passer le moins de temps possibles dans la fonction. 
Surtout que l'on utilise une librairie dont on ne maitrise pas l'implémentation et le temps passé pour récupérer ou changer l'heure.

Je pense avoir décrit le principal, mais n'hésitez pas à me poser des questions, si j'ai oublié quelque chose.

Portrait de hercule124

Bonjour,

Bon boulot,

tu as un but précis derrière la tête , a quoi il va servir .

tu vas le connecter a un réseau ?

Portrait de Walter

Merci Hercule124, non rien de plus, c'est pour afficher la température à l'intérieur du caisson de mon imprimante 3D.
Comme cura estime très mal le temps d'impression, je voulais avoir en plus un chronomètre.

Du coup je ne pense pas le connecter au réseau, à la base je voulais utiliser des digispark(atiny85), mais je ne peux pas les programmer simplement avec mon PC.

Portrait de Anonyme

Pour ce qui est de ton code ceux ce sont pas quelques points qui sont à optimiser mais à le réécrire entièrement, je ne sais pas qui est à l'origine de ce code, mais je ne vois pas trop comment on aurait faire plus compliqué.

Je n'ai pas le temps pour l'instant de le faire, mais je voudrais juste te faire quelques remarques.

  • Tu utilises des interruptions qui ne servent à rien puisque tu ne fais que changer la valeur d'une variable que tu ne prends en compte que plus loin dans le code.
  • Tu as un somme incroyables de variables pour quoi faire ?
  • La sélection des différents modes est très loin d'être efficace.
  • Le système anti rebond comme tu l'appelles n'est pas aussi efficace, ni aussi sûr que quelques éléments de code.
  • Les fonctions sont trop longues et prennent trop de temps ce qui fait que tu ne peux pas avoir un réaction optimum pour l'action des boutons.
  • Il y ad'autres points mais j'arrête là pour le moment

Tu prendras peut être mal ces critiques mais ce n'est pas pour te dénigrer, mais simplement pour te donner des pistes, il n'y a rien de méchant dans ces lignes.

Je pense que j'aurais un moment dans la journée pour réécrire un code plus adapté à ce que tu recherches. Mais dis moi c'est  vraiment toi qui est à l'origine de ce code ?

Portrait de Walter

Salut,

Je ne comprend pas trop là question, c'est moi qui suis l'auteur, pourquoi?

1) Le principe est justement de passer un minimum de temps dans l'interruption et de ne surtout appeler aucune fonction d'une libraire dans l'interruption.
Effectivement je pourrais aussi lire l'état dans la fonction "loop", mais je pense que c'est dommage d'appeler une fonction qui sera inutile 99% du temps.

2) Cela me permet de gérer les différents état et "clignotement" et d'affichage, peut être que certaines variable son superflue( comme blinkInterval), mais je ne crois pas.
Après je n'ai pas cherché à réduire le nombre de variable.

3) De quel point vue, ergonomie ou rapidité de prise en compte?

4) Système c'est effectivement un peu fort, c'est juste un condensateur, c'est possible mais je ne voulais pas le faire par logiciel. En tout cas avec cette petite capa, je n'ai plus aucun problème.

5) Je n'ai pas évalué le temps d'exécution de chaque fonction, mais ce que tu dis m'intrigue, mon code perso étant très court, le temps passé est dans les print qui n'ont pas vocation à rester et les appels d'affichage et de gestions de l'heure.
Même si je sors les appels des librairies des fonctions, je n'ai pas l'impression que cela rendra mes boutons plus réactif.
Je vais faire des tests pour calculer la réactivité de mes boutons du coup et voir ce que je peux changer.

6) Pas de soucis, à chaque jour suffit ça tâche :)

Pourquoi veux tu que je le prenne mal, si je ne veux pas de remarque, je ne demanderais pas votre avis et conseil.
De plus tes remarques étant très constructives, c'est même un plaisir de les lires.

Portrait de Anonyme

Désolé, je suis un peux surbooké en ce moment.

Comme je n'ai pas le même afficheur que toi peux tu me décrire le fonctionnement exacte de ton projet.

Je ferais le code avec un LCD I2C en utilisant que  5 digits (dont un pour " : ", tu devras l'adapter à ton afficheur que je ne connais pas.

Portrait de Walter

Pas de soucis, mon programme étant pleinement fonctionnel, je n'ai pas d'urgence le concernant, c'est plus pour comparer les façon de voir les choses et de coder qui m'intéresse.

Pour reprendre ma description, le programme permet d'afficher l'heure, un chronomètre, la température ambiante en fonction du mode sélectionné.

Mode Off(0), l'affichage alterne toutes les 5s entre l'heure et la température ambiante.
Mode chrono(1), l'affichage alterne toutes les 5s entre le temps chronométré et la température ambiante.
Mode Heure(2), l'affichage alterne entre l'heure actuel(HH:MM) et (00:MM).
Mode Minute(3), l'affichage alterne entre l'heure actuel(HH:MM) et (HH:00)

quelque soit le mode le séparateur (:) clignote avec une fréquence de 1Hz 

Le premier bouton permet de change de mode.
Le deuxième permet de réinitialiser le chrono ou augmenter les heures ou les minutes en fonctions du mode sélectionné.

Le troisième permet de diminuer les heures ou les minutes en fonctions du mode sélectionné.

Portrait de Anonyme

Voilà mon code, il fait 58 lignes de moins, je le trouve plus clair, mais c'est juste mon avis car en plus j'utilise au maximum le français " COCORICO ! " :o)

Tu remarqueras des astuces de programmeur pour ajouter ou soustraire une heure ou une minute à la pendule ! Dans beaucoup de cas la fonction modulo ( % ) fait gagner beaucoup de temps et  de ligne de code !

Je me suis permis un changement en mode Chrono le BpMoins permet de remettre le compteur à 0 et BpPlus permet de retrouver le chrono Initial,

Comme je te l'ai annoncé j'utilise qu matériel différent :

  • Carte Arduino UNO
  • Schield RTC directement embrochable sur l'Arduino
  • Un écran LCD I2C

Je ne trouve pas dans ce projet la nécessité d'utiliser les interruptions, je réserve ce genre de code à les besoin dévolutions aussi rapide de soudaines !

Si tu veux je peux te faire une vidéo et même commenter mon code.

#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include "DHT.h"
#define DHTPIN 11
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define BpMode  8
#define BpPlus  9
#define BpMoins 10
DS3231  RTC(SDA, SCL);
Time T;
unsigned long TIME, sTIME = millis() + 5000, Chrono, TopChrono;
char HEURE, MINUTE, SECONDE;
String sHeure;
int Mode = 0, M, S ;
bool Etat = true, Encore;
void setup() {
  Serial.begin(1000000);
  RTC.begin();
  //RTC.setTime(8, 44, 0);    // Set the time to 12:00:00 (24hr format)
  lcd.init();
  lcd.backlight();
  pinMode(BpMode  , INPUT_PULLUP);
  pinMode(BpPlus  , INPUT_PULLUP);
  pinMode(BpMoins , INPUT_PULLUP);
  TopChrono = millis();
  lcd.setCursor(4, 1);
  lcd.print("Mode : ");
  lcd.print(Mode);
}

void loop() {

  if (!digitalRead(BpMode)) {
    Mode ++ ;
    TIME = millis() + 1000;
    sTIME = millis() + 6000;
    Mode = Mode % 4;
    Serial.println(Mode);
    Etat = 1;
    lcd.clear();
    lcd.setCursor(4, 1);
    lcd.print("Mode : ");
    lcd.print(Mode);
    while (!digitalRead(BpMode)) {
      delay(20);
    }
  }

  switch (Mode) {
    case 0:
      if (TIME < millis()) {
        TIME = millis() + 1000;
        if (Etat)
          LitHeure();
        else
          LitTemperature();
        if (sTIME < millis()) {
          sTIME = millis() + 6000;
          Etat = !Etat;
        }
        break;

      case 1:
        if (Etat)
          LitChrono();
        else if (millis() % 1000 < 100)
          LitTemperature();

        if (sTIME < millis()) {
          sTIME = millis() + 5000;
          Etat = !Etat;
        }
      }
      break;
    case 2:
      ChangeHeure();
      break;
    case 3:
      ChangeMinute();
      break;
  }
}

void LitTemperature () {
  float t = dht.readTemperature();
  String Tmp = String(t, 4);
  lcd.setCursor(4, 0);
  lcd.print(Tmp);
  lcd.setCursor(8, 0);
  lcd.print("C ");

}

void LitHeure() {
  T  = RTC.getTime();
  SECONDE = T.sec;
  lcd.setCursor(6, 0);
  HEURE   = T.hour;
  MINUTE  = T.min;
  lcd.setCursor(4, 0);
  if (HEURE < 10)
    lcd.print(0);
  lcd.print(HEURE, DEC);
  if (SECONDE % 2 == 0)
    lcd.print(":");
  else
    lcd.print(" ");
  lcd.setCursor(7, 0);
  if (MINUTE < 10)
    lcd.print(0);
  lcd.print(MINUTE, DEC);
}
void LitChrono() {
  Chrono  = (millis() - TopChrono) / 1000;
  S = Chrono % 60;
  M = (Chrono % 3600) / 100;
  lcd.setCursor(4, 0);
  if (M == 0)
    lcd.print(" ");
  lcd.print(M);
  lcd.print(":");
  if (S < 10)
    lcd.print(0);
  lcd.print(S);
  if (!digitalRead(BpMoins))
    TopChrono = millis();
  if (!digitalRead(BpPlus))
    TopChrono = 0;
}

void ChangeHeure() {
  if (TIME < millis()) {
    LitHeure();
    TIME = millis() + 1000;
  }
  if (TIME < millis() + 500) {
    lcd.setCursor(4, 0);
    lcd.print("  ");
  }
  if (!digitalRead(BpPlus)) {
    RTC.setTime((HEURE + 1) % 24, MINUTE, 0);
  }
  if (!digitalRead(BpMoins)) {
    RTC.setTime((HEURE + 23) % 24, MINUTE, 0);
  }
  delay(100);
}

void ChangeMinute() {
  if (TIME < millis()) {
    LitHeure();
    TIME = millis() + 1000;
  }
  if (TIME < millis() + 500) {
    lcd.setCursor(7, 0);
    lcd.print("  ");
  }
  if (!digitalRead(BpPlus)) {
    RTC.setTime(HEURE, (MINUTE + 1) % 60 , 0);
  }
  if (!digitalRead(BpMoins)) {
    RTC.setTime(HEURE, (MINUTE + 59) % 60 , 0);
  }
  delay(100);
}

Portrait de Walter

En premier lieu je tiens a te remercié pour le temps passé.
Je trouve mon code très lisible, mais comme c'est le mien forcement je ne suis pas objectif :)
Mais en tout cas le tien est très lisible. 

Par habitude de partagé mon code avec des anglophones, je code ou commit en utilisant uniquement l'anglais, même la documentation :)

C'est vrai que je n'ai pas fait beaucoup d'effort pour réduire les lignes de codes, mais quitte à le publié je voulais aussi qu'il soit facilement réutilisable, lisible et commenté un minimum.
D'ailleurs même si j'ai dû en laisser quelques'un je n'ai pas voulu utiliser d'astuce de codeur, comme les if ternaires ou les modulos, masquage de bit, ....

Effectivement le projet ne nécessite pas des interruptions, après qui peu le plus peu le moins et du coup le code est directement réutilisable pour un projet plus complexe, donc pourquoi s'en privé, surtout que finalement cela ne rajoute pas une grosse complexité de codage.

J'ai tout le matos que tu utilise, donc desque j'ai le temps ​de refaire le montage, j'essaierais ton code.
Mais bon à la lecture, j'ai déjà une bonne idée de ce qu'il donne.
Et la simplicité du projet ne nécessite pas que tu me commente le code.

Merci encore a toi le temps passé, c'est toujours intéressant de comparer les différentes approche d'un programme.

Portrait de Anonyme

Tu dis que tu code exclusivement en Anglais pour le partage avec des anglophones, mais pourquoi ne partages tu rien ici ? (même en Anglais) ou peut être peux-tu nous donner le lien du site sur lequel tu partage tes codes !

Pour ce qui est des interruptions tant qu'à les utiliser, il faut le faire avec plus d'efficacité je pense. Pourquoi lancer toutes les interruptions au début du code, alors qu'à cet instant, seul le changement de mode est nécessaire. En plus si tu actionnes les Bp qui n'ont pas encore de raison de l'être au changement de mode tu risques d'avoir des modifications non voulues. Enfin si tu utilises des interruptions comme plus est moins elles devraient être attachées à des fonctions spécifiques à la position dans ton code ce qui te permettrait d'être beaucoup plus efficace, mais c'est juste mo avis.

Pour le temps passé à ma façon de coder de rien c'est avec plaisir !

J'ai commandé le même afficheur que toi (c'est toujours intéressant de voir d'autre système) et si j'ai un moment je te donnerai ma solution qu'en à l'utilisation des interruptions selon mon idée.

Jetfuzz je ne comprends que ne sois pas venu mettre le boxon ici ?

Portrait de Jetfuzz

Jetfuzz je ne comprends pas que tu ne sois pas venu mettre le boxon ici ?

et c'est qui qui cherche a foutre le boxon !!!!!

parce que jusque la, tu as été agréable !!!
et que le code c'est pas mon truc.
pourvu que ca dure.

Cordialement

Jetfuzz

Portrait de Anonyme

J'adore tu démarres au quart de tour je connais tes adresses IP et je sais que tu es connecté pratiquement tout le temps mais comme tes agressions manquent un peu de temps en temps je les relances de temps à autres, ça marche au top !

Portrait de Jetfuzz

je connais tes adresses IP

laisse moi rire, j'en ai qu'une !!!

et a moins de t'appeler Alex,qui connais mon nom et prénom, tu es incapable de connaître mon ip .....
pour te mettre sur la voie je suis chez orange , et oui même chez orange on peux avoir une IP fixe.
 

 

Portrait de Anonyme

Oui chez toi ....

Portrait de Jetfuzz

mais tu es un grand malade toi !!! même quand le post est constructif, tu essaye toujours de foutre la merde !!!!

Portrait de Anonyme

Si on compare le nombre de mes posts constructifs et tes posts pseudo constructifs, comme dit mon gamin il n'y a pas photo, 80% au moins des tiens sont agressifs même quand je ny réponds pas !

Regarde sans parti pris ce que j'apporte ici et ce que toi tu donnes ! De plus je sais que tu regardes tous mes tutos !

Portrait de Jetfuzz

De plus je sais que tu regardes tous mes tutos !

mais tu es plus fort que dieux tout puissant !!!

Franchement j'en ai rien a b......r des tes tutos !!!

Portrait de Walter

Je comprend pas trop ta remarque, a priori tu es développeur, je suppose que tu n'es pas payé pour diffuser ton code sur ce forum ?
J'ai deux "projets" fonctionnels et complets diffusés sur ce forum, je crois que tu en a aucun dans cette section, donc je trouve que ta remarque affirmant que je ne partage rien est plutôt déplacé, voir même mensonger.
 

Pour ce qui est des interruptions tant qu'à les utiliser, il faut le faire avec plus d'efficacité...

Complètement  et sachant que je n'ai pas cherché à optimisé, c'est pour ça que j'avais indiqué que "SI il y a des points a optimiser, je suis ouvert à toutes propositions."
Par contre normalement l'action des boutons est actif uniquement si le mode correspondant est sélectionné.
Donc sauf oubli de ma pars, il ne devrait pas y avoir de modification non voulu, sauf appui simultané, mais qui du coup est quelque chose de voulu.
Au départ le mode par défaut devrait être le mode "chronos" donc avec deux boutons actifs(3 avec ton code), de plus je trouvais par la suite plus embêtant d'activer/désactiver les interruptions à tout bout champs en fonction du mode sectionné.
je ne suis pas réellement convaincu que cela soit nécessaire, mais la question se pose effectivement et mérite réflexion.

Oui je suis preneur et intéressé d'avoir une autre façon de faire avec les interruptions.

Portrait de Walter

Jetfuzz je ne comprends que ne sois pas venu mettre le boxon ici ?

 Pour le coup c'est toi qui cherche à mettre le boxon avec cette réflexion et je ne comprend pas du tout ce qu'il y a de constructif.
Pourtant tu as à mainte reprise évoquer comme quoi on polluait ce forum, du coup du devrait plutôt être un modèle de vertu et grandeur pour ton gamin,
 

80% au moins des tiens sont agressifs même quand je ny réponds pas !

Je serais curieux que tu nous argumente et documente ses allégation.

Portrait de Anonyme

Disons qu'en ce qui concerne Jetfuzz il vaut mieux que je ne dise pas ce que je pense de lui, sauf que c’est un surexcité et sur vitaminé qui n’a aucun contrôle de lui-même. Pour ce qui est des 80%... tout un chacun peut facilement le vérifier sur l’ensemble de ce site, mais si tu veux je peux faire un récapitulatif de ses posts !

Portrait de Anonyme

Walter où as-tu pris le fait que tu ne partages rien ? Il est vrai que j'ai dit qu'ici je n'ai pas vu grand-chose dans ces pages. Mais comme tu affirmes je cite :

Par habitude de partagé mon code avec des anglophones, je code ou commente en utilisant uniquement l'anglais, même la documentation :)

Je n'ai trouver que cela :

"https://www.les-electroniciens.com/discussions/petite-sonde-temperature-humidite"
J'ai dû mal cherché car je n'ai pas trouvé le code et les commentaires dont tu nous parles ... J'ai pourtant bien fouillé. Mais je suis certainement passé à coté !

Je pense donc que tu partages tes projets ailleurs avec tes amis anglophones puisqu’ici je n'ai pas vu d'anglophone participé à tes créations ... Ce serait sympa comme je te le disais que tu partages aussi le site sur lequel vous échangez. Donc je réitère ma demande.

Tu dis encore que je n'ai rien publié; ???????. C'est vrai que dans cette catégorie je n'ai pas créer de sujet, j'ai préféré les poster sous forme de tutos, il y en a plus d'une douzaine il me semble, sans compter ce que j'ai donné dans d'autres catégories sous forme d'aide.

Tu me traites de menteur, puis je savoir quels mensonges ai-je fait ?

Bien revenons à ce sujet, Walter je viens de recevoir l'afficheur, il faut reconnaître qu'en choisissant ce module tu n'as pas choisi la facilité.

Je reconnais avoir mis un certain temps pour arrivé obtenir l'affichage que je voulais.

Sur le net je n'ai trouvé aucune explication sur les commandes de la library, juste des exemples n'expliquant pas les paramètres des diverses fonctions. Je pense que tu as dû en bavé autant que moi, autrement un grand bravo!, et alors je suis complètement nul.

Maintenant, dans un premier temps je vais faire exactement ton montage, comme toi, avec ton code pour que je puisse voir comment il réagi et par la suite pouvoir coller au maximum à ta réalisation.

Puis j'essayerai de coder ce montage à ma manière avec le même matériel dans le but que tu puisses comparer, nos différences dans la manière de coder comme tu dis trouver cela intéressant.

Portrait de Walter

Ba je l'ai pris dans ton précédent commentaire! 

Tu dis que tu code exclusivement en Anglais pour le partage avec des anglophones, mais pourquoi ne partages tu rien ici ? (même en Anglais) ou peut être peux-tu nous donner le lien du site sur lequel tu partage tes codes !

 

Je pense donc que tu partages tes projets ailleurs avec tes amis anglophones puisqu’ici je n'ai pas vu d'anglophone participé à tes créations ... Ce serait sympa comme je te le disais que tu partages aussi le site sur lequel vous échangez. Donc je réitère ma demande.

De quoi parle tu???
Je t'ai indiqué qu'il me semble tu ne partageais pas le code que tes commanditaires ou employeur te commandait, mais peut être que j'ai mal compris et que ton métier n'est pas developpeur?
Donc je le re dis avec d'autre mots, dans mon métier je travaille avec des anglophones et nos produits sont vendu à l'international, ce qui implique d'utiliser l'anglais pour le code et la documentation des produits.

Tu dis encore que je n'ai rien publié; ???????. C'est vrai que dans cette catégorie je n'ai pas créer de sujet, j'ai préféré les poster sous forme de tutos, il y en a plus d'une douzaine il me semble, sans compter ce que j'ai donné dans d'autres catégories sous forme d'aide.

Tu me traites de menteur, puis je savoir quels mensonges ai-je fait ?

Oui je parle bien de cette section, ou tu n'a rien partagé et dans laquelle tu indique que je ne partage rien, dans un post ou justement je partage mon mini projet.
Donc je le redis, cette affirmation "pourquoi ne partages tu rien ici" est déplacé, voir mensonger.
Alors peut être que ce n'est pas ce que tu as voulu dire, mais de la même façon que ma remarque sur ton manque de partage dans cette section peut visiblement t'avoir choqué, je trouve que ta remarque l'est tout au tant.

Concernant l'afficheur, cool que tu l'ai reçu, je l'ai choisit car je trouve qu'il a une bonne lisibilité avec des couleurs sympathiques, par rapport à des afficheurs LCD plus classique que je peux avoir en stock.
Le fichier d'en-tête est très documenté, bien que les commentaires permettent la génération automatique de documentation, je ne crois pas avoir vu sur le github la documentation générée.
Je crois aussi avoir vu la documentation générée quelque pars sur un site WEB.

Oui je te confirme mon intérêt pour un code alternatif au mien.

Portrait de Anonyme

Désolé Walter mais je n'avais pas compris que c'était dans ton métier que tu avais cette habitude, pardonne mon erreur s'il te plait !.

Franchement je n'avais pas compris et sauf une seconde erreur de ma part tu n'en fais pas mention !!

Portrait de Walter

Pas de soucis, non je ne pense pas en faire mention ailleurs.

Portrait de Anonyme

Tu dis que la library est très documentée mais je ne vois pas où. par exemple :

  • display.showNumberDecEx(1200, 0b01000000, true); en dehors du premier paramètre, à quoi servent les autres ?
  • display.showNumberDec(-1, false); idem
  • display.showNumberDec(4, true, 2, 2); idem
  • etc

Je suis arrivé à afficher à peu près ce que je voulais, mais par tâtonnement, as tu la signification de tous les paramètres notamment l'affichage des deux points ":" et l'affichage du seul point décimal ".", je suis vraiment très intéressé par la logique de cette library et je n'ai rien trouvé sur le net hors mis des exemples mais non commentés point par point. La seule chose que je trouve c'est si vous utilisez tel valeur, vous obtiendrez tel affichage. Mais toujours aucune signification de chaque paramètre.

Merci pour tes explications !

Portrait de Walter

Tu as regardé le fichier d'en-tête ?
Le mien n'a malheureusement pas les deux : et ., je me suis planté lorsque j'ai fait ma commande.
l'auto documentation de la fonction showNumberDecHex?

 //! Display a hexadecimal number, with dot control//!

  //! Dispaly the given argument as a hexadecimal number. The dots between the digits (or colon)

  //! can be individually controlled.

  //!

  //! @param num The number to be shown

  //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot

  //!        between the digits (or colon mark, as implemented by each module). i.e.

  //!        For displays with dots between each digit:

  //!        * 0.000 (0b10000000)

  //!        * 00.00 (0b01000000)

  //!        * 000.0 (0b00100000)

  //!        * 0.0.0.0 (0b11100000)

  //!        For displays with just a colon:

  //!        * 00:00 (0b01000000)

  //!        For displays with dots and colons colon:

  //!        * 0.0:0.0 (0b11100000)

  //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are

  //!        blank

  //! @param length The number of digits to set. The user must ensure that the number to be shown

  //!        fits to the number of digits requested (for example, if two digits are to be displayed,

  //!        the number must be between 0 to 99)

  //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)

  void showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);

Je vais essayé de retrouver la documentation que j'avais trouvé, mais de mémoire c'est simplement la génération de l'auto documentation. 

Portrait de graindesel

Bonjour,

Toujours pas de modérateur sur ce forum ? Walter tu n'étais pas intéressé par la fonction ? C'est lourd de voir tous les posts finir sur le même ton, et ca n'avance a rien a part faire fuir les gens matures...

Alex ? tu vois bien qu'il n'y à pas moyen. Il y a  une tumeur sur le forum.

Au point ou nous en sommes,même un mauvais modérateur serait moins pire qu'aucun modérateur.

Portrait de Anonyme

Walter plus besoin de document sur la library du TM1637 j'ai fait ma fonction qui permet d'afficher n'importe quelle valeur sur cette afficheur et d'une manière très simple

Exemple :

DigitAff("12:48"), DigitAff("__:36) ou encore DigitAff("24°C") etc... Si tu es intéressé fait moi le savoir !

Portrait de Walter

En voulant commencer l'implantation sur une carte de prototypage à bande, j'ai fait quelque changement sur l'utilisation des broches et j'ai remarqué qu'il y avait  du code en doublon.
 

Portrait de Anonyme

Je n'ai pas encore testé ton code je étais sur l'affichage digital.

Portrait de Anonyme

J'ai fini par trouver le manuel de la library TM1637Display  ici robojax-tm1637_display_manual.rar

Mais je te donne ma fonction sous TM1637Display.h qui, pour moi tout du moins, est beaucoup plus simple à utiliser.

Il suffit de créer une Chaîne de 5 caractères au choix dans "0123456789ABCDEF:°-_" puis

  1. On remplace un espace par "_" (Plus facile à visualiser que " ")
  2. Le 3 ème caractère ( obligatoire ) doit être ":" si on veut afficher ce séparateur, tout autre caractère est ignoré, le mieux est de le remplace par "_" ou même un espace
  3. On appelle la fonction DigitAff( paramètre ); // Avec la Chaîne voulue comme paramètre
  4. Au besoin il est possible de rajouter des caractères supplémentaires dans la fonctions. exemple pour "H":
  5.  String Alpha = "0123456789ABCDEF:*-_H"
    et

  6. Ajouter un élément a Car[28] par Car[29]

  7.   byte Car[29] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113, 128, 99, 64,0, 118}; //le code décimale des segments BCEFG soit (0 + 2 + 8 + 0 + 16 + 32 + 64  =118

#include <TM1637Display.h>
// Instantiation and pins configurations
// Pin 2 - > DIO
// Pin 3 - > CLK
int Delais = 1000;
TM1637Display display(2, 3);

void setup()
{

// Exemples :
  display.setBrightness(5);

  for (int n = 0; n < 10; n++) {
    DigitAff(String(n) + "____");
    delay(300);
    DigitAff("-" + String(n) + "___");
    delay(300);
    DigitAff("__-" + String(n) + "__");
    delay(300);
    DigitAff("___-" + String(n) );
    delay(600);
  }

  DigitAff("12:45");
  delay(Delais);
  DigitAff("01:00");
  delay(Delais);
  DigitAff("24 °F");
  delay(Delais);
  DigitAff("94__A");
  delay(Delais);
  DigitAff("64_-B");
  delay(Delais);
  DigitAff("-4_°C");
  delay(Delais);
  DigitAff("88:88");  // Pour tester tous les segments
 delay(Delais);
DigitAff("_____"); // Pour éteindre !!
}

void loop() {}

void DigitAff(String Aff) {
  byte Car[29] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113, 128, 99, 64, 0};
  String Alpha = "0123456789ABCDEF:*-_"; Aff.replace("°","*");
  byte D[4];
  D[0] = Car[Alpha.indexOf(Aff.substring(0, 1))];
  D[1] = Car[Alpha.indexOf(Aff.substring(1, 2))];if(Aff.substring(2,3)==":")D[1]+=128;
  D[2] = Car[Alpha.indexOf(Aff.substring(3, 4))];
  D[3] = Car[Alpha.indexOf(Aff.substring(4, 5))];
  byte data[] = {D[0], D[1], D[2], D[3]};
  display.setSegments(data);
}
Portrait de Walter

Cette documentation est partielle il manque la fonction showNumberDecEx, qui a un paramètre "dots" en plus pour afficher le séparateur à la position voulue.
 

Ta fonction est effectivement plus simple à utiliser si on veut combiner alpha et numérique, en évitant de devoir utiliser une combinaison de showNumberDecEx et setSegments.

je me suis permis de modifier ton code pour qu'il prenne en compte mon afficheur qui a des points entre chaque groupes de 7 segments et qui évite d'avoir des résidus d'ancien affichage si on affiche un nombre plus fiable de caractère.

byte Car[29] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113, 128, 99, 64, 0};

String Alpha = "0123456789ABCDEF:*- .";

void DigitAff(String Aff) {

  Aff.replace("°","*");

  byte *D = (byte*)calloc(4, sizeof(byte));

  int IndexD = -1;

  for (int a=0; a < Aff.length(); a++) {

    if(IndexD >= 0 && (Aff.substring(a, a+1) == ":" || Aff.substring(a, a+1) == ".")) {

      D[IndexD] +=128;

    } else {

      IndexD ++;

      String letter = Aff.substring(a, a+1);

      letter.toUpperCase();

      D[IndexD] = Car[Alpha.indexOf(letter)];

    }

  }

  byte data[] = {D[0], D[1], D[2], D[3]};

  display.setSegments(data);

}

 
Tu devrais proposer tes améliorations à l'auteur de la librairie.

Portrait de Anonyme

Tu as bien fait toute amélioration est bonne à prendre !

Par contre j'ai abandonné ce que j'avais prévu de faire avec les interruptions, je ne comprends pas pourquoi quand j'appuie sur un bouton avec l'interruption "1" c'est de temps en temps l'interruption "2" ou "3" qui est déclenchée donc comme ce n'est pas fiable j'abandonne.

Portrait de Walter

C'est bizarre, je n'ai pas remarqué ce genre de comportement.
c'est quoi ton code ?

Portrait de Anonyme

Ca ma fichu les boules j'ai tout effacé !

Je reprendrai peut être dans quelques temps !

Portrait de Walter

Lol, des fois quand ca ne marche pas, sans explication, c'est un brin agaçant:)

Portrait de Anonyme

J'ai jeté un oeil sur ta modif, mais je vois que tu ne cherches pas la simplicité, pourquoi aller bricoler avec les adresses mémoires ?

Si tu ne te fâches pas je vais essayer de te proposer ma solution à ton afficheur (si j'y arrive, en ce moment rien est écrit )

Portrait de Walter

J'avoue que je ne comprend pas ce que tu veux dire, de quel bricollage tu parle ?
Tu parle d'adresse mémoire, donc je suppose que c'est le calloc.
Mais je ne vois pas en quoi c'est du bricollage.

Ha non je ne vais pas me fâcher parce que tu propose une autre façon de faire :)

En relisant mon code, j'ai remarqué que je ne t'ai pas envoyé la derniére version de ma modification.
C'est casiment rien, mais la variable data est superflue, on peut utiliser directement la variable D qui est du même type et représente les mêmes données.
Et surtout que je ne libére pas la variable allouée, et c'est MAL.

byte Car[29] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113, 128, 99, 64, 0};

String Alpha = "0123456789ABCDEF:*- .";

void DigitAff(String Aff) {

  Aff.replace("°","*");

  byte *D = (byte*)calloc(4, sizeof(byte));

  int IndexD = -1;

  for (int a=0; a < Aff.length(); a++) {

    if(IndexD >= 0 && (Aff.substring(a, a+1) == ":" || Aff.substring(a, a+1) == ".")) {

      D[IndexD] +=128;

    } else {

      IndexD ++;

      String letter = Aff.substring(a, a+1);

      letter.toUpperCase();

      D[IndexD] = Car[Alpha.indexOf(letter)];

    }

  }

  display.setSegments(D);

  free(D);

}

Portrait de Anonyme

Non je ne parle pas de bricolage, j'aurais dû employer le mot utiliser (j'ai dit bricolage par ce que ce n'est pas à la portée de tout le monde de comprendre )

Voilà ma solution pour ton afficheur (Merci de le tester et de me donner le résultat de ton test) par contre il ne faut plus rien mettre en lieu et place des ":" ou "."  s'il ne doivent pas être affichés.

J'ai aussi rajouté des caractères dont j'avais besoin pour une autre appli !

Enfin j'ai testé ton code sur mon afficheur, j'obtiens des "r" à la place des "_" et tu as mis les deux premières lignes et dehors de la fonction !

byte Car[29] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121,
113, 128, 99, 64, 0};
String Alpha = "0123456789ABCDEF:*- .";

J'ai trouvé le problème il vient du fait que tu utilises des 'espace' et moi des 'underscore' pour effacer les caractères donc pas de problème après modif !

Voilà ma solution pour ton afficheur (Merci de le tester et de me donner le résultat de ton test) par contre il ne faut plus rien mettre en lieu et place des ":" ou "."  s'il ne doivent pas être affichés apr rapport à mon premier code.

#include <TM1637Display.h>
// Instantiation and pins configurations
// Pin 2 - > DIO
// Pin 3 - > CLK
int Delais = 1000;
TM1637Display display(2, 3);

void setup()
{

  // Exemples :
  display.setBrightness(5);
  for (int n = 0; n < 11; n++) {
    DigitAff(String(n) + "___");
    delay(100);
    DigitAff("-" + String(n) + "__");
    delay(100);
    DigitAff("_-" + String(n) + "_");
    delay(100);
    DigitAff("___-" + String(n) );
    delay(200);

  }

  DigitAff("12:34");
  delay(Delais);
  DigitAff("5678");
  delay(Delais);
  DigitAff("90AB");
  delay(Delais);
  DigitAff("CDEF");
  delay(Delais);
  DigitAff("6420");
  delay(Delais);
  DigitAff("-4°C");
  delay(Delais);
  DigitAff("88:88");
  delay(200);
  DigitAff("8.888");
  delay(200);
  DigitAff("88:88");
  delay(200);
  DigitAff("888.8");
  delay(200);
  DigitAff("_HOT");
  delay(Delais);
  DigitAff("COOL");
  delay(Delais * 3);
  DigitAff("____");
}

void loop() {
}

//************************************************************
void DigitAff(String Aff) {
  byte Car[32] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113, 99, 64, 0, 118, 92, 56, 120, 128, 128};
  String Alpha = "0123456789ABCDEF*-_HOLT.: "; Aff.replace("°", "*");
  byte D[4] = {0, 0, 0, 0}, Digit = 3;
  int Caract = Aff.length() - 1;
  while (Caract >= 0) {
    D[Digit] += Car[Alpha.indexOf(Aff.substring(Caract, Caract + 1))];
    if (D[Digit] != 128)  Digit --;
    Caract--;
  }
  byte data[] = {D[0], D[1], D[2], D[3]};
  display.setSegments(data);
}

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

Portrait de Walter

J'ai testé ton programme, il fait planté mon ESP8266 avec une erreur de segmentation dû à la tentative d'affichage d'une chaine de plus de 4 caractéres, comme celle-ci:
DigitAff("___-" + String(n) );

Dans le même genre tu utilise le retour de la fonction "indexof" comme index dans le tableau "Car", hors cette focntion peut renvoyer -1 et faire aussi un assez mémoire non voulu, mais qui ne doit pas faire un erreur de segmentation dans ton cas, je pense.

J'ai corrigé les problèmes avec le code suivant:
 

void DigitAff(String Aff) {

  int index;

  byte Car[32] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113, 99, 64, 0, 118, 92, 56, 120, 128, 128};

  String Alpha = "0123456789ABCDEF*-_HOLT.: "; Aff.replace("°", "*");

  byte D[4] = {0, 0, 0, 0}, Digit = 3;

  int Caract = Aff.length() - 1;

  while (Caract >= 0 && Digit < 4) {

    index = Alpha.indexOf(Aff.substring(Caract, Caract + 1));

    D[Digit] += (index >= 0) ? Car[index] : 0xFF;

    if (D[Digit] != 128)  Digit --;

    Caract--;

  }

  byte data[] = {D[0], D[1], D[2], D[3]};

  display.setSegments(data);

}

 

Je ne comprend pas pourquoi tu utilise les caractéres "_" pour éteindre l'afficheur, surtout qu'il s'agit d"un caractére afficheable avec un afficheur 7 segment.
Tu ne trouve pas que le caractére " " est plus approprié ?

J'avais mis les deux variables "Car" et "Alpha" en dehors de la fonction car comme elle ne change jamais, autant ne pas perdre de temps à les déclarer/affecté à chaque appel de la fonction ou alors les déclarer en static.

Portrait de Anonyme

Si tu mets plus de quatre caractères c'est normal que cela plante l'afficheur n'en a que quatre !

Tu peux utiliser le caractère qui te plait pour éteindre tous les segments, j'utilise les 'underscore' car, pour moi c'est plus facile à compter (visuellement) que des espaces.

Pour les variables c'est comme tu veux, je les ai incluses dans la fonction pour faire une fonction autonome voilà tout. le temps de rafraîchissement et négligeable !

Portrait de Walter

Non je trouve pas ça vraiment "normal" :),  c'est quand même mieux lorsque ta fonction ne fait pas rebouter l'ESP quand tu t'es planté dans l'appel de ta fonction, comme dans ton programme.
Surtout si tu propose une amélioration d'une librairie qui peut être mal utilisée par l'utilisateur final.
Avec la correction que j'ai proposée, tu n'a pas de reboot et à l'affichage tu as les 4 derniers caractéres.

Ton affichage ne doit pas être le même que le mien, parce qu'avec ma police de caractère je ne peux pas plus compter les " " que les "_", du coup cela m'ai pas venu à l'esprit. 

Oui, tu peux très bien mettre les variables à l'intérieur de la focntion, cela ne change pas réelement les performances dans ce cas précis.
C'est juste que tu y faisait référence à la suite d'un problème d'affichage chez toi et donc expliquer pourquoi je les avait extraites.

Portrait de Anonyme

J'ai trouvé le problème, tout fonctionne parfaitement et d'une manière très simple, mais vu ton changement d'attitude je ne diffuserai pas le code !

Portrait de Walter

Cool, mais tu as trouvé le problème à quoi ? je n'avais aucun problème en cours avec ton code.

C'est toi qui voit, mais je te rappel que tu ne me punis aucunement, puisque mon projet est pleinement fonctionnel avec la librairie TM1637 de base.

Autant j'apprécie de pouvoir échanger avec un autre developpeur, par contre à aucun moment cela impactera ma liberté d'expression.

J'ai pulbié ce micro-projet est espérant que cela puisse être utile à d'autre, c'est la seul chose que j'en attends.

Portrait de Anonyme

Le problème c'était chez moi qu'il avait lieu, comme je te l'ai dit.

Tout fonctionne chez toi : C'est parfait !

Portrait de Walter

Je ne sais pas quel problème tu avais mais super si tu as résolu ton problème et que tout fonctionne simplement et parfaitement chez toi.
Mais du coup tu ne veux pas diffuser le code que tu as déjà donnée et que j'ai corrigé?
J'avoue que je n'arrive pas à voir ou tu veux en venir.

Portrait de Anonyme

Tu sai très bien quel était mon problème sur les interruptions ! tu y as même fait allusion dans un de tes messages.

Tu n'as rien corrigé du tout, tu l'as adapté à ta façon. C'est à dire rendre transparentes les erreurs de codage, c'est complètement différent  ! Moi je préfère que ça plante ou que cela ne donne pas satisfaction, pour que l'on cherche et supprime les erreurs et ne pas laissé un code faux ce qui pour moi est digne d'un développeur du DIMANCHE. A chacun sa façon de voir les choses.

Il faut pensé industriel c'est à dire qu'une tierce personne peut intervenir sur ce code et ne plus rien comprendre.

Portrait de Walter

Tu aurais pû le mentionner ou préciser que tu as fini le programme, parce que je ne suis pas devin!
Comme tu aime bien la provoque gratuite, tout ceci ne serait pas plutot par peur de montrer tes limitation?

 Alors c'est la premiére fois, que j'entend qu'il est normal qu'un programme plante et dans ton ton cas severe car c'est un sgmentation fault qui fait rebouter l'ESP.
Il faudra que tu me présente tes clients qui accepte ce genre de comportement d'un porgramme.

Le seul choix pas digne d'un developpeur du dimanche, serait de renvoyer /ecrire un message d'erreur ou un code d'erreur indiquant que les paramétres sont hors limite et ne peuvent pas être pris en compte.

Donc oui j'ai corrigé le bug dans ton code, complétement non fonctionnel chez moi, puisque c'est toi même qui as mal employé ta propre fonction avec un texte de 5 caractéres.
On peut effectivement considére que la correction n'est pas complête car n'indique pas que le paramètre donné, n'est pas exploitable.

Et après tu ose prétendre que je ne suis pas un developpeur ou de piétre qualité et une "grosse merde" comme tu aime le proclamer.
Je suis impatient d'avoir le retour de tes connaissances consciencieuses et ravie de dialoguer avec eux.
Malheureusement je ne pense pas que tu sois capable d'un méaculpa et que cela ne va qu'augmenter ta véhémence à mon égard et que tu te ferra un malin plaisir à polluer tout le threead ce lesquels j'interviendrais, ce qui au final punira seulement les auteurs de ces threads

Pages