Vlad Mihai Postat Mai 14, 2015 Autor Partajează Postat Mai 14, 2015 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
nico_2010 Postat Mai 14, 2015 Partajează Postat Mai 14, 2015 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
Liviu M Postat Mai 14, 2015 Partajează Postat Mai 14, 2015 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. SyntaxpinMode(pin, mode) Parameterspin: 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.) 1 Link spre comentariu
Vlad Mihai Postat Mai 15, 2015 Autor Partajează Postat Mai 15, 2015 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... Link spre comentariu
nico_2010 Postat Mai 15, 2015 Partajează Postat Mai 15, 2015 Care este perioada de repetitie a impulsurilor? Link spre comentariu
Vlad Mihai Postat Mai 15, 2015 Autor Partajează Postat Mai 15, 2015 (editat) 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 Mai 15, 2015 de Vlad Mihai Link spre comentariu
nico_2010 Postat Mai 15, 2015 Partajează Postat Mai 15, 2015 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
Vlad Mihai Postat Mai 15, 2015 Autor Partajează Postat Mai 15, 2015 (editat) 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? Editat Mai 15, 2015 de Vlad Mihai Link spre comentariu
nico_2010 Postat Mai 15, 2015 Partajează Postat Mai 15, 2015 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
Vlad Mihai Postat Mai 15, 2015 Autor Partajează Postat Mai 15, 2015 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
nico_2010 Postat Mai 15, 2015 Partajează Postat Mai 15, 2015 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
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum