Station de soudure - Mise à jour et améliorations

Règles du forum
Cette section est dédié a vos projets, descriptions et demandes d'aide.
Merci de limiter le nombre de sujet par projets.
Lorsqu'un sujet deviens long vous pouvez éditer le premier message pour maintenir à jour le descriptif et garder en lisibilité
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 14 avr. 2023, 14:32

f4grx a écrit :et hmmm... genre libopencm3, ca irait pas, pour faire semblant de faire un minimum d'open source dans un lab d'éducation populaire fondé sur les valeurs de l'open source?.


Et hmmm ... Genre faire semblant d'avoir un minimum de respect pour les gens qui se sortent les doigts et qui font du taf gratos sur le peu de temps libre qu'ils ont, c'est possible môssieur l'inspecteur des travaux finis ?

f4grx a écrit :vous pouvez aussi dire que vous avez pas envie, c'est plus direct et plus clair (et compréhensible)


Mdr t ki ?

Ouais t'as raison, en fait la vérité c'est qu'on a pas envie. On met les machines qu'on retrofit sous LinuxCNC, là on envoie une carte open source dans l'espace, on a un gitlab où on met les sources de plein de projets, moi je me fait chier à publier et documenter les trucs que je fais pour le Lab, mais t'as raison ça compte pas, en vrai on fait même pas semblant.

D'ailleurs ton machin libopentruc, c'est bien que tu me fasse découvrir son existence, je le met tout de suite dans ma blacklist, catégorie "communauté toxique".
Avatar de l’utilisateur
Eric
Electrolab::Référent
Messages : 477
Enregistré le : 09 mars 2017, 10:09
Localisation : Electrolab
Référent : Zone Élec

Re: Station de soudure - Mise à jour et améliorations

Messagepar Eric » 14 avr. 2023, 15:20

En sus du Gitlab dont parle @flax, beaucoup de choses ont aussi été publiées sur le Wiki du lab :
- Projets en cours.
- Projets achevés.

Et rappelons que, pour 'celles-ez-ceux-z' qui prennent ce thread en route (on est déjà à la page 7), la station de soudure que l'on souhaite refaire a déjà été décrite - dans sa version première - sur ce wiki, et ceci en trois langues différentes.

Dans le but avéré de poursuivre avec entrain la non-divulgation d''informations, je prévois d'ailleurs de publier sur le Wiki d'ici l'été un article relatant la réparation d'un mini-four à micro-ondes qui a la particularité d'être perclus d'erreurs de conception.
Comme j'ai une horreur absolue de réparer des appareils électroménagers tant c'est pénible, encore prendre le temps de commettre un article sur le sujet, faire des photos et des schémas afin de partager la douleur de cette usante expérience, mais vous n'y pensez pas, mon bon Monsieur !

Eric
... donne (aussi) du Monsieur
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 17 avr. 2023, 14:15

J'ai commencé à faire le code. Déjà le HAL ne passe pas, prend trop de Flash et de RAM. Pour un MCU avec 16k de Flash, pas trop une surprise. Je suis passé sur le LL, là ça rentre, 65% de Flash, 70% de RAM quand-même. Pour ordre de grandeur, dans ma boîte nos bootloaders seuls font en général dans les 12k. 16k c'est petit ...

J'ai une application générale MainAppli. Elle va chapeauter tout le reste. Pour le moment, je lui ai mis Init, Start, Stop et CyclicTask, que j'exécute dans le main généré par CubeMX, et il y a une interruption à 1ms sur un timer qui lance la tâche cyclique en interruption. Pour l'instant je laisse l'initialisation des périphériques dans le main de CubeMX, c'est pas optimal, je sais, mais en première approche ça suffira.

J'ai commencé par le module IHM et encoder. Je suis parti sur l'archi que j'avais fait sur un projet précédent, mais je pense que je vais la modifier pour la rendre plus générique. l'idée d'origine c'était que le module encoder a une pile d'évènements, que l'appli va dépiler à son rythme, un peu comme font tous les OS maintenant. Le type d’évènements c'est "tourne un cran à droite", "tourne un cran à gauche" et je gérais aussi le bouton, et j'avais donc un évènement "clic court" et un évènement "clic long", aussi géré par le module encoder. Je pense que je vais séparer ça, et l'identification du type de clic long ou court devrait plutôt être fait par le module du dessus (IHM).

Je pense que le module encoder doit juste donner des informations "hardware" : le bouton a tourné d'un cran vers la droite ou vers la gauche, le bouton est enfoncé ou pas, et charge au module du dessus d'interpréter ces actions hardware d'un point de vue applicatif. Le truc c'est que ces évènements sont asynchrones, j'ai activé les interruptions externes sur les entrées encodeur pour garantir la réactivité. De cette optique, la pile d'évènements côté encoder permet d'avoir la synchronicité des actions, leur ordre de déroulement, ce qui est bien pour compter le nombre de crans d'encodeur qui sont passés entre deux tours de polling de la tâche cyclique. Donc il faut toujours une pile d'évènements côté encoder, mais uniquement "cran à droite" et "cran à gauche". Le bouton sera géré complètement séparément, et je pense que faire du polling est suffisant, vu que je vais faire du filtrage anti-rebond, pas besoin d'une réactivité maximale, et c'est le module IHM qui gèrera le filtrage ainsi que l'identification du clic long ou court.

Ensuite le module IHM aura une pile d'évènements déjà "pré-formatés" sous forme d'évènements fonctionnels signifiant pour l'appli : "cran à droite", "cran à gauche", "clic court", "clic long".

Dans cette archi, on peut ajouter d'autres types d’évènements dans IHM, par exemple un double clic, il suffit d'ajouter les traitements adaptés pour identifier les différents appui / relâchement, et créer un nouvel évènement IHM "double clic" à ajouter dans la pile. Ou simplement remplacer l'encodeur par des boutons, "yaka" remplacer le module encoder par un module qui fait l'interprétation des boutons et re-créée des évènements qui puissent être interprétés par le module IHM pour reconstruire des incréments / décréments, des clics, etc.

Il faudra que je documente l'archi avec un joli dessin dans le README.md. Il faut que je fasse un fichier d'interface pour remplacer tous les appels au LL par des macros centralisées au même endroit, pour permettre de changer plus facilement l'interface vers le bas-niveau. L'idée c'est d'avoir une appli "agnostique" qui n'ait pas d'éléments de lib bas-niveau trop imbriqués, pour pouvoir la réutiliser sur une autre base / OS.
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 20 avr. 2023, 14:28

Suite de l'IHM : affichage.

Je suis parti sur un triple 7-segments comme l'original. Le module qui va gérer l'affichage va nécessiter:
- Un système de matrice d'indirection pour convertir un chiffre (ou une lettre) en segments à allumer, et activer les bonnes sorties.
- Un système qui convertisse une valeur numérique contenue dans une variable en une série de chiffres en base 10 (parce que nous sommes des gens normaux, nous allons afficher les températures en décimal).
Pour ce qui est de décider quelle grandeur on affiche à un instant t, c'est encore le module IHM qui va gérer ça. Je ne pense pas aller jusqu'à faire un module "menu" qui gère ça, je vais faire une machine d'état directement dans le module HMI.

Pour la conversion en décimal, la méthode la plus évidente c'est de diviser par 10. Problème : on est sur un tout petit MCU, donc j'aimerais éviter de faire des divisions pour économiser du CPU (sauf par des puissance de 2 vu que ça coûte rien). Pour les fonctions de transfert analogiques, il y a une méthode qui passe par des approximation des dénominateurs, j'avais fait un article à ce sujet sur mon blog:
https://blog.randagodron.eu/index.php?post/2020/09/15/%5BBr%C3%A8ve%5D-Fonction-de-transfert-optimis%C3%A9e-pour-mesure-ADC-avec-pont-diviseur
Cet algo génère une erreur, mais je pense ça peut passer ici, si on réduit suffisamment l'erreur ça ne posera pas de problème, vu qu'on a affaire à des entiers. Cette méthode est connue depuis longtemps, voici un article qui la décrit de façon plus générique : https://www.baghli.com/hex2dec.php

Une fois découpé en chiffes distincts, il faut convertir cela en segments à allumer, cela se fera avec une table en const. Vu qu'il y a sept segments, ce sera une table de uint8 / char, et il y aura autant d'entrées que de valeur que je veux pouvoir afficher (chiffres, lettres, symboles ...).

Les valeurs à afficher vont être stockées dans un tableau de trois uint8, qui fera office de "frame buffer". Il y aura une fonction update qui va définir ce qu'il faut afficher en fonction de la machine d'état du "menu" de l'IHM, découper en digits, convertir en segments et remplir le buffer. Puis une fonction refresh qui va gérer la mise à jour des sorties. Dans un premier temps je vais commander alternativement un des 3 digits à chaque update. Si j'arrive à faire l'update à 1ms je pense ça suffira. Par contre, si je suis obligé de ralentir la boucle principale, je vais peut-être changer du stratégie, par exemple utiliser une interruption pour mettre à jour l'affichage de façon asynchrone avec la définition de la valeur à afficher. Bien entendu, pour éviter les problèmes il faudra bloquer cette interruption pendant l'écriture du buffer, pour éviter d'afficher des choses incohérentes.

Pour la LED, qui va clignoter plus ou moins vite en fonction de la puissance envoyée dans l'élément chauffant, l'idée est de la faire clignoter à un rapport cyclique fixe, et augmenter la fréquence de clignotement avec le rapport cyclique du PWM de puissance. Fréquence variable signifie qu'il va falloir le gérer de façon asynchrone avec le reste de l'appli, donc un PWM serait pas mal pour ça.
... Oui, mais il n'y a que deux timers sur le MCU que j'ai chois, yen a un qui est utilisé pour le découpage, et l'autre pour cadencer l'appli. Or, le PWM du découpage est variaté en rapport cyclique - et de toutes façons sans doute pas à une fréquence "visible" pour faciliter la régulation, donc à fréquence fixe. Et le timer de l'appli, ben il va être à fréquence fixe, lui aussi, évidemment. Une solution serait de mettre l'appli sur le même timer que la commande de puissance, ce qui n'a rien de déconnant, c'est ce qu'on fait sur de la régulation moteur. Par contre, la fréquence sera alors assez basse (1kHz voire moins), est-ce que ça ne posera pas problème ? En tous cas si ça marche, ça laisse l'autre timer pour contrôler la LED.
Oui, mais ... je n'ai pas connecté la LED sur une sortie timer :( Donc de toutes façons c'est mort, il faut le gérer en SW. On pourrait utiliser le timer laissé dispo par la manip précédente pour déclencher des interruptions qui iront allumer / éteindre. Pourquoi pas ? Vu que ça doit être visible à l'oeil nu, il n'y a aucune raison de monter trop haut en fréquence, et on peut dire qu'au-delà de 30FPS (ou en-dessous de 30ms) on maintient allumé pour éviter de balancer des interruptions en pagaille. Et je pense qu'il serait bien aussi de faire varier le rapport cyclique en même-temps que la fréquence, pour que ça soit vraiment plus facile à lire.
Sinon on peut aussi faire du pseudo-Bressenham, mettre à jour dans la boucle principale à 1ms (si on arrive à la maintenir à 1ms) et assumer la quantification par la fréquence de cette même boucle. Si ça se trouve ça serait suffisant.

Pour ce qui est des "menus", dans la version d'origine, l'affichage "au repos" c'est la température mesurée effective du fer, et quand on tourne l'encodeur ça affiche la température de consigne qui clignote à ~0.5seconde, et au bout de genre 2 secondes après avoir lâché le bouton ça revient à l'affichage de la température effective. Le bouton poussoir de l'encodeur était connecté au reset de l'Arduino. Le switch standby permettait de couper l'alim du fer sans éteindre la station.

Ici je vais garder l'affichage de la température effective "au repos", quand on tourne le bouton ça affichera la consigne pendant deux secondes, comme avant. Pour le bouton poussoir je vais modifier, je pense ce qui serait pas mal c'est qu'un clic court mette en standby, et en cas de mise en défaut, ça permettra de passer en standby tout en effaçant le défaut, et en appuyant une deuxième fois ça permettra de relancer la régulation. Je n'ai pas d'idée d'usage pour le clic long, pour le moment.

Sinon, j'ai reçu les PCBs :) :coeur:

20230420_112947_small.jpg
20230420_112947_small.jpg (375.26 Kio) Vu 3497 fois
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 21 avr. 2023, 15:53

IHM : quelques précisions sur mes choix d'interface:
Le standby ne coupe pas le PWM, juste il régule à une température différente du mode nominal. J'ai envie de mettre un mode OFF qui coupe carrément, mais je me demande si ça a vraiment du sens.
Donc si on a juste "normal" et "standby", ça chauffe tout le temps, et je me demande s'il ne serait pas pertinent d'avoir un mode "OFF" pour pouvoir faire des réglages "tranquillement" sans que la régulation soit lancée. J'ai prévu un bouton "standby", mais en vrai je pourrais m'en servir comme bouton ON/OFF, sinon utiliser le clic long, ou double-clic.
Dans le code Legacy il y a 3 réglages : température de chauffe, température de standby et gain de la mesure de température. Je me demande comment rendre ces trois réglages accessibles.
Je propose :
En OFF, clic long pour passer en normal, clic court pour cycler sur les trois paramètres, avec affichage d'un trigramme pendant 1 seconde à chaque transition pour savoir ce qu'on change.
OFF -> clic -> "Tmp" -> réglage consigne de température -> clic -> "Stb" -> réglage consigne de température en standby -> clic -> "gan" -> réglage du gain -> clic -> OFF. A chaque étape appui long -> annuler, retour en OFF.
En normal : clic court pour passer en standby, clic long pour passer en OFF, tourner le bouton pour régler la consigne,
En standby : clic court pour passer en normal, clic long pour passer en OFF, tourner le bouton pour régler la consigne de standby.
Je dessinerai la machine d'état ça sera plus clair, pour la doc.

Pour la LED, en fait sur les stations Weller la fréquence de clignotement est fixe et c'est le rapport cyclique qui change en fonction de la charge, avec une fréquence de clignotement humainement visible (genre 200ms) donc je vais peut-être pas trop me prendre la tête avec ça.

Concernant les mesures de temps d'une façon générale, on peut soit compter le nombre de passage dans la tâche cyclique, soit utiliser le compteur d'un des timers (ou le sysTick) pour avoir une valeur précise et asynchrone. Dans un premier temps je vais compter les cycles, et plus tard je ferai une fonction qui va mesure en asynchrone sur le sysTick.

Régulation : le cœur de la meule :) Enfin on y arrive.

Sur Legacy la régulation de température en elle-même est très simple, mais relou à comprendre à cause des noms de fonction mal choisis. Dans solder_station le rapport cyclique à appliquer est mémorisé dans la variable iron_pwm. SI on est ni en défaut ni en standby, c'est ce qui est appliqué dans la fonction update_iron_temperature du script principal, qui fait iron_set_pwm(get_iron_pwm()):
- iron_set_pwm() fait le analogWrite vers la sortie PWM,
- get_iron_pwm() renvoie la valeur de iron_pwm.
Comment écrit-on la variable iron_pwm ? Gràce à la fonction ... set_iron_pwm(), à ne pas confondre avec iron_set_pwm() :-/ Cette fonction est aussi appelée dans update_iron_temperature() et fait set_iron_pwm(compute_iron_pwm(iron_temperature, temperature)):
- compute_iron_pwm() calcule la différence entre la température mesurée et la consigne, puis multiplie par le gain pour que ça donne la valeur de rapport cyclique à appliquer.
C'est de la régulation en boucle fermée classique, lorsque la température mesurée et la consigne sont égales, le PWM passe à 0.
A noter que le rapport cyclique et la température sont traitées sous forme d'entiers, et il n'y a pas d'hysteresis explicite, et en pratique c'est la résolution de la mesure qui va faire office d'hysteresis, donc à +/-1V. C'est assez brutal comme régulation, mais en pratique ça suffit.

C'est vraiment simple, et je n'ai pas l'intention de faire fondamentalement différent, à part quand-même:
- Que ça soit plus lisible, parce que là bon, les noms de fonctions, quand-même ...
- Remplacer le simple gain par un "vrai" PID,
- Utiliser des grandeurs intermédiaires avec une résolution supérieure à l'unité pour faire de la régulation un peu plus fine,
- Ajouter un hysteresis explicite.
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 24 avr. 2023, 14:38

Dans la régulation, il faudra aussi ajouter des protections pour éviter de cramer les pannes. Dans le SW d'origine, c'est simplement un timer, qui va mettre la station en protection si la sortie PWM reste à 100% pendant trop longtemps. C'est très bourrin mais ça marche. Deux problèmes:
- Une fois en protection le code est bloqué, et le seul moyen de débloquer c'est de faire un reset de l'Arduino,
- Si on essaie de souder sur une grosse masse de cuivre (genre un gros plan de masse) avec une panne vraiment trop petite, le SW va croire qu'il y a un problème et se mettre en protection.
Pour le premier point, la solution est déjà décrite : au lieu de bloquer le SW on se met dans un mode "erreur" dont on peut sortir avec une petite manip / procédure, pas besoin de reset le SW, ça sera quand-même plus pratique.
Pour le deuxième point, il faut faire un système de détection un peu plus sophistiqué, et ne pas se contenter de regarder le PWM de sortie mais aussi la mesure de température : si le PWM est kéblo à 100% ET si la température ne bouge pas ou a une valeur aberrante, alors on met en protection.

Il ne manque plus que deux éléments : la sauvegarde en NVM et le watchdog.

Watchdog

Pour le watchdog, dans le software d'origine on utilise tout simplement le watchdog de l'AVR, avec un refresh dans la tâche de fond. Rien d'incroyable, c'est du standard. SUr le STM32L011K4, il y a deux watchdogs:
- IWDG ("independant") qui est un simple timeout, clocké sur une horloge indépendante, donc siimple mais avec une indépendance garantie,
- WWDG ("window") qui est un watchdog à fenêtre, clocké sur un prescaler du APB1, donc permet d'être plus précis sur les mesures de timings, mais n'a pas une horloge indépendante des autres périphériques.

Pour rappel, le but du watchdog est de détecter un blocage de l'application. L'idée est d'avoir un timer qui décrémente en permanence, et quand il atteint zéro il va déclencher un reset du MCU. Pour éviter cela, il faut régulièrement faire une action ("refresh") qui va remettre le timer à sa valeur de départ. Pour que ça soit utile, il faut faire cette action dans une partie "pertinente" du SW, dont on considère que la non-exécution est un signe crédible de plantage de l'applicatif. Un watchdog à fenêtre va avoir le même principe de fonctionnement, mais va aussi déclencher un reset si le refresh est déclenché trop tôt. Il y a donc une fenêtre (d'où le nom) dans lequel est autorisé le refresh. Cela permet de détecter un plantage / blocage, mais aussi un défaut du séquencement, problème d'horloge, interruption qui se déclenche en boucle, ce genre de choses.

En général, sur une application qui a des tâches cycliques en interruption timer, le watchdog "basique" (pas à fenêtre) est refresh dans la tâche de fond, l'idée étant d'identifier qu'une tâche est tankée. Ici la sanction c'est le fait de repasser suffisamment souvent dans la tâche de fond pour refresh le watchdog. Le watchdog à fenêtre serait plutôt refresh dans une tâche cyclique, pour vérifier que l'exécution des tâches reste régulière.

Dans un premier temps je vais juste utiliser le IWDG, et plus tard, peut-être, je réfléchirai à utiliser le WWDG. Étant donné que le risque principal (évènement redouté comme on dit en sûreté de fonctionnement) est de faire cramer la panne, le temps de réaction n'a pas besoin d'être incroyablement rapide. Je vais quand-même mettre 100ms pour éviter de laisser la régulation trop longtemps partir en vrille si jamais on est limite niveau charge CPU.

NVM

... Gros dosselard.

Je voudrai bien réutiliser ce module sur d'autres projets, donc je voudrais bien y mettre d'entrée de jeu tous les mécanismes dont j'aurais besoin sur une plus grosse application, en particulier en appliquant les principes que j'ai appris à mon taf.
Quand on parle de NVM on parle de quoi ? "Non Volatile Memory" ou mémoire non-volatile dans la langue de Depardieu, il s'agit de la mémorisation de valeurs pendant la vie du "produit", valeurs qui peuvent être arbitraires. Le stockage se fait soit dans un composant mémoire dédié (E²PROM, Flash externe en SPI ...) soit directement dans le MCU. Par exemple, dans les PIC et les AVR il y a une E²PROM intégrée. Sur la plupart des MCUs, ce n'est pas une E²PROM, mais une partie de la Flash programme qui est différente et mieux adaptée à des écritures régulières. Vu que j'en suis a expliquer plein de choses, autant continuer.

Pour rappel, encore la mémoire Flash a la particularité d'avoir un état au repos (0 ou 1 en fonction de la techno NAND ou NOR), et on peut écrire dedans avec une granularité assez fine, à l'octet voire au bit près. Mais une fois qu'un bit est écrit à la valeur "pas repos", on ne peut pas l'écrire dans l'autre sens. Le seul moyen de faire revenir un bit à la valeur repos est de déclencher une opération d'effacement, et cette opération ne peut se faire que sur une page complète, page dont la taille est généralement relativement grande (quelques dizaines d'octet à plusieurs ko en fonction du modèle et de l'archi de la Flash). Ce qui veut dire que si on veut modifier une valeur dans une mémoire Flash, il faut identifier la page dans laquelle cette valeur est stockée, recopier toute la page en RAM, faire la modification dans la copie en RAM, effacer la page en Flash puis la réécrire avec la copie en RAM. Tout cela consomme de la RAM, est long, et ya pas intérêt à avoir une interruption ou une coupure d'alim en cours de route. Ajouter à cela le fait que ce type de mémoire a une durée de vie assez limitée, qui se compte en nombre de cycles d'effacements / écriture, cela fait qu'on tâche d'éviter de trop souvent faire des écritures en Flash. En général, on le réserve aux opérations en debug et aux mises à jour de firmware. Pour sauvegarder des valeurs qui changent régulièrement, on va utiliser autre chose.

C'est là qu'on trouve les Data Flash, DFlash, ou E²Flash, qui sont des sections particulières de la Flash programme. Il s'agit toujours de Flash, avec le même principe d'effacement de page, mais les pages sont plus petites, et en général la durée de vie est meilleure que la Flash programme classique. Genre ici sur le STM32 on a des pages de 4 octets et une durée de vie multipliée par 10 (on passe de 10k cycles à 100k).

Si on prend des exemples un peu plus concrets (et que je connais) pour illustrer ça, sur un calculateur de bagnole, on découpe la Flash en plusieurs zones:
- Bootloader
- Application
- Calibrations
- NVFix
- NVRol
Bootloader, application et calibrations sont en Flash programme, NVFix et NVRol c'est en DFlash. Le bootloader est toujours le premier à démarrer, il checke que l'application est valide, si c'est le cas il lance l'application. Les calibrations ce sont des valeurs qui peuvent être modifiées pendant le développement du calculateur, pour de la mise au point, par contre les calibrations sont strictement identiques d'un exemplaire à l'autre. Un jeu de calibration est liée à une version d'application, le fait que ça soit séparé du code de l'application est juste une facilité pour le développement parce que les outils de mise au point peuvent ainsi accéder facilement aux valeurs, mais une fois une application programmée elles ne changent pas. Ca permet aussi de faire des corrections dans les valeurs de calibrations sans re-programmer toute l'appli. Typiquement, sur un moteur thermique (et sur une bagnole "normale"), les cartos sont en calibration, elles sont identiques d'un exemplaire à l'autre. Potentiellement il peut y avoir une appli identique avec deux calibrations différentes pour deux variantes différentes d'un même moteur, ou le même moteur sur deux modèles différents. Quand on veut changer les cartos (je ne juge pas) sur une voiture "normale" du commerce il faut re-programmer la zone de calibration.

NVFix et NVRol servent à stocker les grandeurs qui vont changer pendant la vie du produit, elles seront donc différentes d'un exemplaire à l'autre, même si elles sont potentiellement identiques quand la voiture sort de l'usine.
NVFix ce sont celles qui varient rarement, ou uniquement suite à une action explicite ponctuelle (genre, une écriture de DID en concession). Par exemple : valeur d'étalonnage d'un capteur, numéro de série, ce genre de choses.
NVRol ce sont les valeurs qui changent tout le temps, ou en tous cas son sauvegardées à chaque endormissement du calculateur. Typiquement c'est le kilométrage, la mémorisation des défaut (DTC), etc.

Ces deux mécanismes, NVFix et NVRol vont se partager la DFlash. On va la re-découper en plus petites sections, chaque section (zone) devra être un multiple de la taille d'effacement, et suffisamment grande pour contenir l'intégralité des données qu'on veut y mettre. L'idée, c'est de ne pas écrire dans la même zone deux fois de suite, mais d'alterner, voir de tourner sur un pool de zones. Par exemple si on alloue deux zones, on écrira alternativement sur l'une, puis sur l'autre. ça permet d'éviter de se retrouver avec les données écrites uniquement en RAM (et donc susceptibles de disparaitre si une coupure a lieu) donc d'avoir une sorte de backup, et ça permet aussi de répartir les cycles d'effacement sur la mémoire, au lieu de concentrer sur une sous-partie qui serait écrite en permanence, ou de faire un effacement systématique de toute la DFlash. De cette façon, on allonge la durée de vie, en gros on la multiplie par le nombre de zone (mais on l'use sur "toute sa surface").

Pour savoir quelle zone est valide à un instant T, on utilise des patterns qu'on va écrire. En général il y en a 2 : validité, invalidité. Ce sont deux sous-zones / variables qui sont clairement identifiées dans chaque zone (en général à la fin) et qui sont soit "vierges" / non-écrite, soit écrites avec une valeur unique spécifique (genre 0x5A5A). Une fois qu'une nouvelle zone est écrite avec un nouveau contenu (et qu'on a vérifié son intégrité via un CRC) on écrit le pattern de validité. Cela permet, en passant sur toutes les zones, d'identifier celles qui ont passé cette étape écriture + check. Puis on vient écrire le pattern d'invalidité de la zone précédente.

Si deux zones se suivent et ont chacune leur pattern de validité, mais aucune n'a de pattern d'invalidité, alors c'est que l'opération d'écriture a été interrompue après le check, mais avant l'écriture du pattern d'invalidité. S'il n'y a que deux zones, impossible de savoir laquelle a été écrite en dernier -> les deux sont considérées HS. S'il y a plus de deux zones dans le pool, alors on connaît le "sens" d'écriture des zones, et on donc on peut identifier la plus "récente", et finir l'opération en écrivant le pattern d'invalidité sur la plus "ancienne". Au démarrage, l'appli va passer en revue toutes les zones, pour trouver celle qui est valide, qui va donc soit être la seule à avoir son pattern de validité mais pas son pattern d'invalidité, soit en trouver deux avec validité mais sans invalidité et prendre la plus "récente".

Si aucune zone ne correspond à ces caractéristiques, alors on considère que la NVM est cassée "beyond repair" et on revient aux valeurs par défaut, qui elles sont stockées dans la zone des constantes dans la Flash programme. Plus précisément, on vient écrire les pattern d'invalidité sur toutes les zones, puis on reprend la première du pool de zones, on l'efface, on vient écrire les valeurs par défaut et on écrit son pattern de validité.

En général on prend deux zones pour la NVFix et plus que deux zones pour la NVRol. L'idée c'est que la NVFix est généralement écrite dans des conditions moins "risquées" niveau perturbations et pertes d'alim, donc elle a moins de risque de se retrouver dans la situation où les deux banques sont valides + non-invalidées.

Ça c'est pour la gestion de la zone de DFlash en elle-même. Pour gérer les données qu'elle contient, il faut une "carte" des variables contenues dans une zone. Pour cela, soit on le définit explicitement avec des constantes en #define qui indiquent les adresses individuelles de chaque variable, soit on utilise une structure, voire mieux on stocke chaque variable avec un index qui permet d'identifier de quelle grandeur il s'agit, ou encore mieux, mais qui prend énormément de place, stocker la valeur avec une chaîne de caractère permettant de l'identifier. Pour ce projet, je pense que je vais faire une structure. Au démarrage, il faudra charger le contenu de la structure dans les variables associées.

Avant chaque sauvegarde, on vient reconstruire le contenu de la structure avec le contenu des variables courantes, et on compare avec le contenu correspondant dans la NVM, si la valeur est différente on lance une écriture d'une nouvelle zone avec les nouvelles valeurs.

Pour la station de soudure, je pense qu'il n'y aura que de la NVRol, et on va sauvegarder : consigne de température, consigne en standby, gain. Ce sont des uint16_t, donc il faut au moins 6 octets. Si on ajoute un CRC il faut un peu plus. Vu que la granularité est de 4 octets, je pense pertinent de faire un CRC sur 4 octets, ce qui fait donc au moins 12 octets avec la quantification.
La DFlash fait 512 octets, largement suffisant. On peut y découper en zones de 32 octets pour se prendre un peu de marge, ça fait 16 zones, 2 pour la NVFix (qu'on n'utilisera pas ici) et 14 pour la NVRol. Ce découpage est arbitraire, on pourrait prendre des valeurs différentes.

Celui-là il va prendre du temps à coder et tester ...
Avatar de l’utilisateur
rude_ulm
Electrolab::Membre
Messages : 296
Enregistré le : 03 mars 2017, 10:52
Localisation : Houilles

Re: Station de soudure - Mise à jour et améliorations

Messagepar rude_ulm » 24 avr. 2023, 17:57

Hello

- Une fois en protection le code est bloqué, et le seul moyen de débloquer c'est de faire un reset de l'Arduino,


On peut utiliser le switch qui détecte la mise de la panne sur son support pour resetter les flags d'alarmes, qui se re-déclenchent le cas échéant quand on reprend le fer si le défaut n'a pas disparu (et avec un code qui ne bloque pas :) )

Pour la NVROL ayant expérimenté des flash (dont le nombre d'écritures est limité) arrivées en fin de vie avecdes désagréments à la clé, j'avais fini par utiliser des flash discrètes en dip8 sur support

Dom
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 25 avr. 2023, 00:18

Je n'ai absolument pas réfléchi à la détection de la pose du fer, mais si il y a un mécanisme hardware fonctionnel, le reste ce n'est qu'une affaire de code. Et oui, pourquoi pas reset les flags d'erreur quand on dépose le fer sur le support, c'est une bonne idée.

Pour ce qui est de la NVRol, en ce qui concerne le MCU que j'ai choisi sur ma variante, avec 100k cycles + des pages qui tournent et du CRC je n'ai absolument aucune crainte sur la fiabilité. Mettre une E²PROM en plus c'est vraiment du luxe, en plus il faut se farcir le protocole en SPI ... relou, je ne ferai pas l'effort sur ce projet.
Avatar de l’utilisateur
rude_ulm
Electrolab::Membre
Messages : 296
Enregistré le : 03 mars 2017, 10:52
Localisation : Houilles

Re: Station de soudure - Mise à jour et améliorations

Messagepar rude_ulm » 25 avr. 2023, 11:05

Ceci étant pourquoi ne pas utiliser un composant comme le MAX6675 ou le MAX31855 pour obtenir la température du thermocouple sans chercher on ampli op de course

il faut se farcir le protocole en SPI ..

Et puis là le protocole SPI peut être utilisé pour autre chose comme un afficheur (ou une flash :hehe: )
Avatar de l’utilisateur
Flax
Electrolab::CA
Messages : 1595
Enregistré le : 01 mars 2017, 20:46
Contact :

Re: Station de soudure - Mise à jour et améliorations

Messagepar Flax » 30 avr. 2023, 23:23

Grmpf ... Ne nous dispersons pas trop quand-même.
Je suis resté sur l'archi d'origine dans un premier temps. Effectivement on pourrait utiliser des composants tout-intégrés, mais en général c'est hors-de-prix. Après ce n'est peut-être pas catastrophique si on cherche à élargir la compatibilité au-delà des pannes RT, mais dans l'idée d'avoir quelque chose de simple et pas trop cher, prendre du Maxim ne va pas aider :p
Et puis appro toussa ...
Mais dans une optique d'élargir le périmètre du projet, ça s'envisage totalement. Par contre si on part sur du full-SPI, ça peut compromettre l'utilisation du 1752, qui n'aura pas assez de pins, il faudrait passer sur un boîtier un peu plus gros. Mais là on re-part ENCORE à refaire le design. Pourquoi pas, s'pas ? Mais encore une fois : je n'ai que deux mains, deux yeux et un seul cerveau pas trop disponible, et trop de projets à faire avancer. Ce qui n'empêche pas les autres d'avancer de leur côté, hein ? Je parle juste pour moi.

Sinon, j'ai monté les composants, ça a l'air de marcher pas trop mal, j'ai des bugs de pinout sur la Nucleo OH MAIS QUELLE SURPRISE JE NE M'Y ATTENDAIS PAS C'EST SYSTÉMATIQUE SUR TOUS MES PROJETS et je vais devoir faire 2-3 corrections sur carte équipée, mais globalement pas d'énorme mauvaise surprise pour le moment.
Les entrées encodeur ont l'air de bien marcher, le bouton poussoir aussi, la LED aussi. Pour les 7-segments, le 595 a l'air de faire le taf, par contre le troisième digit ne marche pas parce que j'ai câblé son activation sur une pin qui est reliée à un quartz 32k sur la Nucleo, il va falloir que je tire un fil pour corriger ça.

20230430_231505_small.jpg
20230430_231505_small.jpg (160.81 Kio) Vu 3401 fois


A noter qu'il y a un bug dans la génération de code de CubeMX avec le LL, il teste un registre à l'init des horloges, test qui n'aboutit jamais, je l'ai shunté et ça fonctionne sans souci.
Sinon je débugge mon applicatif petit à petit. Genre là j'ai un bug qui fait afficher n'importe quoi au démarrage, et quand je clique le bouton ça remplit le buffer avec des vraies valeurs. Par défaut la valeur à afficher est "000", et j'ai fait une table d'indirection pour allumer les segments, uniquement en suivant le schéma. Et visiblement la table est bonne du premier coup 8| le genre de truc qui ne m'arrive jamais :gene:

Et il faut que je finisse la rgulation et les menus, et il faut que je gère la NVM, enfin bon, rien de très nouveau depuis la dernière fois.

Retourner vers « Les Projets »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité