Go Down

Topic: Mesure de régime moteur (Read 5609 times) previous topic - next topic

Super_Cinci

#15
Feb 14, 2012, 10:08 pm Last Edit: Feb 15, 2012, 07:02 am by Super_Cinci Reason: 1
Code: [Select]

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout){

// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution.  calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area

// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;

// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask) if (numloops++ == maxloops) return 0;

// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask) if (numloops++ == maxloops) return 0;

// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops) return 0;
width++;
}
return clockCyclesToMicroseconds(width * 21 + 16);
}

Bon, ben tout est là : il n'y a que des while... donc c'est une fonction qui fait perdre énormément de temps... Par contre, elle n'utilise aucun timer ni interruption, et ça marche sur toutes les pins... à voir selon ce que l'on veut faire en plus...

Petit EDIT du matin, la nuit porte conseil...

Si jamais on utilise une interruption et qu'elle intervient pendant pulseIn(), la mesure sera faussée (pulseIn() part sur le nombre de cycles que prennent les boucles while, ce qui fait que toute interruption du code n'est pas comptée, ralenti les boucles, donc diminue la valeur retournée).

rien que :
Code: [Select]

#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)

// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)

volatile unsigned long timer0_overflow_count = 0;
volatile unsigned long timer0_millis = 0;
static unsigned char timer0_fract = 0;

SIGNAL(TIMER0_OVF_vect)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;

m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}

timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}
c'est l'interruption overflow du timer0 qui met à jour les données utilisées dans millis() et micros(), je ne suis pas sûr que ce soit prévu dans le code de pulseIn(), alors oui, c'est ma proc la plus précise...

Jean-François

#16
Feb 15, 2012, 12:18 pm Last Edit: Feb 19, 2012, 10:04 pm by Jean-François Reason: 1
Et en utilisant micros() en comptant la différence entre chaque étincelle, avec un lissage sur trois-quatre mesure, ça n'irait pas ?
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

catsur

#17
Feb 19, 2012, 10:02 pm Last Edit: Feb 19, 2012, 10:08 pm by catsur Reason: 1
Je n'avais pas pris le temps de regarder le code avant ce soir. C'est exactement ce qu'il me faut, je te remercie beaucoup.

J'ai trois questions. J'ai essayé de comprendre ton code, et comme je débute je peine à tout comprendre. Cependant, si j'ai bien compris, tu surveilles les impulsions entrantes dans l'Arduino dans le setup en même temps que tu exécute ton programme dans le loop. Je ne savais pas que c'était possible avec Arduino, c'est donc possible de faire du multitâche?

Seconde question :


Il est tout à fait possible d'utiliser un enroulement autour d'un fil de bougie, je l'ai déjà fait. Je déclenchais un NE555 avec 20 tours de fils telecomm autourdu fil qui sort de la bobine. Pour protéger l'arduino, il suffit de faire le schéma suivant :


Sur ton schéma je ne comprend pas ou tu branches ton NE555 en fait  :smiley-red: :smiley-red: :smiley-red: Il est où sur ton schéma? Au niveau de ton J2 tu te branches sur l'Arduino ou sur ton NE555?

Dernière question un peu plus terre à terre, qu'appelle-tu du fil telecom?

Merci je vais essayer de mettre ça en application.
Une petite visite sur le site de notre projet? C'est par ici : http://ok24.jimdo.com/
Do you want to learn more about our project? Click her

Super_Cinci


Je n'avais pas pris le temps de regarder le code avant ce soir. C'est exactement ce qu'il me faut, je te remercie beaucoup.

ça t'aidera sûrement, mais en effet :

J'ai trois questions
pour l'instant... ;)
. J'ai essayé de comprendre ton code, et comme je débute je peine à tout comprendre. Cependant, si j'ai bien compris, tu surveilles les impulsions entrantes dans l'Arduino dans le setup en même temps que tu exécute ton programme dans le loop. Je ne savais pas que c'était possible avec Arduino, c'est donc possible de faire du multitâche?

Non, ce n'est pas du multitâche au sens de ce qu'il se passe dans ton PC. Une interruption est un évènement physique qui peut intervenir à tout moment : une impulsion sur une entrée spécifique, un timer qui arrive à une certaine valeur... Dès que cet évènement se produit, alors l'arduino stoppe tout ce qu'il faisait avant, et fait ce que tu lui as demandé de faire dans une telle situation (ISR). une fois qu'il a fait ce que tu lui avais dit de faire, il reprend là où il en était avant.

Seconde question :


Il est tout à fait possible d'utiliser un enroulement autour d'un fil de bougie, je l'ai déjà fait. Je déclenchais un NE555 avec 20 tours de fils telecomm autourdu fil qui sort de la bobine. Pour protéger l'arduino, il suffit de faire le schéma suivant :


Sur ton schéma je ne comprend pas ou tu branches ton NE555 en fait  :smiley-red: :smiley-red: :smiley-red: Il est où sur ton schéma? Au niveau de ton J2 tu te branches sur l'Arduino ou sur ton NE555?
l'entrée du 555 (ou la pin INT0 de l'arduino) se câble en direct entre le collecteur du transistor et la résistance qui va au +5V, c-à-d sur J2.

Dernière question un peu plus terre à terre, qu'appelle-tu du fil telecom?
C'est un fil mono brin (rigide) utilisé dans les paires télécomm, en général du 0.5mm². c'est un fil idéal pour nos câblages sur bread-board, que l'on peut trouver par kilos si on connait quelqu'un qui en utilise professionnellement (un monsieur des télécoms quoi...). on le trouve par paire dans des gaines blanches ou grises, j'avais la chance d'avoir papa chez FT R&D, donc je dois avoir une centaine de mètres de 64 paires... de quoi câbler sur quelque siècles...

Bon courage!

catsur



J'ai trois questions
pour l'instant... ;)


Donc me revoilà!

Merci pour ta réponse, désolé je mets du temps à répondre, mais en fait la semaine j'ai pas trop le temps de penser à tout ça.

Donc, je pensais à un truc : si je branche J2 directement sur une entrée de l'arduino, et que je fais un programme dans mon loop du genre :
- Relever le timer
- Un while pour dire "tant que J2 est à 0 je reste là"
- Quand J2 est à 1, je relève le timer (je pense faire une boucle ici pour attendre 10 étincelles pour avoir une valeur plus précise)
- Je fais la différence sur le timer pour connaitre l'interval entre les deux étincelles
- Et hop je connais mon régime moteur!

Ce n'est pas plus simple? :smiley-roll-blue: Bien que je remette pas en cause ton programme bien sûr mais je préfère faire quelque chose que je comprenne car il faut que je progresse en écrivant mes propres programmes!
Une petite visite sur le site de notre projet? C'est par ici : http://ok24.jimdo.com/
Do you want to learn more about our project? Click her

Super_Cinci

#20
Feb 21, 2012, 08:50 pm Last Edit: Feb 22, 2012, 10:30 am by Super_Cinci Reason: 1
ça marchera, pas de soucis. penses à remettre le timer à zéro à chaque relevé, ça t'évitera de faire une différence.

Le seul inconvénient, c'est que tu ne pourras rien faire d'autre pendant la mesure. l'interruption (INT0) fait ce boulot en "tâche de fond" : elle relève le compteur dès que J2 passe à 1. Tu y viendras sûrement plus tard, prends ton temps!

il se peut que tes mesures ne soient pas très précises, il te faudra peut-être une capa de quelque dizaines de nano entre J2 et le 0V histoire d'éviter les rebonds... à voir dans la pratique.

catsur

Ok, je vais faire ça alors dans un premier temps car je peine à comprendre ton code!

Merci en tout cas pour ton aide!
Une petite visite sur le site de notre projet? C'est par ici : http://ok24.jimdo.com/
Do you want to learn more about our project? Click her

Go Up