Basic Web Client Locks Up When Using Timer

Using the basic WiFiWebClientRepeating sketch as a basis, I’ve moved the “repeating” part, making a web client request, from the loop and into a timer interrupt function and the board locks up every time.

I started with the basic example sketch and it all worked fine. I’m using a Mega2560 with a WiFi101 shield. In the example here, I have the timer firing every 10 seconds but I’ve tried it with 5 seconds and 20 seconds and it still fails. I had a watchdog timer at one point and it rebooted as soon as the timer interrupt fired. I stripped that part out to make my example more simple here.

I want to use a timer because the intention for this sketch is to use Blynk which requires that nothing else be in the loop(). This is actually a stripped down version of a much larger sketch where logic in the timer is controlling objects and Blynk is being used to control it. I need to make a web call periodically which led me to this problem.

Any ideas on why this is locking up or any ideas on how to accomplish the same thing without using the timer or the loop?

Here’s the code:
#include <SPI.h>
#include <WiFi101.h>
#include <TimerOne.h>

char ssid = “ssidhere”; // your network SSID (name)
char pass = “passhere”; // your network password
int keyIndex = 0; // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;

// Initialize the Wifi client library
WiFiClient client;

// server address:
IPAddress server(192,168,200,129);

void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println(“WiFi shield not present”);
// don’t continue:
while (true);
}

// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
status = WL_CONNECTED;

// wait 10 seconds for connection:
delay(10000);
}
Serial.println(“Connected”);

Timer1.initialize(10000000); // Once per second
Timer1.attachInterrupt(timerInterrupt);

}

void timerInterrupt() {
// if there’s incoming data from the net connection.
// send it out the serial port. This is for debugging
// purposes only:
while (client.available()) {
char c = client.read();
Serial.write(c);
}

httpRequest();
}

void loop() {
}

// this method makes a HTTP connection to the server:
void httpRequest() {
// close any connection before send a new request.
// This will free the socket on the WiFi shield
client.stop();

// if there’s a successful connection:
if (client.connect(server, 80)) {
Serial.println(“connecting…”);
// send the HTTP PUT request:
client.println(“GET /latest.txt HTTP/1.1”);
client.println(“Host: 192.168.200.129”);
client.println(“User-Agent: ArduinoWiFi/1.1”);
client.println(“Connection: close”);
client.println();
} else {
// if you couldn’t make a connection:
Serial.println(“connection failed”);
}
}

WiFiWebClientRepeating-Timer.ino (2.06 KB)

The Serial functions require interrupts enabled. You shouldn't use any Serial calls in an interrupt. That includes the httpRequest function, since it is called from the interrupt function.

The Serial functions require interrupts enabled.

Receiving serial data does. As of 1.5.6, sending serial data is possible in an ISR.

That includes the httpRequest function, since it is called from the interrupt function.

I don't thing client.write() or client.print() uses interrupts, but expecting to make an HTTP request every exactly 10 seconds is unrealistic.

If a request takes more than 10 seconds to complete, it does not make sense to start another one before the previous one complete, even if it was possible.

The blink without delay example shows how to do things periodically, without any need for timers.

Timer1.initialize(10000000); // Once per second

Using whose watch?

@PaulS: So there is no longer an interrupt driven serial buffer that feeds the serial port output? That is good to know.

There is still an outgoing buffer, and the data in that buffer is still shifted out using an interrupt. What changed was that print() no longer blocks if the buffer is full. Instead, it calls the function that the interrupt handler does, to force one byte to be shifted out, as many times as required until there is room in the buffer.

A couple of clarifications: It is correct that 10 seconds may not be enough time but for now, in my testing, environment, trying to get this going, 10 seconds is a very long time (30ms response) for this simple request. That timer is setup for 10 seconds even though the comment is old - I've been trying a lot of different things.

So far, as I understand it, @pauls and @surferTim don't think there should be an issue, right? I wasn't sure from this if the buffer shifting would be an issue or not.