Loop timing using millis doesn't seem to work

Hi everyone

My code posts temperature data to my web server periodically. If I set the interval to 10 seconds or 30 seconds it works fine, but I’d like it to run every 5 minutes. If I set the interval accordingly, the serial monitor never shows more than ‘ethernet started’. In fact, even 60 seconds doesn’t work; I tried setting the interval to 60000 (instead of 60*1000) but it didn’t make any difference.

I understand unsigned long variables can store 0 to 4,294,967,295 - http://arduino.cc/en/Reference/UnsignedLong

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the address of 1-Wire temp sensor
DeviceAddress insideThermometer = { 0x28, 0xA1, 0x97, 0x82, 0x03, 0x00, 0x00, 0xA9 };

// assign a MAC address for the ethernet controller.
byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// IP & DNS
IPAddress ip(192,168,1,91);
IPAddress myDns(8,8,8,8);

// initialize the library instance:
EthernetClient client;

// server address
char server = “www.cog24.com”;

unsigned long lastConnectionTime = 0; // last time connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 101000; // delay between updates, in milliseconds
// works fine if interval is 10
1000 or 301000, but 3001000 doesn’t seem to work.

void setup() {
// start serial port:
Serial.begin(9600);

// Start up the sensors library
sensors.begin();

// set the resolution to 10 bit
sensors.setResolution(insideThermometer, 10);

// give the ethernet module time to boot up:
delay(1000);

// start the Ethernet connection using a fixed IP address and DNS server:
Ethernet.begin(mac, ip, myDns);

// print the Ethernet board/shield IP address:
Serial.print("Ethernet started at IP address: ");
Serial.println(Ethernet.localIP());
}

void loop() {
// if there’s incoming data from the net connection, send it out the serial port.
// For debugging - not required.
if (client.available()) {
char c = client.read();
Serial.print(c);
}

// if there’s no net connection, but there was one last time
// through the loop, then stop the client:
if (!client.connected() && lastConnected) {

Serial.println(“disconnecting.”);
Serial.println();

client.stop();
}

// if you’re not connected, and enough seconds have passed since
// your last connection, then connect again and send data:
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
Serial.print("lastConnectionTime: ");
Serial.println(lastConnectionTime);
httpRequest();
}

// store the state of the connection for next time through the loop:
lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void httpRequest() {
// if there’s a successful connection:
if (client.connect(server, 80)) {

Serial.print("Getting sensor temperature: ");

// get temperature
sensors.requestTemperatures();
float temp1 = sensors.getTempC(insideThermometer);

Serial.println(temp1);

Serial.println(“connecting…”);

// send the HTTP request:
client.print(“GET /datapost/input.php?client=arduino&temp1=”);
client.print(temp1);
client.println(" HTTP/1.1");

client.println(“Host: www.addressofmyserver.net”);
client.println(“User-Agent: arduino-ethernet”);
client.println(“Connection: close”);
client.println();

// note time that HTTP connection was made:
lastConnectionTime = millis();
}
else {
// if connection failed
Serial.println(“connection failed - disconnecting.”);
client.stop();
}
}

Is there anything obvious that might be causing this?

Thanks

const unsigned long postingInterval = 300UL * 1000UL; // delay between updates, in milliseconds

Thank you very much!

For learning reasons, I have a few questions!

Why doesn’t the ‘unsigned long’ part of the variable declaration force the variable postingInterval into the correct format?

Why does 10 * 1000 work, but 300 * 1000 not?

If we use the UL modifiers, can we do away with unsigned long in the declaration, ie would: const postingInterval = 300UL * 1000UL have the same effect?

Thanks again!

Why doesn't the 'unsigned long' part of the variable declaration force the variable postingInterval into the correct format?

Because the left hand side of the equal sign is not a factor. The right side value is computed, using the types known, and then, after a value is known, it is passed to the assignment operator.

You really should think of the = as a function that takes an argument and performs some action. Because, that is what it is.

Why does 10 * 1000 work, but 300 * 1000 not?

Because 10, 1000, and 300 are all ints. 10 * 1000 is 10000, which is also an int. 300 * 1000 is 300000 which does NOT fit in an int.

If we use the UL modifiers, can we do away with unsigned long in the declaration, ie would: const postingInterval = 300UL * 1000UL have the same effect?

You are free to try that while we laugh. No, it won't work. See the comment above on the = operator for why.

Variable declaration requires a data type. The compiler doesn't infer the variable type from the literal you assign to it.

When you write long a = 100 you are collapsing two statements into one: a variable declaration and an assignment.

Thanks again everyone, that's all really helpful.

BTW, next time use code tags ( # button, not the baloon one )

:)

cog1: Thanks again everyone, that's all really helpful.

One thing to be aware of with those delay functions (especially delay microseconds): Those loops are calibrated for static numbers, not variables. That is, if you do this:

delayMicroseconds(10); - you will get a fairly accurate 10 uS delay. But if you do this:

unsigned long delay = 10; delayMicroseconds(delay); - you will get quite a bit more than a 10 uS delay. This is because the code has to get the value of the variable from memory, then use it in the delay loop as opposed to "already having it".

This overhead is fixed, so longer delays are progressively less affected, but short delays will show significant errors.

FYI......

Krupski: That is, if you do this ... you will get a fairly accurate 10 uS delay. But if you do this ... you will get quite a bit more than a 10 uS delay.

You have an interesting definition of "quite a bit more". The difference is four clock cycles (0.25 uS).

Krupski:
But if you do this:

unsigned long delay = 10;
delayMicroseconds(delay); - you will get quite a bit more than a 10 uS delay.

Maybe. I tried this sketch:

void setup ()
{
  unsigned long delay = 10;
  delayMicroseconds(delay);
}

void loop () {}

Disassembled setup is:

000000a8 <setup>:
  a8:	8a e0       	ldi	r24, 0x0A	; 10
  aa:	90 e0       	ldi	r25, 0x00	; 0
  ac:	0e 94 a1 00 	call	0x142	; 0x142 <delayMicroseconds>
  b0:	08 95       	ret

The compiler optimized the variable into a literal anyway.