Inyerrupcciones y LCD

:) Buenas primero me presento soy Daniel Franco Ramos y ante todo gracias por la ayuda. Mi problema es que estoy realizando un proyecto de un medidor de pulso y uso la Interrupción 2, mas concreta-mente el Timer 2 en modo comparación. esta interrupción deshabilita los 3 y 11 hasta ahí todo bien. Mi problema es que mi proyecto va montado con LCD que 16x2 que van conectados tambien en esa patilla si alguien me puede decir como cambiar la conexión del LCD o alguna otra solución lo agradeceria

No entiendo porque dices que deshabilita “los 3 y 11”. La IRQ 2 no deshabilita nada que no quieras deshabilitar.

Porque no comienzas incluyendo tu código, y tu esquema y vemos como reubicarlo
Pero la libreria LiquidCrystal.h permite que uses cualquier pin para las conexiones del LCD

Mira esto:

El circuito:

  • LCD RS pin to digital pin 12

  • LCD Enable pin to digital pin 11

  • LCD D4 pin to digital pin 5 // se usa modo 4 bits

  • LCD D5 pin to digital pin 4

  • LCD D6 pin to digital pin 3

  • LCD D7 pin to digital pin 2

  • LCD R/W pin to ground

  • 10K resistor:

  • ends to +5V and ground

  • wiper to LCD VO pin (pin 3)

/* Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe
 
 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

Buenas he estado mirando en el datasheet y no encuentro la referencia exacta de porque se deshabilita eh pin 3 y el 11. eso lo leí en un sitio donde te ayudaba a configurar la interrupcion interna te dejo mi codigo aunque aun no tengo metido la parte del lcd y me faltan cosas para acabarlo. code:[ /Variables a usar en la interrupcion por eso son volatiles no necesitan comunicacion con el programa exterior */ volatile int Vm =515; /*valor medio de las señales despues de haber hecho varias pruebas/ volatile int Señal; //Variable que nos da el valor del sensor analogico volatile unsigned long Contador = 0; //Contador de tiempo volatile unsigned long UltimoLatido = 0; //tiempo del ultimo latido

void loop(){ Time = millis(); // tiempo en ms

// configurar la interrpcion para cada 2ms la lea

TCCR2A = 0x02; //activa el bit OCR2A y esto pone el comparador el modo TCCR2B = 0x06; // activa in prescalado de 256 OCR2A = 0X7C; // Es el bit de comparacion establecido en 124 TIMSK2 = 0x02; // activa el bit OCIE2A que habilita la interrupcion del timer 2 en comparacion sei(); // Activa las interrupciones

ISR(TIMER2_COMPA_vect){ cli(); //desactiva las interrupciones temporalmente Señal = analogRead(pulsePin); //leer la entrada del sensor Contador += 2; //contador de tiempo int TDUL = Contador - UltimoLatido; // tiempo transcurrido desde el ultimo latido

/vamos a buscar las pulsaciones el pico y el valle siempre y cuando hayamos encontrado el latido primero estas condicion solo sirve una vez encontrado/ if((Señal < Vm)&&(Pulso == false)&&(TDUL>(TEL/5)*3)){//evitar la onda pequeña

if(Señal < V){ //V es el punto minimo de la onda V = Señal; //Asignar a V el valor de señal } }

if((Señal > Vm) && (Señal > P)){ /si la señal es mayor que P y mayor que el valor medio asignamos el valor maximo/ P = Señal; // P es el maximo }

/*quermos encontrar por primera vez el pulso para ello descartamos cualquier pulsacion que asi que descartamos cualquier anomalia el ritmo maximo de pulsaciones en esfuerzo ronda los 200 a 210 pulsaciones por minuto y con un ataque a al corazon podria llegar a las 250 o incluso mas fijare un maximo de 250 pulsaciones por minuito mas de eso no se identificara solo detectara un fallo o un aviso de ataque cardicaco grave */ if(TDUL > 240){ if( (Señal > Vm) && (Pulso == false) && (TDUL > (TEL/5)*3)){ Pulso = true; digitalWrite(blinkPin,HIGH); TEL = Contador - UltimoLatido; UltimoLatido = Contador;

if(latido2){ latido2 = false; for(int i=0; i<=9; i++){ grupo = TEL; * }* * }* * if(latido1){* * latido1 = false;* * latido2 = true;* * sei();* * return;* * }* * ]*

Que mezcla de cosas. A ver si lo ordenamos un poco. Primero ya entiendo que quieres hacer. Arduino tiene una estructura que se debe respetar.

Define's variables setup() loop()

Rutinas necesarias en el loop()

Bien bajo ese criterio hay cosas que corregir. No estoy seguro del uso de volatile para las variables globales. Falta algo en el loop o interpreto que tu ISR tiene código ue no le pertenece

/*Variables a usar en la interrupcion por eso son volatiles no necesitan comunicacion con
el programa exterior */
volatile int Vm =515;                    /*valor medio de las señales despues de haber hecho varias pruebas*/       
volatile int Señal;                      //Variable que nos da el valor del sensor analogico
volatile unsigned long Contador = 0;     //Contador de tiempo
volatile unsigned long UltimoLatido = 0; //tiempo del ultimo latido

void setup() {
// configurar la interrpcion para cada 2ms la lea

  cli()
  TCCR2A = 0x02;                         //activa el bit OCR2A y esto pone el comparador el modo 
  TCCR2B = 0x06;                         // activa in prescalado de 256
  OCR2A = 0X7C;                          // Es el bit de comparacion establecido en 124
  TIMSK2 = 0x02;                         // activa el bit OCIE2A que habilita la interrupcion del timer 2 en comparacion
  sei();                                 // Activa las interrupciones

 ISR(TIMER2_COMPA_vect){
    cli();                                //desactiva las interrupciones temporalmente
    Señal = analogRead(pulsePin);         //leer la entrada del sensor
    Contador += 2;                        //contador de tiempo
    int TDUL = Contador - UltimoLatido;   // tiempo transcurrido desde el ultimo latido
   
    /*vamos a buscar las pulsaciones el pico y el valle siempre y cuando hayamos encontrado
    el latido primero estas condicion solo sirve una vez encontrado*/
  
   if((Señal < Vm)&&(Pulso == false)&&(TDUL>(TEL/5)*3)){  //evitar la onda pequeña
   
      if(Señal < V){                       //V es el punto minimo de la onda     
        V = Señal;                         //Asignar a V el valor minimo de la señal
      }
    }
   
    if((Señal > Vm) && (Señal > P)){        /*si la señal es mayor que P y mayor que el valor medio asignamos el valor maximo*/
      P = Señal;                            // P es el maximo
    }
                                                   
     
     /*queremos encontrar por primera vez el pulso para ello descartamos cualquier pulsacion
   que asi que descartamos cualquier anomalia el ritmo maximo de pulsaciones en esfuerzo
   ronda los 200 a 210 pulsaciones por minuto y con un ataque a al corazon podria llegar
   a las 250 o incluso mas fijare un maximo de 250 pulsaciones por minuto mas de eso no
   se identificara solo detectara un fallo o un aviso de ataque cardicaco grave */

   if(TDUL > 240){
     if( (Señal > Vm) && (Pulso == false) && (TDUL > (TEL/5)*3)){
       Pulso = true;
       digitalWrite(blinkPin,HIGH);
       TEL = Contador - UltimoLatido;
       UltimoLatido = Contador;
     
     
     if(latido2){
       latido2 = false;
       for(int i=0; i<=9; i++){
         grupo = TEL;
       }
     }
     if(latido1){
       latido1 = false;
       latido2 = true;
       sei();           // ojo con esto activas interrupciones si latido1 es 1 y sino?????
       return;
     }
}

void loop() {   // por ahora a menos que te malinterprete no hay nada en el loop???
}

Finalmente no hay nada que active la interrupción externa que mencionas?

Este código se aplica para la int0 del UNO que es el pin 2, tomado de este link

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);  // 0 es int0 pin2 1 int1 pin 3
}

void loop(){
  digitalWrite(pin, state);
}

void blink(){
  state = !state;
}

NOTA IMPORTANTE: No te conozco pero te recomiendo tengas mucho cuidado con lo que estas haciendo. Si se e trata de un equipo médico (como parece), espero que no sea un desfribilador, si lo es, el campo eléctrico generado en la descarga puede hacer que el arduino se comporte mal. Tal vez solo es un monitor cardíaco y tienes que tomar alguna decisión, en cuyo caso es mas simple pero no menos responsable. Ojala puedas lograr que funcione correctamente. La responsabilidad civil en estos casos nos puede arruinar la vida profesional.

Dicho esto, o mejor, advertido, estoy para ayudarte en lo que necesites.

No te preocupes no tengo intención de electrocutar a nadie y conozco los riesgo de la electricidad en el cuerpo pero mi proyecto no tiene ningun riesgo lo que intento hacer es un monitor cardíaco como bien has dicho pero por una técnica no invasiva que es la pulsioximetría que mediante un led y una ldr se detecta el pulso. Solo tienes un sensor de pinza en el dedo. Bueno solo aclararte eso para que veas que no ayudas a un loco, Bueno y decirte que muchas gracias por tu respuesta voy a echar un vistazo a lo que me has comentado y ya te diré.

bien... como siempre postean parte del código uno se imagina cualquier escenario. Arduino es fantástico pero tiene algunos cuestiones en los que debe prestarsele atención.

Okay.

Bueno tu mismo dijiste que el código estaba inconcluso pero al menos ahora tiene orden pero no se para donde vas. Eso que mostraste parecia estar concentrado en la rutina del timer. O sea tomas muestras a intervalos regulares, cuentas y puedes sacar los BPM (beats per minute), ademas de medir cuestiones importantes de la gráfica sistole/diástole.

Mira te explico un poco mi idea es hacer un programa principal que cuando detecte el pulso encienda y apague un led con cada pulso, otro que cambie su intensidad según la onda cardíaca y que me imprima los valores en un lcd y también que me los mande hacia la computadora para crear una interfaz con otro programa seguramente matlab yy con esa señal recibida mostrar la onda cardíaca en el ordenador. la idea es que pueda funcionar conectado al ordenador con su interfaz o no conectado solo mostrando pulsaciones en LCD. En este momento estaba centrado en el trabajo de la interrupción porque es lo que menos manejo por eso mi código esta bastante desordenado. Mi idea es que mi interrupción lea cada 2ms valla asignando los valores máximos y mínimos y encuentre las pulsaciones esa es mas o menos la parte del codigo que he puesto y que es la que he estado probando he necesitado muchas pruebas para poder identificar bien el pico de la onda ahora me toca calcular las pulsaciones por minuto. Bueno todo esto viene a que para adelantar trabajo me puse a ver como se conectaba un lcd que no fuera pinchado porque la caja que compre no me lo permite y me vi en el problema de que vi que utilizaba los pines que supuestamente deshabilita mi interrupción interna y quise resolver el problema antes que otros. Ademas es mi primera vez programando arduino y tengo algunos líos grandes. Solo decirte que muchas gracias por tu ayuda.

Con respecto al LCD ya te expliqué que es lo que menos debe quitarte el sueño. A menos que este cableado y use el pin2 fisicamente hablando, sino lo conectas a cualquier pin. Como te puse antes.

El resto va como te dije. Tienes tu interrupción cada 2mseg. Eso digamos funciona. Entonces la int0 en el pin2 no la necesitas. ya estás en camino. Lo que falta es sumar el LCD, y presentar los BPM (beats per minute) o PPM (pulsos por minuto) como quieras llamarlo. Toma una foto del LCD a ver si es común, y otra con undiagrama que muestre que pines te quedan o lo escribes. Y asignamos los pines al LCD y ya lo tienes en camino.

Una sugerencia, yo hice un proyecto con un LCD, y vi que daba bastantes mejores resultados el usar un conversor I2C para el LCD. Los hay muy baratos, se simplifica mucho el cableado y el resultado es muy bueno.

Muchas gracias todas sugerencias son buenas. Una pregunta a ver si me la podeis aclarar no tengo muy claro si un return en lenguaje arduino te saca de la interrupcion se que en leguaje C si alguien me puedo contestatar

Una buena respuesta esta en este link, supongo que por las cosas que manejas no tienes problemas con el inglés.

Gracias surbyte he tenido una semana ocupada y no he podido mirarlo antes el link esta bien he leído parte del foro aunque mi ingles no he tan bueno como quisiera para entenderlo todo bien y el traductor pone cosas rara pero haciendo pruebas con un programa básico de interrupción que he creado me he dado cuenta de que el return te saca de la interrupción como era normal, muchas gracias por tu aportación.

Bueno insisto con ordenar las cosas y como parte de tu mayor consulta tiene que ver con el LCD y elproblema con el pin 3 y 11, te voy a pedir que hagas un esquema de las cosas que tienes conectadas al arduino.

Hazlo a mano alzada o con algun programa y lo subes para poder entender todo. Incluye el LCD tal como lo tienes conectado.

Bueno sigo esperando que me llegue mi pantalla así que no puedo enviar la foto en el momento que llegue os la mando. y ahora una duda que tengo a ver si me la podéis resolver si no veis conveniente resolverla aquí abriré otro hilo. Mi duda es como consigo detectar el maximo de la onda del pulso, no se si me explico voy cogiendo maximos pero no se como detectar el maximo del pulso.

  /*Habilitar la Interrupcion y sus contactos*/
  #include             //incluir y habilitar las entradas y las interrrupciones
  #include 
  
  
  /*Declaracion De Variables*/
  volatile int Contador;
  volatile int Senal;                   // Guarda los datos de la señal del sensor
  long Time = 0;                        // Variable que va a guardar el Tiempo
  const int analogInPin = A0;           // Entrada del Sensor Analogico 
  int LedPin=13;
  volatile int H =512;                      // VAlor del Pico  
  volatile int L = 512;                     // Valor del valle
  volatile unsigned long UL = 0;
  volatile int TEL = 600;



 void setup(){
 Serial.begin(115200);                  // velocidad a la que ira el procesador
 pinMode(LedPin, OUTPUT);
  
  TCCR2A = 0x02;                         //activa el bit OCR2A y esto pone el comparador el modo  
  TCCR2B = 0x06;                         // activa in prescalado de 256
  OCR2A = 0X7C;                          // Es el bit de comparacion establecido en 124
  TIMSK2 = 0x02;                         // activa el bit OCIE2A que habilita la interrupcion del timer 2 en comparacion
  sei();         // Activa las i
 }
 void loop(){
   
  Serial.print("sensor = " );                       
  Serial.print(Senal);      
  Serial.print("\t Contador = ");      
  Serial.println(Contador);   
  Serial.print("\t Maximo = ");      
  Serial.println(H);
  Serial.print("\t Minimo = ");      
  Serial.println(L); 
  

 }


ISR(TIMER2_COMPA_vect){                         // entra cuando timer2 cuenta 124
  cli(); 
 Senal = analogRead(analogInPin);   
 digitalWrite(LedPin, !digitalRead(LedPin));
 Contador +=2;
 int Tm = Contador - UL;
 if(Senal > 600 && Tm > (UL/5)*3 )
 if(Senal > H){
 H = Senal;
 }
 if(Senal 

Aqui dejo las fotos de la pantalla ha tardado un poco en llegarme

0 fotos

djfr0002: Aqui dejo las fotos de la pantalla ha tardado un poco en llegarme

A ver si alguien me puede echar una mano para que solo me cuente un pulso aqui dejo el codigo el bit bandera no se me desactiva en el momento que quiero

  /*Habilitar la Interrupcion y sus contactos*/
  #include             //incluir y habilitar las entradas y las interrrupciones
  #include 
  
  
  /*Declaracion De Variables*/
  volatile unsigned long Contador;
  volatile int Senal;                   // Guarda los datos de la señal del sensor
  long Time = 0;                        // Variable que va a guardar el Tiempo
  const int analogInPin = A0;           // Entrada del Sensor Analogico 
  int LedPin=13;
  volatile int H =512;                      // Valor del Pico  
  volatile int L = 512;                     // Valor del valle
  volatile unsigned long UL = 0;
  volatile int TEL = 600;
  volatile int Umbral;
  volatile boolean Subiendo = false;    // onda subiendo
  volatile boolean Bajando = false;     // onda bajando
  volatile boolean Fs = false;          // Final de Subida
  volatile boolean Fb = false;          // Final de Bajada
  volatile int Tm = 0;
  int Pulso =0;

  


 void setup(){
 Serial.begin(115200);                   // velocidad a la que ira el procesador
 pinMode(LedPin, OUTPUT);
  
  TCCR2A = 0x02;                         //activa el bit OCR2A y esto pone el comparador el modo  
  TCCR2B = 0x06;                         // activa in prescalado de 256
  OCR2A = 0X7C;                          // Es el bit de comparacion establecido en 124
  TIMSK2 = 0x02;                         // activa el bit OCIE2A que habilita la interrupcion del timer 2 en comparacion
  sei();                                 // Activa las i
 }
 void loop(){
   
  Serial.print("sensor = " );                       
  Serial.print(Senal);      
  Serial.print("\t Contador = ");      
  Serial.println(Contador);   
  Serial.print("\t Maximo = ");      
  Serial.println(H);
  Serial.print("\t Minimo = ");      
  Serial.println(L); 
  Serial.print("\t Pulso = ");
  Serial.println(Pulso);
  Serial.print("\t Fs Fb Sub Baj = ");
  Serial.print(Fs);
  Serial.print(Fb);
  Serial.print(Subiendo);
  Serial.print(Bajando);
  Serial.print("\t Umbral = ");
  Serial.print(Umbral);
  Serial.print("\t Tm = ");
  Serial.print(Tm);
  Serial.print("\t Contador = ");
  Serial.print(Contador);
  Serial.print("\t UL = ");
  Serial.print(UL);
  
  if (Fs){
    Fs = false;
    Pulso += 1;
    

  }

 }


ISR(TIMER2_COMPA_vect){                         // entra cuando timer2 cuenta 124
  cli(); 
 Senal = analogRead(analogInPin);   
 digitalWrite(LedPin, !digitalRead(LedPin));
 Contador +=2;
 Umbral = (H + L)/2;

 if((Senal < Umbral) && (Tm > (UL/5)*3) ){
 if(Senal < L){

 Bajando = true;
 Subiendo = false;
 L = Senal;
 }
 }
 if((Senal > Umbral) && (Senal > H) ){

 Subiendo = true;
 Bajando = false;
 H = Senal;
 }
 if (Subiendo && (Senal < H) && (! Fs) ){

 Subiendo = false;
 Tm = Contador - UL;
 UL = Contador;
 H = 512;
 Fs = true;

 }

}