I am trying to add wifi shield to a project that itself is already complete. It has a user interface, data collection, processing and logging. In most operations, you can navigate the user interface, make changes, while the data collection, processing and logging are done in the background (so no use of delay()).
Now I am adding wifi shield. It seems to have lots of pure delay() in the library code:
int WiFiClient::connect(IPAddress ip, uint16_t port) {
_sock = getFirstSocket();
if (_sock != NO_SOCKET_AVAIL)
{
ServerDrv::startClient(uint32_t(ip), port, _sock);
WiFiClass::_state[_sock] = _sock;
unsigned long start = millis();
// wait 4 second for the connection to close
while (!connected() && millis() - start < 10000)
delay(1);
if (!connected())
{
return 0;
}
}else{
Serial.println("No Socket available");
return 0;
}
return 1;
}
I bet I can just call ServerDrv::startClient to avoid the 10 second delay but I don't know if there are delays in the startClient. Is this very common in Ethernet/WiFi library to have lots of hard delay()? So while you are trying to connect to network, you are not supposed to tend to user inputs?!
There is no 10 second delay unless something went wrong. But I see a lot of code here on the forum written for "perfect world". Unfortunately for me, I live in "real world". If that code did not have that 10 second timeout, it would lock up there forever if it did not establish a connection.
unsigned long start = millis();
// wait 10 second for the connection to establish IF NECESSARY
// if the connection is established immediately, there is no delay
while (!connected() && millis() - start < 10000)
delay(1);
if (!connected())
{
return 0;
}
edit: If you want to know what I mean by "perfect world" code, here is the same code function written for "perfect world".
int WiFiClient::connect(IPAddress ip, uint16_t port) {
// this will ALWAYS get a socket
_sock = getFirstSocket();
// this will ALWAYS start the client
ServerDrv::startClient(uint32_t(ip), port, _sock);
WiFiClass::_state[_sock] = _sock;
// all this will ALWAYS work ok, so return success
return 1;
}
In most operations, you can navigate the user interface, make changes, while the data collection, processing and logging are done in the background
No, you can't. There is no "foreground" or "background" process space on the Arduino. There is exactly one process space. You can have the Arduino show a menu, for instance, and do other stuff while the user studies the menu and makes a choice, but that other stuff is not happening "in the background".
I would like to see people that should know better not propagating the myth that stuff happens "in the background" on the Arduino, when it does not.
Paul, you came to conclusion to quickly. A portion of the user interface is rendered on a phi-panel, which has its own ATMEGA328, LCD, and keypad. While the user is deciding on a choice, Arduino can do its own thing in the background. The user response is then sent to serial port to be picket up. If the wifi library uses delay() the user response is not processed until the delay() is over.
For most other parts of the project, the arduino keeps a number of timers to execute small chunks of code that will not take enough time for the user to notice the delay. So if the wifi library is using delay(), then the user interface will freeze.
Thanks SurferTim. I think I might use timers and connected() together so the call to lower level wifi library function wont hang all other timed events.
While the user is deciding on a choice, Arduino can do its own thing in the background.
This presupposes a foreground process, too. The Arduino doesn't have a foreground and a background. It has a ground.
I see that you assume an absolute definition of foreground and background as parallel processes not time-division multiplexed processes. My intention was to use these terms from a user's point of view. As long as the user is not seeing a 20ms or so delay navigating the menu, all the timed codes are just happening "in the background" while the user is interacting with the menu "in the foreground". Unless there is some parallel processing, everything happens one at a time. I don't think this point helps explaining what I am doing, but I get the point.
I would like to see people that should know better not propagating the myth that stuff happens "in the background" on the Arduino, when it does not.
Hey I sometimes like myths. I heard that millis() auto increments in the 'background' without the user having to do anything. If one never calls millis() does the tree still make a sound when it falls over in the background forest?
An interrupt suspends the active executing program, runs some other code, and then resumes running the code that was running. There was no "background activity performed".