NE555 et arduino - Fréquence incorrecte.

Bonjour !

Je suis bidouilleur et débutant en électronique et arduino.
J'ai quelques uns des nombreux tutos de base (avec led, boutons, potentiomètre...)
Je m'attaque maintenant à la réalisation d'un compte tour pour ma moto.
Mais pour commencer j'aimerais simuler les impulsions de l’allumage, pour apprendre déjà et tester le compte tour.

J'utilise pour ça ce petit montage à ba se de NE555 :

Avec C : 1µF ; R1 : 200R ; R2 47K . Ca devrait me donner 15.318Hz soit environ 918RPM, un régime de ralentit à peu près...

Pour tester j'utilise ce code trouvé sur ce forum :

/*
 size = 2996
 Version 1.0
 
 To measure a frequency pulse and display in the serial monitor.
 
 Connect the pulse source to pin 2. 
 The source have to be a +5 V to Gnd signal.
 
 In this experiment, I use a second Arduino to generated
 a pulse.  A 555 in astable mode can be use.
 Just connect pin 3 of the 555 to pin 2 of the Arduino.
 
 Program by Serge J Desjardins aka techone
 Toronto, Ontario, Canada
 
 Compile and Tested 

*/

byte freqpin = 2;

unsigned long timeone;

unsigned int frequency;
unsigned int timediff;

unsigned int tcount=0;

// sample time of 1 second or 1000 ms.
unsigned int sampletime=1000;

volatile unsigned int count=0;

void setup()
{
 pinMode(freqpin, INPUT);
 attachInterrupt(0,freqinput,RISING);
 // set interrupt pin 2 and use rising ( from gnd to +5 ) 
  Serial.begin(9600); 
} 

void loop()
{
 /* Use while() loop and use millis(). 
    Calculate the time difference and compare the 
    value with the sample time. 
 */
 // activate the interrupt
 tcount=0;
 count=0;
 timediff=0;
 attachInterrupt(0,freqinput,RISING);

 timeone=millis();
 while(timediff<sampletime)
 {
  tcount=count;
  timediff=millis()-timeone; 
 }
 // de-activated the interrupt
 detachInterrupt(0);
 
 // Calculated frequency
frequency=tcount; 
 
 // Display frequency
 Serial.print("Test while - ");
 Serial.print("Frequency : ");
 Serial.println(frequency,DEC);
 delay (100);
 
}  

// The interrupt routine
void freqinput ()
{
  count++;
}

J'utilise tout ça avec un Pro Mini 5v et j'alimente le NE555 par le vcc du Pro mini.

Alors problèmes :
Sur le moniteur il m'affiche entre 16 et 17Hz voir 18. Et quand je transforme en RPM on est pas vraiment bon :~
Non seulement ce n'est pas bon et pas stable, mais j'ai aussi remarqué que ça changer selon la tension d'alimentation du NE555...
Avec des piles je n'est pas le même résultat. :astonished:

Bref, des idées ? des solutions ?

Merci d'avance XD

Salut,

je vois pas trop comment tu veux procéder. Normalement tu n'as pas à jouer avec attachInterrupt() detachInterrupt en permanence, ce qui doit mettre un sacré bordel ...

Plutôt :

#define sampletime 1000
#define  freqpin  2

unsigned long timeone;

volatile unsigned int count=0;

void setup()
{
 pinMode(freqpin, INPUT);
 attachInterrupt(0,freqinput,RISING);
  Serial.begin(9600); 
  timeone=millis();

} 

void loop() {

if(millis()>=(timeone+sampletime)) {
timeone=millis();
count=0;
float Freq = count / (sampletime/1000.0);
  Serial.print("Frequency : ");
 Serial.println(frequency,DEC);
 }
 
}  

void freqinput ()
{
  count++;
}

arf il me sort ça du coup :

Frequency : 17.0000000000
Frequency : 33.0000000000
Frequency : 49.0000000000
Frequency : 66.0000000000
Frequency : 82.0000000000
Frequency : 98.0000000000
Frequency : 114.0000000000
Frequency : 131.0000000000
Frequency : 147.0000000000
Frequency : 163.0000000000
Frequency : 179.0000000000
Frequency : 195.0000000000
Frequency : 212.0000000000

Je viens de tester ce code trouvé sur le net et pareil les valeurs sont fausses.

const unsigned long serialPeriod = 1000;       // print to the serial console every second
unsigned long timeSerialDelay = 0;

volatile unsigned long numInterrupts = 0;

void setup()
{
  Serial.begin(9600);
  
  attachInterrupt(0, isr, FALLING); // interrupt on falling edge
}

void loop()
{
  outputRPM();
}

void isr()
{
  numInterrupts++;
}

void outputRPM()
{
  if((millis() - timeSerialDelay) >= serialPeriod)
  {
    unsigned long RPM = (numInterrupts*60);
    
    Serial.print(RPM);
    Serial.println(" RPM");
    
    numInterrupts = 0;
    timeSerialDelay = millis();
  }
}

Il me donne 960RPM et ça passe à 1020 par moment. :~

R3mi:
Il me donne 960RPM et ça passe à 1020 par moment. :~

bonjour
des interruptions arrivent toujours dans la loop
et ça crée des "problemes" avec le serial et les autres actions
il faut desactiver l'interrupt lorsque la temp est atteinte (là la seconde) et remettre count à zero en sortie
essaye ça (repiqué du code de B@tto)
NB testé compil OK , mais pas en situation et en situation entre 5Hz et 50KHz resultat OK

#define sampletime 1000
#define  freqpin  2

unsigned long timeone;

volatile unsigned int count=0;

void setup()
{
 pinMode(freqpin, INPUT);
 attachInterrupt(0,freqinput,RISING);
  Serial.begin(9600); 
  timeone=millis();
} 

void loop() {

if(millis()>=(timeone+sampletime)) {
  noInterrupts();
timeone=millis();
float Freq = count / (sampletime/1000.0);
  Serial.print("Frequency : ");
 Serial.println(Freq,DEC);
 count=0;
 interrupts();
 }
 
}  

void freqinput ()
{
  count++;
}

R3mi:
J'utilise pour ça ce petit montage à ba se de NE555 :
555 (NE555) Astable Circuit Calculator
Avec C : 1µF ; R1 : 200R ; R2 47K . Ca devrait me donner 15.318Hz soit environ 918RPM, un régime de ralentit à peu près...
[...]
Alors problèmes :
Sur le moniteur il m'affiche entre 16 et 17Hz voir 18. Et quand je transforme en RPM on est pas vraiment bon :~

Salut,
à vrai dire ces chiffres ne m'étonnes pas vraiment. Un oscillateur à base de 555 est tout sauf un instrument de précision... Le site que tu donne en lien effectue un calcul théorique de la fréquence, mais ne tiens pas du tout compte des tolérances des composants utilisés. Quand on sait que la tolérance sur un condensateur peut monter jusqu'à 80%, je ne suis pas vraiment étonné qu'un montage donnant théoriquement une fréquence de 15,318 Hz (ouah) sorte finalement un truc à 17Hz.

La deuxième chose, c'est qu'un temps d’échantillonnage de seulement 1 seconde pour un signal de ~15 Hz c'est un peu court pour avoir une résolution suffisante. Essaie d'augmenter ce temps (la variable sampletime) à 10 ou 30 secondes.

À la limite si tu veux vraiment un temps d'échantillonnage court, il vaudrait mieux que tu mesure la période plutôt que la fréquence : tu t'assures de commencer la mesure exactement sur un front montant (ou descendant, au choix), tu laisse passer 15 périodes (exactement), et tu relève le temps que s'est écoulé. Pas le temps de proposer un code qui fasse ça pour l'instant, désolé :frowning:

Oups j'avais oublié la RAZ de count (post édité)

B@tto:
Oups j'avais oublié la RAZ de count (post édité)

Ton code ne compile B@tto :grin:
et là où est la RAZ de count ... c'est peut etre prématuré :grin:

#define sampletime 1000
#define  freqpin  2

unsigned long timeone;

volatile unsigned int count=0;

void setup()
{
 pinMode(freqpin, INPUT);
 attachInterrupt(0,freqinput,RISING);
  Serial.begin(9600); 
  timeone=millis();

} 

void loop() {

if(millis()>=(timeone+sampletime)) {
timeone=millis();
count=0;
float Freq = count / (sampletime/1000.0);
  Serial.print("Frequency : ");
 Serial.println(frequency,DEC);
 }
 
}  

void freqinput ()
{
  count++;
}

ça mieux :grin:

#define sampletime 1000
#define  freqpin  2

unsigned long timeone;

volatile unsigned int count=0;

void setup()
{
 pinMode(freqpin, INPUT);
 attachInterrupt(0,freqinput,RISING);
  Serial.begin(9600); 
  timeone=millis();

} 

void loop() {

if(millis()>=(timeone+sampletime)) {
timeone=millis();

float Freq = count / (sampletime/1000.0);
  Serial.print("Frequency : ");
 Serial.println(Freq,DEC);
 count=0;
 }
 
}  

void freqinput ()
{
  count++;
}

Puuaaaaa, efficace et rapide le forum arduino. XD

Grâce à vos modifs du code j'ai une valeur plus proche des calculs (16 - 16.2).
D'après haifger la différence n'a rien d'alarmant. (En fait je pensais avoir fait une erreur quelque part)
Pour ce que je veux faire avec c'est bien suffisant en tout cas.

Merci !
(Je reviendrai vous embêtez dans pas longtemps, j'ai pleins de questions ]:smiley: )

Haaan bien vu ! Mais on peut améliorer encore si on chipote car pendant les calculs ou les Serial.print des count++ peuvent se produire :

#define sampletime 1000
#define  freqpin  2

unsigned long timeone;

volatile unsigned int count=0;

void setup()
{

 pinMode(freqpin, INPUT);
 attachInterrupt(0,freqinput,RISING);
 timeone=millis();
 Serial.begin(9600); 

} 

void loop() {

if(millis()>=(timeone+sampletime)) {

float Freq = count / (sampletime/1000.0);
timeone=millis();
count=0;

 Serial.print("Frequency : ");
 Serial.println(Freq,DEC);

 }
 
}  

void freqinput ()
{
  count++;
}

B@tto:
.... Mais on peut améliorer encore si on chipote car pendant les calculs ou les Serial.print des count++ peuvent se produire :

bonjour
oui ce n'est qu'une approche, mais pour un compte-tours simple ...

en tous cas pour moi ça fait un bon detecteur de 50Hz "ambiant
le uno seul ne renvoi rien de coherent, mais avec un simple fil en l'air de 15 cm ~ sur pin2
ça renvoi bien du 50 Hz :grin:

Bonjour,

Je me permets de participer car je suis en train justement de réaliser un allumage electronique programmable moto. Le principe de calcul étant le meme.

Pour plus de précision, je conseille d'utiliser un timer 16bit et un prescaler de 4us le tout en interruption . Le but du timer étant de compter le nombre d'impulsions "n" de 4 us par tour de vilebrequin.

dans la loop on affiche cycliquement le RPM :

T = n * 4us (en seconde)
F = 1/ T (en hertz)
RPM = F * 60 (en tours / minute)

On évoquait ici les solution faciles et basée sur du pur Arduino.

Evidemment qu'avec une utilisation des timers directe c'est bien plus précis et efficace :wink:

N'hésite pas à partager ton code quand tu auras fini ce qui pourrait aider notre ami :slight_smile:

Oui bien sur avec plaisir dès que j'aurais terminé la mise au point. :slight_smile: