interrupción puerto serie

Buenas tardes:
mi pregunta es si se puede generar que cada vez que tenga un dato a travez de puerto serie sea prioridad y se ejecute en ese momento aunque en el programa me este generando un rutina de retardo, un delay

Mirate los post sobre interrupciones de http://tallerarduino.wordpress.com/
Descárgate de la pagina de atmel la docu de tu MCU para saber los registros que son y
Y este post también te ayudara http://www.cursomicros.com/ es c para avr.

Finalmente según que librerías uses en tu proyecto podrían generarse algunas incompatibilidades

orlando,

Actualmente Arduino usa dicha interrupción internamente. Cada vez que se recibe un dato serie, se activa dicha interrupción y guarda el dato recibido en un buffer. Las funciones Serial.available() o Serial.read() que usa el lenguaje Arduino, lo que hacen es ir leyendo ese buffer donde se van almacenando los datos. De esta forma, puedes hacer otras cosas en tu código sin perder lo que estás recibiendo por serie.
El buffer creo que tiene un tamaño de unos 64 bytes o algo así... podrías modificarlo cambiando una constante.

Puedes ver el código para ver como lo hacen en la carpeta /hardware/arduino/cores/arduino y el fichero HardwareSerial.cpp

¿qué es lo que quieres hacer?

Saludos

Igor R.

buenas tardes:
gracias por las respuestas, les contare que quiero realizar:
tendré dos botones físicos y dos botones en el programa visual basic, los cuales uno es para encender y el otro para apagar, es lo mismo para fisico o como el programa, y lo que necesito es encender un led por 30 segundos y poder apagarlo en cualquier momento mientras este prendido, he realizado algunas pruebas con visual basic y recibo los datos pero cuando intento apagar no puedo interrumpir el programa para que el led se apague. Mi idea seria interrumpir el programa y apagar el led inmediatamente, esta interrumpción quiero realizarla tanto fisica como por puerto serial(con el visual basic)

mi programa original es:

const int boton = 28; //boton encendido
const int apagar = 31; // boton apagado
int buttonState = 0;
int buttonapagado = 0;
void setup() {
//Definimos la velocidad de transferencia a 9600 baudios
Serial.begin(9600);
//y el pin 13 como salida
pinMode(39,OUTPUT);
pinMode(boton, INPUT);
pinMode(apagar,INPUT);

}
void loop() {
buttonState= digitalRead (boton);
buttonapagado=digitalRead (apagar);
if (buttonState == HIGH){ // si el boton externo se presiona

digitalWrite(39,HIGH);
Serial.print("Encendido");
Serial.print("\t");
delay(30000); // 30 segundos, mientras se ejecute el delay quiero interrumpir
digitalWrite(39,LOW);
Serial.print("Apagado");
Serial.print("\t");

}

if (buttonapagado == HIGH){

digitalWrite(39,LOW);
Serial.print("Apagado");
Serial.print("\t");
delay(2000);

}

//Mientras el puerto serie este accesible
while (Serial.available()) {
//Guardamos en dato el valor leido del puerto serie
byte dato = Serial.read();

switch (dato){
//Si es '1' encendemos el led
case '1':
digitalWrite(39,HIGH);
Serial.print("Encendido");
Serial.print("\t"); // imprime un tabulado
delay(30000); // mientras se ejecuta este delay quiero interrumpir y que apague
digitalWrite(39,LOW);
Serial.print("Apagado");
Serial.print("\t");
break;

//Si es '2' apagamos el led
case '2':
digitalWrite(39,LOW);
Serial.print("Apagado""\t");
Serial.print("\t"); // imprime un tabulado
break;
}
}
}

hola, quetal estaba al dope y me puse a escribir un poco mientra espero un respuesta dispuesto en el foro. :slight_smile: :

en cuanto a tu problema primero que no encuentro logica en que pongas dos botones para encender/apagar un solo led,
asi el programa que ise lo idee paara uno solo.

en segundo termino cuando haces un delay haces una pausa en el programa, no ejecuta nada mas hasta que se cumpla ese tiempo.
ested debe tomar el tiempo, (q es el tiempo ? ...ya paso :)) millis();

si no tiene bien en claro los operadores logico que uso, entra qui he informate.http://arduino.cc/en/Reference/HomePage
como tambien Estructuras de control, los if, for , while, ..etc.

en en tercer termino usted debe verificar lo que envia, efectivamente es el valor enviado al arduino, en el formato que usted decea.

por ultimo, El programa, no lo he probado , pero lo que puede haber algun error. pero la esencia de lo que usted pretende
esta. donde debera modificarlo para su gusto. SLUDOS!!

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
int time=0;
int dato =0;
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);  
 Serial.begin(9600);  
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  SerialReceive();
  if ( (buttonState == HIGH) || ( dato == 1 )) {  
         time = millis(); //  1000miilis is un second   
    if(time <= 30000){  // mientras 30 second 
         // turn LED on:    
    digitalWrite(ledPin, HIGH); 
    
    
    }
   
   
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
   buttonState ==  LOW ;
   time= 0;
  }
}
else if ( (((buttonState == LOW) && ( time <= 30000) ))  ||  ( (dato == 0 ) && ( time <= 30000)) )
      {  digitalWrite(ledPin, LOW);
          buttonState ==  LOW ; 
          time =0;
      }
      
}


void SerialReceive()
{
  
  while(Serial.available())
  {
    
   
  dato = Serial.read();
   
  }
  
}

Hola Omnicoptero, muchas gracias por responder, revise tu programa y lograste entender una parte de lo que quiero realizar, ahora te explicare la lógica que tiene el programa. Ese led en realidad es la activación a un motor durante 30 segundos, quiero tener una parada de emergencia para detener en cualquier momento el motor, que pueda ser por un pulsador o por el computador, la interfaz de comunicación seria visual basic.
Revise tu programa y la función milis cuenta hasta infinito, la idea es que solamente cuente hasta 30 segundos, igual es buena idea pero no se adapta a lo que deseo; lo otro que necesito que se trabaje con pulsadores. espero que me hayas entendido y me puedas seguir ayudando. gracias.

Lo que tienes que hacer es aplicar el encendido/apagado sin delays.

Mírate el ejemplo del IDE BlinkWithoutDelay y aplicalo a tu código, eso resolverá tu problema...y sin tocar las interrupciones.

En principio, tienes que usar la función millis() pero no para saber el tiempo absoluto, sino el tiempo transcurrido desde un evento hasta otro:

inicio = millis();  // comienzan los 30 segundos
...
if(millis()-inicio >= 30000)  // Comprobamos si han pasado 30 segundos
{
  ...
}

Yo estoy metido en un asunto parecido, pero complicado por el hecho de que el arduino está durmiendo. Se despierta una vez cada hora para tomar datos con distintos sensores y grabarlo en una SD antes de volver a dormirse.

Estoy desarrollando un programa en pascal (Lazarus) que permite ponectarse con el arduino (via puerto serie o bluetooth), para pedirle que mida en ese momento, configurar la hora de un RTC o volcar los datos de su tarjeta SD. En funcionamiento normal no hay problema, pero durmiendo es otra cosa... y encima usando el mismo interruptor para las alarmar y el puerto serie...

Esta es la duda que he planteado en el foro en inglés...
http://arduino.cc/forum/index.php/topic,109723.0.html

Pero exploraré también la opción de usar milis para el tiempo de espera desde que recibe la interrupción hasta que decide qué tarea hacer. Gracias por las ideas chicos!

@madepablo: Para realizar lo que quieres, puedes utilizar un modo de bajo consumo en el que esté activa la UART. En el link hay un ejemplo que lo aplica.

http://rubenlaguna.com/wp/2008/10/15/arduino-sleep-mode-waking-up-when-receiving-data-on-the-usart/index.html/

@Jorgepl,

Gracias!. La verdad es que vi ese ejemplo hace ya tiempo, pero ahora que lo necesitaba ni me acordaba de él... Muchísimas gracias! Lo he probado y me funciona, así que voy a ver si puedo ir adaptando mi código para que cuadre en ese esquema lógico...

Muchas gracias!

@jorgepl tendrias mas ejemplo con programa comunicación a través de puerto serial, ocupando las instrucciones millis por favor