Running two pieces of code at once

I am having a problem with code that works nice when it is standalone but it doesn't work when it is integrated with a program that needs to write to LCD, turn ON LEDs, read potenciometers... The whole code is to slow to detect inputs from a sensor that is only activaed for a few miliseconds. The question here is how can I keep the part of the code that keeps LCD and other things running and also run the sensor code at the same time. I know arduino isn't capable of multithreading but is there a piece of code that can get what I want?

with one interruption :)

A little more info would be nice! Probably you mean function interrupts() and NoInterrupts() ?

Yes, for example if your sensor goes from 0 to 1 or something like that, you can act as if you're watching constantly that sensor.

Anyway you can't execute two pieces of code at the same time, but you can emulate something similar (like protothreads, using millis() in conjunction with a large switch/case, etc)

Sorry but I still don't understand what to do. A link to an exaple or something please? And if I read something about interupts on the playground correctly it only works with digital inputs 2 and 3. And I am using analog inputs for these sensors. Of course I may be completly wrong!

A link to an exaple or something please?

BlinkWithoutDelay Metro MsTimer2

The general idea behind 'protothreads' is that you log the current time, and the time each of your events last finnished. That way, you can say: When there's been 20 milliseconds since last update, update again. And your program, if designed well, should be able to simulate multitasking.

I find it useful to use FSMs for my 'multithreaded' applications. :)

I tryed MsTimer2 and it didn't work. But I think that BlinkWithoutDelay is working. It will need some more testing but for now it seems to be working.

Just made a simple example:

/*
|| Simple Protothreading
||
|| Contributed:
|| Alexander Brevig
*/
//define pins
#define ledPin1 12
#define ledPin2 13

//define program constants
#define NUMBER_OF_ACTIONS 2

//contain all information needed by a protothread
typedef struct{
unsigned long previousTrigger;
unsigned int interval;
void (*function)();
}ProtoThread;

//variables
ProtoThread protoThreads[NUMBER_OF_ACTIONS] = {
{0,600,action1}, //triggers every 600 millisecond
{1000,1000,action2} //predelay 1000 milliseconds, then from then on always trigger every 1000 millisecond
};
boolean led1 = LOW;
boolean led2 = LOW;

void action1(){
digitalWrite(ledPin1,led1);
led1 ? led1=LOW : led1=HIGH;
}

void action2(){
digitalWrite(ledPin2,led2);
led2 ? led2=LOW : led2=HIGH;
}

void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
digitalWrite(ledPin1,led1);
digitalWrite(ledPin2,led2);
}

void loop()
{
for (byte i=0; i<NUMBER_OF_ACTIONS; i++) {
if (millis() - protoThreads_.previousTrigger > protoThreads*.interval) {_
_ protoThreads.previousTrigger = millis();
protoThreads.function();
}
}
} [/quote]
[edit]
See TimedAction for the class implementation of this logic. And reply #7 using it.
[/edit]*_

I don't thik that this is simple :)!

As for my last post - it is not working. It is working if someone is moving fast but if someone is moving slow it thinks that someone left the room and not enter it. So sensor 1 is activated before sensor 2 while in reality sensor 2 was activated before.

I don't thik that this is simple :)!

Maybe not simple code but it should be simple to use. I actually made this idea into a library.

TimedAction

As for my last post - it is not working.

I do not see any code, so I do not know how to help you. :-[

…program that needs to write to LCD, turn ON LEDs, read potenciometers…The question here is how can I keep the part of the code that keeps LCD and other things running and also run the sensor code at the same time. I know arduino isn’t capable of multithreading but is there a piece of code that can get what I want?

I tried to illustrate how to do this using my library linked above :slight_smile:

This will print to screen whenever it is time for that particular task to get executed. So if you just implement the functions it should do what you want.

Happy coding!

/*
||
|| Description:
||
||
|| @author Alexander Brevig
|| @version 1.0
||
*/

#include <TimedAction.h>

#define SENSOR_TRIGGER RISING

#define UPDATE_LCD_INTERVAL 500 //updates the LCD every 500 milliseconds
#define UPDATE_LED_INTERVAL 50 //updates the LEDs every 50 milliseconds
#define UPDATE_POTENTIOMETERS_INTERVAL 20 //updates the potentiometers every 20 milliseconds

TimedAction lcdAction = TimedAction(0,UPDATE_LCD_INTERVAL,updateLCD);
TimedAction ledAction = TimedAction(0,UPDATE_LED_INTERVAL,setLEDStates);
TimedAction potentiometerAction = TimedAction(0,UPDATE_POTENTIOMETERS_INTERVAL,readPotentiometers);

volatile unsigned int sensorTriggered = 0;
unsigned int sensorBuffer = 0;

void setup(){
Serial.begin(9600);
//attachInterrupt(0,logSensor,SENSOR_TRIGGER); //every time SESOR_TRIGGER happens on pin 2 logSensor will be executed
}

void loop(){
lcdAction.check();
ledAction.check();
potentiometerAction.check();
if ( sensorBuffer != sensorTriggered ){ Serial.print("sensorTriggered: "); Serial.println(sensorTriggered); }
}

void updateLCD(){
//TODO - implement
Serial.println(“updateLCD”);
}

void setLEDStates(){
//TODO - implmement
Serial.println(“setLEDStates”);
}

void readPotentiometers(){
//TODO - implement
Serial.println(“readPotentiometers”);
}

//attacthInterrupt ISR routine
void logSensor(){
//TODO - implement
sensorTriggered++;
}

PostScriptum: Sorry for the doublepost, but I wanted to quote OP.

Great! I meant it looks complicated but it looks simple to use. I will try it and see if it works as it should.

Tryed it but it isn't working! Well it is working just not good enough. It is working like all the others. I think that this isn't working fast enough. Normal loop with only sensor checking code works realy fast and only once in 10 tryes I get a wrong reading. But here I get it half of the time. But I don't think that this is possible to improve with this protothreads - the real problem is probably in my sensor reading code and this just makes it more visible.

If you really need something multithreading you can use another atmega (ie arduino standalone) conected by serial to your lcd management arduino

roli: Could you maybe post your code as is?

:)

Here is the complete arduino sketch. http://pastebin.com/m647b74d2

I can't post in on the forum because it is too long. But I doesn't have much comments and it is not optimized at all.

THe function vstop() is the one that checks the sensors. I am using Metro library because it gives me the best results.

And idea about using two microcontrollers isn't that bad. I thought of it myself before (I am running out of pins here ::)). I will complete this project using only this but sometime in the future I may use more arduinos.

I spotted a few delay() calls, that will ofcourse mess timebased code a bit. Quite a large program:)

Have you read about the map(val,fromL,fromH,toL,toH) I think some of your code (the code where you set variables according to analogRead could be replaced by val = map(analogRead(pin),0,1024,0,9); or something in the likes of that.

Also I would suggest maybe structure your program like this:

//get input and set states //do logic related to input //set output according to states

Then everything gets its own place in time. I use Finite State Machines for this purpose. I found it increases executions time of a loop, and decreases debugging time.

The code is big but it is not finished yet - It will be bigger. ;D

Have you read about the map(val,fromL,fromH,toL,toH) I think some of your code (the code where you set variables according to analogRead could be replaced by val = map(analogRead(pin),0,1024,0,9); or something in the likes of that.

I know about that but I didn't remeber it when I was creating that part.

So I mounted my sensors yesterday and they are working preaty good but I still get some errors - someone went in but the sensor thinks someone went out. I added a little delay at the part where the first sensor sets the time and it is working better but still not as good as I want.

AlphaBeta, your code is so straight forward it makes managing multiple threads seem trivial. Thanks for contributing!

and sorry to steal the thread but my problem seems relevant.

The only thing I've been pondering is what there is to do if you want one function to update say, every 10ms, but the other function has a loop in it that takes 250 ms to complete.

I wish I knew more about ISR's because it seems to me the fastest way to accomplish this is either to make the simple function an interrupt called by a hardware timer during the long loop, or to nest the small loop within the longer one and use some timer code.

What REALLY makes things tough though is that if it's a library function that is making the code have such a long delay, nesting the two together means dismantling the library and just dumping it into the main program code. that sounds messy.

hopefully I'm just being noobish and i've already answered my question with the ISR thoughts..

The program I'm working on will hopefully be able to count the frequency of an input (hence the long loop) while driving a multiplexed display (short loop).

80HD, yes, multirate schedulers really need to be kicked off as distinct interrupt service handlers (with the slowest rate job being the non-interrupt "normal" code). And then you have to be extra sure that any variables shared between them are properly protected, since one routine might be interrupted anytime, even halfway through updating a lowly int variable's value.