Go Down

Topic: Arduino Multithreading (Read 21630 times) previous topic - next topic

juliandasilva

Hi, the link to download DuinOS had changed to this:

http://robotgroup.com.ar/duinos/wiki

There you will find in the downloads section the v0.1 and the v0.2 versions.

Regards,
Julián
http://robotgroup.com.ar

juliandasilva

Hi, the link to download DuinOS (the port of FreeRTOS to Arduino) had changed to this:

http://robotgroup.com.ar/duinos/wiki

There you will find (in the downloads section) the v0.1 and the v0.2 versions.

Regards,
Julián
http://robotgroup.com.ar

juliandasilva

#17
Aug 25, 2010, 02:48 pm Last Edit: Aug 25, 2010, 02:48 pm by juliandasilva Reason: 1
I forgot the forum DuinOS discussion thread:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1256745982/0

Regards,
Julián
http://robotgroup.com.ar

AyuCat

Hi.
I want to keep pushing the button to the sound which is played at regular intervals.And,I want to output the time the button is pushed.
At this moment,I respectively made the module which outputs time by the button push and the module which plays a sound at regular intervals.

1.the module which plays a sound at regular intervals
Code: [Select]

#include <Tone.h>
Tone notePlayer;

void setup(void)
{notePlayer.begin(13);}

void loop(void)
{notePlayer.play(1000,50);  
 delay(1000); // ISI
}


2.The module which outputs time by the button push
Code: [Select]

#define BUTTON 7

int val=0;
int  old_val=0;
unsigned long time=0;

void setup(void)
{pinMode(BUTTON,INPUT);
Serial.begin(9600);}

void loop(void)
{ val=digitalRead(BUTTON);
 delay(5);
 time=millis();
 
if (((val==HIGH) &&(old_val==LOW)))
{Serial.println(time);}
 
old_val=val;  }


Next, I want to integrate these by using multithread.
What should I do?

pluggy

#19
Aug 31, 2010, 10:47 am Last Edit: Aug 31, 2010, 10:48 am by stephen_t Reason: 1
Lose the delay statements, take a look at the blink without delay example in the IDE, then the two sketches have to be interleaved so they work as one.  

The arduino is a primitive computer by anything approaching modern standards, it has no multithreading or multitasking ability, it can do only one thing at once, although with care, it needn't be much hardship.
http://pluggy.is-a-geek.com/index.html

marklar

I would not attempt to check them both in the loop due to the fact that your loop may be busy and not see the button being pressed.

Here is a working example of how I multi-task using your button example code.  This should just plug right in.

In your exact case the loop process may be quick .. but that is bound to change so a process like this will help you be able to expand your application later.

Overview:
You can use a timer for the button check.

If you do use a timer, you will want to remove the delay or your code will stall due to not being able to complete the task in the small timer window.

You should not need the delay or need to debounce if you put your button check code in a timer routine.

Example Code:
Code: [Select]

//Find timer at http://www.arduino.cc/playground/Main/MsTimer2
#include <MsTimer2.h>


//--- Button Pin
#define BUTTON 7
//--- used to store old value
int  old_val=0;
unsigned long time=0;
boolean buttonPressNew = false;

void checkButton(){
 //IMPORTANT: NO DELAY OR LONG ACTION HERE .. just change button status and take action in the loop

 //-- no need for val to be global .. just takes up 2 bytes for nothing being global.
 int val = digitalRead(BUTTON);
 //-- If they are not the same then ...
 if( val != old_val ){
   //-- Reset last value
   old_val = val;
   //-- If value is turned on .. then we need to tell the system it was hit once ..
   //   but not do it over and over until released
   if( val ){
     buttonPressNew = true;
   }
 }

}

void setup() {
 //--- Starndard Setup
 pinMode(BUTTON,INPUT);
 Serial.begin(9600);

 //--- Initialize timer2 .. using 20ms for this example
 MsTimer2::set(20, checkButton);
 MsTimer2::start();
}

void loop() {
 //Do any normal processing here ... it can run as long as you like and not effect the reading of the button.

 //Simple Example ... a delay .. this will only process a single button click.
 // so in this example .. if the button is pressed twice in this delay period .. it picks up only one time.
 // if the button check was in the loop .. it would not see the button at all.
 // if multiple button presses being excepted while in this delay .. and the action is quick .. it can be run in the loop
 //   or a counter added
 delay(5000);
 
 // This flag is set when a button is pressed .. take action in the loop and reset
 if( buttonPressNew ){
   // Take action based on the button being pressed...

   // then reset
   buttonPressNew = false;
   //IMPORTANT: Notice serial printing done here .. not in timer process
   Serial.println("Button Was Pressed");
 }
 
}



Final Notes:
You could add a counter to track the number of times the button was pressed while the loop was busy if desired.  

Also .. if the action you are taking is really fast .. then you can go ahead and just take the action right in the checkButton() function .. you may need to expand beyond 20ms to fit in your process.  Expanding too far will effect your button press responsiveness.


Hope this helps.

deSilva

Just as an exercise, this is an example of typical co-operative scheduling. As C does not have co-routines there is a trick needed to split the time consuming phases of tasks into sections, by switching into thenext section through action codes.

This example can easily be extended by more specific return codes, as for priorities, or synchronization to time marks...
Code: [Select]
// Simplified co-operative scheduling for Arduino
// 2010 by DeSilva v1.0

byte (*action[])(byte,long) ={pA, pB};
const int nmbActions =sizeof(action)/sizeof(&pA);
byte actionCode[nmbActions] ;
byte nextAction =0;

void setup() {
 
}

void loop() {
   actionCode[nextAction]  = (*action[nextAction])(actionCode[nextAction], millis());
   if (++nextAction>=nmbActions) nextAction = 0;  
}

byte pA(byte code, long theTime){
 switch (code) {
   case 0:
        return 1;
   case 1:
        return 2;
   default:
        return 0;        
  }  
}
byte pB(byte code, long theTime){
   return 0;        
}


Go Up