0
\$\begingroup\$

I am currently measuring the frequency of a square wave using input capture on the atmega328p. Once it detects the frequency, I have the code lighting up one LED above a certain cutoff (i.e. about 150 hz) and one below.

volatile uint8_t flag;

volatile unsigned int capture1, capture2, CaptOvr;

volatile unsigned long T1Ovs, timer0_ovflow;


volatile  long ticks;
volatile double period;
unsigned long int frequency;
float Ttime;

void timer1_init(void)
{

  // Starting timer 1 in normal mode
//  TCCR1B= 0x00;
  TCCR1A = 0x00;
  // setting interrupt flag register to 0.
  //TIFR1=0x00;
  // timer 1 setup without any pre scalars, and enabling
  //input capture on rising edge
  TCCR1B =  (1<< ICES1);
  TCCR1B |=(1<<CS12)|(1<<CS10);

  // setting the timer/counter i/o locations to 0.
  //TCNT1H=0x00;
  //TCNT1L=0x00;
  // enabling input capture
 TIMSK1|=(1<<ICIE1)|(1<<TOIE1);
  // enabling global interrupt
  sei();
}


ISR (TIMER1_CAPT_vect)
{

 if (flag==0)
 {

    capture1 = ICR1;
    //setting overflow_counter to 0.
   T1Ovs=0;
    //doubleOverflowError=0;
 }
else if (flag==1)
 {
    capture2 = ICR1;

  //saving the value of overflow_counter to total_overflow
   CaptOvr = T1Ovs; 
  }
  flag++;
}

ISR(TIMER1_OVF_vect)
{
    T1Ovs++;
}


void setup() {
  // put your setup code here, to run once:
 // initialize timer
  Serial.begin(9600);
    timer1_init();
    //timer0_init();
   DDRD = (1<<PORTD7)|(1<<PORTD6);//|(1<<PORTD5);
   PORTD = (0<<PORTD7)|(0<<PORTD6);//|(0<<PORTD5);
}

void loop() {
  // put your main code here, to run repeatedly:
  //flag = first_capture;

      //while (flag != wait);


   if (flag==2)
      {

      flag=0;

        ticks = (capture2 - capture1) + (CaptOvr * 0x10000L);
       // T1Ovs=0;
       // Ttime= ((256*ticks)/16000000);
          frequency = (16000000/ticks)/1024;
   // frequency= (1/Ttime);

Serial.println ((frequency));

      if ((frequency>=100))
      {
          PORTD = (1<<PORTD7);
          //PORTD=(0<<PORTD6);

      }
    else if ( (frequency<100))
      {
        PORTD = (1<<PORTD6)|(0<<PORTD5);
      //  PORTD=(1<<PORTD6);
        }

      }       


}

so now, I want to turn on a 3rd led which will turn on when there isnt any signal being sent to the interrupt pin.( and it will turn off when a signal is being sent). This is the part i am currently stuck on. any suggestion or help would be greatly appreciated.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Use another timer and set it up to expire after a period equal to the period of the lowest frequency you intend to detect. For example, say you want the "no signal" LED to light when the input frequency is less than 1 Hz. Then set the period of this new timer to 1 second. Anytime an edge is detected, reset this timer's counter so that it will expire in 1 second. This way the timer will never expire as long as you're getting edges more often than once per second. But when you don't get an edge within one second than this timer will expire and in the timer's ISR you can light the "no signal" LED.

\$\endgroup\$
0
\$\begingroup\$

This looks very Arduino'y, but the concept is the same for about every controller.

Think of a timeframe where you expect at least one transition, let's assume 1 second. Using the millis() function, you should be able to get the number of milliseconds since your device started.

Now, add a variable, let's name it time_last_signal

Whenever you detect a transition, update time_last_signal with the current value of millis().

In your loop, continuously check, if the difference between the current millis() value and your time_last_signal value is larger than 1000 [ms]. If that is the case, you haven't received a transition for more than 1s and you should switch on that LED. As soon as you receive the next transition, turn off the LED (you can do that on every transition, the state of the pin will not really change).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.