Buenas,
Queria hacer una consulta acerca de los INTERRUPT. Tengo un multiswitch y quiero leer las señales a traves de arduino, son 9 señales, una de arranque y las demas de control.
Pero tengo un problema , las señales se leen perfectamente, tambien se guardan en una matriz pero cuando llega la hora de jugar con esa matriz el programa no responde. He probado que a la hora de utilizar los valores de la matriz estos meterlos dentro de la funcion noInterrupt() y cuando finalize interrupt() pero me sigue pasando exactamente lo mismo.
Me gustaria saber si alguien le ha sucedido algo parecido o tiene idea y me pueda dar una solución con el fin de resolverlo.
Adjunto el codigo completo y seguidamente lo describo por fases para un mayor entendimiento.
#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()
Ahora lo explicare paso por paso.
Esta linea de codigo es la que se encarga de llamar a la funcion calReceiver cada vez que por la entrada cambia el voltaje, es decir cada interrupcion.
attachInterrupt(Interrupcion,calcReceiver,CHANGE);
Cuando esto sucede se llama a 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();
}
}
Cuando acaba entra en loop de nuevo y en esta parte es cuando se carga la matriz con los valores que envia la señal de radio.
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
Todo el codigo restante solo sirve para mostrar informacion y saber cuando empieza de nuevo el arranque es decir cuando poner la matriz a 0 de nuevo.
El problema como anteriormente he dicho es que la matriz se carga con los valores pero a la hora de mostrarlos y utilizar esos valores en condiciones resulta imposible.
Gracias a las personas que colaboran y se ayudan sin intereses.