Delay's are breaking my code

Hello there!

I'm using a MIfare's SM130 RFID tag reader and a etherShield (cheap chinese knockoff, uses the ENC28J60). It shows the tag on the web so my server can read it.

My loop consists of:

void loop(){ httpServer(); seekForTag(); }

Using both functions will make my webserver crash randomly (100 to 2k requests). If I remove the seekForTag fuction I can send infinite requests for the web server ( tested for more than 50k requests).

SeekForTag consists of sending data through a software serial port and "waiting" for the answer. Basically: - Send Serial command to the SM130 - DELAY(RFID_TIME) so the SM130 has some time to process the data (RFID_TIME is 20 ms, lower give me some errors) - Read everything from the serial port - Return

So, here's the catch, if I change the loop() to this: void loop(){ httpServer(); delay(RFID_TIME); }

The webserver will still crash, so I believe the problem is because that the RFID seekForTag function is taking too much time with it's Delay and has nothing to do with the Serial data being sent/read.

If I set a timer to output 1,2,3.. every second on the main serial port, it will continue to run, although the web server can't be acessed anymore.

  • The httpServer function continues to be called by the program. (verified by adding Serial.print(".") on it)
  • If RFID_TIME is a short delay, let's say, 1 ms, the server won't lock it self up;
  • I have tried resetting all the used variables using memset;
  • Note that if the loops only contains the httpServer nothing will crash, it'll continue to work for over 50k requests from a client;
  • Running the httpServer from a timer blows the code up, causing random codes to be read from the SM130.

Where are you getting the code for httpServer() from? It sounds to me that there is a bug in it, and I can't find it in the documentation for the Ethernet shield.

Maybe the HTTP server is getting some sort of overrun condition on the input stream if it isn't called frequently enough? It's the sort of thing that could feasibly take you into dodgy error handling scenarios that might not have been tested properly.

Perhaps you would be better off avoiding delays (or anything else slow) in the main loop and run that at a high frequency, and use the ubiquitous 'blink without delay' approach to do other things on a timed basis.

PeterH: Maybe the HTTP server is getting some sort of overrun condition on the input stream if it isn't called frequently enough?

That's what I suspect is happening.

PeterH: Perhaps you would be better off avoiding delays (or anything else slow) in the main loop and run that at a high frequency, and use the ubiquitous 'blink without delay' approach to do other things on a timed basis.

IMO it is better to fix the buggy http server than treat the symptom. I suspect is is possible to generate inputs that crash the http server even without any delay calls.

dc42: Where are you getting the code for httpServer() from? It sounds to me that there is a bug in it, and I can't find it in the documentation for the Ethernet shield.

I created it using examples from the etherShield library. Basically I copied the whole packet processing part and added my parser for the packet buffer (analyzing everything past the "GET / " string). Removing my code didn't do anything. Note that this is not the official library, it's a Rip off of the original ethernet shield, pretty much everything is software implemented and causes a lot of crashes (Also experienced this using the PIC Mini web board)

PeterH: Maybe the HTTP server is getting some sort of overrun condition on the input stream if it isn't called frequently enough? It's the sort of thing that could feasibly take you into dodgy error handling scenarios that might not have been tested properly.

Perhaps you would be better off avoiding delays (or anything else slow) in the main loop and run that at a high frequency, and use the ubiquitous 'blink without delay' approach to do other things on a timed basis.

I can't think of a proper way to use the timers to buy time for the SM130 to "think", it NEEDS time, it's a slow processing. The arduino MUST wait until it's processing is done, using the answer it gives for "command not complete" is pretty much the same as waiting a said time and takes a lot more processing.

dc42: IMO it is better to fix the buggy http server than treat the symptom. I suspect is is possible to generate inputs that crash the http server even without any delay calls.

I made shell scripts to wget/ping the page as fast as they could, executed 5 of them simultaneously on two different machines. I couldn't get it to crash. I also tried to send HUGE packets of data, but the buffer size is limited by a #define, so I felt pretty dumb after trying it...

I found a way to avoid this problem: Re-init the HTTP server. I still can't think of the exact reason this "fixes" it, but I'm pretty tired and it's working (over 100k unfailed requests already). I'm re-initializing the ENC28J60 every 4 seconds. I really don't want to use this, but it'll have to do for now. It takes around 1.5 seconds to restart, that's a lot of time. Since the actual system will not send more than 4000 requests per hour, I think it does the job pretty well handling over 100k in less than 1 hour.

Thank you guys for the support!

hey, has anybody got a code snippets for reading out the firmware version of a SM130 RFID shield? I'm currently using an Arduino diecimila with Atmega 168. All the samples I've tried didn't work.