Sari la conținut
ELFORUM - Forumul electronistilor

Numarare pulsuri rapide


Vlad Mihai

Postări Recomandate

Salut, 

 

Nico  multumesc de sugestii,  cunostiintele mele de software sunt minimale (cum am mai precizat sunt electronist), cand am probleme de genul, deobicei postez pe forum si sunt salvat de Liviu M si thunderer, dar as  aprecia daca mai indruma exact ce sa modific. Deci sa modific int pulse_counter cu volatile? Nu stiu cum sa implementez   cea de-a 2-a remarca....

Link spre comentariu

In loc de:

int pulse_counter = 0;

scrie:

volatile int pulse_counter = 0;

Ai in continuare un exemplu de utilizare a INPUT COMPARE (sursa http://www.gammon.com.au/timers):

 

(Ai ramane surprins sa afli ca nu sunt nici electronist nici programator IT)

// Frequency timer using input capture unit// Author: Nick Gammon// Date: 31 August 2013// Input: Pin D8 volatile boolean first;volatile boolean triggered;volatile unsigned long overflowCount;volatile unsigned long startTime;volatile unsigned long finishTime;// timer overflows (every 65536 counts)ISR (TIMER1_OVF_vect) {  overflowCount++;}  // end of TIMER1_OVF_vectISR (TIMER1_CAPT_vect)  {  // grab counter value before it changes any more  unsigned int timer1CounterValue;  timer1CounterValue = ICR1;  // see datasheet, page 117 (accessing 16-bit registers)  unsigned long overflowCopy = overflowCount;    // if just missed an overflow  if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)    overflowCopy++;    // wait until we noticed last one  if (triggered)    return;  if (first)    {    startTime = (overflowCopy << 16) + timer1CounterValue;    first = false;    return;      }      finishTime = (overflowCopy << 16) + timer1CounterValue;  triggered = true;  TIMSK1 = 0;    // no more interrupts for now  }  // end of TIMER1_CAPT_vect  void prepareForInterrupts ()  {  noInterrupts ();  // protected code  first = true;  triggered = false;  // re-arm for next time  // reset Timer 1  TCCR1A = 0;  TCCR1B = 0;    TIFR1 = bit (ICF1) | bit (TOV1);  // clear flags so we don't get a bogus interrupt  TCNT1 = 0;          // Counter to zero  overflowCount = 0;  // Therefore no overflows yet    // Timer 1 - counts clock pulses  TIMSK1 = bit (TOIE1) | bit (ICIE1);   // interrupt on Timer 1 overflow and input capture  // start Timer 1, no prescaler  TCCR1B =  bit (CS10) | bit (ICES1);  // plus Input Capture Edge Select (rising on D8)  interrupts ();  }  // end of prepareForInterrupts  void setup ()   {  Serial.begin(115200);         Serial.println("Frequency Counter");  // set up for interrupts  prepareForInterrupts ();     } // end of setupvoid loop ()   {  // wait till we have a reading  if (!triggered)    return;   // period is elapsed time  unsigned long elapsedTime = finishTime - startTime;  // frequency is inverse of period, adjusted for clock period  float freq = F_CPU / float (elapsedTime);  // each tick is 62.5 nS at 16 MHz    Serial.print ("Took: ");  Serial.print (elapsedTime);  Serial.print (" counts. ");  Serial.print ("Frequency: ");  Serial.print (freq);  Serial.println (" Hz. ");  // so we can read it    delay (500);  prepareForInterrupts ();   }   // end of loop
Link spre comentariu

In functie de versiunea de Arduino pe care o ai, sunt sanse sa trebuiasca sa definesti in mod diferit pinul pe care faci achizitia:

Prior to Arduino 1.0.1, it was possible to configure the internal pull-ups in the following manner:pinMode(pin, INPUT); // set pin to inputdigitalWrite(pin, HIGH); // turn on pullup resistors

 

 

As of Arduino 1.0.1, it is possible to enable the internal pullup resistors with the mode INPUT_PULLUP. Additionally, the INPUT mode explicitly disables the internal pullups.

Syntax

pinMode(pin, mode)

Parameters

pin: the number of the pin whose mode you wish to set

mode: INPUT, OUTPUT, or INPUT_PULLUP. (see the digital pins page for a more complete description of the functionality.)

Link spre comentariu

Salut, am testat codul propus de nico dar nu   cred ca merge (e vorba  despre  codul luat   ca  exemplu de pe site-ul repesctiv). Codul a fost testat pe o placa arduino uno.

iata ce primesc pe serial:

 

Mai incerc alte solutii...

post-216107-0-06822400-1431667696_thumb.jpg

Link spre comentariu

Nu stiu care este  perioada de repetitie a pulsurilor de asta vreau sa le numar in interval de un minut sau o secunda si sa aflu:

 rezultate mai  bune am cu urmatorul cod:

#define INTERRUPT_INPUT 2 int pulse_counter = 0;  void setup(){  Serial.begin(9600);       // For noise suppression, enable pullup on interrupt pin  digitalWrite(INTERRUPT_INPUT, HIGH);  attachInterrupt(INTERRUPT_INPUT - 2,                  interrupt_handler,                  FALLING);}  void loop(){  // Keep LCD blank till a pulse comes in  if (pulse_counter > 0)  {     Serial.print("Z");   //sync data    Serial.println(pulse_counter);    Serial.print("n");    delay(20);  }  delay(20);}  void interrupt_handler(){  pulse_counter = pulse_counter + 1;}

Dar ma apuc sa  configurez generatorul de semnal sa imi dea un anumit numar de pulsuri de 10us  si sa le numar si sa vad daca isi face treaba

Editat de Vlad Mihai
Link spre comentariu

Este posibil ca impulsurile sa vina neperiodic, caz in care indicatiile din inregistrare ar putea fi corecte

In exemplul pe care l-am postat captura se face pe frontul crescator al impulsului si de aici posibila eroare.

Incearca sa inlocuiesti:

TCCR1B =  bit (CS10) | bit (ICES1);  // plus Input Capture Edge Select (rising on D8)

cu:

TCCR1B =  bit (CS10);  // plus Input Capture Edge Select (falling on D8)
Link spre comentariu

Am facut modifcarile  date  de  tine, uite ce  primesc pe  serial:

 

Explica-mi te rog ce face codul asta.... din ce  am inteles eu, citeste niste pulsuri intr-un anumit interval de timp?

E posibil sa nu ajunga  10us latimea pulsului?

post-216107-0-60791000-1431671359_thumb.jpg

Editat de Vlad Mihai
Link spre comentariu

Codul pus ca exemplu este un frecventmetru putin atipic. Spun asta deoarece in loc sa masoare impulsurile intr-o perioada de timp data (baza de timp) el masoara numarul de impusuri de ceas (62.5ns=16MHz) cuprinse intr-o perioada a semnalulului de intrare a carui frecventa vrem sa o cunoastem (este principiul frecventmetrului reciproc).

Functionarea este urmatoarea: Atunci cand se aplica un semnal necunoscut pe portul PB0 (ICP) microcontroller-ul detecteaza primul front crescator (sau descrescator, functie de setari) si efectueaza o citire a registrului ICR, iar pe urmatorul front crescator (descrescator) efectueaza o noua citire si dezactiveaza intreruperile.

Diferenta intre cele doua citiri reprezinta perioada semnalului (dupa unele prelucrari matematice).

In forma prezentata, frecventmetrul nu poate citi frecvente mai mari decat 200 - 250kHz, insa cu un prescaler adecvat poate citi circa 80MHz , la un nivel de semnal de 5V.

Link spre comentariu

Am inteles multumesc de lamuriri, deci in principiu cred ca putem spune  ca masoara bine, si ca pulsurile de la senzori nu sunt  chiar atat  simetrice ca perioada de repetitie.

Link spre comentariu

Este foarte posibil ca pulsurile sa fie lipsite de o anumita periodicitate in aparitie. Fara sa stiu ce aplicatie ai (si/sau ce senzori folosesti) nu pot spune mai multe.

Poti folosi softul postat (cu modificari) doar pentru a numara impulsurile, ignorand perioada lor.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări