0

I have an Arduino with ethernet shield and there are 8 different URLs that can be called to perform different actions.

The program loads and runs as expected for the most part, but, if it is busy doing an action, it won't accept the next one until the current action has finished.

Basically, the code's main loop listens for a client connection, then has a bunch of ifs that look in the URL that was called (for a query string) and then process the command.

I have looked at a few answers on here, but none deal with listening to HTTP requests. One recommended a library, but, I couldn't quickly get it to compile, and the other answer recommended a state machine - I do like this approach, however, I haven't had time to implement and it doesn't "feel" right as the listening for a HTTP request works on a if(client) basis.

I was wondering if anyone has done this before and/or has any advice?

  • What sort of action would it be busy doing? Generally I would expect the server to decode the HTTP request almost instantly, and then do the action (eg. return some data). Is your setup such that this might take some time? – Nick Gammon Aug 12 '15 at 1:17
  • @NickGammon - it needs to operate a solenoid for ~2 seconds which doing inline in the http request code means that it stops listening for new requests. – William Hilsum Aug 12 '15 at 8:43
  • 2
    Then you need to start with the basics. Look at the BlinkWithoutDelay example to see how to write non-blocking code. I'll bet your sketch is littered with delay() calls. There is no place for delay() in a proper program, except for tiny (a millisecond or so) delays for timing purposes. Also, get to grips with the concept of the Finite State Machine (there are many resources and tutorials online). – Majenko Aug 12 '15 at 10:29
  • Not sure if it will work for your case, but you can try using interrupt to quickly jump to some signal and back to your main loop. This is similar to concurrency in a web server, since Arduino cannot run things in parallel. – Pie 'Oh' Pah Aug 12 '15 at 16:28
  • it needs to operate a solenoid for ~2 seconds which ... means that it stops listening for new requests - as the other comments point out you just need to restructure. Turn the solenoid on, remember when you did that, and check in the loop which is listening for new requests if the time is up to turn it off again. – Nick Gammon Aug 12 '15 at 20:37
2

It can be done. The Arduino is a single tasking environment so you have to make sure your code is non-blocking.

BlinkWithoutDelay is a good starting point (thanks @Majenko) but you should also look at the Timer1 library.

Basically your programs needs to do all the steps it can right away and whenever it does something that could block, it must do it asynchronously and during a later loop() run check if it's finished and continue with the next task. The alternative (if you know how long your task will take) is to use the timer interrupt with the library mentioned above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.