Minuscule bug sur les mesures U & I - Version imprimable +- F1ATB forum (https://f1atb.fr/forum_f1atb) +-- Forum : Forum de F1ATB (https://f1atb.fr/forum_f1atb/forum-3.html) +--- Forum : Routeur Photovoltaïque (https://f1atb.fr/forum_f1atb/forum-4.html) +--- Sujet : Minuscule bug sur les mesures U & I (/thread-624.html) |
Minuscule bug sur les mesures U & I - Youpimatin - 17-10-2024 Je suis en UxI en v12.03 Il y a un tout petit bug sur les mesures U et I toutes les 1 heure 11 minutes et 35 secondes (soit 4295 secondes, soit 2^32 µs) Rien de très important ni d'urgent, cela peut juste déclencher de façon très brève les actions sans raison, ça a eu cet effet chez moi ce matin (Et l'échelle du graph sur Home Assistant est plus grande que nécessaire.) Désolé pour les petits bugs trouvés, André, je vais essayer de chercher de mon côté s'il est possible de mitiger ou d'éviter ça dans le code simplement. Une piste (peut-être complètement fausse) : -> La valeur retournée par la fonction micros() déborde toutes les 2^32µs -> Concernant la ligne iStore = (micros() % 20000) / 200; : 2^32 a un reste quand on le divise par 20000, du coup je suppose que des échantillons sont stockés dans le tableau à des index erronés pendant 1 appel (ou 2?) de MeasurePower() Micros() = 4294967295 implique que iStore = 36 Micros() = 0 implique que iStore = 0 et on ne va pas jusqu'au bout du tableau ? A l'occasion, j'essayerai de compiler une version avec des tableaux de 128 mesures, voir si ça passe niveau timing sur le core0 (128*150µs = 19.2ms, presque pas d'aliasing) RE: Minuscule bug sur les mesures U & I - F1ATB - 17-10-2024 Ok, on se trompe toutes les 71 min. C'est tolérable. RE: Minuscule bug sur les mesures U & I - Youpimatin - 19-10-2024 Certes... voici néanmoins une solution clé en main, André : void MeasurePower() { //Lecture Tension et courants pendant 20ms int iStore; value0 = analogRead(AnalogIn0); //Mean value. Should be at 3.3v/2 static unsigned long OverflowOffset = 0; static unsigned long PrevMicros = 0; unsigned long NowMicros; unsigned long MeasureMillis = millis(); while (millis() - MeasureMillis < 21) { //Read values in continuous during 20ms. One loop is around 150 micro seconds NowMicros = micros(); if(NowMicros < PrevMicros) { OverflowOffset += 7296; } iStore = ((NowMicros + OverflowOffset) % 20000) / 200; //We have more results that we need during 20ms to fill the tables of 100 samples volt[iStore] = analogRead(AnalogIn1) - value0; amp[iStore] = analogRead(AnalogIn2) - value0; PrevMicros = NowMicros; } } ...pas forcément la plus élégante, mais fonctionnelle et rapide, un copier-coller et c'est bon. RE: Minuscule bug sur les mesures U & I - F1ATB - 19-10-2024 OK je note pour une prochaine version. Avez vous testé si cela ne prend pas trop de temps pour avoir au moins les 100 mesures. Cdlt André RE: Minuscule bug sur les mesures U & I - Youpimatin - 19-10-2024 Je n'ai pas testé, mais j'en suis persuadé ! J'ai ajouté en gros: - Deux affectations - Une comparaison - Une addition d'entiers Si cela prends les 50µs de marge moyenne par cycle de mesures UI, je mange mon chapeau on doit plutôt être sous les 50ns Bon, on est à plus de 100 mesures par cycle, par contre ce n'est pas parfait sur le long terme, mieux mais pas parfait (on voit la différence entre sans et avec la modif avec le changement à partir de 15h au milieu du graph) : RE: Minuscule bug sur les mesures U & I - Sgb31 - 21-10-2024 Bonjour, YA t-il un impact lorsque les mesures se font via un Shelly EM ? RE: Minuscule bug sur les mesures U & I - F1ATB - 21-10-2024 Non pas d'impact avec Shelly Em uniquement pour UxI ou le compteur des microsecondes n'est pas un multiple de 200. La version 12 . 05, sortie ce jour, corrige ce petit souci. Cordialement, André. RE: Minuscule bug sur les mesures U & I - Youpimatin - 22-10-2024 Bonsoir André, voici une meilleure solution, belle, propre et qui fonctionne enfin à 100%, testée sur 24h, plus aucune mauvaise mesure de V et de I (enfin... à part les valeurs au démarrage, mais c'est un autre problème) : typedef union { uint64_t U64; struct { unsigned long Lower; unsigned long Upper; } U32; } uint64_32; void MeasurePower() { //Lecture Tension et courants pendant 20ms int iStore; value0 = analogRead(AnalogIn0); //Mean value. Should be at 3.3v/2 static uint64_32 Micros64 = {0}; unsigned long Micros32; unsigned long MeasureMillis = millis(); while (millis() - MeasureMillis < 21) { //Read values in continuous during 20ms. One loop is around 150 micro seconds Micros32 = micros(); if(Micros32 < Micros64.U32.Lower) { Micros64.U32.Upper ++; } Micros64.U32.Lower = Micros32; iStore = (Micros64.U64 % 20000) / 200; //We have more results that we need during 20ms to fill the tables of 100 samples volt[iStore] = analogRead(AnalogIn1) - value0; amp[iStore] = analogRead(AnalogIn2) - value0; } } Bonne soirée à vous, et si besoin d'explications je reste disponible. RE: Minuscule bug sur les mesures U & I - F1ATB - 22-10-2024 Là, il faut que je révise pour tout comprendre. Je n'ai pas l'habitude d'utiliser ces structures. Je mettrai ce code dans une prochaine révision. Cela fonctionne, je vous fais confiance. @+ André |