Go Down

Topic: void loop() keep looping while functions run (Read 978 times) previous topic - next topic

svh1985

Hello,

Im new to Arduino but I do have some programming experience.

And I have a question regarding the standard loop.

Sample code:
Code: [Select]

void loop()
{
functA();
functB();
}

void functA()
{
//some code which takes 5 seconds to run
}

void functB()
{
//some code which takes 1 seconds to run
}


When the loop starts it will obviously first run functA(); and then start functB();
The thing is that functB(); will be started after 5 seconds and keeps being started after an interval of 5 seconds.

What I want to accomplice is that functB(); keeps running every 1 second and not being slowed down by functA();

Is there a way to do this?

Thanks!

Arrch

Don't use delay() in your functions and take a look at the Blink Without Delay example.

svh1985

Hi Arrch,

Thanks for your reply.

The delay is not caused by delay(). I send an ICMP ping to a host and once the host goes offline it will timeout.. this timeout takes around 5 seconds. So once the host is online the function will run in 1 second but when it it's offline it will take 5 seconds.

It would be nice to run the functions asynchronous.

Nick Gammon

http://www.gammon.com.au/blink

Quote
The delay is not caused by delay().


Can you post the "some code" please?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

svh1985

Sure, I found code on the Internet that I use and modify to my needs:

Code: [Select]

/*
Repeatedly ping a number of servers and output the response to serial and pins 2,3,4

pin 2: ping request sent
pin 3: ping response received
pin 4: ping response not received

This software requires the ICMPPing library, available at

http://www.blake-foster.com/projects/ICMPPing.zip

Portions of this code were derived from code available at

http://www.blake-foster.com/project.php?p=44

My thanks go to Blake for his hard work.

If you do not wish to output to the serial port, comment out the line
#define serialOut 1
If you do not wish to output to the LEDs, comment out the line
#define ledOut 1

The lines
byte ip[] = {192,168,0,177}; // ip address for ethernet shield
byte pingAddr[8][4] = { {91,121,5,142}, {91,121,5,143}, {91,121,5,144}, {91,121,5,145}, {91,121,5,146}, {91,121,5,147}, {91,121,5,148}, {91,121,5,149} }; // ip address to ping

need to be changed to suit your own needs. If your network has DHCP the arduino
will automatically grab an IP address for itself.
*/

#include <SPI.h>
#include <Ethernet.h>
#include <ICMPPing.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // mac address for ethernet shield
byte ip[] = {172,16,0,60}; // ip address for ethernet shield
byte pingAddr[1][4] = { {172,16,0,112}};
int numAddresses = 1; //sizeof(pingAddr[0]);
bool deviceFound = false;
int lampCountdown = 10;

SOCKET pingSocket = 0;

char buffer [256];

int delayMS = 1 * 1000; // check every 1 seconds (delay between successive pings (60 * 1000 = 60 seconds))

#define serialOut 1
#define ledOut 1

#ifdef ledOut
#define ledPing 2
#define ledOk 3
#define ledFail 4
#define lamp 5

void startPing()
{
digitalWrite(ledPing, HIGH);
}

void endPing()
{
digitalWrite(ledPing, LOW);
}

void pingSuccess()
{
deviceFound = true;

}

void pingFail()
{
deviceFound = false;

}
#endif

void setup()
{
#ifdef ledOut
pinMode(ledPing, OUTPUT);
pinMode(ledOk, OUTPUT);
pinMode(ledFail, OUTPUT);
pinMode(lamp, OUTPUT);

// initialising, turn all LEDs on
digitalWrite(ledFail, HIGH);
digitalWrite(ledOk, HIGH);
digitalWrite(ledPing, HIGH);
#endif

#ifdef serialOut
// start serial port:
Serial.begin(9600);
Serial.println("Starting ethernet connection");
#endif
// start Ethernet
if (Ethernet.begin(mac) == 0) {
#ifdef serialOut
Serial.println("Failed to configure Ethernet using DHCP");
#endif
// DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}

int i = 0;

void loop()
{
pingDevice();

if(deviceFound==true){
lampCountdown=10;
digitalWrite(ledFail, LOW);
digitalWrite(ledOk, HIGH);
digitalWrite(lamp, HIGH);
}else{
if(lampCountdown<=0){
digitalWrite(lamp, LOW);
}else{
digitalWrite(ledFail, HIGH);
digitalWrite(ledOk, LOW);
Serial.print("Device not found: ");
Serial.println(lampCountdown);
lampCountdown--;
}
}
}

void pingDevice(){

bool pingRet; // pingRet stores the ping() success (true/false)
#ifdef ledOut
startPing();
#endif

ICMPPing ping(pingSocket);
byte pingAddr2[] = { pingAddr[i][0], pingAddr[i][1], pingAddr[i][2], pingAddr[i][3] };
pingRet = ping(4, pingAddr2, buffer);

#ifdef ledOut
delay(250);
endPing();
#endif

#ifdef serialOut
Serial.print("i:");
Serial.print(i);
Serial.print(" ");
Serial.println(buffer);
#endif

#ifdef ledOut
if(pingRet) // Failure
pingSuccess();
else
pingFail();
#endif

i++;

if(i >= numAddresses)
i = 0;
delay(delayMS);
}


Arrch

#5
Dec 20, 2012, 10:19 pm Last Edit: Dec 20, 2012, 10:24 pm by Arrch Reason: 1
Quote
The delay is not caused by delay(). I send an ICMP ping to a host and once the host goes offline it will timeout.. this timeout takes around 5 seconds. So once the host is online the function will run in 1 second but when it it's offline it will take 5 seconds.


Ok, so let's rephrase. Take a look at the blink without delay example to run the second function every 1 second and ensure that neither function are blocking.


It would be nice to run the functions asynchronous.


If you want true multitasking, get a Propeller.

Nick Gammon


The delay is not caused by delay().


Code: [Select]

int delayMS = 1 * 1000; // check every 1 seconds (delay between successive pings (60 * 1000 = 60 seconds))

...

void pingDevice(){

...

  delay(delayMS);
}


The one-second delay there won't be helping.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

Inside the library I guess you are using:

Code: [Select]

bool ICMPPing::waitForEchoReply()
{
time_t start = millis();
while (!W5100.getRXReceivedSize(socket))
{
if (millis() - start > PING_TIMEOUT) return false;
}
return true;
}


You may need to rework so that rather than looping until a timeout, you check and then return. In other words, handle timing-out a different way. Effectively this makes it asynchronous.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

svh1985

Thanks for your reply's.

I will try to implement these suggestions this weekeind and post my findings back here.

Cheers!

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy