How to employ multithreading with Rduino

Asked

Viewed 1,244 times

7

I’m making a bell with Andy. This bell shall be composed of:

  • 01 Arduino UNO,
  • 01 Buzzer,
  • 01 Transmitter 433 Mhz,
  • 01 Receptor 433 Mhz.

My doubt revolves around how I can treat the listener who will be listening the control controls 433 Mhz and at the same time make the treatment to that Buzzer oscillates using delays.

My code is basically this. I am using the Rfremote library I found in this link https://github.com/renatoaloi/RFremote

#include <RFremote.h>
SignalPatternParams params;
RFrecv rfrecv;

int status_prog = 0;

const int buzzer = 11;
const char *BOTAO1 = "0100100100110110110100100110110100100110110110110110100100110100100110100100110100110";
const char *BOTAO3 = "0100100100110110110100100110110100100110110110110110100100110100100100110100110100110";

void setup()
{
  Serial.begin(9600);
  delay(500);

  Serial.println("INICIADO!");

  // COMPATEC remote
  params.spaceMin = 10000;
  params.spaceMax = 15000;
  params.dotMin = 450;
  params.dotMax = 600;
  params.traceMin = 950;
  params.traceMax = 1150;
  params.skipFirst = 0;
  params.skipLast = 0;

  rfrecv = RFrecv(&params);
  rfrecv.begin();

  pinMode(buzzer,OUTPUT);

}

void loop()
{

  if (rfrecv.available()) // LISTENER DO CONTROLE - RECEBE ID DO CONTROLE/TECLA VIA FREQUENCIA 433 Mhz
  {
    if (strncmp((char*)rfrecv.cmd, BOTAO1, CMD_SIZE) == 0) { 
      status_prog = 1; // LIGA O BUZZER
    }
    if (strncmp((char*)rfrecv.cmd, BOTAO3, CMD_SIZE) == 0) {
      status_prog = 3; // DESLIGA O BUZZER
    }
  }

  if(status_prog == 1) {  // SE O BOTÃO PRESSIONADO FOR EQUIVALENTE A 1 LIGA
      tone(buzzer, 650); // ACIONA BUZZER COM A TONALIDADE 650
      delay(400);        // PAUSA POR 400 MS
      noTone(buzzer);    // DESLIGA BUZZER
      delay(400);        // PAUSA POR 400 MS
  }

  if(status_prog == 3){ 
    noTone(buzzer);      // SE O BOTÃO PRESSIONADO FOR EQUIVALENTE A 3 DESLIGA
  }

}

If I remove the delay in this part

if(status_prog == 1) {  // SE O BOTÃO PRESSIONADO FOR EQUIVALENTE A 1 LIGA
   tone(buzzer, 650); // ACIONA BUZZER COM A TONALIDADE 650
   //delay(400);        // PAUSA POR 400 MS
   //noTone(buzzer);    // DESLIGA BUZZER
   //delay(400);        // PAUSA POR 400 MS
}

the program works correctly.

I think the delay(400) ends up taking the time that the program as a whole has to listen to the control. What would be the approach to take in this case? A Thread would be welcome...

2 answers

6


Arduino doesn’t support multithreading, but I’ve heard of libraries that simulate it. However, the simplest is not to use delays (which actually leave the program "deaf and dumb"), and calculate whether it is time to turn on or off the Buzzer based on the time elapsed since the program started running (using the function millis()). Something like that (untested):

bool oscilando = false;
bool tocando = false
long comeco = 0;
long intervalo = 400;

void loop()
{
  unsigned long agora = millis();

  if (rfrecv.available()) // LISTENER DO CONTROLE - RECEBE ID DO CONTROLE/TECLA VIA FREQUENCIA 433 Mhz
  {
    if (strncmp((char*)rfrecv.cmd, BOTAO1, CMD_SIZE) == 0) { 
      oscilando = true;
      tocando = false;
      comeco = agora;
    }
    if (strncmp((char*)rfrecv.cmd, BOTAO3, CMD_SIZE) == 0) {
      oscilando = false;
      tocando = false;
      noTone(buzzer);
    }
  }

  if(oscilando && agora - comeco > intervalo) {
      tocando = !tocando;
      comeco = agora;
      if(tocando) {
          tone(buzzer, 650);
      } else {
          noTone(buzzer);
      }
  }
}

3

To complement a little reply from @bfavaretto on Mult-task on Arduino

The Arduino can come to support multtasking (multitasking) based on time-sharing, even in AVR controllers that are 8 bits, but this is only applicable in very simple codes and if the activity requires calculations and controls and real time, but no doubt the ideal is to use an Arduino DUE case I really need Multtask, I started some studies with Freertos and I arrived at Duinos, I even made a Fork and some updates but for lack of time stopped.

The use of RTOS even in 8bit architecture helps a lot in tasks that require a good synchronization to trigger doors and read doors as long as they are simple tasks and calculations. It is possible to run even in the Arduino UNO up to 3 basic tasks, let’s assume reading some level meters, drive pumps so that everything works in three independent control blocks or synchronized.

The advantage is often to have a better timing and as you say, RTOS, brings us results in real time, which eliminates the use of functions such as delay() and reduces the simplicity of the code in the logic layer of ifprocesso, eliminando diversas variáveis de controle de tempo, como usado quando se quer eliminar o uso dodelay()`;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.