# Call a function problem

I am trying to replace the delay(1000) in the following code to millis.

This works:

``````    int z = 1;
while (z <= totToolZones) {
Serial.print("z = ");
Serial.println(z);
z++;
delay(1000);
}
``````

This does not:

`````` currentMillis = millis();
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= PollInterval) {
previousMillis = currentMillis;
int z = 1;
while (z <= totToolZones) {
Serial.print("z = ");
Serial.println(z);
z++;
}
}
``````

In the setup(), I have:

``````int totToolZones = 12;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long PollInterval = 1000;
``````

What I need to accomplish is to print the Serial.println(z); every PollInterval ( 1 second).
Print z=1 wait 1 second print z=2 wait 1 second Print z=3 etc. etc.

The above code prints all 12 (totToolZones ) every 1 second
The top code with the delay(1000) works correctly and prints z=1 wait 1 second prints z=2 wait 1 second prints z=3 etc. etc.

I cannot understand what I am doing incorrectly.

The example I used was from Blink without Delay example.

Play with this:

``````unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= PollInterval and z<= totToolZones) {
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z);
z++;
}
``````

int totToolZones = 12;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long PollInterval = 1000;

If this is in setup these go out of scope when loop is run.

hi

first of all you have 2 x "usigned long currentMillis" in your skecth a Local and global one.
local is more then enough.

you dont need the While loop, thats the reason why it print 1 to 12 every 1 sec.

make "z" Global varaible and not local.

and "(unsigned long)currentMillis" you dont need to point out its a unsigned long beacuse you allready declarde that.

Declare z as a global variable then

``````currentMillis = millis();
if (currentMillis - previousMillis >= PollInterval)
{
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z % totToolZones);
z++;
}
``````

UKHeliBob:
Declare z as a global variable then

``````currentMillis = millis();
``````

if (currentMillis - previousMillis >= PollInterval)
{
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z % totToolZones);
z++;
}

What stops z from incrementing forever?

This code, thanks UKHeliBob, works to some degree in that I do get the delay between each print.

``````currentMillis = millis();
if (currentMillis - previousMillis >= PollInterval)
{
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z % totToolZones);
z++;
}
``````

However, if I set the totToolZones=6, then I get the following print:

``````z = 1
z = 2
z = 3
z = 4
z = 5
z = 0
z = 1
z = 2
z = 3
z = 4
z = 5
z = 0
``````

I do not get the last numeral (6).
This "loops" forever and it should stop print once it has reached totToolZones:

``````z = 1
z = 2
z = 3
z = 4
z = 5
z = 6
``````

Then stop.

What I ideally require is to be able set an additional delay as follows:

``````z = 1
delay 1 second
z = 2
delay 1 second
z = 3
delay 1 second
z = 4
delay 1 second
z = 5
delay 1 second
z = 6

NOW DELAY 10 seconds

z = 1
delay 1 second
z = 2
delay 1 second
z = 3
delay 1 second
z = 4
delay 1 second
z = 5
delay 1 second
z = 6

REPEAT
``````

Once I have this running, I will replace the "Serial.print" with a "Wire.write as each zone is an UNO that is connected via I2C.

The demo Several Things at a Time illustrates the use of millis() to manage timing.

…R

@aarg:
Many thanks, works well:

``````unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= PollInterval and z<= totToolZones) {
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z);
z++;
}
``````

How do I put this in an additional “loop” that will call the above every XXX seconds?

What stops z from incrementing forever?

Nothing, but the

`````` Serial.println(z % totToolZones);
``````

prevents the actual value of z being printed.

NOTE : z should be declared as an unsigned int to prevent it going negative.

it should stop print once it has reached totToolZones:

I don't believe that was clear in your original requirement.

I have a BT device connected to an UNO using SoftwareSerial.
When a string is received that StartsWith “P”, I need to call a function “pollZones()”
This function must “loop” through the number of “zones” and Serial.print “z = n”, where n == zones 1 through “totToolZones”.
The problems I have are:
1). The pollZones() Serial.print only prints 1 “zone” (z = 1) each time a “P” is received.
The pollZones() should print all zones each time a “P” is received.
As an example of how pollZones() should work with totToolZones==4:

``````Rx Android: >P,4,#<
GOT P
Total Zones: 4
z = 1  // now wait PollInterval = 100;
z = 2  // now wait PollInterval = 100;
z = 3  // now wait PollInterval = 100;
z = 4  // now wait PollInterval = 100;
``````

What I am actually getting is:

``````Rx Android: >P,4,#<
GOT P
Total Zones: 4
z = 1
Rx Android: >P,4,#<
GOT P
Total Zones: 4
z = 2
Rx Android: >P,4,#<
GOT P
Total Zones: 4
z = 3
Rx Android: >P,4,#<
GOT P
Total Zones: 4
z = 4
``````

2). In the void loop() function, pollZones() is only called on the first occurrence of “if (rxZoneT.startsWith(“P”))” and not every time “rxZoneT.startsWith(“P”)” is received.

My entire sketch is:

``````#include <SoftwareSerial.h>
SoftwareSerial portBT(13, 11);
int totToolZones = 0;
int z = 1;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long PollInterval = 100;

void setup() {
Serial.begin(9600); //setup serial for input and output
portBT.begin(9600);
}

void loop() {
static char buffer[24];
String rxZoneT(buffer);
Serial.print("Rx Android: >");  // For DEBUG
Serial.print(rxZoneT);  // For DEBUG
Serial.println("<");  // For DEBUG

if (rxZoneT.startsWith("P")) { // Only action this routine if "P" is the first character in string "rxZoneT".
Serial.println("GOT P");
// Parse the string "rxZoneT" to obtain the totToolZones - string can be variable length and is not a statis length.
int index1 = rxZoneT.indexOf(',');
int index2 = rxZoneT.indexOf(',', index1+1);
String zonesTotal = rxZoneT.substring(index1+1, index2);
totToolZones = zonesTotal.toInt();
Serial.print("Total Zones: ");  // For DEBUG
Serial.println(totToolZones);  // For DEBUG

pollZones();  // Start the polling of the zones - Call pollZones();
}
}
}

void pollZones(){
// poll zones from "1" until "totToolZones" reached at an interval of "PollInterval" between zone polls
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= PollInterval and z<= totToolZones) {
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z);
z++;
}
}

{
static int pos = 0;
int rpos;
case '\n': // Ignore new-lines
break;
case '\r': // Return on CR
rpos = pos;
pos = 0;  // Reset position index ready for next time
return rpos;
default:
if (pos < len-1) {
buffer[pos] = 0;
}
}
}
// No end of line has been found, so return -1.
return -1;
}
``````

Declan:
@aarg:
Many thanks, works well:

``````unsigned long currentMillis = millis();
``````

if (currentMillis - previousMillis >= PollInterval and z<= totToolZones) {
previousMillis = currentMillis;
Serial.print("z = ");
Serial.println(z);
z++;
}

``````

How do I put this in an additional "loop" that will call the above every XXX seconds?
``````

You just put it in loop() and it will run every time that loop() runs.

void setup()
{
// code that only runs once
}

void loop()
{
// code that runs over and over
}

NOT

void main()
{
// code that runs over and over has to have its own loop
}

Yip, but that related to replacing delay() with millis

Declan:
Yip, but that related to replacing delay() with millis

Make life easy for us.

...R

@Robin2, thanks for advise - Done

Could someone please point me in the right direction - this is driving me crazy

Declan:
Could someone please point me in the right direction - this is driving me crazy

See what you make of this

``````unsigned long longPeriod = 10000;
unsigned long shortPeriod = 1000;
unsigned long startTime;
unsigned long currentTime;
byte state = 0;
byte counter;
byte maxCount = 6;

void setup()
{
Serial.begin(115200);
startTime = millis();
}

void loop()
{
switch (state)
{
case 0:  //wait for long period to elapse
currentTime = millis();
if (currentTime - startTime >= longPeriod)
{
counter = 0;
startTime = millis();
state = 1;
}
break;

case 1:  //count up at short period intervals
currentTime = millis();
if (currentTime - startTime >= shortPeriod)
{
Serial.println(counter);
counter++;
if (counter >= maxCount)
{
state = 0;
}
else
{
startTime = millis();
}
}
}
}
``````

As written it waits 10 seconds then prints 0 to 5 at 1 second intervals, waits again then repeats. Please ask if you have any questions.

@ UKHeliBob - Thanks, That works great.
I will drop into my code and let you know how I progress.