Ir al contenido principal

Arduino multihilo

 El multithreading  o multihilo en arduino no es posible

Pero podemos aprovechar que si tiene un buen reloj, para crear subrutinas que se ejecuten de manera concurrente de modo que parezca que si se están ejecutando al mismo tiempo.

En Arduino se diría el uso de millis en lugar del delay.

Para nuestro caso práctico analizaremos el intentar leer una entrada digital (proveniente de un pulsante) mientras hacemos parpadear un led. 

Para iniciar veremos el ya conocido parpadeo de un led (Pin 13) "Blink"


// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

El lazo loop se detiene para poder encender y apagar el led, quiere decir que si colocamos la lectura del dato digital al finalizar el parpadeo del led, es posible que no seamos capaces de detectar el pulso o que presionemos en el instante en que la arduino se encuentra "dormida", para solucionar este inconveniente en lugar de usar delay, se recomienda usar "millis"  de esta forma la ejecución no se detiene, y se puede ir revisando el valor del dato digital a la par. 
A continuación se presenta el código para el mismo fin del Blink pero ahora con el uso de millis()

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.
  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Funcionaría similar a un cronómetro, donde existe un tiempo inicial y un tiempo actual, la diferencia de estos tiempos se compara en cada paso del loop() con el valor del intervalo deseado.
Entonces es posible encender y apagar el led sin necesidad de detener a la arduino. Puede ser que mientras se ejecutan las líneas de comparación en lugar de tener un intervalo de 1000 ms se tenga de 1003 ms por ejemplo, pero no va a ser detectable por el ojo humano. 

Ahora bien, estamos listos para la integración del parpadeo de un led a la lectura de un dato digital. Esto se presenta a continuación.
// constants won't change. Used here to set a pin number:
const int ledPin =  12;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
    // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
  pinMode(13,OUTPUT);
}

void loop() {
  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
    
    // read the input pin:
    int buttonState = digitalRead(pushButton);
    Serial.println(buttonState);
    digitalWrite(13,buttonState);
  }
}

Entradas populares de este blog

AUTOAJUSTE PID: CASO PRÁCTICO DE SINTONIZACIÓN EN IMPRESORA 3D

CONTROLADOR PID Un controlador  PID es permite controlar un sistema en lazo cerrado para que alcance el estado de salida deseado. El controlador PID está compuesto de tres elementos para una acción Proporcional, Integral y Derivativa. Estas tres acciones son las que dan nombre al controlador PID. Recordemos un poco que es un controlador PID y que parámetros debemos ajustar Existe gran interés en realizar la sintonización de controladores PID en diferentes software, a continuación se presenta un ejemplo en el que se simula un control PID usando software libre SCILAB, a través de Xcos AUTOTUNIG AUTOAJUSTE DE CONTROLADORES PID El controlador PID es la solución más común a los problemas prácticos de control. Aunque controladores con acción proporcional e integral han sido utilizados desde la época en que los molinos de viento y las máquinas de vapor eran las tecnologías dominantes, la forma actual del controlador PID emergió con los controladores neumáticos en los años 30 del siglo pasad

CONTROL DIFUSO

LÓGICA DIFUSA El concepto de lógica difusa es muy común, está asociado con la manera en que las personas perciben el medio, por ejemplo ideas relacionadas con la altura de una persona, velocidad con la que se mueve un objeto, la temperatura dominante en una habitación, cotidianamente se formulan de manera ambigua y depende de quien percibe el efecto físico o químico, será su enunciado acerca de tal fenómeno.  Una persona puede ser alta o baja, algo puede moverse rápido o lento, una temperatura puede ser baja o moderada o alta, se dice que estas afirmaciones acerca de una variable son ambiguas por que rápido, bajo, alto son afirmaciones del observador, y estas pueden variar de un observador a otro.  Entonces podemos afirmar que la información puede ser valiosa, aún cuando no sea cuantificada. Podemos entender información como: Hace mucho frío en la habitación Corte el pan en rebanadas Agregue azúcar al gusto El carro se desplaza muy rápido Prepare el horno a una temperatura alta La comp

RNA

Transparencias de la clase Ejercicio de entrenamiento de perceptron: Pedro Ponce Cruz. Inteligencia Artificial con aplicaciones a la Ingeniería Comandos Básicos para RNA en Matlab PERCEPTRÓN %perceptrón para compuerta or entrada = [0 0 1 1; 0 1 0 1]; objetivo = [0 1 1 1]; net= perceptron; net = train(net,entrada,objetivo); view(net) salida = net(entrada) pesos=net.IW{1,1} bias=net.b{1,1} salida = 0 1 1 1 pesos = 1 1 bias = -1 %perceptrón para compuerta and entrada = [0 0 1 1; 0 1 0 1]; objetivo = [0 0 0 1]; net= perceptron; net = train(net,entrada,objetivo); view(net) salida = net(entrada) pesos=net.IW{1,1} bias=net.b{1,1} salida = 0 0 0 1 pesos = 2 1 bias = -3 A continuación se presenta el código en Matlab para entrenamiento de RNA para identificación de las vocales: clc; clear all format long %cada letra ha sido formada de 5x5 p1=[1;1;1;1;1; 1;0;0;0;1; 1;1;1;1;1;