HTTP_POST hangs up PortentaH7 when is use it to send a file name to the server and save said file on SD card but strangely only the second time i send the request. I have attached a sketch that should reproduce the issue and reflects what i'm trying to do.
I've tried this both using Arduino IDE 2.0.0 and VSCode + PlatformIO.
I'm using a PortentaH7 Rev2 and breakout.
#include <WiFi.h>
#warning Using WiFi for Portenta_H7.
#include <Portenta_H7_AsyncWebServer.h>
#include <SDMMCBlockDevice.h>
#include <FATFileSystem.h>
#include <ArduinoJson.h>
SDMMCBlockDevice block_device;
mbed::FATFileSystem fs("fs");
char ssid[] = "SSIDname";
char pass[] = "123456789"; // I use it this way since i want it to be a WiFi A.P.
int status = WL_IDLE_STATUS;
AsyncWebServer server(80);
void handleRoot(AsyncWebServerRequest *request)
{
String html ="<!DOCTYPE html> <html> <head> </head> <body> <label for=\"fname\">File Name:</label><br> <input type=\"text\" id=\"fname\" name=\"fname\" value=\"\"><br> <label for=\"temperature\" name=\"tname\">Temp:</label><p id=\"temp\"></p><br> <button class=\"button\" type=\"button\" onclick=logTemp()>LogTemp</button> <script> function logTemp(){ var xhr = new XMLHttpRequest(); var filename=document.getElementById(\"fname\").value; const params={\"fname\":filename}; xhr.open(\"POST\", \"/logTemp\",true); xhr.setRequestHeader(\"Content-Type\",\"application/json;charset=UTF-8\"); xhr.send(JSON.stringify(params)); } setInterval(function(){getTemperature();},2000); function getTemperature(){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(this.readyState==4 && this.status==200){ document.getElementById(\"temp\").innerText=this.responseText;} }; xhr.open(\"GET\",\"/temperature\",true); xhr.send(); } </script> </body> </html>";
request->send(200, "text/html",html);
}
void handleNotFound(AsyncWebServerRequest *request)
{
String message = "File Not Found\n\n";
message += "URI: ";
message += request->url();
message += "\nMethod: ";
message += (request->method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += request->args();
message += "\n";
for (uint8_t i = 0; i < request->args(); i++)
{
message += " " + request->argName(i) + ": " + request->arg(i) + "\n";
}
request->send(404, "text/plain", message);
}
String readTemperature(){
int lower=20,upper=50;
int num=(rand()%(upper-lower+1))+lower;
return String(num);
} // A random val in range function since no sensor is connected
void printWifiStatus()
{
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("Local IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void saveTestFile(String file, String fileName){
FILE *testFile;
String fspref ="/fs/";
fspref+=fileName;
fspref+=".json";
testFile=fopen(fspref.c_str(),"w+");
fprintf(testFile, file.c_str());
fclose(testFile);
}
void setup() {
// put your setup code here, to run once:
#pragma region WIFI_SETUP&CARD_MOUNT
Serial.begin(115200);
while (!Serial);
delay(200);
Serial.print("\nStart Async_AdvancedWebServer on "); Serial.print(BOARD_NAME);
Serial.print(" with "); Serial.println(SHIELD_TYPE);
Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION);
Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION);
///////////////////////////////////
status = WiFi.beginAP(ssid,pass);
if(status != WL_AP_LISTENING){
Serial.println("Creating access point failed");
// don't continue
while (true);
}
printWifiStatus();
Serial.println("Mounting SDCARD...");
int err = fs.mount(&block_device);
if (err) {
// Reformat if we can't mount the filesystem
// this should only happen on the first boot
Serial.println("No filesystem found, formatting... ");
err = fs.reformat(&block_device);
}
if (err) {
Serial.println("Error formatting SDCARD ");
while(1);
}
DIR *dir;
struct dirent *ent;
int dirIndex = 0;
Serial.println("List SDCARD content: ");
if ((dir = opendir("/fs")) != NULL) {
// Print all the files and directories within directory (not recursively)
while ((ent = readdir (dir)) != NULL) {
Serial.println(ent->d_name);
dirIndex++;
}
closedir (dir);
} else {
// Could not open directory
Serial.println("Error opening SDCARD\n");
while(1);
}
if(dirIndex == 0) {
Serial.println("Empty SDCARD");
}
///////////////////////////////////
#pragma endregion
server.on("/logTemp", HTTP_POST, [](AsyncWebServerRequest * request){
},NULL,[](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) {
String jsondata;
for (size_t i = 0; i < len; i++) {
jsondata+=(char)data[i];
}
DynamicJsonDocument doc(100);
deserializeJson(doc,jsondata);
String testFile_name=doc["fname"];
doc["temp"]=readTemperature().c_str();
String testSer;
serializeJson(doc,testSer);
saveTestFile(testSer,testFile_name);
request->send(200);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest * request)
{
request->send(200,"text/plain",readTemperature().c_str());
});
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
{
handleRoot(request);
});
server.onNotFound(handleNotFound);
server.begin();
}
void check_status()
{
static unsigned long checkstatus_timeout = 0;
#define STATUS_CHECK_INTERVAL 10000L
// Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change.
if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
{
checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL;
}
}
void loop() {
// put your main code here, to run repeatedly:
check_status();
}