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;
 }
 }
JRobert
15.4k3 gold badges24 silver badges51 bronze badges
asked Sep 29, 2016 at 15:30
2
  • 1
    The standard answer, which works for most simple programs, is to get rid of delay(), as explained in the Blink Without Delay tutorial. Commented Sep 29, 2016 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? Commented Sep 29, 2016 at 16:00

2 Answers 2

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.
answered Sep 29, 2016 at 15:50
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
}
answered Sep 30, 2016 at 17:35

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.