Commande automatique de groupe électrogène - machine à états et autres questions

bricofoy:
word_A = b0011001100001111, j'ai bien 00110011 octet de poids fort, et 00001111 octet de poids faible

Oui

alors (byte)word_A == b00001111 ou b00110011 ?

(byte)word_A == b00001111

ok, donc il y a une erreur dans ta précédente réponse :

barbudor:
Oui le cast (byte)word ne va prendre que l'octet de poids fort. Par exemple, il n'est pas nécessaire de faire (byte)(word & 0xFF).

il fallait lire, si j'ai bien compris, "ne va prendre que l'octet de poids faible"

j'ai bon ?

Oui, oui, tu as raison
Je suis trop fatigué
Je dis n'importe quoi

:(=>[]

pas de soucis :slight_smile:

je m'interroge sur l'opportunité de séparer ma machine à états en deux, une qui gère uniquement le fonctionnement du moteur, et une qui gère les entrées pour pouvoir simplifier les conditions de changement d'état.
Mais comme les deux seraient amenées à agir sur les mêmes sorties, je doute de la faisabilité de la chose. Ou alors je sépare mon registre de sorties en deux. Mais au final cela va t-il vraiment simplifier ? vu que du coup je vais me retrouver avec une machine dont les conditions de changement d'état dépendent de l'état de l'autre machine... oula non, en fait ça va pas le faire. Heu oui désolé je réfléchis en live, là

Nouvelle version du code (en pièce jointe), nettement plus complète. Normalement la machine à états est finie, à deux ou trois correction dans les conditions près.

groupe.ino (12.2 KB)

J'aime bien ton code : define (au lieu de variables inutiles comme dans beaucoup d'exemples Arduino), machine d'état.
C'est dommage que tu n'ai pas une syntaxe différente pour les variables, les états, .. qui rendrait le code plus lisible.
Pour la packing des bits dans le BYTE, j'aurais utilisé des décalages plutot qu'une multiplication.

Tu sautes 2 échelons direct dans la secte des Adorateurs de la Machine d'Etat :slight_smile:

barbudor:
J'aime bien ton code : define (au lieu de variables inutiles comme dans beaucoup d'exemples Arduino), machine d'état.

Merci :slight_smile:

C'est dommage que tu n'ai pas une syntaxe différente pour les variables, les états, .. qui rendrait le code plus lisible.

Ben pourtant, j'ai justement essayé de faire un truc où les nom indiquent ce que ça représente, comme vet_** pour "valeur état *", ve_ pour "valeur entrée **" etc etc

Tu verrais ça plutôt comment ?

Pour la packing des bits dans le BYTE, j'aurais utilisé des décalages plutot qu'une multiplication.

Heu, où donc ? J'utilise partout des additions, il me semble ?

Il n'y a que dans

void lecture_entrees() {
  // lecture des entrées, stockage dans une seule variable byte pour economiser de la ram et faciliter les manipulations
  entrees = ve_alim * digitalRead(e_alim);
  entrees += ve_ext * digitalRead(e_ext);
  entrees += ve_prh * digitalRead(e_prh);
  entrees += ve_run * digitalRead(e_run);
  entrees += ve_rst * digitalRead(e_rst);
  ubat = coef_ubat * analogRead(e_ubat);
  temps_courant = millis();
}

qu'il y a des multiplications, mais c'est une multiplication par 1 ou 0 de la constante à additionner ou non au registre. Donc au final, ça reste une addition :smiley:

Tu sautes 2 échelons direct dans la secte des Adorateurs de la Machine d'Etat :slight_smile:

Ciel ! 8)

Depuis que j'ai fait du grafcet au lycée et des réseaux de pétri en école d'ingé, j'aime bien les MET, au moins c'est pas (trop) le bordel dans les conditions.

Reste que pour la mise en oeuvre, j'ai comme d'habitude fait les choses à l'envers. En partant du codage "en live" au lieu de faire ma machine sur le papier avant.

Et du coup, j'ai une zone merdique autour des état et_decomp et et _demarreur, qui sont plus ou moins inter-dépendants, et mon état et_run qui regroupe en fait des sortes de sous-états puisque les sorties diffèrent selon certaines conditions...

bricofoy:

C'est dommage que tu n'ai pas une syntaxe différente pour les variables, les états, .. qui rendrait le code plus lisible.

Ben pourtant, j'ai justement essayé de faire un truc où les nom indiquent ce que ça représente, comme vet_** pour "valeur état *", ve_ pour "valeur entrée **" etc etc

Tu verrais ça plutôt comment ?

Voici en gros mes choix a titre purement personnel :

Variable globale ou fonction globale : NomDeLaVariable ou NomDeLaFonction (majuscule sur le début de chaque mot)

Variable locale d'une fonction ou fonction locale d'un module ou fonction/variable membres d'une classe : nomDeLaVariable nomDeLaFonction (minuscule au début, majuscule début des autres mots)

Paramètre d'une fonction : _nomDeParamètre (comme une variable locale mais avec _ devant)

Types : NomDuType_t
Enums (j'utilise systématiquement des enums pour mes états) :
typdef enum {
DEBUT,
EN_COURS,
ARRET
} EtatsMoteur_t;

EtatsMoteur_t EtatMoteur;

Ce sont des choix personnels, chacun fait fait fait c'qui lui plait plait plait XD

Il n'y a que dans

void lecture_entrees() {

// lecture des entrées, stockage dans une seule variable byte pour economiser de la ram et faciliter les manipulations
  entrees = ve_alim * digitalRead(e_alim);
  entrees += ve_ext * digitalRead(e_ext);
  entrees += ve_prh * digitalRead(e_prh);
  entrees += ve_run * digitalRead(e_run);
  entrees += ve_rst * digitalRead(e_rst);
  ubat = coef_ubat * analogRead(e_ubat);
  temps_courant = millis();
}




qu'il y a des multiplications, mais c'est une multiplication par 1 ou 0 de la constante à additionner ou non au registre. Donc au final, ça reste une addition :-D

J'aurais écris :

  entrees = digitalRead(e_alim) << BIT_ALIM
             | digitalRead(e_ext) << BIT_EXT
             | digitalRead(e_prh) << BIT_PRH
             | digitalRead(e_run) << BIT_RUN
             | digitalRead(e_rst) << BIT_RST;

Encore question de goût.

pour les variables : en effet, maintenant que tu le dis, j'ai quelques réminiscences de stage chez Motorola ou il y avait des convention de codage dans ce style... Pour une prochaine version je remettrai ça d'équerre.
Pour le type "enum" pour les états, j'avais prévu au départ de faire un truc comme ça, sauf que les cours d'infos sont loin, que j'ai pas trouvé rapidement d'exemples démonstratifs sur le net, et que c'est pas détaillé dans l'arduino référence.
Du coup, j'ai fait ce que je savais faire...

En plus là je stocke l'état dans un byte, soit me semble t'il la plus petite variable possible sur un arduino. Avec une enum, concrètement ça bouffe quoi comme place en mémoire ?
Bon ceci dit je suis je pense bien loin d'arriver au bout de la ram de la bestiole, mais bon...

pour la lecture des entrées, oui en effet maintenant que tu l'a écris, ça parait tout simple :grin: mais les décalages, c'est nouveau pour moi, et ça ne me vient pas naturellement. Je suppose qu'en plus d'être plus clair, ton code est nettement plus rapide à l'execution, non ?

Avec une enum, concrètement ça bouffe quoi comme place en mémoire ?

Normalement un compilo bien élevé implémente l'énum dans la plus petite variable possible.
Donc ca devrait être un byte aussi.

ton code est nettement plus rapide à l'execution, non ?

Pareil, un compilo bien optimisé devrait savoir traduire automatiquement une multiplication par une puissance en un décalage.
Mais au cas ou... mieux vaut l'écrire comme cela :wink:

Bon, ça progresse. Le code n'a guère évolué, mais il est nettement moins plein de bugs.
Et le hard a commencé à se profiler.

J'ai failli graver un premier PCB hier, et je me suis rendu compte in-extremis que mon design était trop grand et ne rentrait pas dans le boîtier... oui je sais, organisation, tout ça, blablabla.... :ouin:

Donc là je suis en train de rerouter la carte en plus petit...

Dommage, mon premier essai de transfert thermique d'impression laser sur le cuivre semblait bien réussi.
A ce sujet, pour ceux qui veulent se lancer dans l'aventure de la gravure low-cost, le papier glacé des pubs SNCF est PARFAIT pour faire ça :slight_smile: :slight_smile: c'est impressionnant, le toner se transfère intégralement sur la carte, et le papier se décolle de lui-même avec juste un peu d'eau bouillante :slight_smile:

groupe.zip (535 KB)

groupe.ino (20.8 KB)

ça progresse lentement, mais ça progresse !

un petit coup de gravure, avec un engin qui ne m'avait pas servi depuis 19ans !!

la carte finalement gravée, nouvelle version (la première ne rentrait pas dans le boîtier !! la honte )

un petit coup de sérigraphie, ça présente quand même mieux :

dessous aussi, et aussi étamage à froid :

des p'tits trous, encore des p'tits trous...

mise en place des composants :

le merdier avec enfin tous les composants à leur place :

et les premiers bugs physiques :

forcément, les MOS avec D et S inversés, ça se polarise pas trop bien... :confused:

d'ailleurs à ce sujet, existe-il plusieurs brochages des 2n2222 en TO92 ? ceux que j'ai sur la carte ont collecteur et émetteur inversés par rapport à toutes les datasheet que j'ai pu trouver, j'ai pas vraiment compris...

Sympa
bravo

Question : comment as tu fait la sérigraphie ?

comme pour le typon : transfer de toner au fer à repasser. Il faut une vielle imprimante laser sur laquelle on peut vraiment régler la densité sur "foncé" (sur les récentes que j'ai essayé, impossible d'avoir un résultat assez noir)

ensuite, le papier qui marche le mieux pour faire le transfert, c'est... le papier glacé des pubs SNCF !! j'ai essayé plein d'autres papiers, finalement comme je n'avais plus de pub, j'ai fait avec du papier couché, ça marche correctement, mais le papier est super ennuyeux à décoller.

bricofoy:
comme pour le typon : transfer de toner au fer à repasser. Il faut une vielle imprimante laser sur laquelle on peut vraiment régler la densité sur "foncé" (sur les récentes que j'ai essayé, impossible d'avoir un résultat assez noir)

ensuite, le papier qui marche le mieux pour faire le transfert, c'est... le papier glacé des pubs SNCF !! j'ai essayé plein d'autres papiers, finalement comme je n'avais plus de pub, j'ai fait avec du papier couché, ça marche correctement, mais le papier est super ennuyeux à décoller.

Belle rea en DiY

simple reflexion en ce concerne la serigraphie :
autant apres finalisation/gravure du cuivre, le toner appliqué est évacué
autant en en application sur face compo il reste (c'est d'ailleurs le but :grin:) , je ne suis pas sur qu'employer cette méthode ne soit pas source "de grouilles ou autres embrouilles" 8)

Compte tenu des formulations des toner(s) (particules carbonées/conductrices/liants/etc...) c'est une "source" à ne pas negliger (rapide = amorçage en proximité sur du V )

Ben je me suis posé la question, et j'ai essayé avec mon testeur d'isolement : à 1000V une ligne de toner ne conduit pas.

Donc j'ai allègrement hachuré ma partie détection présence 220V coté cuivre :stuck_out_tongue: Et test effectué, ça n'a pas cramé :slight_smile:

Bon, il est 20h35, je termine juste de déboguer la carte et le code après 2 nuits blanches, je dois encore monter le merdier sur le groupe, et aller livrer et installer le tout... Youpi !!

Une question quand même : quel intérêt à utiliser une Arduino mini/nano au lieu de mettre directement le chip sur la carte.
Vu le reste de ta carte, c'est quans même pas un paudre DIP28, 2 capas et 1 résistance qui t'on fait peeur ?
Ca revient quand même 2 fois plus cher que les composants tous seuls.

par facilité. pour l'usb intégré, parceque je ne sais pas flasher un micro, etc etc etc et aussi parceque je ne me suis pas vraiment posé la question, en fait :stuck_out_tongue:

Bon, cela dit, le résultat est très mitigé, voire catastrophique. La carte fonctionne parfaitement posée sur la table. Montée sur le groupe, c'est la déchéance : à la première tentative de démarrage, dès que le démarreur est activé, l'arduino reboote.

Il est minuit vendredi soir, je viens d'avoir le client au téléphone et de lui promettre que la machine serait chez lui dans une heure.
Oscillo, et, conclusion : il semble que la tension batterie tombe en dessous de 8V au moment de l'activation de démarreur, du coup le LM317 + le régul de l'arduino, ben ça fout la merde et ça reboote. Ajout d'une diode sur l'alim et d'un gros condo avant le LM317. ça semble résoudre le soucis. Pas longtemps. Ajout désespéré de 100nF de découplage un peu partout sur la carte, ok, le démarrage manuel passe.
Essai de démarrage commandé par l'entrée distante : le moteur démarre, mais se coupe aussitot. Et impossible de comprendre à quel moment le programme chie, car lorsque le câble usb est branché, tout fonctionne impeccable. Conclusion logique : l'USB apporte la stabilité de l'alim, et ça fonctionne. Ajout d'un gros condo sur le 5V, rien à faire, même résultat. C'est très étrange car dans ce cas, ce n'est pas la carte qui reboote, c'est vraiment le programme qui commande l'arret moteur et le passage en défaut. Et bien entendu, absolument impossible de savoir ce qui se passe, vu que dès l'USB est branché, ça marche. Par contre, impossible de suivre le déroulement du programme via l'usb : la liaison se réinitialise et change de tty/USBx dès l'activation de démarreur. Perturbation EM, je suppose, pourtant j'ai rajouté des condos de partout.
Du coup, en désespoir de cause à 3h du mat, je massacre une seconde nano dont j'avais de toutes manières cramé l'atmega (mais dont le FTDI fonctionne) en me disant que je vais m'en servir de convertisseur USB/série TTL pour voir ce qui se passe en me branchant direct sur masse/Tx/RX de la nano en place sur la carte, mais non, rien, impossible ça ne communique pas. Et d'ailleurs je ne comprends pas bien pourquoi ?
Ce qui est étrange, c'est que quand j'active le log sur mon soft, l'arduino raconte plein de trucs, donc il envoie en ontinu des données. La led Tx de l'arduino est allumée, ok, mais si je débranche l'usb, couic, plus rien. Pourtant il balance toujours, vu que si je rebranche l'usb, ça se rallume, et en relançant la console série, je vois ce que ça balance (ha oui, j'ai viré le condo Cje sais plus combien, qui provoque le reset auto de l'arduino via le FTDI). Mais du coup impossible de voir ce qui est raconté sur le port série sans que l'usb ne soit branché, ce qui est un peu merdique.
Comment faire pour que ça marche ??

Bref, misère sur toute la ligne, finalement comme la démarrage manuel fonctionne à peu près à chaque fois, on livre le groupe chez le client samedi matin tout de même.

La je vais recevoir deux autre groupes à équiper, je vais donc pouvoir reprendre les essais. Et tu as raison, je vais sans doute utiliser direct un Atmega328 en boitier dil sur la carte, au moins je pourrai faire ce que je veux avec le port série...

Pour ton problème le mieux serait de pouvoir debugger sans apporter le 5V de l'USB puisque celui-ci améliore le résultat. Tu peux bricoler un câble USB avec Masse , D-, D+ sans le 5V. Ou bien enlever la schotky D1 sur la Nano.
Il faut aussi empêcher l'auto-reset en enlevant le condo C4.
Cela devrait permettre devoir ce qui se passe.

Je comprend pas :

Par contre, impossible de suivre le déroulement du programme via l'usb : la liaison se réinitialise et change de tty/USBx dès l'activation de démarreur

Pour l'ATMega328, ca s'achete pre-flashé avec le bootloader Arduino.

.

le condo C4 il a déja viré, justement pour pouvoir débugger sans que ça reboote.

mais de toutes manières, je ne peux pas le faire, vu que même quand l'atmega ne reboote pas, le FTDI lui, si, et la liaison USB change de port com, du coup le temps de fermer la console, changer de port et la rouvrir, ben je ne sais pas ce qu'il s'est passé.

c'est pour ça que je voulais utiliser la partie USB de ma seconde nano grillée pour essayer d'avoir une liaison série stable et qui ne me ramène pas une alim, sauf que ça ne marche pas, ça donne l'impression que de débrancher la prise USB désactive la liaison série de l'atmega, j'avoue ne pas trop bien comprendre.