Go Down

Topic: Problem solved: After an IRQ my code stops allways at the same point. Why?? (Read 426 times) previous topic - next topic

ArduinoStarter1

Jul 08, 2013, 09:25 pm Last Edit: Jul 09, 2013, 01:41 pm by ArduinoStarter1 Reason: 1
After an IRQ my code stops allways at the same point (after 8/16s in my subroutine "mastercontroller"). I'm wrestling with it for several weeks and will become a little bit crazy. Who can tackle the problem?

I have a function (called mastercontroller), which is triggered every 1/16 s (Timer1, 16Hz). Every part of a second a task is executed (sampling analog values, calculating power, processing of data, storage of data to SRAM/SD-card and son on). See attached blockdiagram.
Procedure "FixPeriodtime" is triggered by IRQ0 (pin 2 connected to the output contact of the external Wh-counter); here the time (in ms) between two energypulses is fixed in ms (Timer5 runs at 1000Hz).

Although the periodtime is comes in at an undifined timestamp, the power of the measured installation (P=3600 Ws/periodtime) is calculated at 9/16 s within the procedure "mastercontroller".

Code: [Select]

attachInterrupt(0, FixPeriodtime, FALLING);


Code: [Select]

//Interrupt every 62.5 ms (16 Hz) with timer 1, written on 20130617
ISR(TIMER1_COMPA_vect)
{
//intIRQ++;
Mastercontroller();
}


Code: [Select]

//Between two kWh-pulses, the timeticks (1 ms) are accounted
ISR(TIMER5_COMPA_vect)          // timer compare interrupt service routine
{
 ulngCount++;  //Every 1 ms
}


Code: [Select]

//Interrupt request for impulse of kWh-counter on pin 2 (IRQ0)
void FixPeriodtime()
{
 ulngTimecounter=ulngCount; //Store periodtime between two kWh-pulses
 Serial.print (ulngTimecounter); Serial.println("");
 ulngCount=0;               //Reset ms-counter
 blnIRQflag=true;           //Set flag to update the display
}


Code: [Select]

//Interrupt request for impulse of kWh-counter on pin 2 (IRQ0)
void FixPeriodtime()
{
 ulngTimecounter=ulngCount; //Store periodtime between two kWh-pulses
 Serial.print (ulngTimecounter); Serial.println("");
 ulngCount=0;               //Reset ms-counter
 blnIRQflag=true;           //Set flag to update the display
}


Code: [Select]

//Clock function
void Mastercontroller() {
float sngEfi_exp, Pdc, sngHi25_temp;

//See explanation in "6. Arduino_experimenten.xlsx", sheet "Timercontrol"

cnt1=cnt1+1;                     //Increment 62.5 ms counter
Serial.print (cnt1); Serial.println("");
//Msg_WriteText("RTC benaderd")

if (cnt1==1){ }                                        //
if ((cnt1+1) % 3==0) { Read_analogValues(); }          //Take every 2,5,8,11,14 sixteenth of a second samples of analog inputs

if (cnt1==9) {
   digitalWrite(LoggingLED,on);                                //Turn LogggingLED1 on
   if (blnMeten = true) {                                      //Check for "Logging-meu" of "Setting-menu"
       digitalWrite(kWhpulsLED,on);                            //Turn kWhpulsLED on
       Serial.print("Stop 1 bereikt");Serial.println("");
       if (blnIRQflag==true){                                  //Update values after kWh-pulse
           Serial.print(intADC_value0); Serial.print(intADC_value1);Serial.print(intADC_value2);Serial.println("");
           sngGi_nc = sngOffset0+sngK0*intADC_value0/5;        //Calculate Gi_nc
           sngTm = sngOffset1+sngK1*intADC_value1/5;           //Calculate Tm
           sngTamb = sngOffset2+sngK2*intADC_value2/5;         //Calculate Tamb
           sngGi_25 = sngGi_nc*(1-sngAlpha*(sngTm-25));        //Calculate corrected Gi
           Put2histogram(sngGi_25, sngTm, sngTamb);            //Put measured values in histogram
           intADC_value0=0; intADC_value1=0; intADC_value2=0;  //Reset values, calculations have been done
           
           //Calculation of Hi
           sngHi25_temp = sngGi_25 * ulngTimecounter*0.001/3600;          //Irradiation during last period [Wh/m²]
           sngHi25= sngHi25 +  sngHi25_temp;                        //Cumulative irradiance [Wh/m²]
           sngPfi = (3600*sngEnergypulse)/ulngTimecounter*0.001;    //Calculate Pfi in [W]
           sngEfi = sngEfi + sngEnergypulse;                        //Cumulative Efi [Wh]
           sngPR = 1000 *sngEfi/(lngPstc * sngHi25_temp);           //Calculated Performance Ratio
       
           //Calculation of expected power
           //Pdc=sngGi_25 * lngPstc * (1+sngBeta *(25-sngTm))* Get_RelEffMod(sngGi_25);   //See formula xx
           //sngEfi_exp = Pdc* ......
           
           //Assesment of performance
           if (sngEfi_exp/sngEnergypulse >= sngLim1)
               { digitalWrite(PRgoodLED, on);  digitalWrite(PRpoorLED, off); digitalWrite(PRbadLED, off); }
           if (sngEfi_exp/sngEnergypulse <= sngLim2)
               { digitalWrite(PRgoodLED, off);  digitalWrite(PRpoorLED, off); digitalWrite(PRbadLED, on); }
           if (sngEfi_exp/sngEnergypulse > sngLim2 and sngEfi_exp/sngEnergypulse < sngLim1)
               { digitalWrite(PRgoodLED, off);  digitalWrite(PRpoorLED, on); digitalWrite(PRbadLED, off); }
           LCD_logging_text();                                   //Update every second display
           blnIRQflag = false;                                   //Reset interrupt flag
       }  //End of interrupt handling
   }      //End if blnMeten
}   //End cntl==8

//if (cnt1==16 && blnMeten==1)  {                  //Temporaly removed 20130617
if (cnt1==16)  {
  cnt1=0;  
 //Make calculations  
   digitalWrite(LoggingLED,off);                  //turn LoggingLED off
   digitalWrite(kWhpulsLED,off);                  //turn kWhpulsLED off
   //Get_timePCF8583()
   second= second+1;
   if (second==60) { second=0; minute= minute+1; }
   if (minute==60) { minute=0; hour= hour+1; }
   if (hour==24)   { hour=0;  /*Synchronize_internalclock()*/ }
   
   }  //End If

}   //End mastercontrol function
[code]
[/code]

AWOL

I stopped looking after I found serial I/O in ISR.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ArduinoStarter1

AWOL, can you explain something more about your remark?

AWOL

At least one of your ISRs calls serial I/O functions.
Serial I/O uses interrupts.
That's a problem.
I can't see all your code, so I can't say more.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ArduinoStarter1

Thanx AWOL, I will rewrite my code, so that no IO-transfer will be within my ISR.

AWOL

Quote
I will rewrite my code, so that no IO-transfer will be within my ISR

No need to go that far - just ensure you don't call any buffered interrupt-driven I/O in your ISR.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ArduinoStarter1

I moved only a few lines; that makes the difference! My problem has been solved.
This forum was very very helpfull with only ONE remark.
Thnx again AWOL

Go Up