Jump to content
Sign in to follow this  
CPP_Technologist

Millis() and Micros() Issue during ISR

Recommended Posts

I am trying to detect the width of a pulse signal (that should be anywhere from 1ms to 20ms wide) using two ISRs on the MSP430G2553.  One ISR is triggered by the rising edge, and the other by the falling edge.  The first ISR reads micros() and stores the value in a variable called Time1.  The second ISR reads micros() and stores the value in a variable called Time2.  The pulse width of the signal is equal to Time2-Time1.  

 

The problem is, Time1 and Time2 always end up being equal, even though they are read in two different ISRs on two separate signal edges-- this should be impossible.  Anyone know how this is happening?  Does entering an ISR stop whatever micros() is referencing? 

 

I've tried using millis() as well, but the problem persists.  

 

I've used a similar code on the Arduino using "CHANGE" as the interrupt trigger and reading micros() for time1 or time2 depending on the status of a pin-- and that works-- so I'm assuming the launchpad must deal with micros() differently?

 

Here is some code that demonstrates the problem on the launchpad:

 

 

volatile unsigned long Time;
volatile unsigned long Time1;
volatile unsigned long Time2;
 
void setup(){
   Serial.begin(9600);
  pinMode(5,INPUT);
  pinMode(6,INPUT);
  attachInterrupt(5,CapturePulse1,RISING);
  attachInterrupt(6,CapturePulse2,FALLING);}
  
  void loop(){}
  
  void CapturePulse1(){
    Time1=millis();
    Serial.print(Time1);
  }
  
  void CapturePulse2(){
    Time2=millis();
    Serial.print(Time2);
    Time=Time2-Time1;
    Serial.print(Time);
  }
    

 

 

Share this post


Link to post
Share on other sites

If you want to measure a pulse this small, avoid writing to serial during the interrupt. Writing to serial is "slow"; only about 1000 characters per second (1ms per character). This means that writing a time in 4 digits (and an enter) over serial would take 6ms.

Because the second interrupt is triggered directly after the first interrupt (which took 6ms); the background processes have no time to update the millis/micros counters.

To fix this - assuming these pulses occur say once per second - you should print Time1 during CapturePulse2. Maybe even better; set a flag when CapturePulse2 is finished and let loop() do the printing then (and clear the flag).

Share this post


Link to post
Share on other sites

Sorry this took so long, but my new code using the suggestions above still registers no difference in the time between the rising and falling edges of the pulse.  Even if I generate a very long pulse, like a second or so, the time between the rising and falling edges is shown as zero.  

 

Extra Info:

I am making these pulses by placing my finger between a phototransistor and a light source.  The phototransistor is running in "open collector" mode with a 1K resistor.  When my finger blocks the light source, I should see the phototransistor output go high, (because this is an inverting configuration) and I've verified that this occurs.  Pins 6 and 7 are both connected directly to the phototransistor output, so they should theoretically see a rising edge and then a falling edge, and the edges must necessarily occur at different times, so I can't see any hardware related reason this won't work.

 

The only thing I can figure, at this point, is that the rising edge trigger is actually triggering on the falling edge, or vice versa, causing each interrupt to be executed at the same time (if that's even possible).  

 

 My new code is shown below:

 

 

volatile unsigned long Time;
volatile unsigned long Time1;
volatile unsigned long Time2;
volatile int flag1;
volatile int flag2;
 
void setup(){
   Serial.begin(9600);
  pinMode(6,INPUT);
  pinMode(7,INPUT);
  attachInterrupt(6,CapturePulse1,RISING);
  attachInterrupt(7,CapturePulse2,FALLING);}
  
  void loop(){
  if (flag1&&flag2){
    Time=Time2-Time1;
  Serial.println(Time1);
  Serial.println(Time2);
  Serial.println("Difference is ");
  Serial.println(Time);
  flag1=0;
  flag2=0;}}
  
  void CapturePulse1(){
    Time1=micros();
    flag1=1;
  }
  
  void CapturePulse2(){
    Time2=micros();
    flag2=1;
  }

 

Any help is GREATLY appreciated.

 

 

ETA:  

 

Just realized that RISING doesn't work.  Both Interrupts are indeed being triggered on the falling edge.  Anyone know how to fix this?

Share this post


Link to post
Share on other sites

Could this just be noise / hysteresis in the signal?  I.e. when it finally goes low, there's some fuzzyness and rebound that needs to be worked out.... a debounce routine might be in order.

 

ISR #1 could set a third variable indicating last millis() of its execution, ISR #2 runs but refuses to do anything until the millis() minus that third variable is above a certain threshold.

Share this post


Link to post
Share on other sites

It could be some sort of noise problem, however it certainly didn't exist when I used this circuit with the arduino, (at 5V, so maybe S/N ratio was small enough or the arduino just has more hysteresis).   

 

I think the version of Energia code I'm using may have a bug:

 

I decided to break the circuit up and have one phototransistor trigger the rising edge interrupt pin and one phototransistor trigger the falling edge interrupt pin.  I've noticed that they both end up triggering their respective interrupts when I remove my finger from their light beam-- it seems that they are both triggering on the falling edge for some reason, even though I specified rising for one of them in the code.  

 

I think I read something about rising not working somewhere, I'm going to see if I can find out where I read it.  

 

ETA:

 

The problem was a bug in the library Energia.h.  It specifies the wrong values for RISING and FALLING.  The solution was already discussed here:  (See post #6)

 

http://forum.43oh.com/topic/3214-how-to-using-attachinterrupt/

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...