Pages: 1 [2]   Go Down
Author Topic: Arduino Multithreading  (Read 18020 times)
0 Members and 1 Guest are viewing this topic.
Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 188
Sé feliz
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 188
Sé feliz
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Argentina
Offline Offline
Full Member
***
Karma: 0
Posts: 188
Sé feliz
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: August 25, 2010, 07:48:38 am by juliandasilva » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
#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?
Logged

Lancashire, UK
Offline Offline
Edison Member
*
Karma: 9
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: August 31, 2010, 03:48:14 am by stephen_t » Logged


Florida
Offline Offline
Sr. Member
****
Karma: 4
Posts: 431
hookedup!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
//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.
Logged

0
Offline Offline
Edison Member
*
Karma: 0
Posts: 1103
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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;        
 }
Logged

Pages: 1 [2]   Go Up
Jump to: