Slow Interrupts

Hi all,

I've run into trouble with some stuff. I built a beam break rpm tachometer and it works fine and dandy but when I add a couple of extra lines to it and an 2 digit 7 segment display, the attachInterrupt slows down dramatically and does not pick up most of the breaks. I've even avoided using the delay() function (using IsTime() instead) and have tried skimming down the code but with no luck.

Does anyone have any ideas how to I guess increase the polling rate or prioritize the interrupt on an Arduino?

Thanks in advance.

Agreed.

Read this before posting a programming question

How to use this forum

Oops, I'm so sorry. I thought I had posted it. Here you go

#define TIMECTL_MAXTICKS  4294967295L
#define TIMECTL_INIT      0
#define A A0
#define B A1
#define C A2
#define D A3
#define E A4
#define pinF A5
#define G 3
#define BTN1 10
#define BTN2 9
#define CA1 12
#define CA2 11

int IsTime(unsigned long *timeMark, unsigned long timeInterval){
  unsigned long timeCurrent;
  unsigned long timeElapsed;
  int result=false;
  timeCurrent=millis();
  if(timeCurrent<*timeMark){
    timeElapsed=(TIMECTL_MAXTICKS-*timeMark)+timeCurrent;}
  else {
    timeElapsed=timeCurrent-*timeMark;  }
  if(timeElapsed>=timeInterval) {
    *timeMark=timeCurrent;
    result=true;}
  return(result);}

int ledPin = 13;
unsigned long timeMark=0;
unsigned long timeInterval=1;
unsigned long time;
unsigned long time_old;
int start=10;
int digit1=0;
int digit2=0;
int counter;
byte even_odd;
String stringOne, stringTwo, one, two;

const int segs[7]= {A,B,C,D,E,pinF,G};
const byte numbers[10] = { 0b1000000, 0b1111001, 0b0100100, 0b0110000, 0b0011001, 0b0010010,
0b0000010, 0b1111000, 0b0000000, 0b0010000 };

void setup() {
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(E, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(BTN1, INPUT);
  pinMode(BTN2, INPUT);
  pinMode(CA1, OUTPUT);
  pinMode(CA2, OUTPUT);
  attachInterrupt(0,object_interrupt,HIGH);
  Serial.begin(9600);
  stringOne=String("Counter=");
  one=String("Time=");
  two=String("ms");
}

void loop() {
    stringTwo=String(counter);
    counter=0;
    digit1=(counter/10)%10;
    digit2=counter%10;
    
    if (digitalRead(BTN1) == HIGH) {
    start++;
    }
    if (digitalRead(BTN2) == HIGH) {
    start--;
    }
    
    unsigned long startTime = millis();
    for (unsigned long elapsed=0; elapsed < 600; elapsed = millis() - startTime) {
    if(IsTime(&timeMark,timeInterval)){
    lightDigit1(numbers[digit1]);}
    if(IsTime(&timeMark,timeInterval)){
    lightDigit2(numbers[digit2]);}
    }
    
  if ((even_odd & 0x01)==0){ 
      counter++;
      Serial.println(one+time+two);
      Serial.println(stringOne+stringTwo);
      time=0;}
    else if ((even_odd & 0x01)!=0){
      time=0;}
    }

void lightDigit1(byte number) {
  digitalWrite(CA1, LOW);
  digitalWrite(CA2, HIGH);
  lightSegments(number);}

void lightDigit2(byte number) {
  digitalWrite(CA1, HIGH);
  digitalWrite(CA2, LOW);
  lightSegments(number);}

void lightSegments(byte number) {
  for (int i = 0; i < 7; i++) {
    int bit = bitRead(number, i);
    digitalWrite(segs[i], bit);}
}

void object_interrupt(){
  even_odd++;
  time=(millis()-time_old);
  time_old=millis();}

First, all the things modified inside object_interrupt should be declared volatile.

Okay I did that but it doesn't seem to have changed anything. I see why the change is necessary though.

  stringTwo=String(counter);

The String class is quite slow, you know. Why are you doing this?

To be honest, I don't really understand what your code is doing. Timing a tachometer should be simple. I have various frequency counters here:

Why is the string line slow? I need it to update every loop to display the number of times the beam was broken.

I figured it out, the display code was holding the number of interrupts back. I changed some values and the polling has sped up significantly.

  stringOne=String("Counter=");
  one=String("Time=");
  two=String("ms");
...
    stringTwo=String(counter);
...
  Serial.println(one+time+two);
  Serial.println(stringOne+stringTwo);

With all due respect, this is incredibly convoluted. What about:

Serial.print ("Time=");
Serial.print (time);
Serial.println ("ms");
Serial.print ("Counter=");
Serial.println (counter);

The String class takes time. A lot of it. I timed it:

And there is always the Streaming library if you prefer to display everything at once:

http://arduiniana.org/libraries/streaming/

Ah, I see what you mean and I take no offense at your remark about my code. I have to ask about it to know that I was wrong or could've done it better. I changed the code to reflect that and it seems much cleaner. Thanks for all of the help.