Bienvenue aux nouveaux arrivants sur FantasPic !
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
notion de Laps de temps
Bonsoir à tous,
Non je n'ai pas boudé le site, bien au contraire...
Aujourd'hui, je suis face à une difficulté de "time".
je suis entrain de programmer un Module MPU6050 qui comprends 7 capteurs sur 6 axes:
- 3 pour l'acceleration [X-Y-Z]
- 3 pour le gyro [X-Y-Z]
Coté progammation et pic:
-MPLAB X v5.10
-Compliteur XC8 v2.31
-PIC18F4550 (avec oscill interne)
-I²C pour communiquer avec le Module
-UART pour afficher en liaison serie avec TeraTerm
1/Accel
les valeurs Brutes des 3 Axes Acc sont bien lues-->ok
je convertis ces valeurs et je calcul les angles en degres-->ok
2/Gyro
les valeurs Brutes des 3 Axes Gyro sont bien lues-->ok
je convertis ces valeurs et je calcul les offset sur les 3 axes gyro-->ok
je retranche bien ces offsets dans la suite du programme-->ok
je convertis bien ces valeurs en °/S pour obtenir des degres-->
3/Association des valeurs GYRO & Acc pour eliminer/compenser les perturbation:
Application du filtre Passe-Bas sur Acc-->ok
Application du filtre Passe-Haut sur Gyro->Nok
Biensur, vous l'aurez tous compris, je ne suis pas un génie et je n'ai pas réinventer la poudre (je me suis inspirer d'un programme Arduino)...
il existe une fonction qui permet de calculer un laps de temps ecouler entre 2 moments sans pour autant arreter le programme de fonctionnement: fonction milli();
cette fonction retourne un laps de temps entre 2 moments....
j'essaye de trouver une fonction similaire adapter sur nos PIC sans passer par les interruptions qui ferait une pause de sequence fatale pour le calcul.
j'avais pensé à une sorte d'interruption "vituelle", juste un flag de debordement en incrementant un compteur....
auriez vous une idée voir uen fonction toute faite???
evidemment n'etant pas egoiste, le projet terminé, je le proposerai en TUTO
Merci à vous..
franck
Non je n'ai pas boudé le site, bien au contraire...
Aujourd'hui, je suis face à une difficulté de "time".
je suis entrain de programmer un Module MPU6050 qui comprends 7 capteurs sur 6 axes:
- 3 pour l'acceleration [X-Y-Z]
- 3 pour le gyro [X-Y-Z]
Coté progammation et pic:
-MPLAB X v5.10
-Compliteur XC8 v2.31
-PIC18F4550 (avec oscill interne)
-I²C pour communiquer avec le Module
-UART pour afficher en liaison serie avec TeraTerm
1/Accel
les valeurs Brutes des 3 Axes Acc sont bien lues-->ok
je convertis ces valeurs et je calcul les angles en degres-->ok
2/Gyro
les valeurs Brutes des 3 Axes Gyro sont bien lues-->ok
je convertis ces valeurs et je calcul les offset sur les 3 axes gyro-->ok
je retranche bien ces offsets dans la suite du programme-->ok
je convertis bien ces valeurs en °/S pour obtenir des degres-->
3/Association des valeurs GYRO & Acc pour eliminer/compenser les perturbation:
Application du filtre Passe-Bas sur Acc-->ok
Application du filtre Passe-Haut sur Gyro->Nok
Biensur, vous l'aurez tous compris, je ne suis pas un génie et je n'ai pas réinventer la poudre (je me suis inspirer d'un programme Arduino)...
il existe une fonction qui permet de calculer un laps de temps ecouler entre 2 moments sans pour autant arreter le programme de fonctionnement: fonction milli();
cette fonction retourne un laps de temps entre 2 moments....
j'essaye de trouver une fonction similaire adapter sur nos PIC sans passer par les interruptions qui ferait une pause de sequence fatale pour le calcul.
j'avais pensé à une sorte d'interruption "vituelle", juste un flag de debordement en incrementant un compteur....
auriez vous une idée voir uen fonction toute faite???
evidemment n'etant pas egoiste, le projet terminé, je le proposerai en TUTO
Merci à vous..
franck
notion de Laps de temps
Bonjour francknvs, et tout le forum,
Il faudrait que tu nous donnes le temps mini et maxi que tu veux.
Sinon, sans aucune interruption, il y le timer1 qui est très simple à mettre en oeuvre, comptage jusqu’à 65535 sans utiliser les diviseurs.
il y a 2 façons de l'utiliser, soit on compte les instructions qui se déroule pendant le programme , soit on compte les instructions sur une pin dédié au comptage d'un nombre de battement.
En version ASM ça donne ceci
A+
Il faudrait que tu nous donnes le temps mini et maxi que tu veux.
Sinon, sans aucune interruption, il y le timer1 qui est très simple à mettre en oeuvre, comptage jusqu’à 65535 sans utiliser les diviseurs.
il y a 2 façons de l'utiliser, soit on compte les instructions qui se déroule pendant le programme , soit on compte les instructions sur une pin dédié au comptage d'un nombre de battement.
En version ASM ça donne ceci
Code : Tout sélectionner
clrf TMR1L
clrf TMR1H
bsf T1CON,TMR1ON ; lancer le timer1
; <<<========== ; comptage du temps
bcf T1CON,TMR1ON ; arrêt du timer1
movf TMR1H,W ; récupérer le temps high dans la variable res16
movwf res16
movf TMR1L,W ; récupérer le temps low dans la variable res8
movwf res8
A+
notion de Laps de temps
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour Frank et à tous,
En C, usage d'un timer exemple ici
sur les nouveaux PIC comme le 18F27K42 il y a un compteur 24 bits avec FOSC en entree , donc résolution maxi
pour mesurer une duree d'execution ...
sinon, utiliser le debugger pour compter le nb d'instruction écoulés ..
En C, usage d'un timer exemple ici
sur les nouveaux PIC comme le 18F27K42 il y a un compteur 24 bits avec FOSC en entree , donc résolution maxi
pour mesurer une duree d'execution ...
sinon, utiliser le debugger pour compter le nb d'instruction écoulés ..
notion de Laps de temps
Bonjour à tous, une remarque sur les timers
Les timers 16 bits sur processeur 8 bits présentent un problème. Il faut 2 instructions pour lire ou écrire la valeur 16 bits du timer. Si le débordement du timer se produit entre ces 2 instructions, la valeur 16 bits lue ou écrite sera fausse.
Pour contrer cela ils ont prévu un registre tampon pour TMRxH, non accessible directement, alors que TMRxL est en accès direct read/write.
On lit en premier TMRxL, cela met à jour le tampon TMRxH. Les 16 bits sont ainsi prélevés en même temps. TMRxH peut être ensuite être lu. Pour l'écriture on écrit d'abord le tampon TMR0H, ensuite on écrit TMRxL, cela déclenche l'écriture des 16 bits en même temps dans le timer.
En ce qui concerne le 18F4550, ce mécanisme est toujours actif sur le timer 0. Pour le timer 1 c'est sur option, on l'active avec le bit RD16 dans la config du timer.
Ma version des fonctions Arduino-like, sans utiliser les interruptions.
Les timers 16 bits sur processeur 8 bits présentent un problème. Il faut 2 instructions pour lire ou écrire la valeur 16 bits du timer. Si le débordement du timer se produit entre ces 2 instructions, la valeur 16 bits lue ou écrite sera fausse.
Pour contrer cela ils ont prévu un registre tampon pour TMRxH, non accessible directement, alors que TMRxL est en accès direct read/write.
On lit en premier TMRxL, cela met à jour le tampon TMRxH. Les 16 bits sont ainsi prélevés en même temps. TMRxH peut être ensuite être lu. Pour l'écriture on écrit d'abord le tampon TMR0H, ensuite on écrit TMRxL, cela déclenche l'écriture des 16 bits en même temps dans le timer.
En ce qui concerne le 18F4550, ce mécanisme est toujours actif sur le timer 0. Pour le timer 1 c'est sur option, on l'active avec le bit RD16 dans la config du timer.
Ma version des fonctions Arduino-like, sans utiliser les interruptions.
Code : Tout sélectionner
// 18F4550 Fosc = 8MHz
#pragma config FOSC = INTOSC_EC
#pragma config WDT = OFF
#include <xc.h>
unsigned long step_us=0, step_ms=0;
unsigned long MicroSec(void)
// temps écoulé en us depuis reset, résolution 8us
// revient à 0 après 70 minutes (8192 overflows timer)
{
unsigned int tmr = TMR0L; tmr += (unsigned int)TMR0H<<8;
return step_us + 8L*tmr;
}
unsigned long MilliSec(void)
// temps écoulé en ms depuis reset
// revient à 0 après 50 jours
{
unsigned int tmr = TMR0L; tmr += (unsigned int)TMR0H<<8;
return step_ms + (step_us + 8L*tmr)/1000;
}
void main(void)
{
OSCCON = 0x72; // intosc Fosc=8MHz, Fcy=2MHz, Tcy=500ns
T0CON = 0x83; // timer0 16 bits prescaler 16, step 8us, overflow 524ms
while (1) {
// clignotement led chaque seconde
static unsigned long ms_last=0;
unsigned long ms = MilliSec();
if (ms-ms_last > 1000) {
ms_last = ms;
TRISCbits.TRISC2 = 0; // toggle led
LATCbits.LATC2 = !LATCbits.LATC2;
}
// compter les overflows timer (à faire au moins chaque 1/2 seconde)
if (INTCONbits.TMR0IF) {
INTCONbits.TMR0IF = 0;
step_us += 65536L*8;
if (!step_us) step_ms += 4294967;
}
}
}
notion de Laps de temps
Bonsoir,
Merci à vous trois pour vos reponses rapides et consisent
Je suis actuellement en déplacement et je ne peux essayer vos solutions (vivement ce we)
Je viens tout juste de me mettre au pic18f apres m etre formé au 16f876....
De plus je ne suis pas a l aise avec le nouveau compilateur proposé (XC8 en v2.31)....les
variables des bibliothèques sont un peu differentes sans parler des header...
Je vais essayer de mettre en oeuvre les timer.
Tempsx,
Merci pour tes remarques, meme si ça fait un petit moment que j ai abandonné, cela m avais bien servi a comprendre le fonctionnement des instructions et surtout la bonne gestion precise du temps liée par nos pic.
Paul,
Merci egalement pour tes conseils et sur la richesse de ton site où je me presse d aller faire un petit tour incognito pour "pomper" ton savoir faire face à une difficulté.
En tout cas un grd merci à vous 3
Satinas,
Ton code proposé semble correspondre exactement à mon attente,
Je comprends que c est une conversion de la fonction milli() et micro() d arduino en C qui permet de retourner un laps de temps entre 2 moments...ou en tout cas depuis le dernier reset
Franck
Merci à vous trois pour vos reponses rapides et consisent
Je suis actuellement en déplacement et je ne peux essayer vos solutions (vivement ce we)
Je viens tout juste de me mettre au pic18f apres m etre formé au 16f876....
De plus je ne suis pas a l aise avec le nouveau compilateur proposé (XC8 en v2.31)....les
variables des bibliothèques sont un peu differentes sans parler des header...
Je vais essayer de mettre en oeuvre les timer.
Tempsx,
Merci pour tes remarques, meme si ça fait un petit moment que j ai abandonné, cela m avais bien servi a comprendre le fonctionnement des instructions et surtout la bonne gestion precise du temps liée par nos pic.
Paul,
Merci egalement pour tes conseils et sur la richesse de ton site où je me presse d aller faire un petit tour incognito pour "pomper" ton savoir faire face à une difficulté.
En tout cas un grd merci à vous 3
Satinas,
Ton code proposé semble correspondre exactement à mon attente,
Je comprends que c est une conversion de la fonction milli() et micro() d arduino en C qui permet de retourner un laps de temps entre 2 moments...ou en tout cas depuis le dernier reset
Franck
notion de Laps de temps
Bonjour,
Les 2 fonctions Arduino sont les mêmes, elles reviennent à 0 après 70 minutes et 50 jours.
Dans l'exemple, il faut vérifier toutes les 1/2 seconde si le flag timer est passé à 1.
Si tu as des calculs longs, tu peux augmenter la résolution du timer, et ainsi surveiller le flag moins souvent. En passant au timer 1 avec prescaler 256, ce sera toutes les 8 secondes. Mais dans ce cas la fonction MicroSec() perd en précision, elle retournera au mieux des 1/10 de ms.
D'autre part, il manque un test du flag timer en début des 2 fonctions, pour détecter un éventuel débordement qui n'a pas encore été pris en compte. Du genre -> if (INTCONbits.TMR0IF) Update();
Les 2 fonctions Arduino sont les mêmes, elles reviennent à 0 après 70 minutes et 50 jours.
Dans l'exemple, il faut vérifier toutes les 1/2 seconde si le flag timer est passé à 1.
Si tu as des calculs longs, tu peux augmenter la résolution du timer, et ainsi surveiller le flag moins souvent. En passant au timer 1 avec prescaler 256, ce sera toutes les 8 secondes. Mais dans ce cas la fonction MicroSec() perd en précision, elle retournera au mieux des 1/10 de ms.
D'autre part, il manque un test du flag timer en début des 2 fonctions, pour détecter un éventuel débordement qui n'a pas encore été pris en compte. Du genre -> if (INTCONbits.TMR0IF) Update();
notion de Laps de temps
- Claudius
Passioné- Messages : 260
- Âge : 69
- Enregistré en : septembre 2015
- Localisation : ELANCOURT (78 - YVELINES)
- Contact :
Bonjour,
Si je comprends parfaitement que le retour à zéro se passe tous les 70 minutes ou 50 jours, je trouve que tester toutes les 1/2 seconde (voire plus, suivant la résolution attendue) est rédhibitoire pour l'utilisateur; cela l'oblige à gérer un second timer pour ne pas rater l’événement ;-))
Par principe, il est impératif de cacher la cuisine qui est en dessous et donc passer par un traitement très bref qui pallie à ce défaut en implémentant par exemple:
- Une interruption sur débordement du timer qui devient donc transparent pour l'utilisateur
- Une comptabilisation sous interruption d'un compteur le plus large possible qui, inexorablement, retournera à terme à zéro (cas de l’implémentation sur les Arduino) avec naturellement les protections habituelles de lecture / écriture concurrentes sous It et hors It
- Une gestion au plus près d'un timer hard (raz, armement et lecture) dans le cas d'une durée en µS attendue
Edit: S'agissant de:
3/Association des valeurs GYRO & Acc pour éliminer/compenser les perturbations:
Application du filtre Passe-Bas sur Acc-->ok
Application du filtre Passe-Haut sur Gyro->Nok
... je serai intéressé (principe retenu, algorithme, erreurs constatées, etc.) du fait que c'est Nok pour le filtre passe-haut sur le Gyro hormis la demande citée en objet
Est-ce l'implémentation du filtre de Kalman comme décrit dans l'article Bruit, filtre Kalman et fusion des capteurs qui pose problème ?
A suivre...
Si je comprends parfaitement que le retour à zéro se passe tous les 70 minutes ou 50 jours, je trouve que tester toutes les 1/2 seconde (voire plus, suivant la résolution attendue) est rédhibitoire pour l'utilisateur; cela l'oblige à gérer un second timer pour ne pas rater l’événement ;-))
Par principe, il est impératif de cacher la cuisine qui est en dessous et donc passer par un traitement très bref qui pallie à ce défaut en implémentant par exemple:
- Une interruption sur débordement du timer qui devient donc transparent pour l'utilisateur
- Une comptabilisation sous interruption d'un compteur le plus large possible qui, inexorablement, retournera à terme à zéro (cas de l’implémentation sur les Arduino) avec naturellement les protections habituelles de lecture / écriture concurrentes sous It et hors It
- Une gestion au plus près d'un timer hard (raz, armement et lecture) dans le cas d'une durée en µS attendue
Edit: S'agissant de:
3/Association des valeurs GYRO & Acc pour éliminer/compenser les perturbations:
Application du filtre Passe-Bas sur Acc-->ok
Application du filtre Passe-Haut sur Gyro->Nok
... je serai intéressé (principe retenu, algorithme, erreurs constatées, etc.) du fait que c'est Nok pour le filtre passe-haut sur le Gyro hormis la demande citée en objet
Est-ce l'implémentation du filtre de Kalman comme décrit dans l'article Bruit, filtre Kalman et fusion des capteurs qui pose problème ?
A suivre...
Enregistreur de traces GPS & Boussole GPS parlante (PIC & Arduino)
notion de Laps de temps
bonsoir Claudius,
mon "Nok" dans:
Correspond à mes étapes de réalisation sur le projet,
je n'ai pas encore attaqué l'association des valeurs des 6 capteurs sur les axes,il me fallait la routine permettant de calculer un laps de temps entre 2 moments.
cordialement,
franck
mon "Nok" dans:
3/Association des valeurs GYRO & Acc pour éliminer/compenser les perturbations:
Application du filtre Passe-Bas sur Acc-->ok
Application du filtre Passe-Haut sur Gyro->Nok
Correspond à mes étapes de réalisation sur le projet,
je n'ai pas encore attaqué l'association des valeurs des 6 capteurs sur les axes,il me fallait la routine permettant de calculer un laps de temps entre 2 moments.
cordialement,
franck
notion de Laps de temps
Bonsoir
Une nouvelle version, bug free, le premier qui trouve un bug gagne une boîte de masques à peine entamée.
Si tu utilises l'interruption timer, l'ISR fait un Update(). dans ce cas plus besoin de tester le flag dans le while(1). Il faut désactiver l'interruption lors de l'exécution de MicroSec().
Une nouvelle version, bug free, le premier qui trouve un bug gagne une boîte de masques à peine entamée.
Si tu utilises l'interruption timer, l'ISR fait un Update(). dans ce cas plus besoin de tester le flag dans le while(1). Il faut désactiver l'interruption lors de l'exécution de MicroSec().
Code : Tout sélectionner
// 18F4550 Fosc = 8MHz 17/06/2021
#pragma config FOSC = INTOSC_EC
#pragma config WDT = OFF
#include <xc.h>
unsigned long step_ms=0, step_us=0;
void Update(void)
// traiter overflow timer
{
INTCONbits.TMR0IF = 0;
((unsigned int*)&step_us)[1] += 8; // step_us += 8*65536;
if (!((unsigned int*)&step_us)[1]) step_ms += 4294967;
}
unsigned long MicroSec(void)
// temps écoulé en us depuis reset, résolution 8us
// revient à 0 après 70 minutes (8192 overflows timer)
{
unsigned int tmr;
((unsigned char*)&tmr)[0] = TMR0L;
((unsigned char*)&tmr)[1] = TMR0H;
// si l'overflow se produit à cet instant précis, TMR0 doit être relu
if (INTCONbits.TMR0IF) {
Update();
((unsigned char*)&tmr)[0] = TMR0L;
((unsigned char*)&tmr)[1] = TMR0H;
}
return step_us + 8L*tmr;
}
unsigned long MilliSec(void)
// temps écoulé en ms depuis reset
// revient à 0 après 50 jours
{
return step_ms + MicroSec()/1000;
}
void main(void)
{
OSCCON = 0x72; // intosc Fosc=8MHz, Fcy=2MHz, Tcy=500ns
T0CON = 0x83; // timer0 16 bits, prescaler 16, step 8us, overflow 524ms
while (1) {
// traiter overflow timer (à faire au moins chaque 1/2 seconde)
if (INTCONbits.TMR0IF) Update();
}
}
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 60 invités