Je subodore un calcul de moyenne glissante, mais la problématique étant tellement obscure en effet ...C'est surtout que ne nous a pas dit grand chose du problème !
Si tu pouvais détailler la problématique exacte (et surtout lire les réponses) ...
Par exemple pourquoi cumuler les valeurs ?
Vont elles être utilisées pour autre chose que le calcul de la moyenne
Edit: croisement avec Jack !
Bonsoir ...
je vais vous expliquer encore une fois , car on tombe dans un problème de mal compris ...
le fait de cumuler jusqu'à la fin va ne me permet pas de afficher les 5000 échantillonne à chaque fois quand n augmente ...
alors il faut que à chaque fois quand je reçois une interruption de lire 5k pts et de faire la moyenne avec les 5k pts précédents et les afficher ... voila le programme pour bien comprendre le cahier de charge ..
Code:void __attribute__((interrupt, no_auto_psv)) _INT0Interrupt(void) { for(i=0;i<5000;i++) { AD1CON1bits.SAMP = 1; // start sampling while (!AD1CON1bits.DONE); // wait until the value is ready to read voie_1[i] = (ADC1BUF0+n*voie_1[i])/(n+1); // lire la valeur stocké dans le buffer } n=n+1; IFS0bits.INT0IF =0; // clear flag INT0 }
Peut-être que le français n'est pas ta langue maternelle, mais désolé, je ne comprends rien à ton problème car soit les phrases ne veulent rien dire, soit il manque encore des informations.le fait de cumuler jusqu'à la fin va ne me permet pas de afficher les 5000 échantillonne à chaque fois quand n augmente ...
J'ai beau regarder ton programme, je ne vois pas à quel moment tu fais la moyenne des 5000 points avec les 5000 points précédents.il faut que à chaque fois quand je reçois une interruption de lire 5k pts et de faire la moyenne avec les 5k pts précédents et les afficher
Je ne vois pas non plus à quel moment la moyenne est affichée dans ce programme d'interruption.
Dernier point mystérieux: que fais-tu des valeurs stockées dans le tableau voie_1 une fois que le programme d'interruption est terminé?
Je ne comprends pas non plus le rôle de n qui correspond au nombre d'entrées dans le programme d'interruption et qui n'est donc jamais remis à zéro alors qu'il sert au calcul de ta moyenne.
De toutes manière je trouve que ce programme est mal écrit car un programme d'interruption doit être le plus court possible, ce qui n'est pas le cas ici puisqu'il dure le temps de lire les 5000 échantillons. Pourquoi ne pas avoir créé une fonction d'interruption pour chaque fin de conversion de l'ADC?
Merci Jack pour votre temps , oui effectivement c'est pas ma langue maternelle ,
en fait voila la moyenne ( au fur et à mesure) voie_1[i] = (ADC1BUF0+n*voie_1[i])/(n+1); mais comme j'ai vous dit , je tombe sur le problème de cumule des arrondi...
au début n est initialisé par 0, et dans la fonction main() je la compare avec N total saisi par l'utilisateur" (nombre de sommation).
quand je sort de l'interruption , dans la fonction main() j'affiche 5000pts moyenné et j'attend la prochaine interruption ....
pour refaire la même chose jusqu’à n=N
Merci
Tu affiches 5000 points ou la moyenne des 5000 points?j'affiche 5000pts moyenné
Non j'affiche 5000 pts ... et a chaque fois il faut faire la moyenne avec les 5k pts suivants...
C'est bizarre mais admettons ...
Pour les problèmes d'arrondi, plutôt que de calculer la moyenne au fur et à mesure, pourquoi ne pas tout cumuler dans un entier long et diviser à la fin des 5000 mesures?
Faut-il absolument 5000 mesures à chaque fois, car avec 4096, un simple décalage de 12 bits suffirait et éviterait une division.
Oui il faut que je fais la moyenne à chaque fois, et l'afficher
voie_1[0] avec voie_[0] suivant et faire la moyenne ...voie_1[1] avec voie_[1] suivant et faire la moyenne... etc (pour étre synchronisé) c'est ça le rôle du boucle for
si j'ai pas l'affichage à chaque coup ça va être facile, je vais cumuler et à la fin je devise par N, mais par contre le cahier de charge demande d'afficher la moyenne à chaque coup
C'est trop mystérieux pour que j'y trouve une quelconque logique.
cas stockage de la somme et du nombre:
l'ajout consiste à:
somme = somme + nouveau
nombre = nombre + 1
print (somme / nombre) # une variable cachée
=> un incrément, une addiction, une division.
cas stockage de la moyenne et du nombre:
moyenne = moyenne * nombre
moyenne = moyenne + nouveau
nombre = nombre + 1
moyenne = moyenne / nombre
print (moyenne)
=> un incrément, une addiction, une multiplication, une division.
donc le dernier cas complique avec une multiplication en plus et fait perdre de la précision. le seul faible avantage et de ne nécessiter que 2 variables.
Jusqu'ici tout va bien...
lapsus marrantune addiction
J'ai hésité à relever pour ne pas poluer le fil !
Et donc pour que ce post reste utile: dans le cas 2 de polo, justement, on va accumuler les erreurs d'arrondis, ce que Jack proposait d'éviter, avant que ce fil ne parte en sucette:
Je comprends de moins en moins la demande perso...
On "moyenne" une sérié de 5 000 valeurs saisies puis récupérées d'on ne sait d'où, puis de plusieurs séries de 5 000 valeurs, le nombre même 5 000 n'apparaît qu'au bout de plusieurs post alors que le nombre de saisie a été demandé depuis le début...
On parle d'économie de mémoire, on accumule allégrement les tableaux de 5 000 float (je suppose ?).
En dév, le mot synchronisé a un sens bien précis...pour être synchronisé
Et j'en passe...
J'ai glissé Chef !
Correcteur ortografik qui transforme les coquilles en co()uilles + relecture en diagonale...
En plus, je n'avais pas lu tout le fil, d'où réponse en déphasage...
Bon, pour une moyenne glissante, il faut en effet la file des échantillons (un tableau et un index du point courant) pour pourvoir retrancher l’échantillon sortant.
Et puisqu'on est en moyenne glissante avec un nombre d'échantillon fixe, il suffit de sommer les x[i] et de multiplier la somme par (1./N) avant d'afficher.
Jiav,
Ton code (avec moyenne, résidu et nombre): la moyenne obtenue est alors entière (sauf multiplication pour passer en "virgule fixe").
C'est sûr que là, pas de pb lié aux floats, et on maîtrise les débordements (à condition de réaliser régulièrement le calcul de la moyenne, sinon, le résidu peut tout de même intégrer)...
J'aime bien... (ça me rappelle un peu Bresenham et sa version généralisée)
Jusqu'ici tout va bien...
Oui Polo c'est exactement ce qu'il faut faire, avec les tableaux de type float, on tombe pas sur le problème de cumule des arrondis , je vais essayer le maximum possible de ne pas avoir plus d'erreurs ..
Merci à votre aides les amis ...
Avec un tableau de float tu vas occuper le double de RAM par rapport à un tableau d'uint16_t et tu as dit que tu étais déjà limite de ce côté-là.
Oui Jack , c'est ça ...
je vais essayer d'avoir le moindre erreur possible avec tab de type int