Hello everyone, I am asking for your help with the following.
I have a program with 2 external interrupts, sometimes it happens that both signals arrive simultaneously, when this happens the arduino does not respond, how could I control this event?
Fix your code. With proper coding no interrupts can be lost.
The question must be asked, what are you doing that you need interrupts in the first place?
Oftentimes interrupts are not really necessary.
All interrupts have a priority as to when the associated code is executed. When one code is done the waiting interrupt code is executed. Simultaneous is irrelevant.
First of all, thank you all for responding.
I am using two flowmeters that could operate at a frequency between 30 and 50 Hz, in order to measure the pulse time as accurately as possible I am using interruptions.
If I try them separately they work fine, but if they both work at the same time the code does not work correctly.
The time taken by the code inside the interrupt is approximately 10Us.
It's time you showed us the code.
Does that mean you are using the SAME CODE for each interrupt? I sure hope not!!!!
I created separate code for each interrupt, with different variables.
I'm sorry I can't show the code now because I have it on my work PC, I'll upload it first thing tomorrow morning.
See if you can include a schematic or a block diagram of your project!
so why you decided to open the thread if you haven't a code right now?
Ok, thank you.
Hello dears
I already found the problem, it happened that I had a problem with the source that powered the flowmeters. When I connected the 2 ones, the voltage dropped and it did not correctly send the low pulse to the Arduino.
Now that this has been corrected, the interruptions work fine.
Thank you very much for your interest in helping me
I present to you sections of the code:
attachInterrupt(digitalPinToInterrupt(sonda_caudal_1), int_caudal_1, FALLING);
attachInterrupt(digitalPinToInterrupt(sonda_caudal_2), int_caudal_2, FALLING);
void int_caudal_1()
{
int t_filtro_c1 = millis() - res_millis_filtro_c1;
if(t_filtro_c1 > 5)
{
pulsos_caudal_1++;
//se toma una muestra de 100 pulsos para calcular el tiempo de los pulsos
if(pulsos_referencia_c1 == 0)
{res_millis_pulsos_c1 = millis();}
pulsos_referencia_c1++;
if(pulsos_referencia_c1 >= 100)
{tiempo_pulso_c1 = millis() - res_millis_pulsos_c1;}
res_millis_filtro_c1 = millis();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void int_caudal_2()
{
int t_filtro_c2 = millis() - res_millis_filtro_c2;
if(t_filtro_c2 > 5)
{
pulsos_caudal_2++;
//se toma una muestra de 100 pulsos para calcular el tiempo de los pulsos
if(pulsos_referencia_c2 == 0)
{res_millis_pulsos_c2 = millis();}
pulsos_referencia_c2++;
if(pulsos_referencia_c2 >= 100)
{tiempo_pulso_c2 = millis() - res_millis_pulsos_c2;}
res_millis_filtro_c2 = millis();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void reset_flanco_int_1()
{
if(!digitalRead(sonda_caudal_1))
{res_millis_filtro_c1 = millis();} //se resetea el tiempo para que no detecte rebote en el flanco ascendente
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void reset_flanco_int_2()
{
if(!digitalRead(sonda_caudal_2))
{res_millis_filtro_c2 = millis();} //se resetea el tiempo para que no detecte rebote en el flanco ascendente
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void calcular_m3_y_caudal_1()
{
m3_absolutos_1 = (float) pulsos_caudal_1 * 0.000002188;
m3_parciales_1 = (float) m3_absolutos_1 - m3_parciales_1_inicial;
if(pulsos_referencia_c1 >= 100)
{
litros_minuto_1 = (float) factor / tiempo_pulso_c1; // (60000 * 0,2188) / tiempo_pulso
pulsos_referencia_c1 = 0;
con_reset_lec_caudal_1 = 0;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void calcular_m3_y_caudal_2()
{
m3_absolutos_2 = (float) pulsos_caudal_2 * 0.000002188;
m3_parciales_2 = (float) m3_absolutos_2 - m3_parciales_2_inicial;
if(pulsos_referencia_c2 >= 100)
{
litros_minuto_2 = (float) factor / tiempo_pulso_c2; // (60000 * 0,2188) / tiempo_pulso
pulsos_referencia_c2 = 0;
con_reset_lec_caudal_2 = 0;
}
}
The sections of the code are useless, to help you we need to see the code in full.
You interrupt routines not looks good, using a millis() inside the interrupt is a dangerous. But nothing can be suggested without seeing the entire code.
Your routines called by interrupts are very large.
Interrupt routines should be as small as possible.
I suggest that when entering the interrupt routine, just turn on a flag and exit the routine,
This frees up the microcontroller for new interrupts.
And outside the interrupt routine you test the flag and then execute the specific instructions necessary for calculations indicated by the interrupts.
Hello ruilviana.
I understand what you are saying, what I am doing in this routine is measuring the time of a pulse to determine the flow rate. I also have a counter to avoid noise (anti-bounce). This routine that I have done takes between 8 and 10Us, which I think is not much. At least it doesn't affect my code at the moment.
As I said in the previous comment, the program is working well, even now I have put 4 interruptions.
But if there is another way to do it better I would greatly appreciate it.
You use millis() within your interrupt routines.
See what is written in the Arduino reference about millis().
millis() relies on interrupts to count, so it will never increment inside an ISR . Since delay() requires interrupts to work, it will not work if called inside an ISR. micros() works initially but will start behaving erratically after 1-2 ms.
My suggestion:
attachInterrupt(digitalPinToInterrupt(sonda_caudal_1), int_caudal_1, FALLING);
attachInterrupt(digitalPinToInterrupt(sonda_caudal_2), int_caudal_2, FALLING);
bool flag_calda_1 = false;
bool flag_calda_2 = false;
void int_caudal_1()
{
flag_calda_1 = true;
}
void int_caudal_2()
{
flag_calda_2 = true;
}
.....................???????w
if (flag_calda_1 == true){
flag_calda_1 = false;
int t_filtro_c1 = millis() - res_millis_filtro_c1;
if(t_filtro_c1 > 5)
{
pulsos_caudal_1++;
//se toma una muestra de 100 pulsos para calcular el tiempo de los pulsos
if(pulsos_referencia_c1 == 0)
{res_millis_pulsos_c1 = millis();}
pulsos_referencia_c1++;
if(pulsos_referencia_c1 >= 100)
{tiempo_pulso_c1 = millis() - res_millis_pulsos_c1;}
res_millis_filtro_c1 = millis();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
.....................???????w
if (flag_calda_2 == true){
flag_calda_2 = false;
int t_filtro_c2 = millis() - res_millis_filtro_c2;
if(t_filtro_c2 > 5)
{
pulsos_caudal_2++;
//se toma una muestra de 100 pulsos para calcular el tiempo de los pulsos
if(pulsos_referencia_c2 == 0)
{res_millis_pulsos_c2 = millis();}
pulsos_referencia_c2++;
if(pulsos_referencia_c2 >= 100)
{tiempo_pulso_c2 = millis() - res_millis_pulsos_c2;}
res_millis_filtro_c2 = millis();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void reset_flanco_int_1()
{
if(!digitalRead(sonda_caudal_1))
{res_millis_filtro_c1 = millis();} //se resetea el tiempo para que no detecte rebote en el flanco ascendente
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void reset_flanco_int_2()
{
if(!digitalRead(sonda_caudal_2))
{res_millis_filtro_c2 = millis();} //se resetea el tiempo para que no detecte rebote en el flanco ascendente
}
////////////////////////////////////////////////////////////////////////////////////////////////////
I am not using delays within the interrupt, I am only capturing the time of the millis() function, if I only activate a flag I could lose time with other routines that are responsible for sending this data to the cloud, however, I will look at how to optimize it. thank you so much!
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.