I wanted to ask about the INTERRUPT. I have a multiswitch and I want to read the signals through Arduino, they are 9 signals, one start and the other control.
But I have a problem, the signals are read perfectly, they are also stored in a matrix but when it comes time to play with that matrix the program does not respond . I have tried that when using the values of the matrix these put them inside the function noInterrupt()
and when it finishes interrupt()
but it keeps happening exactly the same.
I would like to know if someone has experienced something similar or has an idea and can give me a solution in order to solve it.
I enclose the complete code and then describe it in phases for a better understanding.
#define Interrupcion 0 // INTERRUPT 0 = DIGITAL PIN 3 - use the interrupt number in attachInterrupt,.....pines 2 y/ó 3 en UNO.
#define ch7 3 // INTERRUPT 0 = DIGITAL PIN 3 - use the PIN number in digitalRead # changed to pin 3 for micro
volatile int pulso = 1500; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long inicio_flanco = 0; // set in the interrupt
volatile unsigned long valor_inicio_flanco = 0; // set in the interrupt
volatile boolean nuevo_pulso = false; // set in the interrupt and read in the loop
unsigned long dead_time;
unsigned long current_time;
char buffer[80] = "";
int Multi_Switch[50]; //tamaño de la matriz para albergar los 9 valores
int switch_num = 0; // variable para indicar el switch de los 8 posibles
int valor_pulso = 1000; // variable Xpara el valor del pulso a leer, inicializado a 1000
void setup()
{
// should only have to see 8 of these... 9th should be sync signal
Multi_Switch[0] = 1500;// inicializa en el valor central de cada interruptor
Multi_Switch[1] = 1500;
Multi_Switch[2] = 1500;
Multi_Switch[3] = 1500;
Multi_Switch[4] = 1500;
Multi_Switch[5] = 1500;
Multi_Switch[6] = 1500;
Multi_Switch[7] = 1500;
Multi_Switch[8] = 1500;
// tell the Arduino we want the function calcReceiver to be called whenever INT0 (digital pin 3) changes from HIGH to LOW or LOW to HIGH
// catching these changes will allow us to calculate how long the input pulse is
attachInterrupt(Interrupcion,calcReceiver,CHANGE);
//we will be sending a ton of data
Serial.begin(57600);//57600
dead_time = millis();
Serial.println("system ready");
}
void loop()
{
if(nuevo_pulso == true)
{
//copy to our non volatile var
valor_pulso = pulso; // pulso es el valor volatil. valor_pulso es el valor a utilizar
if (switch_num < 50)
{
Multi_Switch[switch_num] = valor_pulso;
}
switch_num++;
nuevo_pulso = false;
} // end nuevo_pulso
sprintf(buffer ,"valor_pulso %d , counter %d", valor_pulso, switch_num);
Serial.println(buffer);
//servo channel orientation normal
if (valor_pulso < 1000)
{
sprintf(buffer ,"valor_pulso < 1000 %d %d this is sync signal", valor_pulso, switch_num);
Serial.println(buffer);
switch_num = 0;
}
//servo channel orientation reversed
if (valor_pulso > 2000)
{
sprintf(buffer ,"valor_pulso > 2000 %d %d this is reversed sync signal", valor_pulso, switch_num);
Serial.println(buffer);
switch_num = 0;
}
// Failsafe
current_time = millis();
//it has been 3 seconds since we got a servo pulse...
if ((current_time - dead_time ) > 3000)
{
Serial.println("receiver lost signal");
//change Multi_Switch[0]..Multi_Switch[7] to failsafe values
}
// put your code here to run through values stored in Multi_Switch[0]...Multi_Switch[7] to position switches/lights/horns/servos accordingly
delay(10); // delay in between reads for stability
// other processing ...
} //end of void loop()
void calcReceiver()
{
// if the pin is high, its the start of an interrupt
if(digitalRead(ch7) == HIGH)
{
// get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its easy to understand and works very well
valor_inicio_flanco = inicio_flanco;
inicio_flanco = micros();
}
else
{
// if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
// start time inicio_flanco from the current time returned by micros()
if(inicio_flanco && (nuevo_pulso == false))
{
pulso = (int)(micros() - inicio_flanco);
inicio_flanco = 0;
// tell loop we have a new signal on the CHANNEL channel
// we will not update pulso until loop sets
// nuevo_pulso back to false
nuevo_pulso = true;
//reset our dead-man's switch
dead_time = millis();
}
}
} //end of void calcReceiver()
Now I will explain it step by step.
This line of code is responsible for calling the function calReceiver
every time that the input changes the voltage , ie every interruption.
attachInterrupt(Interrupcion,calcReceiver,CHANGE);
When this happens it is called calcReceiver.
void calcReceiver()
{
// si la entrada va a alto,es el inicio de una interrupcion
if(digitalRead(ch7) == HIGH)
{
// mide el tiempo en microsegundos - when our code gets really busy this will become inaccurate, but for the current application its easy to understand and works very well
valor_inicio_flanco = inicio_flanco;
inicio_flanco = micros();
}
else
{
//// si la entrada va a bajo, el pulso ha terminado y es el momento de calcular su duracion restando el tiempo de inicio menos el tiempo final devuelto por la funcion micros()
// if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
// start time inicio_flanco from the current time returned by micros()
if(inicio_flanco && (nuevo_pulso == false))
{
pulso = (int)(micros() - inicio_flanco);
inicio_flanco = 0;
// tell loop we have a new signal on the CHANNEL channel
// we will not update pulso until loop sets
// nuevo_pulso back to false
nuevo_pulso = true;
//reset our dead-man's switch
dead_time = millis();
}
}
When it finishes it loops again and in this part is when the matrix is loaded with the values that the radio signal sends.
if(nuevo_pulso == true)
{
// si detecta un pulso, guarda el valor en la matriz, si no, sigue el loop
//copy to our non volatile var
valor_pulso = pulso; // pulso es el valor volatil. valor_pulso es el valor a utilizar
if (switch_num < 50)
{
Multi_Switch[switch_num] = valor_pulso;
}
switch_num++;
// cambiar el boleano a falso al terminar
// con pulso, mientras sea verdadero, calcInput no actualizara el pulso
nuevo_pulso = false;
} // end nuevo_pulso
All the remaining code is only used to show information and to know when the start-up starts again ie when to put the matrix to 0 again.
The problem as I said before is that the matrix is loaded with the values but at the time of showing them and using those values in conditions is impossible.
Thanks to the people who collaborate and help each other without interests. :)