Advertisement
TolentinoCotesta

Measure duty cycle

Feb 5th, 2020
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.54 KB | None | 0 0
  1. // Duty cycle calculation using input capture unit
  2. // Author: Nick Gammon
  3. // Date: 5 November 2013
  4.  
  5. // Input: Pin D8
  6.  
  7. volatile boolean first;
  8. volatile boolean triggered;
  9. volatile unsigned long overflowCount;
  10. volatile unsigned long startTime;
  11. volatile unsigned long finishTime;
  12.  
  13. // timer overflows (every 65536 counts)
  14. ISR (TIMER1_OVF_vect)
  15. {
  16.   overflowCount++;
  17. }  // end of TIMER1_OVF_vect
  18.  
  19. ISR (TIMER1_CAPT_vect)
  20.   {
  21.   // grab counter value before it changes any more
  22.   unsigned int timer1CounterValue;
  23.   timer1CounterValue = ICR1;  // see datasheet, page 117 (accessing 16-bit registers)
  24.   unsigned long overflowCopy = overflowCount;
  25.  
  26.   // if just missed an overflow
  27.   if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
  28.     overflowCopy++;
  29.  
  30.   // wait until we noticed last one
  31.   if (triggered)
  32.     return;
  33.  
  34.   if (first)
  35.     {
  36.     startTime = (overflowCopy << 16) + timer1CounterValue;
  37.     TIFR1 |= bit (ICF1);     // clear Timer/Counter1, Input Capture Flag
  38.     TCCR1B =  bit (CS10);    // No prescaling, Input Capture Edge Select (falling on D8)
  39.     first = false;
  40.     return;  
  41.     }
  42.    
  43.   finishTime = (overflowCopy << 16) + timer1CounterValue;
  44.   triggered = true;
  45.   TIMSK1 = 0;    // no more interrupts for now
  46.   }  // end of TIMER1_CAPT_vect
  47.  
  48. void prepareForInterrupts ()
  49.   {
  50.   noInterrupts ();  // protected code
  51.   first = true;
  52.   triggered = false;  // re-arm for next time
  53.   // reset Timer 1
  54.   TCCR1A = 0;
  55.   TCCR1B = 0;
  56.  
  57.   TIFR1 = bit (ICF1) | bit (TOV1);  // clear flags so we don't get a bogus interrupt
  58.   TCNT1 = 0;          // Counter to zero
  59.   overflowCount = 0;  // Therefore no overflows yet
  60.  
  61.   // Timer 1 - counts clock pulses
  62.   TIMSK1 = bit (TOIE1) | bit (ICIE1);   // interrupt on Timer 1 overflow and input capture
  63.   // start Timer 1, no prescaler
  64.   TCCR1B =  bit (CS10) | bit (ICES1);  // plus Input Capture Edge Select (rising on D8)
  65.   interrupts ();
  66.   }  // end of prepareForInterrupts
  67.  
  68.  
  69. void setup ()
  70.   {
  71.   Serial.begin(115200);      
  72.   Serial.println("Duty cycle width calculator");
  73.   // set up for interrupts
  74.   prepareForInterrupts ();  
  75.   } // end of setup
  76.  
  77. void loop ()
  78.   {
  79.   // wait till we have a reading
  80.   if (!triggered)
  81.     return;
  82.  
  83.   // period is elapsed time
  84.   unsigned long elapsedTime = finishTime - startTime;
  85.  
  86.   Serial.print ("Took: ");
  87.   Serial.print (float (elapsedTime) * 62.5e-9 * 1e6);  // convert to microseconds
  88.   Serial.println (" uS. ");
  89.  
  90.   // so we can read it  
  91.   delay (500);
  92.  
  93.   prepareForInterrupts ();  
  94. }   // end of loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement