Read an input signal with just ONE INTERRUPT!!!

Hello everyone!

I’m working on a controlled vehicle using Arduino. The code is already done but I realised that there are too many interruptions. I use an interruption when an input signal goes high and another interruption when it goes low. In that way, with two interruptions I can follow an input signal, and knowing when it goes high and low I can measure the time that the signal has been high (length of pulse).

Someone told me that I can use one interruption instead of two. In that way, somehow I measure the time that the input has been pulsed and when it goes down I do the interruption. So basically I read the time that is high without any interruption and when it goes down I act on the system using an interruption and knowing the time it has been high (because my response will be proportional to this pulse length). I have heard that you can measure the length of pulse with an internal timer of Arduino independent of the code, without using any interruption. And when I do the interruption I can read this timer. But I don’t know how.

My problem is that I don’t know how to measure the length of an input signal without using two interruptions (I have to use just one!)

Anyone could help me please? I would be very grateful!

Thank you very much for your attention!
Sincerely, Santiago

The first thing to establish is whether you need to use interrupts at all.

Please post your code here or attach it if it is too big.

If you use an interrupt with a trigger of CHANGE then you can test the pin state in the ISR. If it is HIGH save the value of millis() or micros() as the start time. If it is LOW save the value of millis() or micros() as the end time. Now you can calculate the length of time it was HIGH

SantiagoMeCer:
Someone told me that I can use one interruption instead of two. In that way, somehow I measure the time that the input has been pulsed and when it goes down I do the interruption. So basically I read the time that is high without any interruption and when it goes down I act on the system using an interruption and knowing the time it has been high (because my response will be proportional to this pulse length).

You should probably ask the person who told you that.
I think it can be done by using the Input Capture Register of Timer1. You can set the ICR to capture the Timer1 count at the instant the signal goes high. Then you use one interrupt when the signal goes LOW. Subtract the ICR value from the current count in Timer1 to get the number of timer ticks between the ICR triggering (signal goes HIGH) and the interrupt (signal goes low). Calculate time from the timer tick count and the duration of each timer tick.

Thank you very much for your answers and sorry for my the late reply. I have been so busy these days but now I will focus on this car project.

I copy down you my ISR (Interrupt Service Routine). As you can see I do an interruption when there's a RISE and where there's a FALL in order to calculate the pulse_duration, that is what I want to calculate.

My question was if I can calculate this pulse_duration just with one interrupt in the FALL.

I have checked about ICR, but I don't really understand what it does and if it can help me. So if you think that ICR would solve my problem, could you explain me how it would be in my code?

Thank you again for your answers!


ISR (PCINT1_vect)
{
current_time = micros();
// Is input 14 HIGH?
if (PINC & B00000001) {
// It was the input 14 low (RISE)
if (pulse_state == 0) {
// Update pulse_state
pulse_state = 1;
edge_time = current_time; //time of the RISE
}
}
// Is input 14 LOW? It was the input 14 HIGH (FALL)
else if (receiver_steer.pulse_state == 1) {
// Update pulse_state
pulse_state = 0;
pulse_duration = current_time - edge_time; //we get the pulse duration
}

My question was if I can calculate this pulse_duration just with one interrupt in the FALL.

If you know what time you got off work, but not what time you started, how can you know you get paid enough?

What accuracy do you need for your time measurement? It makes a huge difference.

I use the InputCapture function without interrupts for high accuracy with an ultrasonic distance finder.

#include <util/delay.h>

const byte InputCapturePin = 8;
const byte TriggerPin = 9;

void setup()
{
  Serial.begin(9600);
  TCCR1A = 0;         // Normal Mode
  TCCR1B = 1;         // Prescale to 1

  pinMode(InputCapturePin, INPUT);
  pinMode(TriggerPin, OUTPUT);
  digitalWrite(TriggerPin, 0);
}

void loop()
{
  unsigned int StartTime, EndTime;
  unsigned long TriggerTime;

  TCCR1B |= 0x40;        // Capture on Rising Edge
  TIFR1 |= 0x20;          // Reset Interrupt Capture Flag
  _delay_us(100);
  if (TIFR1 & 0x20)
  {
    Serial.println("Echo pin already high");
    return;
  }
  PORTB |= 2;            // Trigger On
  _delay_us(20);
  PORTB &= 0xFD;         // Trigger Off

  for (TriggerTime = micros(); micros() - TriggerTime <= 500L;)
  {
    if (TIFR1 & 0x20)
    {
      StartTime = ICR1;
      break;
    }
  }
  if ((TIFR1 & 0x20) == 0)
  {
    Serial.println("Echo didn't reset");
    return;
  }

  TCCR1B &= 0xBF;        // Capture on Falling Edge
  TIFR1 |= 0x20;          // Reset Interrupt Capture Flag
  for (TriggerTime = micros(); micros() - TriggerTime <= 16000L;)
  {
    if (TIFR1 & 0x20)
    {
      EndTime = ICR1;
      break;
    }
  }
  if ((TIFR1 & 0x20) == 0)
  {
    Serial.println("No Echo Received");
    return;
  }
  Serial.print("Elapsed Time = ");
  Serial.println(EndTime - StartTime);
}

You can configure the input capture hardware to fire on rising edge or falling edge. Wrapping it in an interrupt is doable. Or, if you can use the BlinkWithoutDelay state machine method, and if your loop routine is shorter than one half of the on/off cycle of the input pin, you don't need any interrupts at all. Just check the Interrupt Capture Flag each time through your loop routine, and if it gets set, the ICR1 register has a time stamp of the last time the pin fired. Your code doesn't need to be timing accurate if the loop executes quickly enough.

You do need to worry about wrap-around, since the time stamp is only 16 bits, and at full accuracy it's in 62.5 nanosecond units (clockspeed is 16 MHz) instead of microseconds. Also, the inputCapture pin is pin 8.

PaulS:
If you know what time you got off work, but not what time you started, how can you know you get paid enough?

I know it can sound strange and I don't know how it can be done. I don't know how to get the pulse duration only with an interrupt in the FALLLING. Even I don't know if it is possible.

But I'm on a project and this is what my "boss" told me to do... and right now, I found nothing.

So this is a commercial enterprise? Should you be asking for free help then?

Are you sure it's the pulse length that you need to measure and not the frequency ?

What happened to the idea of using a CHANGE interrupt and reading the pin to discover whether it was a falling or rising event that had occurred ?

aarg:
So this is a commercial enterprise? Should you be asking for free help then?

It is not commercial.

aarg:
So this is a commercial enterprise? Should you be asking for free help then?

??

If one wants to make money, why not seek the lowest cost solution? If you could get a decent haircut for free, wouldn't you?

BTW, Arduino itself is a commercial enterprise... do you feel bad about your time spent enriching their company/principals/employees supporting their products?

BulldogLowell:
??

If one wants to make money, why not seek the lowest cost solution? If you could get a decent haircut for free, wouldn't you?

BTW, Arduino itself is a commercial enterprise... do you feel bad about your time spent enriching their company/principals/employees supporting their products?

Well, the issue has become split now that we know that the "boss" is really a wife or something like that... :slight_smile:

I do support Arduino directly, I contributed money when I downloaded the IDE. It does not contradict my ideology to support a company (with my forum contributions) that seems to honour open source principles and doesn't seem to embrace the cannibalistic trade practices of many others. They seem to recognize their proper role in the ecosystem that they have created, and don't engage in aggressive IP battles to my knowledge. They don't seem to be milking patents instead of innovating the way some other companies do.

The issue of requesting help is a matter of degree. If a good engineer encounters a stumbling block and goes to forums for answers, I have no problem with it. That is properly utilizing the online resource of community knowledge to increase their own. In the ideal internet paradigm, they will pay it back someday by helping someone else in a similar way. Such an environment need not discriminate between employees, students, and hobbyists.

However this doesn't look so good when it's stretched to include an incompetent pretender who is merely exploiting the anonymity of the web to engage knowledgeable people to perform the work which their managers believe they are doing. That is unprofessional unless they disclose their actual situation.

There is nothing wrong with accepting a free haircut, per se. But parking my Mercedes, putting my suit on the rack, donning ragged clothes and going to stand in line with needy people for one if that were the purpose for the offer, wouldn't be moral.

I know it can sound strange and I don't know how it can be done. I don't know how to get the pulse duration only with an interrupt in the FALLLING. Even I don't know if it is possible.

I really don't see how you can tell how long a pin has been HIGH knowing only when it went LOW.

If you know when it went HIGH and when it went LOW, then it is trivial to determine how long it was high.

If you know that the signal is periodic, that is that it will be HIGH for just as long as it is LOW, then you can time the interval between two FALLING edges and divide by two.

If you know something more about the signal than you are telling us, now is the time to do so.

aarg:
There is nothing wrong with accepting a free haircut, per se. But parking my Mercedes, putting my suit on the rack, donning ragged clothes and going to stand in line with needy people for one if that were the purpose for the offer, wouldn't be moral.

hyperbolic rants aside, there is no rule that folks can't seek free help for their own gain. Look at Stack Overflow lately?

aarg:
They seem to recognize their proper role in the ecosystem that they have created, and don't engage in aggressive IP battles to my knowledge.

Are you shit'in me? This has been one of the great IP battles in the space!

Well back to the topic, I guess...