Attiny44A Arduino Multitasking

2

Estoy tratando de hacer parpadear un led así como encender / apagar un motor paralelamente utilizando attiny44A a continuación está mi código:

Controlador de bomba:

   digitalWrite(pump1, HIGH);
   delay(5000);
   digitalWrite(pump1, LOW);
   digitalWrite(pump2, HIGH);
   delay(5000);

Led Blink:

    digitalWrite(ledB, HIGH);
    delay(500);
    digitalWrite(ledB, LOW);
    delay(500);

¿Cómo puedo hacer esto ejecutar paralley juntos

    
pregunta Daniel Euchar

3 respuestas

5

Hay algunas formas de hacerlo, como el uso de interrupciones de temporizador, etc., pero otra forma es usar una máquina de estados simple para realizar un seguimiento de cuándo ocurrieron los últimos eventos. Considere esto más como un ejemplo de cómo hacerlo porque no está probado y no soy un usuario de Arduino, por lo que es posible que tenga algunos tipos de datos incorrectos. Pero un enfoque sería algo como:

boolean led_on = false;
unsigned long led_toggle_ms = 0;
boolean pump1_on = false;
unsigned long pump_toggle_ms = 0;

void loop()
{
    if (millis() - led_toggle_ms >= 500)
    {
        led_toggle_ms = millis();
        led_on = !led_on;
        digitalWrite(ledB, led_on);
    }
    if (millis() - pump_toggle_ms >= 5000)
    {
        pump_toggle_ms = millis();
        pump1_on = !pump1_on;
        digitalWrite(pump1, pump1_on);
        digitalWrite(pump2, !pump1_on);
    }
}

Al hacer un seguimiento de la hora en que ocurrió algo por última vez en lugar de usar delay , permite que el resto del código continúe ejecutándose. Tenga en cuenta que según la millis () documentación , el valor se desbordará después de aproximadamente 50 días, así que si desea que la aplicación se ejecute Durante más tiempo habrá que tenerlo en cuenta. Si no te importa un fallo momentáneo después de 50 días, podría ser algo simple como:

if ((millis() - led_toggle_ms >= 500) || (millis() < led_toggle_ms))
    
respondido por el PeterJ
2

También puede simular algunas tareas paralelas que se ejecutan en algunos intervalos preconfigurados.

Nota: usé la operación directa a nivel de bits para controlar el parpadeo del led, pero puedes hacerlo usando digitalWrite por supuesto

#include <Arduino.h>

//------------------------------------------------------------------------------
// Declarations // should be in the .h file

#define THA 0
void threadA(unsigned long time);

#define THB 1
void threadB(unsigned long time);

#define THC 1
void threadC(unsigned long time);

//------------------------------------------------------------------------------
// Initializations

const unsigned int pump1 = _BV(0);  //0b00000001, bit position, bit 0 in PORTB, == digital pin 9
const unsigned int ledB = _BV(1); //0b00000010, bit position, bit 1 in PORTB, == digital pin 10

// Threads definitions
// You can add or remove threads here
void (*THREADS[])(unsigned long) = {threadA, threadB, threadC};
int THINT[] = {0, 500, 5000}; // Interval for each threads

//------------------------------------------------------------------------------
// Threads

// Main loop, no interval
void threadA(unsigned long time){

}

// Every 500ms
void threadB(unsigned long time){
  PORTB ^= ledB; // Just toggle a led ON/OFF on bit ledB on PORTB
}

// Every 5000ms
void threadC(unsigned long time){
  PORTB ^= pump1; // Toggle the motor
}

//------------------------------------------------------------------------------
// Arduino core

void setup(){
  DDRB |= ledB | pump1; // Enable ledB and pump1 as output
}

// The loop method handle threads by launching each threads one after the other when their time come
void loop(){
  const int nbThread = sizeof(THREADS)/sizeof(&threadA); // Number of threads
  unsigned long threadTime[nbThread];
  char nextThread = 0;

  while(1){
    if((threadTime[nextThread] + THINT[nextThread]) < millis()){
      threadTime[nextThread] = millis();
      (*THREADS[nextThread])(threadTime[nextThread]);
    }

    if(++nextThread >= nbThread)
      nextThread = 0;
  }
}
    
respondido por el Tronix117
0

Hay dos maneras de hacer esto. La forma cruda es reemplazar el

  

delay(5000);

en el código del controlador de la bomba con 5 veces el código de parpadeo del led. Crudo, pero funciona. Aunque no es muy flexible ...

De otra manera es usar interrupciones de temporizador. Básicamente, se inicia un temporizador y se genera una interrupción a intervalos establecidos. Luego cuenta las interrupciones y cuando alcanza un cierto número de 'pulsos', toma las medidas necesarias.

Para hacer esto, debe conocer la velocidad de reloj de su arduiono, configurar los multiplicadores / divisores del temporizador, etc. y crear el código de interrupción apropiado. Esto es una respuesta demasiado, pero es demasiado para una respuesta, pero un Google para "interrupciones de temporizador" debería ayudarlo a comenzar.

Arduino tiene una biblioteca con temporizador: enlace - No estoy seguro de que haya algo similar para el ATTiny.

    
respondido por el RJR

Lea otras preguntas en las etiquetas