DrAzzy:
I think in order to help with this we’d need to see your code.
OK, I have tried to extract the important parts of the code for sharing, see below.
Note that the device also handles other tasks so I am looking for a way to let the loop continue while waiting for a delay to time out inside the processing and then return to the next line after the delay.
It is similar to how one would use an RTOS where the delay is part of the RTOS and signals that a task is put on hold during the wait and resumed after the delay has passed.
HandleDHTsensors() is the current problem because it switches on power to the DHT sensors and then waits for 2 seconds using function delay(2000) before proceeding to read the sensors. Sensor reading also takes some time (in the DHT library). Then DHT power is removed (no delay here) and the data are sent to the web server with a short delay following each sensor’s transmission.
So the delays inside HandleDHTsensors() are depending on the sensor count and can be upwards of 4-10 seconds.
void ReplyCmd(char* buf, int len) //Called from RespondToCommand()
{
buf[len++]=ETX; //Need to add final ETX
buf[len]=0;
//add the report string to the cnftxbuf global buffer
strcat(cnftxbuf, buf); //Content processed inside HandleConfigServer()
SerialDebug.println(buf);
}
void RespondToCommand(char* cmd) //Called from ProcessConfigCall()
{
byte b, m;
byte iptmp[4];
int len;
long bl, n;
unsigned int i, tdht;
int p, err=0;
char msg[80], tmp[10];
char command;
uint8_t mac[6];
char mac_char[18];
String TimeMsg = "";
memset(&mac_char, 0, sizeof(mac_char));
command = *cmd++;
switch (command)
{
//Lots of command cases not shown..
case 'e': //Execute a command on the ESP8266
//First byte is a command code
//Following bytes are command specific paqrameter(s)
//Return result message
switch (*cmd)
{
case '1': //Check WiFi signal level
if (!GetWifiSignalLevel(tmp))
{
strcpy(msg,"WiFi_RSSI=");
strcat(msg, tmp);
strcat(msg," dB");
}
else strcpy(msg,"WiFi_RSSI=ERR"); //Wrong state of WiFi
ReplyCmd(msg, strlen(msg));
break;
case '2': //Make DHT measurement
strcpy(msg, "DHT measurement started");
ReplyCmd(msg, strlen(msg));
HandleDHTsensors(millis()); //Takes some time to process!
break;
case '3': //Return current NTP time
#ifdef USE_NTP_TIME
NTP.getTime();
TimeMsg = NTP.getTimeDateString();
strcat(msg, TimeMsg.c_str());
#else
strcpy(msg, "NTP time undefined");
#endif
ReplyCmd(msg, strlen(msg));
break;
case '4': //Toggle DHT 5V power for testing
bool currstate, newstate;
currstate = bool(digitalRead(DHT_POWERPIN));
newstate = !currstate;
DHT_Power_Ctrl(newstate);
strcpy(msg, "DHT power toggled: ");
utoa(newstate, tmp, 10); //convert value to a string
strcat(msg, tmp);
ReplyCmd(msg, strlen(msg));
break;
default:
break;
}
break;
default:
strcpy(msg, "ERR unknown command");
ReplyCmd(msg, strlen(msg));
err=2; //To block the reply below if cmd not found
}
if ((err != 2)&&(command < 0x61)) //Write commands use capital letter as cmd byte, reply is OK or ERR
{
if (err==1)
strcpy(msg, "ERR");
else
strcpy(msg, "OK");
ReplyCmd(msg, strlen(msg));
}
}
void ProcessConfigCall(char *buf, int len) //Called from HandleConfigServer()
{
int res;
char msg[] = "ERROR-Buffer Overrun";
char cmd[BUFSIZE];
res = AddDataToCmdbuf(buf, len);
switch (res)
{
case -1:
ReplyCmd(msg, sizeof(msg));
ResetBuffer();
return;
case 0:
return;
case 1: //Full command detected so extract it and process request
if (PopCommand(cmd)== 0)
{
SerialDebug.print("Rx: "); SerialDebug.println(cmd);
RespondToCommand(cmd);
}
}
}
void HandleConfigServer() //Called from loop()
{
uint8_t i;
char cnfBuf[100]; //Buffer for config server
unsigned int cnfBytesAvail, cnfBytesIn, cnfBytesOut;
//------- check if there are any new Config clients -------------
if (tcpConfigSrv->hasClient())
{
for (i = 0; i < MAX_CONF_CLIENTS; i++)
{
//find free/disconnected spot
if (!tcpConfigClients[i] || !tcpConfigClients[i].connected())
{
if (tcpConfigClients[i]) tcpConfigClients[i].stop();
tcpConfigClients[i] = tcpConfigSrv->available();
SerialDebug.print("New Config client: "); SerialDebug.println(i);
continue;
}
else
SerialDebug.println("New Config client rejected: No free socket");
}
//no free/disconnected spot so reject
WiFiClient tcpConfigClient = tcpConfigSrv->available();
tcpConfigClient.stop();
}
//--------------- check client for commands ---------------------------
// Check for Config data ------
for (i = 0; i < MAX_CONF_CLIENTS; i++)
{
if (tcpConfigClients[i] && tcpConfigClients[i].connected())
{
//get data from the config client and push it to the Configuration function
while ((cnfBytesAvail = tcpConfigClients[i].available()) > 0)
{
cnfBytesIn = tcpConfigClients[i].readBytes(cnfBuf, min(sizeof(cnfBuf), cnfBytesAvail));
if (cnfBytesIn > 0)
{
ProcessConfigCall(cnfBuf, cnfBytesIn);
delay(0);
}
}
}
}
//----------- Now check if there are config data responses to be returned -----------
//Send buffered data back to config clients
if ((cnfBytesOut = strlen(cnftxbuf)) > 0)
{
for (i = 0; i < MAX_CONF_CLIENTS; i++)
{
if (tcpConfigClients[i] && tcpConfigClients[i].connected())
{
//Now check if there are config data to be returned
tcpConfigClients[i].write((uint8_t*)cnftxbuf, cnfBytesOut);
}
delay(0);
}
cnftxbuf[0] = 0; //Reset buffer after transmit
}
}
void loop()
{
//Check if a new DHT reading is requested:
unsigned long tickcount = millis();
if (first_dht_done == 0)
{
first_dht_done = 1;
HandleDHTsensors(tickcount);
}
else
if ((dht_interval > 0) && ((unsigned long)(tickcount - lasttickcount) >= dht_interval)) //Regular reading scheduled
{
HandleDHTsensors(tickcount); //This task takes some time to complete, longer for more sensors
}
HandleConfigServer(); //Interactive configuration, receive and execute commands
HandleWebConfigServer();
//Check for firmware update request
httpServer.handleClient();
//Send startup report, only once
if (StartMessageSent == false)
{
if (WiFi.status() == WL_CONNECTED)
{
SendStartReport();
StartMessageSent = true;
}
}
//Handle software reset
if (Resetflag)
{
if (resetwait == 0) //First time here
resetwait = millis(); //Get start time
if((millis() - resetwait) > 1000) //Wait 1000 ms until reset
ESP.restart(); //then reset
}
}