Need help with "speed optimization"

This is for an automotive project. The hardware is an arduino uno. I am interfacing it with a TI TPIC8101 IC, also a secondary uno is doing the SPI programming and interpreting the TPIC8101 output (irrelevant to my issue).

I have a window as small as .278ms and as large as 2ms. The window is between two interrupts. Basically the first (interrupt 0) is increasing a count by one and the other (interrupt 1) resets the count to 0. The window between the interrupts is not adjustable but is directly related to engine speed (up to 9k rpm). The input to the interrupts are TTL square waves.

I can post a screenshot from an oscilloscope if necessary.

edit: Attached oscilloscope screenshot. Yellow is reset interrupt and blue is the counter.

I am consistently missing the "reset" interrupt.

I have found lots of information about optimizing the speed of arduino code. However, my lack of programming knowledge has left me baffled when trying to apply it.

I'm a second semester electrical/computer engineering student that tinkers between classes and work. I am so close to finishing this but this has completely stalled my progress. Any help on this would be appreciated!

Edit: Updated code 12:07 3/16/14

#define intHold 7
#define waitPin 8

volatile int c = 0;
volatile int r = 0;

void setup()
{
  pinMode(intHold, OUTPUT);                    //intHold output to TPIC8101 on pin 6
  digitalWrite(intHold, LOW);
  attachInterrupt(0, count, RISING);           //24 tooth interrupt on pin 2 calls to function count below
  attachInterrupt(1, reSet, RISING);           //1 tooth "reset" interrupt on pin 3 calls to function reSet below
  
  Serial.begin(9600);
  Serial.println("Setup");                     //verify setup completed
}

void loop()
{

                                              //Listen For Knock between teeth four and six
                                              //Holds intHold high between teeth four and six
    if(c == 4)
    {
      digitalWrite(intHold, HIGH);
      Serial.println("tooth 4");
    }
    if(c == 6)
    {
      digitalWrite(intHold, LOW);
      Serial.println("tooth 6");
    }
    
                                            
                                            //Listen For Knock Between Teeth 10 and 12
                                            //Holds intHold high between teeth 10 and 12
    if(c == 10)
    {
      digitalWrite(intHold, HIGH);
      Serial.println("tooth 10");
    }
    if(c == 12)
    {
      digitalWrite(intHold, LOW);
      Serial.println("tooth 12");
    }
    
                                            //Verify resets are working
    if(r == 1)
    {
      Serial.println("reset");
      r = 0;
    }      
}

                                            
                                            //Increase tooth count by one
void count()
{
 c++;
}
                                            
                                            //Reset tooth count
void reSet()
{
  c = 0;
  r = 1;
}

ScopeScreenShot.jpg

volatile int c = 0;
int r = false;

void reSet()
{
c = 0;
r = !r;
}

Shouldn't r be declared volatile as it is changed in the ISR?

Is serial communication affecting the speed?

Next, how much noise is on the reset interrupt? Maybe it's not getting a clean rising edge?

Variable r is int, do you mean boolean?

My, very limited bandwidth, DSO203 shows a pretty clean signal.

Updated OP with oscilloscope screenshot. The reset interrupt is yellow.

The r variable also needs to be volatile.

Pete

I'll take a stab in the dark (I'll wait for mike if I'm wrong lol)

But... I think the voltage is not high enough or is just on the borderline to trigger a rising edge.

If that's correct, you may need to boost the voltage signal.

cjdelphi:
I'll take a stab in the dark (I'll wait for mike if I'm wrong lol)

But... I think the voltage is not high enough or is just on the borderline to trigger a rising edge.

If that's correct, you may need to boost the voltage signal.

That's my fault for not setting the V/div to the same for both channels. The yellow channel is on 2v/div. 2.5ish div = 5 volts. So the reset interrupts is right at 5 volts but the counter interrupt is 3.5ish volts. I believe the minimum for a TTL high is 2 volts.

Updated original code to have r as a volatile int.

Tested after update. Still having the same issue unfortunately.

Thanks for all the responses so far!!!

original:

int r = false;

updated:

volatile int r = 0;

Bugga...

I even designed a circuit !

I believe the minimum for a TTL high is 2 volts.

On the Arduino, it's 6/10th of the nominal voltage. For a 5V Arduino, that would be 3.0V.

PaulS:
On the Arduino, it's 6/10th of the nominal voltage. For a 5V Arduino, that would be 3.0V.

Thank you. That's very useful information.

cjdelphi:
Bugga...

I even designed a circuit !

Nice! I love Every Circuit.

Just reread my previous post and wanted to clarify that I was not being sarcastic about the useful information.

Spilly:
I am consistently missing the "reset" interrupt.

How do you know?

If I do:

Serial.println(c);

To print the count. It just keeps increasing.

Also, with the current "sketch" it stops printing after a few "tooth 12" are printed.

#define intHold 7
#define waitPin 8

volatile int r = 0;

void setup()
{
  pinMode(intHold, OUTPUT);                    //intHold output to TPIC8101 on pin 6
  digitalWrite(intHold, LOW);
  attachInterrupt(1, reSet, RISING);           //1 tooth "reset" interrupt on pin 3 calls to function reSet below
  
  Serial.begin(9600);
  Serial.println("Setup");                     //verify setup completed
}

void loop()
{
    if(r == 1)
    {
      Serial.println("reset");
      while ( true );
    }      
}

void reSet()
{
  r = 1;
}

Result?

Setup
reset

Which means you have been barking up the wrong tree. Essentially the code you used to diagnose your original problem was creating even more problems. I suspect cjdelphi hit the nail on the head...
http://forum.arduino.cc/index.php?topic=226252.msg1636659#msg1636659

Rather than wasting your time and ours barking up the wrong tree I suggest we all find the tree that actually contains the critter of interest. In other words, do what you should have done in your first post: describe what you want your code to do.

Most likely do to my lack of programming knowledge, your last post is difficult to follow. I'm going to assume when you refer to cjdelphi's post you are talking about the serial.println?

As to what I want the code to do, count the number of pulses at interrupt zero, hold a pin high between teeth (indicated by the count) 4 and 6 and then go low at 6. The same between teeth 10 and 12. Interrupt one needs to reset the count.

Interrupt zero is from a 12 toothed wheel and interrupt one is from a one tooth wheel. Both wheels are turning at the same speed on the same shaft.

The reset interrupt is supposed to set the count so that c==1 correlates to tooth one. Without this reset I have no idea what tooth just caused the interrupt and what the current degree position is.

Why do you need to use interrupts?