2

I am checking for ways to implement multi threathing in Arduino, I have also tried using the library TimerOne but it doesn't seem to work, what I'm trying to make is an Arduino application then, every time a certain amount of time passes, it pops an item from the stack, and between these times, the application allows me to add items to the stack, both processes working in parallel of course.

The items popped and pushed are numbers.

I have already tried some other questions, but their solutions don't work, especially one that seems very useful, but for some reason doesn't work, I'm speaking about the one of the TimerOne library.

Any suggestion to fix the problem some other way would be cool.

Here is the code:

#include <TimerOne.h>
#include <QueueList.h>
#include <StackList.h>

const uint16_t  NOTE_B0     =   31;
const uint16_t  NOTE_C1     =   33;
const uint16_t  NOTE_CS1    =   35;
const uint16_t  NOTE_D1     =   37;
const uint16_t  NOTE_DS1    =   39;
const uint16_t  NOTE_E1     =   41;
const uint16_t  NOTE_F1     =   44;
const uint16_t  NOTE_FS1    =   46;
const uint16_t  NOTE_G1     =   49;
. . . ETC . . .
const uint16_t  NOTE_DS8    = 4978;


uint16_t Notas[] =
{
      NOTE_B0   
    , NOTE_C1   
    . . . ETC . . .
    , NOTE_C8   
    , NOTE_CS8
    , NOTE_D8
    , NOTE_DS8
};

QueueList<int> KeyNotesNode = QueueList<int>();
StackList<int> StackNote = StackList<int>();

char receivedChar1 = '<';
char receivedChar2 = '<';

char receivedChar[] = {receivedChar1, receivedChar2};

int TempInt = 0;
bool newData = false;

bool itPopUp = false;

int modality = 0;

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

  if(modality == 0){
    Serial.println("Ingrese el tipo de funcionalidad deseada");
    Serial.println("1.- Constructor de canciones en tonos");
    Serial.println("2.- Juego de imposicion musical");
  }

  Timer1.initialize(150000);
  Timer1.attachInterrupt( setForPop );
}

void loop() {
  //Checa y controla la recepcion de los char a traves de la consola de arduino

  if (Serial.available()) 
  {
    receiveChar();
    showReceivedChar();
  }

//   . . .  Here is some code to process the reception of data from serialData  . . .


// From somewhere here start the loop

// . . . LOOPED . . .

    //Here is used the data
    if(modality == 1){
       //This option doesn't matter
    }
    else if(modality == 2){
      StackNote.push( (((int)(receivedChar[0]-'0'))*10)+((int)receivedChar[1]-'0') );
      Serial.println("Agregado receivedChar exitosamente a la Pila");
      Serial.print("Tamano Total Lista: ");
      Serial.println(StackNote.count());
      Serial.print("Dato:");
      Serial.println( (((int)(receivedChar[0]-'0'))*10)+((int)receivedChar[1]-'0') );
      Serial.print("Dato(get):");
      receivedChar[0] = '<';
      receivedChar[1] = '<';
    }
}

    //Run and show the data on the stack
     if(modality == 1)
     {
           //This option doesn't matter
      }
      else if(modality == 2)
      {

        if(itPopUp){   //With this variable i want to control when it is show, this code is inside loop()
          Serial.print("Reproducido con exito la nota: "); //se escribe 'éxito' pero la consola no acepta tildes, que se arrepienta :P
          TempInt = StackNote.pop();
          Serial.println(TempInt);
          tone(9,Notas[((int)TempInt)],500);
          delay(500);
        }
      }


  } //Here the loop() end

//This function i want to run it asyncronously
 void setForPop(){
    if(itPopUp){
      itPopUp = !itPopUp;
    }
    else{
      itPopUp = !itPopUp;
    }
 }
  • 1
    The standard answer, which works for most simple programs, is to get rid of delay(), as explained in the Blink Without Delay tutorial. – Edgar Bonet Sep 29 '16 at 15:43
  • your 'setForPop' does exactly the same thing. Whatever the value of itPopUp, the result will be always the same. Also what is receiveChar() and showReceivedChar() function? Can you paste the full code? – brtiberio Sep 29 '16 at 16:00
1

You will not have full parallel execution in an Arduino (only one CPU).

  • You might do multi-threading by implementing a small OS (e.g. FreeRTOS)
  • Or write your own task scheduler.
  • Or even just do state machine looping forever checking if push or pop has to be executed.
  • Last and preferred solution: I would consider running the normal Push task always and execute the Pop task (function in fact) using interrupts.
1

I haven't used the TimerOne library, but I have had good success with the SimpleTimer library. http://playground.arduino.cc/Code/SimpleTimer

It's served me well in handling building small iot apps. As the arduino has to both maintain connection info as well as doing it's processing data, this library seems to handle keeping both happy pretty well.

Here's an example in use: https://github.com/adbacker/bcc2016/blob/master/bcc2016.blynk.kitchensink/bcc2016.blynk.kitchensink.ino

The money bit is at the end => the setup and loop functions. (note: yes, I know. the comment says every second, but it's actually every 2 seconds...)

void setup()
{
  Serial.begin(115200); // See the connection status in Serial Monitor
  pinMode(WATER_SENSOR_PIN, INPUT); //water sensor pin, init as input
  Blynk.begin(auth, WIFI_SSID, WIFI_PW);
  while (Blynk.connect() == false) {
    Serial.println("trying to connect ....");
  }

dht.begin();

// Setup a function to be called every second
timer.setInterval(2000L, sendTemp);
timer.setInterval(2000L, updateLcd);
timer.setInterval(2000L, checkForWater);
}

void loop()
{
  Blynk.run(); // Initiates Blynk
  timer.run(); // Initiates SimpleTimer
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.