Want to make 2 different requests, but how to say to the "void requestCB" function to which requests the result belongs ?
Rollmops67 opened this issue · 8 comments
Hello !
Rather a question than an issue :
I'm new to asyncHTTPrequest.
I generally use the standard HTTPClient, but I'm looking for an asynchronous solution.
I did try the code in the "Examples" section and it works fine to extract one value (in my case "Pedf")
But I would like to extract another value from another request at a different url.
So in my sketch I prepared 2 functions to call, "sendRequest_0()" and "sendRequest_1()"
But how to say to the "void requestCB(......" function which value to extract ?
I think there must be a very simple solution, but I'm not familiar with the syntax of this library.
Thanks in advance for any help !
Roland
Here my code for a better understanding (runs on an ESP32)
#include <WiFi.h>
#include <AsyncTCP.h>
#include <asyncHTTPrequest.h>
unsigned long top_lect;
int intervalle = 5000 ;
const char* ssid = "xxxxxxxxxx";
const char* password = "yyyyyyyyyyyyyyy";
const int TimeOut_connexion =40;
int timeOut_counter =0;
float Pedf;
float Psol;
asyncHTTPrequest request;
// First request
void sendRequest_0() // to gather the responseText() for the "Pedf" value
{
if(request.readyState() == 0 || request.readyState() == 4)
{
request.open("GET", "http://192.168.1.12/emeter/0");
request.send();
}
}
/*********** The second request I would like to make ********************
*
*void sendRequest_1() // // to gather the responseText() for a second value
*{
* if(request.readyState() == 0 || request.readyState() == 4)
* {
* request.open("GET", "http://192.168.1.12/emeter/1");
* request.send();
* }
*}
*
************ The second request I would like to make END *****************/
void requestCB(void* optparm, asyncHTTPrequest* request, int readyState)
{
if(readyState == 4)
{
// Serial.println(request->responseText());
Pedf = atof(((request->responseText()).substring(9,18)).c_str());
Serial.println(Pedf);
}
}
void setup()
{
setCpuFrequencyMhz(80); // réglage de la fréquence de la CPU (80, 160 ou 240 Mhz, en dessous le WiFi ne marche pas)
Serial.begin(115200);
delay(2000);
Serial.print("Connection au WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(250);
Serial.print(".");
timeOut_counter++;
if (timeOut_counter > TimeOut_connexion) ESP.restart(); // redémarrage de l'ESP si pas de connexion pendant 10 sec
}
Serial.println("\n");
Serial.println("Adresse IP : "+(WiFi.localIP().toString()));
request.onReadyStateChange(requestCB);
}
void loop()
{
if (top_lect+intervalle<millis()) // condition vraie toutes les "intervalle" secondes
{top_lect=millis(); sendRequest_0(); } // aller à la routine de lecture des données du ShellyEM
}
Just to be clear, an instance of this class can only handle one request at a time. That said:
One solution is to simply change the callback to a different appropriate function prior to each request.
Another solution is to use the callback parameter to point to something that can be used to differentiate between the various requests.
Hello and thank you for the fast answer !
Not knowing very well AsyncHTTPrequest and it different syntaxes (there is not much information) your 2 propositions are not of big help...
Change the callback to a different appropriate function, why not, but there are not many examples I can look how to do, and what function to use...
I think that your second solution is maybe related to the "void* optparm" option in the "void requestCB" function ?
But I tried to figure out how it works but I can't find where this "optparm" is defined and how to redirect (??) the callback with it.
Do you maybe have an example ?
TIA !
Roland
Maybe something like this:
// First request
void sendRequest_0() // to gather the responseText() for the "Pedf" value
{
if(request.readyState() == 0 || request.readyState() == 4)
{
request.onReadyStateChange(request1CB);
request.open("GET", "http://192.168.1.12/emeter/0");
request.send();
}
}
void sendRequest_1() // // to gather the responseText() for a second value
{
if(request.readyState() == 0 || request.readyState() == 4)
{
request.onReadyStateChange(request2CB);
request.open("GET", "http://192.168.1.12/emeter/1");
request.send();
}
}
void request1CB(void* optparm, asyncHTTPrequest* request, int readyState)
{
if(readyState == 4)
{
// Serial.println(request->responseText());
Pedf = atof(((request->responseText()).substring(9,18)).c_str());
Serial.println(Pedf);
}
}
void request2CB(void* optparm, asyncHTTPrequest* request, int readyState)
{
if(readyState == 4)
{
// Serial.println(request->responseText());
Pedf = atof(((request->responseText()).substring(9,18)).c_str());
Serial.println(Pedf);
}
}
Ohhh thanks.
Ah, its the "request.onReadyStateChange(requestxxx);" wich does the magic !
i will try it.
Roland
I just tried it, with the result that the ESP32 crashes each time the 2 requests are launched at the same time.
I changed my code so the first request starts every 5 seconds, and the second request 2,5 seconds after, and now it works !
Many many thanks !
Roland
Edit :
Oooops,
After about 10 minutes it crashed, with a guru meditation error :
23:24:01.076 -> Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.
23:24:01.076 ->
23:24:01.076 -> Core 1 register dump:
23:24:01.076 -> PC : 0x00440022 PS : 0x00060930 A0 : 0x820044f1 A1 : 0x3fca6b50
23:24:01.076 -> A2 : 0x3fca2b78 A3 : 0x40010000 A4 : 0x3fca2b70 A5 : 0x0000000c
23:24:01.076 -> A6 : 0x02c95354 A7 : 0x00ffffff A8 : 0x820043f5 A9 : 0x3fca6b40
23:24:01.076 -> A10 : 0x3fca2b78 A11 : 0x3fca6b5c A12 : 0x3fca6b58 A13 : 0x00000000
23:24:01.076 -> A14 : 0x00000001 A15 : 0x3fca2d40 SAR : 0x0000000a EXCCAUSE: 0x00000014
23:24:01.076 -> EXCVADDR: 0x00440020 LBEG : 0x400570e8 LEND : 0x400570f3 LCOUNT : 0xffffffff
23:24:01.076 ->
23:24:01.076 ->
23:24:01.076 -> Backtrace: 0x0044001f:0x3fca6b50 0x420044ee:0x3fca6b80 0x42004504:0x3fca6ba0 0x4200481e:0x3fca6bc0
23:24:01.076 ->
23:24:01.076 ->
23:24:01.076 ->
23:24:01.076 ->
23:24:01.076 -> ELF file SHA256: a65d66640a0063d8
23:24:01.076 ->
23:24:01.076 -> Rebooting...
23:24:01.076 -> ESP-ROM:esp32s3-20210327
23:24:01.076 -> Build:Mar 27 2021
23:24:01.076 -> rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
23:24:01.076 -> Saved PC:0x420195f5
23:24:01.076 -> SPIWP:0xee
23:24:01.076 -> mode:DIO, clock div:1
23:24:01.076 -> load:0x3fce3808,len:0x44c
23:24:01.076 -> load:0x403c9700,len:0xbe4
23:24:01.076 -> load:0x403cc700,len:0x2a38
23:24:01.076 -> entry 0x403c98d4
Roland
Simultaneous requests work with the ESP8266. The ESP32 is a different animal. I don't use this with ESP32 because there is really no need to provide the asynchronous HTTP functionality with ESP32. You can just create a FREERTOS task to do the transaction with either HTTPclient or the underlying esp_http_client and blocking will only affect that task while your other tasks continue to execute. You get the added benefit of being able to use both processors.
OK, I will try this way.
Thanks for the time spend.
Roland