Created
October 1, 2020 09:56
-
-
Save SimenZhor/04b0f4aa3f3fd5e52bfec7202dcac961 to your computer and use it in GitHub Desktop.
Revisions
-
SimenZhor created this gist
Oct 1, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,94 @@ // Pulse Width measurement using input capture unit // Author: Simen E. Sørensen //(overflow calculations based on code by Nick Gammon 31 August 2013: // https://www.gammon.com.au/forum/?id=11504) // Date: 01 October 2020 // Input: Pin D8 (Arduino Uno (and I think Arduino Nano as well)) volatile boolean risingEdge; volatile boolean fallingEdgeFlag; volatile unsigned long overflowCount; volatile unsigned long pulseStartTime; volatile unsigned long pulseFinishTime; float pulseWidth; //us ISR(TIMER1_OVF_vect){ // timer overflows (every 65536 counts) overflowCount++; } ISR(TIMER1_CAPT_vect){ noInterrupts(); unsigned int timer1CounterValue = ICR1; unsigned long overflowCopy = overflowCount; // Check if we have just missed an overflow if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF) overflowCopy++; if(risingEdge){ //Store counting value, reconfigure to trigger on falling edge pulseStartTime = (overflowCopy << 16) + timer1CounterValue; risingEdge = false; // Change to trigger on falling edge // ICES1 = 0 means Falling Edge Trigger TCCR1B &= ~bit(ICES1); // Set ICES1 low, keep all other bits in TCCR1B interrupts(); // Re-enable interrupts, so we can catch the falling edge return; }else{ //Read counting value, set flag that values can be calculated, reconfigure to trigger on rising edge pulseFinishTime = (overflowCopy << 16) + timer1CounterValue; fallingEdgeFlag = true; TIMSK1 = 0; // pause interrupts until pulse width has been calculated } } void initTC(){ noInterrupts (); // protected code fallingEdgeFlag = false; // re-arming for new pulse risingEdge = true; // This function sets rising edge as the event trigger // reset Timer 1 configuration registers TCCR1A = 0; TCCR1B = 0; TIFR1 = bit (ICF1) | bit (TOV1); // clear flags so we don't get a bogus interrupt TCNT1 = 0; // Reset counter overflowCount = 0; // Reset overflow counter // Configure Timer 1 // TOIE1 = Overflow IRQ, ICIE1 = Event IRQ TIMSK1 = bit (TOIE1) | bit (ICIE1); // interrupt on Timer 1 overflow and input capture // Select clock, select event trigger and apply filter (filter causes 4 clock cycles on delay but does not alter the pulsewidth measurement) // CS10 = no prescaler (TC_CLK = F_CLK), ICES1 = Rising Edge Trigger, ICNC1 = Input Capture Noise Canceller TCCR1B = bit (CS10) | bit (ICES1) | bit(ICNC1); // Set CS10, ICES1 and ICNC1 - clear all other bits in TCCR1B interrupts (); } void calculatePulseWidth(){ unsigned long numCounts = pulseFinishTime - pulseStartTime; // Period time = 1/F_CPU (= 62.5 ns at 16 MHz) pulseWidth = float(numCounts) / (F_CPU*0.000001); // Pulse width = Period time * Num counts } void reArmTC(){ //Function only added for clarity in naming initTC(); //re-arm for next pulse } void setup(){ Serial.begin(9600); Serial.println("Pulse Width Counter"); pulseWidth = 0; //us // set up for interrupts initTC(); } void loop(){ if(fallingEdgeFlag){ calculatePulseWidth(); Serial.print ("PulseWidth: "); Serial.print (pulseWidth); Serial.println (" µs. "); reArmTC(); } }