ESP32 server.on("/get"... Save to SD card problem

Hello!

I use ESP32-WROOM-DA module with SD-card module.
I have a function what appends text into a file:

void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

In the setup part of my code SD card is working:

void setup() {
  Serial.begin(115200);

  hspi = new SPIClass(HSPI);

  hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, SD_CS);
  hspi->setFrequency(SPI_FRQ);

  if (!SD.begin(SD_CS, *hspi, SPI_FRQ)) {
    Serial.println("Card Mount Failed");
    return;
  }
    appendFile(SD, "test.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");
}

But in the server.on("/get" part it doesnt work:

server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
  appendFile(SD, "test.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");
}

In this part it prints to serial "Failed to open file for appending.
In this part i can get info from the SD card (card size and so on...)

Please help me why cant i access the file from this part

My full code is here:

#include <Arduino.h>
#include <Arduino_JSON.h>
//#include "FS.h"
#include "SD.h"
#include <SPI.h>

#define HSPI_SCK 17
#define HSPI_MISO 16
#define HSPI_MOSI 2
#define SD_CS 15
#define SPI_FRQ 32000000
SPIClass * hspi = NULL;

#include <RF24.h>

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>

AsyncWebServer server(80);
AsyncEventSource events("/events");

JSONVar readings;
int aktualisPontszam = 0;

const char* ssid = "MySSID";          // Your WiFi SSID
const char* password = "MyPass";  // Your WiFi Password

struct __attribute__((packed)) Struct1 {  // test data structure
  uint8_t seq;          // sequence number
  uint8_t id;           // node ID if multiple transmitters
  uint16_t dist;
  uint16_t conf;
  uint8_t crc;          // CRC check
  uint8_t gpsage;
  long szelesseg;
  long hosszusag;
  long magassag;
  uint8_t megbizhatosag;
  float hdop;
  float vdop;
} data;

const char* PARAM_INPUT_1 = "pontszam";
const char* PARAM_INPUT_2 = "szelesseg";
const char* PARAM_INPUT_3 = "hosszusag";
const char* PARAM_INPUT_4 = "magassag";
const char* PARAM_INPUT_5 = "gpsage";
const char* PARAM_INPUT_6 = "megbizhatosag";
const char* PARAM_INPUT_7 = "hdop";
const char* PARAM_INPUT_8 = "vdop";
const char* PARAM_INPUT_9 = "dist";
const char* PARAM_INPUT_10 = "conf";

// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="ISO-8859-1">
  <script type="text/javascript">
    window.addEventListener('load', getReadings);

    function getReadings(){
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          var myObj = JSON.parse(this.responseText);
          console.log(myObj);
          var temp = myObj.temperature;
          document.getElementById("input2id").value = myObj.dist;
          document.getElementById("input3id").value = myObj.dist;
        }
      }; 
      xhr.open("GET", "/readings", true);
      xhr.send();
    }

    if (!!window.EventSource) {
      var source = new EventSource('/events');
      
      source.addEventListener('open', function(e) {
        console.log("Events Connected");
      }, false);

      source.addEventListener('error', function(e) {
        if (e.target.readyState != EventSource.OPEN) {
          console.log("Events Disconnected");
        }
      }, false);
      
      source.addEventListener('message', function(e) {
        console.log("message", e.data);
      }, false);
      
      source.addEventListener('new_readings', function(e) {
        console.log("new_readings", e.data);
        var myObj = JSON.parse(e.data);
        console.log(myObj);
        document.getElementById("input2id").value = myObj.dist;
        document.getElementById("input3id").value = myObj.conf;
        document.getElementById("input4id").value = myObj.szelesseg;
        document.getElementById("input5id").value = myObj.hosszusag;
        document.getElementById("input6id").value = myObj.magassag;
        document.getElementById("input7id").value = myObj.gpsage;
        var megbizhatosagstring = "NaN";
        if(myObj.megbizhatosag == 1){
          megbizhatosagstring = "3DFix";
        }
        if(myObj.megbizhatosag == 2){
          megbizhatosagstring = "DGPS";
        }
        if(myObj.megbizhatosag == 3){
          megbizhatosagstring = "Float RTK";
        }
        if(myObj.megbizhatosag == 4){
          megbizhatosagstring = "Fix RTK";
        }
        if(myObj.megbizhatosag == 5){
          megbizhatosagstring = "NOFIX";
        }
        document.getElementById("input8id").value = megbizhatosagstring;
        document.getElementById("input9id").value = myObj.hdop;
        document.getElementById("input10id").value = myObj.vdop;
      }, false);
    }

    function autofillpontszam() {
      console.log("kezdes");
      const queryString = window.location.search;
      const urlParams = new URLSearchParams(queryString);
      if(urlParams.has('pontszam') && urlParams.get('pontszam') != ''){
        var aktualispontszam = parseInt(urlParams.get('pontszam'));
        document.getElementById("input1id").value = aktualispontszam;
      }
    }
  </script>
  <style type="text/css">
  .form-style-2{
    max-width: 100%;
    padding: 20px 12px 10px 20px;
    font: 13px Arial, Helvetica, sans-serif;
  }
  .form-style-2-heading{
    font-weight: bold;
    font-style: italic;
    border-bottom: 2px solid #ddd;
    margin-bottom: 10px;
    font-size: 15px;
    padding-bottom: 3px;
  }
  .form-style-2 label{
    display: block;
    margin: 0px 0px 5px 0px;
  }
  .form-style-2 label > span{
    width: 100px;
    font-weight: bold;
    float: left;
    padding-top: 8px;
    padding-right: 5px;
  }
  .form-style-2 span.required{
    color:red;
  }
  .form-style-2 .tel-number-field{
    width: 40px;
    text-align: center;
  }
  .form-style-2 input.input-field, .form-style-2 .select-field{
    width: 100%;	
    margin-top: 10px;
  }
  .form-style-2 input.input-field, 
  .form-style-2 .tel-number-field, 
  .form-style-2 .textarea-field, 
  .form-style-2 .select-field{
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    border: 1px solid #C2C2C2;
    box-shadow: 1px 1px 4px #EBEBEB;
    -moz-box-shadow: 1px 1px 4px #EBEBEB;
    -webkit-box-shadow: 1px 1px 4px #EBEBEB;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    padding: 7px;
    outline: none;
  }
  .form-style-2 .input-field:focus, 
  .form-style-2 .tel-number-field:focus, 
  .form-style-2 .textarea-field:focus,  
  .form-style-2 .select-field:focus{
    border: 1px solid #0C0;
  }
  .form-style-2 .textarea-field{
    height:100px;
    width: 55%;
  }
  .form-style-2 #submitbutton{
    border: none;
    padding: 20px;
    background: #FF8500;
    color: #fff;
    box-shadow: 1px 1px 4px #DADADA;
    -moz-box-shadow: 1px 1px 4px #DADADA;
    -webkit-box-shadow: 1px 1px 4px #DADADA;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    width: 100%;
  }
  .form-style-2 #submitbutton:hover{
    background: #EA7B00;
    color: #fff;
  }
  .fullsizediv{
    width: 100%;
    display: block;
    margin-bottom:5px;
  }
  .fullsizeinput{
    width: 100%;
    display: block;
    margin-bottom:5px;
  }
  .halfsizeinput{
    width: 50%;
    display: block;
    margin-bottom:5px;
    float: left;
  }
  </style>
  </head><body onload="autofillpontszam()">
  <script>
  function submitFormData() {
    var xhr = new XMLHttpRequest();
    var input1dataforsend = document.getElementById("input1id").value;
    var input2dataforsend = document.getElementById("input2id").value;
    var input3dataforsend = document.getElementById("input3id").value;
    xhr.open("GET", "/get?pontszam="+input1dataforsend+"&melyseg1="+input2dataforsend+"+"&melyseg2="+input3dataforsend, true);
    xhr.send();
  }
  </script>
  <div class="form-style-2">
  <div class="form-style-2-heading">Mert melysegek mentese</div>
  <form action="/get">
    <div class="fullsizeinput"><label for="input1id"><span>Pontszam: </span><input type="text" id="input1id" name="pontszam" class="input-field" value=""></div>
    <div class="halfsizeinput"><label for="input2id"><span>Melyseg(mm): </span><input readonly="readonly" type="text" id="input2id" name="dist" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input3id"><span>Conf(%): </span><input readonly="readonly" type="text" id="input3id" name="conf" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input4id"><span>Szelesseg: </span><input readonly="readonly" type="text" id="input4id" name="szelesseg" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input5id"><span>Hosszusag: </span><input readonly="readonly" type="text" id="input5id" name="hosszusag" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input6id"><span>Magassag: </span><input readonly="readonly" type="text" id="input6id" name="magassag" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input7id"><span>GPS age: </span><input readonly="readonly" type="text" id="input7id" name="gpsage" class="input-field" value="%STATE%"></div>
    <div class="fullsizeinput"><label for="input8id"><span>Megbizhatosag: </span><input readonly="readonly" type="text" id="input8id" name="megbizhatosag" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input9id"><span>Hdop: </span><input readonly="readonly" type="text" id="input9id" name="hdop" class="input-field" value="%STATE%"></div>
    <div class="halfsizeinput"><label for="input10id"><span>Vdop: </span><input readonly="readonly" type="text" id="input10id" name="vdop" class="input-field" value="%STATE%"></div>
    <div class="fullsizeinput"><button id="submitbutton"  onclick="submitFormData()">SD mentes</button></div>
  </form>
</body></html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

// for this test using a simple checksum - replace with CRC check
unsigned char checksum(unsigned char *data, uint8_t *crc) {
  unsigned char sum = 0;
  while (data != crc) {
    sum += *data;
    data++;
  }
  return sum;
}

#define CE_PIN 4
#define CSN_PIN 5

bool radioNumber = 1;
const uint8_t pipes[][6] = { "1Node", "2Node" };

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10];  // this must match dataToSend in the TX
bool newData = false;

//===========

 String getRadioReadings(){
    readings["dist"] = data.dist;
    readings["conf"] = data.conf;
    readings["szelesseg"] = data.szelesseg;
    readings["hosszusag"] = data.hosszusag;
    readings["magassag"] = data.magassag;
    readings["gpsage"] = data.gpsage;
    readings["megbizhatosag"] = data.megbizhatosag;
    readings["hdop"] = data.hdop;
    readings["vdop"] = data.vdop;
    String jsonString = JSON.stringify(readings);
    return jsonString;
}

void readFile(fs::FS &fs, const char * path) {
  Serial.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }

  Serial.print("Read from file: ");
  while (file.available()) {
    Serial.write(file.read());
  }
  file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void setup() {
  Serial.begin(115200);

  hspi = new SPIClass(HSPI);

  hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, SD_CS);
  hspi->setFrequency(SPI_FRQ);
  //hspi->begin();


  if (!SD.begin(SD_CS, *hspi, SPI_FRQ)) {
    Serial.println("Card Mount Failed");
    WebSerial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC) {
    Serial.println("MMC");
  } else if (cardType == CARD_SD) {
    Serial.println("SDSC");
  } else if (cardType == CARD_SDHC) {
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  appendFile(SD, "hajoscan.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");

  radio.begin();
  if (radio.isChipConnected())
    Serial.println("\n\nReceiver NF24 connected to SPI");
  else {
    Serial.println("\n\nNF24 is NOT connected to SPI");
    while (1)
      ;
  }
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  // radio.setDataRate(RF24_1MBPS);
  radio.setDataRate(RF24_250KBPS);
  radio.printDetails();
  if (!radioNumber) {
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1, pipes[1]);
  } else {
    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1, pipes[0]);
  }
  radio.startListening();
  Serial.print("data sizeof (bytes):  ");  // print size of data structure in bytes
  Serial.println(sizeof(Struct1));
  radio.setPayloadSize(sizeof(Struct1));
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("WiFi Failed!\n");
    return;
  }
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  server.on("/readings", HTTP_GET, [](AsyncWebServerRequest *request){
    String json = getRadioReadings();
    request->send(200, "application/json", json);
    json = String();
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String sdCardMessage;
    String inputParam;
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage += "pontszam: ";
      inputMessage += request->getParam(PARAM_INPUT_1)->value();
      sdCardMessage += request->getParam(PARAM_INPUT_1)->value();
      inputMessage += " / ";
      String aktualisPontszamString = request->getParam(PARAM_INPUT_1)->value();
      if(aktualisPontszamString == ""){
        aktualisPontszam = 0;
      }
      aktualisPontszam = aktualisPontszamString.toInt();
      aktualisPontszam += 1;
    } else {
      aktualisPontszam = 1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage += "szelesseg: ";
      inputMessage += request->getParam(PARAM_INPUT_2)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_2)->value();
      inputMessage += " / ";
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage += "hosszusag: ";
      inputMessage += request->getParam(PARAM_INPUT_3)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_3)->value();
      inputMessage += " / ";
    }

    // GET input4 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_4)) {
      inputMessage += "magassag: ";
      inputMessage += request->getParam(PARAM_INPUT_4)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_4)->value();
      inputMessage += " / ";
    }

    // GET input5 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_5)) {
      inputMessage += "gpsage: ";
      inputMessage += request->getParam(PARAM_INPUT_5)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_5)->value();
      inputMessage += " / ";
    }

    // GET input6 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_6)) {
      inputMessage += "megbizhatosag: ";
      inputMessage += request->getParam(PARAM_INPUT_6)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_6)->value();
      inputMessage += " / ";
    }

    // GET input7 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_7)) {
      inputMessage += "hdop: ";
      inputMessage += request->getParam(PARAM_INPUT_7)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_7)->value();
      inputMessage += " / ";
    }

    // GET input8 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_8)) {
      inputMessage += "vdop: ";
      inputMessage += request->getParam(PARAM_INPUT_8)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_8)->value();
      inputMessage += " / ";
    }

    // GET input9 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_9)) {
      inputMessage += "dist: ";
      inputMessage += request->getParam(PARAM_INPUT_9)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_9)->value();
      inputMessage += " / ";
    }

    // GET input10 value on <ESP_IP>/get?input3=<inputMessage>
    if (request->hasParam(PARAM_INPUT_10)) {
      inputMessage += "conf: ";
      inputMessage += request->getParam(PARAM_INPUT_10)->value();
      sdCardMessage += "#";
      sdCardMessage += request->getParam(PARAM_INPUT_10)->value();
      inputMessage += " / ";
    }

    sdCardMessage += "\r\n";
    Serial.println(sdCardMessage);
    const char* dataMessage;
    dataMessage = sdCardMessage.c_str();

    appendFile(SD, "hajoscan.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");
    
    WebSerial.println(inputMessage);
    //request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("+ inputParam + ") with value: " + inputMessage +"<br><a href=\"/\">Return to Home Page</a>");
    //request->send_P(200, "text/html", index_html);
    request->redirect("/?pontszam="+String(aktualisPontszam));
  });

  // WebSerial is accessible at "<IP Address>/webserial" in browser
  WebSerial.begin(&server);

  server.addHandler(&events);

  server.onNotFound(notFound);
  server.begin();

}

//=============

void loop() {
  static uint8_t seq_check = 0;
  static int crcErrors = 0, seqErrors = 0, frames = 0;
  if (radio.available()) {
    while (radio.available()) {
      int length = radio.getPayloadSize();
      Serial.print("received ");
      Serial.print(length);
      if (length != sizeof(data)) {
        Serial.println(" bytes - invalid packet size!");
        return;
      }
      Serial.print(" bytes Frame No: ");
      Serial.print(++frames);
      radio.read(&data, sizeof(data));
      Serial.print(" crc: 0x");
      Serial.print(data.crc, HEX);
      if (checksum((unsigned char *)&data, &data.crc) == data.crc)
        Serial.print(" CRC OK  ");
      else {
        Serial.print(" CRC ERROR!  ");
        crcErrors++;
      }
      Serial.print(" errors ");
      Serial.print(crcErrors);
      Serial.print(" seq:   ");
      Serial.print(data.seq);
      if (seq_check == data.seq) Serial.print(" seq OK  - ");
      else {
        Serial.print(" seq error! expected ");
        Serial.print(seq_check);
        seqErrors++;
      }
      Serial.print(" - seq errors ");
      Serial.println(seqErrors);
      /*
      Serial.print("dist:");
      Serial.println(data.dist);
      Serial.print("conf:");
      Serial.println(data.conf);
      Serial.print("gpsage:");
      Serial.println(data.gpsage);
      Serial.print("szelesseg:");
      Serial.println(data.szelesseg);
      Serial.print("hosszusag:");
      Serial.println(data.hosszusag);
      Serial.print("magassag:");
      Serial.println(data.magassag);
      Serial.print("hdop:");
      Serial.println(data.hdop);
      Serial.print("vdop:");
      Serial.println(data.vdop);
      Serial.print("megbizhatosag:");
      Serial.println(data.megbizhatosag);
      */
      events.send(getRadioReadings().c_str(),"new_readings" ,millis());
      seq_check = ++data.seq;
    }
  }
}


try

server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
  appendFile(SD, "/test.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");
}

It doesn't help. I tried it before.
First append in the setup root works fine (if file dont exists create file than write header in it), but in the server get part dont works. Cant find the file.

well it needs a '/' at the beginning of each of file, that i know for sure.
Are you saying that this works ?

appendFile(SD, "hajoscan.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");

 radio.begin();

Anyway, is the RF24 connected on VSPI ?

comment out the radio.begin() and see if that makes the SD card work again.

There is also a 'begin()' method in the RF24.h library. That let's you add a pointer to the SPI object which let;s you set a specific set of pins in the same way as you do with the SD card. It might be good to do this explicitly as well.

The appendFile command work is the setup root without "/" sign.

I commented out the radio.begin row, and nothing happens (nothing good :smiley: )
Yes the D5 pin is VSPI_CS.

and the other pins ?

that is weird. It shouldn't really. Can you verify that it is actually written onto the SD card ?

It somehow must be related to the RF24 though. there is no reason for the same function not to work inside the callback, unless somehow the SD_CS pin get's set high somewhere.

Maybe just add

void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);
  pinMode (SD_CS, OUTPUT);
  digitalWrite(SD_CS, LOW);
  File file = fs.open(path, FILE_APPEND);

Also, Are you using the builtin LED ? That is connected to GPIO 2 which you are using for HSPI_MOSI (poor choice of pin really)

Pinout was the problem, thank you!
With this pinout it works well:

#define HSPI_SCK 14
#define HSPI_MISO 27
#define HSPI_MOSI 13
#define SD_CS 15
#define SPI_FRQ 32000000
SPIClass * hspi = NULL;

void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);
  /*
  pinMode (SD_CS, OUTPUT);
  digitalWrite(SD_CS, LOW);
  */
  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void setup() {
  Serial.begin(115200);
  hspi = new SPIClass(HSPI);
  hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, SD_CS);
  hspi->setFrequency(SPI_FRQ);

  if (!SD.begin(SD_CS, *hspi, SPI_FRQ)) {
    Serial.println("Card Mount Failed");
    WebSerial.println("Card Mount Failed");
    return;
  }
appendFile(SD, "/hajoscan.txt", "pontszam#szelesseg#hosszusag#magassag#gpsage#megbizhatosag#hdop#vdop#melyseg#conf\r\n");

}

I musn't use this part:

pinMode (SD_CS, OUTPUT);
  digitalWrite(SD_CS, LOW);

Thanks for your help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.