dies haben für mir funktioniert:

für die datenmesser esp:

#include <Wire.h>

#include <SoftwareSerial.h>

// HC12 Pin-Konfiguration

#define HC12_TX 17

#define HC12_RX 16

SoftwareSerial hc12(HC12_TX, HC12_RX);

// ADXL345 I2C-Adresse

#define ADXL345_ADDR 0x53

void setup() {

  Serial.begin(115200);       // Serieller Monitor

  hc12.begin(9600);           // HC12 Baudrate

  Wire.begin();               // I2C starten

  // ADXL345 initialisieren

  Wire.beginTransmission(ADXL345_ADDR);

  Wire.write(0x2D);           // Power-Control-Register

  Wire.write(0x08);           // Messmodus aktivieren

  Wire.endTransmission();

}

void loop() {

  // Winkelgeschwindigkeit vom ADXL345 lesen

  int16_t x, y, z;

  readADXL345(x, y, z);

  // Daten an HC12 senden

  String data = String(x) + "," + String(y) + "," + String(z);

  hc12.println(data);

  Serial.println("Gesendet: " + data);

  delay(100); // Sendeintervall

}

void readADXL345(int16_t &x, int16_t &y, int16_t &z) {

  Wire.beginTransmission(ADXL345_ADDR);

  Wire.write(0x32); // Startadresse der Daten

  Wire.endTransmission(false);

  Wire.requestFrom(ADXL345_ADDR, 6, true);

  if (Wire.available() == 6) {

    x = Wire.read() | (Wire.read() << 8);

    y = Wire.read() | (Wire.read() << 8);

    z = Wire.read() | (Wire.read() << 8);

  }

}

für den datenspeicher esp:

#include <SdFat.h>

// HC12 Pin-Konfiguration

#define HC12_TX 17

#define HC12_RX 16

// Puffergröße für eingehende Daten

#define BUFFER_SIZE 100

// SD-Karte Objekt

SdFat SD;

// SD-Karten Konfiguration

#define SD_CONFIG SdSpiConfig(SS, SHARED_SPI, SD_SCK_MHZ(25))

// Datenpuffer

char dataBuffer[BUFFER_SIZE];

void setup() {

  Serial.begin(115200); // Serieller Monitor

  Serial2.begin(9600, SERIAL_8N1, HC12_RX, HC12_TX); // HardwareSerial für HC12

  Serial.println("Initialisiere SD-Karte...");

  // SD-Karte initialisieren

  if (!SD.begin(SD_CONFIG)) {

    Serial.println("SD-Karte konnte nicht initialisiert werden. Überprüfe die Karte und die Verbindungen.");

    while (1); // Endlosschleife bei Fehler

  }

  Serial.println("SD-Karte erfolgreich initialisiert.");

}

void loop() {

  // Daten von HC12 empfangen

  if (Serial2.available()) {

    size_t index = 0;

    unsigned long startMillis = millis(); // Timeout für langsame Daten

    while (Serial2.available() && index < BUFFER_SIZE - 1) { // Platz für Null-Terminierung lassen

      char c = Serial2.read();

      // Nur druckbare Zeichen und Zeilenendezeichen akzeptieren

      if (isPrintable(c) || c == '\n') {

        dataBuffer[index++] = c;

      }

      // Prüfe auf Nachrichtenende

      if (c == '\n') {

        break;

      }

      // Timeout prüfen

      if (millis() - startMillis > 1000) { // 1 Sekunde Timeout

        Serial.println("Timeout beim Empfang von Daten!");

        break;

      }

    }

    dataBuffer[index] = '\0'; // Null-Terminierung des Strings

    // Ausgabe auf dem Seriellen Monitor

    if (index > 0) {

      Serial.print("Empfangen: ");

      Serial.println(dataBuffer);

      // Daten in CSV-Datei schreiben

      if (writeToFile("/data.csv", dataBuffer)) {

        Serial.print("Daten gespeichert: ");

        Serial.println(dataBuffer);

      } else {

        Serial.println("Fehler beim Speichern der Daten auf der SD-Karte.");

      }

    } else {

      Serial.println("Keine gültigen Daten empfangen.");

    }

  }

}

// Funktion zum Schreiben in die Datei

bool writeToFile(const char* path, const char* data) {

  File dataFile = SD.open(path, FILE_WRITE);

  if (dataFile) {

    dataFile.println(data);

    dataFile.close();

    return true;

  } else {

    Serial.println("Fehler beim Öffnen der Datei. Stelle sicher, dass die SD-Karte genügend Speicherplatz hat und beschreibbar ist.");

    return false;

  }

}

...zur Antwort

//Diese funktioniert bei mir am besten

#include <Arduino.h>

#include <WiFi.h>

#include "SPIFFS.h"

#include <AsyncTCP.h>

#include <ESPAsyncWebServer.h>

#include <Arduino_JSON.h>

#include <Adafruit_BMP085.h>

#include <Adafruit_Sensor.h>

#include <Servo.h>

const char* ssid   = "ParachuteDrop";

const char* password = "parachutedrop";

Adafruit_BMP085 sensor;

float altitude = 0.0;

float currentAltitude = 0.0;

float pressure = 0.0;

JSONVar readings;

const float maxElevation = 1.5;

const float seaLevelPressure = 101325.0;

Servo servo;

const int SERVOPIN = 4;

const int servoOpenPosition = 0;

const int servoClosePosition = 90;

const int LEDPIN = 2; //LED_BUILTIN;

bool locked = false;

// Create AsyncWebServer object on port 80

AsyncWebServer server(80);

AsyncWebSocket webSocket("/ws");

// Generally, you should use "unsigned long" for variables that hold time

// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;  // will store last time DHT was updated

const long interval = 1000;  

const char index_html[] PROGMEM = R"rawliteral(

<!DOCTYPE HTML><html>

<head>

 <meta name="viewport" content="width=device-width, initial-scale=1">

 <style>

  html {

   font-family: Arial;

   display: inline-block;

   margin: 0px auto;

   text-align: center;

  }

  h2 { font-size: 3.0rem; }

  p { font-size: 3.0rem; }

  .units { font-size: 1.2rem; }

  .bmp-labels{

   font-size: 1.5rem;

   vertical-align:middle;

   padding-bottom: 15px;

  }

   .button {

  padding: 15px 50px;

  font-size: 24px;

  text-align: center;

  outline: none;

  color: #fff;

  background-color: #0f8b8d;

  border: none;

  border-radius: 5px;

  -webkit-touch-callout: none;

  -webkit-user-select: none;

  -khtml-user-select: none;

  -moz-user-select: none;

  -ms-user-select: none;

  user-select: none;

  -webkit-tap-highlight-color: rgba(0,0,0,0);

  }

  .button:active {

   background-color: #0f8b8d;

   box-shadow: 2 2px #CDCDCD;

   transform: translateY(2px);

  }

  .state {

   font-size: 1.5rem;

   color:#8c8c8c;

   font-weight: bold;

  }

 </style>

</head>

<body>

 <h2>Parachute Drop</h2>

 <p>

  <span class="bmp-labels">Altitude</span> 

  <span id="altitude">%ALTITUDE%</span>

  <sup class="units">m</sup>

 </p>

 <p>

  <span class="bmp-labels">Pressure</span>

  <span id="pressure">%PRESSURE%</span>

  <sup class="units">hPa</sup>

 </p>

 <p class="state">Lock state: <span id="state">%STATE%</span></p>

 <p><button id="button" class="button">Toggle</button></p>

</body>

<script>

 var gateway = `ws://${window.location.hostname}/ws`;

 var websocket;

 window.addEventListener('load', onLoad);

 function getInformations(){

  websocket.send("getReadings");

 }

  

 function initWebSocket() {

  console.log('Trying to open a WebSocket connection...');

  websocket = new WebSocket(gateway);

  websocket.onopen  = onOpen;

  websocket.onclose  = onClose;

  websocket.onmessage = onMessage; // <-- add this line

 }

 function onOpen(event) {

  console.log('Connection opened');

  getInformation();

 }

 function onClose(event) {

  console.log('Connection closed');

  setTimeout(initWebSocket, 2000);

 }

 function onMessage(event) {

  console.log(event.data);

   

  var state;

  var myObj = JSON.parse(event.data);

  var keys = Object.keys(myObj);

  for (var i = 0; i < keys.length; i++){

    var key = keys[i];

    document.getElementById(key).innerHTML = myObj[key];

  }

 }

 function onLoad(event) {

  initWebSocket();

  initButton();

 }

 function initButton() {

  document.getElementById('button').addEventListener('click', toggle);

 }

 function toggle(){

  websocket.send('toggle');

 }

</script>

</html>)rawliteral";

void initWiFi() {

 Serial.print("Setting AP (Access Point)…");

  

 WiFi.softAP(ssid, password);

 IPAddress IP = WiFi.softAPIP();

 Serial.print("AP IP address: ");

 Serial.println(IP);

 Serial.println(WiFi.localIP());

}

void initSPIFFS() {

 if (!SPIFFS.begin(true))

  Serial.println("An error has occurred while mounting SPIFFS");

 else {

  Serial.println("SPIFFS mounted successfully");

// Filename sensor.csv

  File file = SPIFFS.open("/sensor.csv", FILE_WRITE);

  if (!file) {

   Serial.println("There was an error opening the file for writing");

   return;

  }

  if (file.println("Uptime;Pressure;Altidue;Current Altitude;Locked;"))

   Serial.println("File was written");

  else

   Serial.println("File write failed");

  file.close();

 }

}

void AppendSensorDatatoFile(int CurrentMillis, float Pressure, float Altitude, float CurrentAltitude, bool Locked) {

 File file = SPIFFS.open("/sensor.csv", FILE_APPEND);

 if (!file) {

  Serial.println("There was an error opening the file for writing");

  return;

 }  

 file.print(CurrentMillis); file.print(";"); file.print(Pressure); file.print(";"); file.print(Altitude); file.print(";"); file.print(CurrentAltitude); file.print(";"); file.print( Locked ? "LOCKED" : "OPEN" ); file.println(";");

 file.close();

}

void initSensor() {

 if (!sensor.begin(0x76)) {

  Serial.println("Could not find a valid BMP085 sensor, check wiring!");

  while (1);

 }  

}

void setServo(bool Locked){

 digitalWrite(LEDPIN, Locked);

 if ( Locked ) {

  servo.write(servoClosePosition);

 } else {

  servo.write(servoOpenPosition);

 }

}

void initServo() {

 pinMode(SERVOPIN, OUTPUT);

 servo.attach(SERVOPIN);

 setServo(false); delay(1000);

  

 setServo(true); delay(1000);

 setServo(false);

}

void initLED() {

 pinMode(LEDPIN, OUTPUT);

 digitalWrite(LEDPIN, locked);

}

String getInformation(){

 readings["altitude"] = String(altitude);

 readings["pressure"] = String(pressure);

 readings["state"] = locked ? "LOCKED" : "OPEN";

 String jsonString = JSON.stringify(readings);

 return jsonString;

}

void notifyClients() {

 String information = getInformation();

 webSocket.textAll(information);

}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {

 AwsFrameInfo *info = (AwsFrameInfo*)arg;

 if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {

  data[len] = 0;

  if (strcmp((char*)data, "toggle") == 0) {

   locked = !locked;

   if ( locked )

    currentAltitude = altitude;

   else

    currentAltitude = 0.0;

   setServo(locked);

  }  

  notifyClients();

 }

}

void handleWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {

 switch (type) {

  case WS_EVT_DISCONNECT:

   Serial.printf("Disconnected!\n", client->id());

   break;

  case WS_EVT_CONNECT:

   {

    IPAddress ip = client->remoteIP();

    Serial.printf("Connected from %d.%d.%d.%d", client->id(), ip[0], ip[1], ip[2], ip[3]);

   }

   break;

  case WS_EVT_DATA:

   handleWebSocketMessage(arg, data, len);

   break;

  case WS_EVT_PONG:

  case WS_EVT_ERROR:

   break;

 }

}

void initWebSocket() {

 webSocket.onEvent(handleWebSocketEvent);

 server.addHandler(&webSocket);

}

void setup(){

// Első beállítás

 Serial.begin(115200); // Soros kommunikáció beállítása

 initWiFi(); // WiFi beállítás

 initSPIFFS(); // fájlrendszer beállítása

 initSensor();

 initLED();

 initServo();

 initWebSocket();

// Route for root / web page

 server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){

  request->send_P(200, "text/html", index_html);

 });

 server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){

  request->send(SPIFFS, "/sensor.csv", "text/csv", true);

});

// Start server

 server.begin();

}

 

void loop(){  

 unsigned long currentMillis = millis();

 if (currentMillis - previousMillis >= interval) {

  previousMillis = currentMillis;

  pressure = sensor.readPressure();

  altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.190294957183635));

   

  Serial.print("altidue: "); Serial.println(String(altitude));

  Serial.print("current: "); Serial.println(String(currentAltitude));

  AppendSensorDatatoFile(int(currentMillis/1000.0), pressure, altitude, currentAltitude, locked);

   

  if ( locked && altitude >= currentAltitude + maxElevation )

  {

   currentAltitude = 0.0;

   locked = false;

   setServo(locked);

  }

  notifyClients();

 }

 webSocket.cleanupClients();

}

...zur Antwort