Page 1 of 1

Can't get a response from external interrupt.

Posted: Mon Jan 01, 2018 10:24 pm
by photomankc
I'm working on an implementation of a Ping))) sonar sensor. The electrical aspects are working and I've been able to get 5V to 3V interface worked out. The scope is showing the correct behavior is occurring. The 20 usec trigger pulse is being generated and the echo pulse is returning.

What I can not get to operate is an external interrupt to trigger on the falling (or rising) edge of the echo pulse. The ISR is never called and that's a bit of a black box to me. I have the statements entered as I understand they need to be to create an interrupt on an external pin but nothing is occurring. Looking to see if there is anything I'm missing as far as how this is supposed to be done.

Defined a few globals just to detect the ISR running:

Code: Select all

	
#define PIN_SONAR0  13
#define PIN_SONAR1  16
#define PIN_SONAR2  17

Code: Select all

volatile uint   sys_son0_isr_count;
volatile uint   sys_son1_isr_count;
volatile uint   sys_son2_isr_count;

Code: Select all

attachInterrupt(digitalPinToInterrupt(PIN_SONAR0), sonar0_isr, FALLING);
attachInterrupt(digitalPinToInterrupt(PIN_SONAR1), sonar1_isr, FALLING);
attachInterrupt(digitalPinToInterrupt(PIN_SONAR2), sonar2_isr, FALLING);

Code: Select all

void sonar0_isr()
{
  sys_son0_isr_count++;
  sys_sonar0.update_isr();
}


void sonar1_isr()
{
  sys_son1_isr_count++;
  //sys_sonar1.update_isr();
}


void sonar2_isr()
{
  sys_son2_isr_count++;
  //sys_sonar2.update_isr();
}


This is the code from the SRF05 object that triggers the sonar ranging cycle. In this the trigger pin is set to output and the trigger pulse is produced. Then the pin is switched back to input to listen for the start of the echo pulse and note the time that occurs.

Code: Select all

/** @brief Trigger the sonar sensor ranging cycle.
 *
 *  @return: 0 on success, failure otherwise.
 */
inline int SRF05::trigger()
{
  uint trigger_time;
  uint delays = 200;

  // Clear any previous echo time.
  m_us_trigger = 0;
  m_us_echo    = 0;

  if (!m_enable)
    return SON_NOT_ENA;

  // Send a trigger pulse of at least 20usecs
  pinMode(m_tpin, OUTPUT);
  digitalWrite(m_tpin, HIGH);
  delayMicroseconds(20);
  digitalWrite(m_tpin, LOW);
  pinMode(m_tpin, INPUT);

  // Wait for the echo input to show a positive pulse or timeout
  while(digitalRead(m_epin) == LOW and delays)
  {
    delayMicroseconds(10);
    delays--;
  }

  // If the echo line raised then record the trigger time and report
  // success.  Otherwise report failure.
  if (delays)
  {
    m_us_trigger = micros();
    return SON_OK;
  }
  else
    return SON_NO_ECHS;
}
The return code from the trigger method indicates that we are detecting the initial transition of the echo pulse from low to high. So the pulse is there and it's on the expected pin. I'm not sure where to go from here. I don't understand why the interrupt is not occurring.

ETA: m_tpin and m_epin can be the same pin number, they are just separated to allow for sensors that have separate trigger and echo lines. In this case they are the same.

Re: Can't get a response from external interrupt.

Posted: Wed Jan 10, 2018 3:42 pm
by photomankc
Well,

It appears this is not an easy one. My only guess is that it has to do with setting the pin back and forth from input to output when handling the single pin Ping))) sensor? Looking into the guts of the attachInterrupt() function I can't see anything obvious that I would be doing wrong here.

I've worked around it with a 20us timer interrupt to poll for the state change on whichever pin has sent the latest trigger pulse. That is an unsatisfying solution. it's an obvious drain on the execution speed of the loop but still remains fast enough to get all the jobs done in a 20ms time slice without having to wait staring at the sensor pin for the incoming echo pulse each time so it will work.

Re: Can't get a response from external interrupt.

Posted: Sun Feb 18, 2018 11:24 pm
by jgustavoam
Hi , where is configuration of interrupt pins as INPUT ?
https://www.arduino.cc/reference/en/lan ... interrupt/

Code: Select all

pinMode(PIN_SONAR0, INPUT);
pinMode(PIN_SONAR1, INPUT);
pinMode(PIN_SONAR2, INPUT);