Go Down

Topic: Procesos en paralelo, multihilo, simultaneos y otras yerbas (Read 1 time) previous topic - next topic

PeterKantTropus

Jul 23, 2016, 06:56 pm Last Edit: Jul 24, 2016, 06:20 pm by PeterKantTropus
Cada tanto aparecen preguntas sobre estos tópicos en foro. En algunos casos son preguntas validas sobre procesos en paralelo, pero en la mayoría de las ocasiones se trata de un mal diseño de funciones.
Generalmente es un intento de integrar dos o mas códigos que funcionan bien por separados, pero juntos tienen comportamientos inesperados.
Por ese motivo me decidí a escribir un modesto tutorial   sobre el tema, utilizando dos funciones de lo mas sencillas.
Las funciones están basadas en los ejemplos blink y blinkWithoutDelay

El objetivo del programa es encender dos leds, uno rojo y otro verde, a diferentes frecuencias.

Led rojo con delays parpadeando cada 500 ms

Code: [Select]
int ledRojo = 14;
void setup() {                
  pinMode(ledRojo, OUTPUT);    
}

void loop() {
LedRojo;
}

void LedRojo()
{
  digitalWrite(ledRojo, HIGH);  
  delay(500);              
  digitalWrite(ledRojo, LOW);    
  delay(500);              
}


El mismo caso, pero sin delay  

Code: [Select]

const int ledPinRojo =  14;      // the number of the LED pin


int ledStateRojo = LOW;             // ledState used to set the LED
long previousMillisRojo = 0;        // will store last time LED was updated
long intervalRojo = 500;           // interval at which to blink (milliseconds)

void setup() {
   pinMode(ledPinRojo, OUTPUT);      
}

void loop()
{
LedRojo ;
}


void LedRojo()
{
  unsigned long currentMillis = millis();
   if(currentMillis - previousMillisRojo > intervalRojo) {
     previousMillisRojo = currentMillis;  
      if (ledStateRojo == LOW)
      ledStateRojo = HIGH;
       else
      ledStateRojo = LOW;
     digitalWrite(ledPinRojo, ledStateRojo);
  }
}


En ambos casos se comportan igual



Las funciones para un led Verde son equivalentes (parpadeando a un segundo)

Code: [Select]
int ledVerde = 15;
void setup() {                
  pinMode(ledVerde, OUTPUT);    
}

void loop() {
LedVerde;
}

void LedVerde()
{
  digitalWrite(ledVerde, HIGH);  
  delay(1000);              
  digitalWrite(ledVerde, LOW);    
  delay(1000);              
}



Y su equivalente sin delay

Code: [Select]
const int ledPinVerde =  15;      // the number of the LED pin
int ledStateVerde = LOW;             // ledState used to set the LED
long previousMillisVerde = 0;        // will store last time LED was updated
long intervalVerde = 1000;           // interval at which to blink (milliseconds)

void setup() {
   pinMode(ledPinVerde, OUTPUT);      
}

void loop()
{
LedVerde ;
}


void LedVerde()
{
  unsigned long currentMillis = millis();
   if(currentMillis - previousMillisVerde > intervalVerde) {
     previousMillisVerde = currentMillis;  
      if (ledStateVerde == LOW)
      ledStateVerde = HIGH;
       else
      ledStateVerde = LOW;
     digitalWrite(ledPinVerde, ledStateVerde);
  }


}








Hasta aquí parece una complicación sin sentido no utilizar  delays , pero cuando se integra el codigo

con delays el programa tiene un comportamiento inesperado.



Code: [Select]
int ledRojo = 14;
int ledVerde = 15;

void setup() {                
  pinMode(ledRojo, OUTPUT);  
  pinMode(ledVerde, OUTPUT);
}

void loop() {
LedRojo;
LedVerde;
}

void LedRojo()
{
  digitalWrite(ledRojo, HIGH);  
  delay(500);              
  digitalWrite(ledRojo, LOW);    
  delay(500);              
}

void LedVerde()
{
  digitalWrite(ledVerde, HIGH);  
  delay(1000);              
  digitalWrite(ledVerde, LOW);    
  delay(1000);              
}




El problema reside en las funciones, se completan antes de devolver el control a la función void loop, por lo tanto se ejecutan en serie una detrás de la otra.

Es en este momento cuando aparecen los post de mulhilo y procesos en paralelo.
Sin embargo el código integrado sin utilizar delays funciona correctamente


Code: [Select]

const int ledPinRojo =  14;      // the number of the LED pin


int ledStateRojo = LOW;             // ledState used to set the LED
long previousMillisRojo = 0;        // will store last time LED was updated
long intervalRojo = 500;           // interval at which to blink (milliseconds)

const int ledPinVerde =  15;      // the number of the LED pin
int ledStateVerde = LOW;             // ledState used to set the LED
long previousMillisVerde = 0;        // will store last time LED was updated
long intervalVerde = 1000;           // interval at which to blink (milliseconds)

void setup() {
   pinMode(ledPinRojo, OUTPUT);
   pinMode(ledPinVerde, OUTPUT);  
}

void loop()
{
LedRojo ;
LedVerde ;
}


void LedRojo()
{
  unsigned long currentMillis = millis();
   if(currentMillis - previousMillisRojo > intervalRojo) {
     previousMillisRojo = currentMillis;  
      if (ledStateRojo == LOW)
      ledStateRojo = HIGH;
       else
      ledStateRojo = LOW;
     digitalWrite(ledPinRojo, ledStateRojo);
  }
}


void LedVerde()
{
  unsigned long currentMillis = millis();
   if(currentMillis - previousMillisVerde > intervalVerde) {
     previousMillisVerde = currentMillis;  
      if (ledStateVerde == LOW)
      ledStateVerde = HIGH;
       else
      ledStateVerde = LOW;
     digitalWrite(ledPinVerde, ledStateVerde);
  }


}





Como conclusión podemos decir que en la mayoría de los casos no son necesarios procesos en paralelos y se debe evitar a toda costa utilizar delays y otras estructuras que detengan el programa en algún punto.

Saludos
"Si no entra como tornillo, entra como clavo"


Go Up