Interrupt on MEGA misses pulses

Hello,

This script which I use for my DIY weather station is missing pulses!!!!
The sensor are used are IR sensor/course. they counts wholes in a disc.
The read out is done by means of a xbee and display.

Your help is apreciated.

Theo

ps. script placed in attachment was not accepted?????

//Teller programma voor windrichting
//DD 26-01-2011
//xbee_send_serial_Data_teller_01_04
//zonder display !!!!! WERKT NIET ECHT LEKKER MEER TELT NIET PER EEN OP/NEER!!!!!!!!!!!!
// DISPLAY FUNCTIE VERWIJDERD.
//Op een mega board met serial voor xbee te zenden naar coordinater
//probleem interrupt 5 op pin 18 checken nu middels input opgelost
//display dusdanig aansluiten dat interrupt niet in de weg zitten
//vervalt dus ook IR sensor noord set op input 4
//bij opstarten eerst een volle slag maken met e wind vaan.
//#include <ctype.h>
// e.e.a. met windsnelheids meeting interrupt 4 pin 19

#define encoder0PinA 2 // interrupt
#define encoder0PinB 3 // interrupt
#define encoder0PinC 18 // interrupt 5 op pin 18
#define encoder0PinD 19 // interrupt 4 op pin 19
volatile unsigned int encoder0Pos = 16;
unsigned long time;
unsigned long timeold;
unsigned long timenew;
unsigned long millisnew;
unsigned int tmp_Pos = 0;

int led = 13; // for checking nul ""o"" doorgang
int ledA = 24;
int ledB = 26;
boolean A_set;
boolean B_set;
boolean set_new;
int count;
int setmillsnew;

void setup()
{

pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
pinMode(encoder0PinC, INPUT);
pinMode(encoder0PinD, INPUT);
pinMode(led, OUTPUT);
pinMode(ledA, OUTPUT);
pinMode(ledB, OUTPUT);
boolean A_set;
boolean B_set;
boolean set_new;
count = 0;
timeold = 0;
timenew = 0;

// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);

// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);

// encoder pin on interrupt 5 (pin 18)
attachInterrupt(5, doEncoderC, CHANGE);

// encoder pin on interrupt 4 (pin 19)
attachInterrupt(4, doEncoderD, RISING);

Serial.begin (9600);
set_new = false;

}

void loop()
{
time = timenew - timeold;

if (tmp_Pos != encoder0Pos)
{
Serial.print("<W:");
Serial.print(encoder0Pos, DEC);
Serial.print(":");
//Serial.print(time, DEC);
Serial.print(count, DEC);
Serial.print(">");
tmp_Pos = encoder0Pos;
}
if (encoder0Pos < 16){
encoder0Pos= encoder0Pos + 18;
}

}

void doEncoderA() { // Interrupt on A changing state
if (digitalRead(encoder0PinA) == HIGH) { // Low to High transition?
A_set = true;
digitalWrite(ledA, LOW);
if (!B_set) {
encoder0Pos = encoder0Pos + 1;
}
}
if (digitalRead(encoder0PinA) == LOW) { // High-to-low transition?
A_set = false;
digitalWrite(ledA, HIGH);
}

}

void doEncoderB() { // Interrupt on B changing state
if (digitalRead(encoder0PinB) == HIGH) { // Low-to-high transition?
B_set = true;
digitalWrite(ledB, LOW);
if (!A_set) {
encoder0Pos = encoder0Pos - 1;
}
}
if (digitalRead(encoder0PinB) == LOW) { // High-to-low transition?
B_set = false;
digitalWrite(ledB, HIGH); }

}

void doEncoderC() {
if (digitalRead(encoder0PinC) == LOW) {
digitalWrite( led , HIGH);
encoder0Pos = 16;
}
else{ digitalWrite( led , LOW);
}
}

void doEncoderD() {
if(digitalRead(encoder0PinD) == HIGH) {
if(set_new == true) {
while (count <= 100) {
count ++;
}

}
set_new == true;
millisnew = millis();
count = 0;
}
}

I have the same problem on a mega 1280. Int 4 will NOT count pulses from the rain gauge no matter what. All the other int pins will count just fine. That pin is also a serial port and that works great.

Ok, Bill

I also use a 1280 mega board. On a earlier test the count was ok after i implement the forth interrupt it went wrong. So I thinks
it has someting to do with the code.
To test the inputs i programmed led,s to check the inputs that looks good to me.
Still i,am looking for a solution.
Howe did you solve your problem?

Hear from you,

Theo

After some hours spending on trails it looks like the pulses will be work
well as long as the code is in the void loop().
If to much code id in the void (interrupt) it will disturb the program.
Hopefully it is of help for you.
Theo

ps
I manage to count the wind speed pulses and proces them in the void loop()

Billcramer 07,

For your information,
I manage to read and proces all the pulses from my interrupts.
It appeard to be program faults.
Enclosed you find the new script.

Regards,
Theo

// Teller programma voor windrichting en windspeed
// DD 30-01-2011
// xbee_send_serial_Data_wind_dir_speed_teller_01
// geeft 16 als noord en verder 16 posities als wind richting
// geeft milliseconden per 10 omwentellingen
// Op een mega board met serial voor xbee te zenden naar coordinater
//
//
//
// bij opstarten eerst een volle slag maken met de wind vaan.
// 
// 

#define encoder0PinA 2  // interrupt puls A
#define encoder0PinB 3  // interrupt puls B
#define encoder0PinC 18 // interrupt 5 op pin 18 puls NOORD
#define encoder0PinD 19 // interrupt 4 op pin 19 puls windspeed

volatile unsigned int encoder0Pos = 16;
unsigned long time;
unsigned long millisnew;
unsigned long millisold;
unsigned int tmp_Pos = 0;

boolean A_set;
boolean B_set;
boolean set_new;
int count;
int tmp_count;


void setup() 
{ 
  pinMode(encoder0PinA, INPUT); 
  pinMode(encoder0PinB, INPUT); 
  pinMode(encoder0PinC, INPUT);
  pinMode(encoder0PinD, INPUT);

  boolean A_set;
  boolean B_set;
 
  count = 0;
  millisold = 0;
  millisnew = 0;
  tmp_count = 1;
  time = 0;
 
  attachInterrupt(0, doEncoderA, CHANGE);// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(1, doEncoderB, CHANGE);// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(5, doEncoderC, CHANGE);// encoder pin on interrupt 5 (pin 18)
  attachInterrupt(4, doEncoderD, CHANGE);// encoder pin on interrupt 4 (pin 19)
  
  Serial.begin (9600);
}

void loop()
      { 
 if (tmp_Pos!=encoder0Pos)
                  {
                   Serial.print("<W:");
                   Serial.print(encoder0Pos, DEC);
                   Serial.print(">"); 
                   tmp_Pos = encoder0Pos;        
                  }
 if (encoder0Pos < 16){
                     encoder0Pos= encoder0Pos + 18;
                      }
 if (tmp_count != count)
                     {
                    tmp_count = count;   
           
                    if(count == 1){
                                  millisold=millis();
                                  }
                   if(count == 10){
                                  millisnew=millis();
                                  count =0;   
                                  time = millisnew - millisold;    
                                  Serial.print("<D:");
                                  Serial.print(time, DEC);
                                  Serial.print(">");
                                  }
                   } 
    } 
      
void doEncoderA() {                                                                                  // Interrupt on A changing state
        if (digitalRead(encoder0PinA) == LOW) {                                                      // Low to High transition?
                                          A_set = false;
                                                     if (!B_set )   {
                                                                    encoder0Pos = encoder0Pos ++;
                                                                   }        
                                              }
        if (digitalRead(encoder0PinA) == HIGH) {                                                     // High-to-low transition?
                                         A_set = true;
                                              }
                   }

void doEncoderB()   {      // Interrupt on B changing state
        if (digitalRead(encoder0PinB) == LOW)  {                                                    // Low-to-high transition?
                                          B_set = false;
                                                     if (!A_set )   {
                                                                    encoder0Pos = encoder0Pos - 1;
                                                                   }
                                              }
       if (digitalRead(encoder0PinB) == HIGH)  {                                                    // High-to-low transition?
                                        B_set = true;
                                              }
                   }

void doEncoderC() {
      if (digitalRead(encoder0PinC) == LOW)  {
                                              encoder0Pos = 16;
                                             }
                 }
 

void doEncoderD()  {
        if(digitalRead(encoder0PinD) == HIGH)  {
                                                count++;
                                               }  
                   }