Save config in modem + esp communication

This commit is contained in:
Jonas Niesner
2025-06-24 18:04:08 +02:00
committed by GitHub
parent 9eef89c64b
commit 33dbd5001e
7 changed files with 1767 additions and 383 deletions

View File

@@ -12,6 +12,7 @@ lib_deps =
vshymanskyy/TinyGSM@^0.12.0
koendv/RTT Stream@^1.4.1
arduino-libraries/ArduinoHttpClient@^0.6.1
bblanchon/ArduinoJson@^6.21.4
build_unflags = -DNRF52 -DUSE_LFXO
build_flags = -DNRF52840_XXAA -DUSE_LFRC
upload_protocol = jlink

View File

@@ -0,0 +1,45 @@
<?php
// Sensor Data Receiver - POST JSON Version
// This script receives sensor data via POST with JSON payload
header('Content-Type: application/json');
// Get JSON input
$json_input = file_get_contents('php://input');
$data = json_decode($json_input, true);
// Create response array
$response = array(
'status' => 'success',
'message' => 'Data received successfully',
'timestamp' => time(),
'received_data' => $data
);
// Check if JSON was parsed successfully
if ($data === null) {
$response['status'] = 'error';
$response['message'] = 'Invalid JSON data received';
$response['raw_input'] = $json_input;
http_response_code(400);
} else {
// Log the received data to a JSON file
$log_filename = 'sensor_data_' . date('Y-m-d') . '.json';
$log_entry = array(
'timestamp' => date('Y-m-d H:i:s'),
'data' => $data
);
// Append to daily log file
file_put_contents($log_filename, json_encode($log_entry, JSON_PRETTY_PRINT) . "\n", FILE_APPEND | LOCK_EX);
// Also log to a general log file
$general_log = 'sensor_data_all.json';
file_put_contents($general_log, json_encode($log_entry, JSON_PRETTY_PRINT) . "\n", FILE_APPEND | LOCK_EX);
$response['logged_to'] = $log_filename;
}
// Output response as JSON
echo json_encode($response, JSON_PRETTY_PRINT);
?>

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,7 @@
#include <TinyGsmClient.h>
#include <RTTStream.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>
#include "ens210.h"
#include "SparkFun_VEML6030_Ambient_Light_Sensor.h"
#include "sensors.h"
@@ -28,24 +29,130 @@ bool espmodemrail = 0;
bool espon = 0;
bool modemon = 0;
void measuretemp();
void measurepressure();
void ButtonState();
void measureBattery();
void lightsense();
void powerupesp();
bool espSerialInitialized = false;
int currentFileHandle = -1;
bool fileOpen = false;
volatile int32_t wdcounter = 0;
unsigned long lastTransmissionTime = 0;
bool modemInitialized = false;
// Power management functions
void wd_handler();
void gpioinit();
void measureacc();
void powerupmodem();
void softpwrup();
void powerdownesp();
void powerdownmodem();
void testmodem();
void getgps();
void httpreq();
void disconnectmodem();
void connectmodem();
void initmodem();
// Sensor data management functions
void sampleallsensors();
void sensorpwr(bool onoff);
void sensorpwr(bool onoff);
void collectAllSensorData();
// New refactored sensor functions (implemented in main.cpp)
float readBatteryVoltage();
float readLightSensor(float gain = 0.25, int integrationTime = 100);
bool readTemperatureHumidity(float& temperature, float& humidity);
bool readPressure(float& pressure, float& sensorTemp);
bool readAccelerometers(float& acc1_x, float& acc1_y, float& acc1_z,
float& acc2_x, float& acc2_y, float& acc2_z);
bool readGPS(float& latitude, float& longitude, float& speed, float& altitude,
int& visibleSatellites, int& usedSatellites, float& accuracy);
bool readModemInfo();
bool readNetworkInfo();
void checkModemStorageSpace();
// HTTP Data Transmission System
struct ServerConfig {
const char* server;
const char* endpoint;
int port;
const char* apn;
const char* username;
const char* password;
};
bool initializeModem();
bool connectToNetwork();
bool disconnectFromNetwork();
bool sendSensorDataToServer(const SensorData& data, const ServerConfig& config);
bool sendSensorDataToServer(const SensorData& data);
void testModemAndNetwork();
void manageModemLifecycle();
// Data transmission scheduling
extern unsigned long lastTransmissionTime;
extern unsigned long transmissionInterval;
extern bool modemInitialized;
// GPS configuration
extern bool enableGPS;
extern unsigned long gpsTimeout;
// Abstracted File System Functions
bool modemFileOpen(const String& filename, int mode);
bool modemFileWrite(const String& data);
bool modemFileRead(String& data, int length = 1024);
bool modemFileSeek(int offset, int origin);
bool modemFilePosition(int& position);
bool modemFileClose();
bool modemFileDelete(const String& filename);
bool modemFileExists(const String& filename);
int modemFileSize(const String& filename);
String modemFileList();
bool checkModemReady();
// Configuration Storage
struct ModemConfig {
String device_name;
unsigned long transmission_interval;
bool enable_gps;
unsigned long gps_timeout;
String server_url;
String server_endpoint;
int server_port;
String apn;
String username;
String password;
bool enable_storage;
int max_stored_files;
ModemConfig() {
device_name = "Dev 1";
transmission_interval = 300000;
enable_gps = true;
gps_timeout = 15000;
server_url = "api.64eng.de";
server_endpoint = "/sensordata.php";
server_port = 80;
apn = "internet";
username = "";
password = "";
enable_storage = true;
max_stored_files = 10;
}
};
// Global configuration variable
extern ModemConfig deviceConfig;
void blinkLED(int times, int delayon, int delayoff, bool green);
bool saveConfigToModem(const ModemConfig& config);
bool loadConfigFromModem(ModemConfig& config);
void printConfig(const ModemConfig& config);
void LoadDeviceConfig();
void displaySensorDataSummary();
// ESP communication functions
bool initializeESPSerial();
void powerupESP();
void powerdownESP();
bool sendCommandToESP(const String& command);
bool readESPResponseDebug(String& response, unsigned long timeout = 5000);
void testESPCommunication();
// ESP response parsing functions
bool parseESPResponse(const String& rawResponse, String& filteredResponse, bool& hasOK);
bool sendESPCommandAndGetResponse(const String& command, String& response, unsigned long timeout);
// UART bit-banging functions
void uartSendByte(uint8_t byte);
bool testESPConnection();

View File

@@ -0,0 +1,39 @@
#include "sensors.h"
// Global sensor data instance
SensorData sensorData;
// Implementation of toJSON method
String SensorData::toJSON() const {
String json = "{";
json += "\"timestamp\":" + String(timestamp) + ",";
json += "\"sensors\":{";
json += "\"light\":{\"lux\":" + String(lux) + "},";
json += "\"battery\":{\"voltage\":" + String(battery_voltage, 2) + "},";
json += "\"environment\":{";
json += "\"temperature\":" + String(case_temperature, 1) + ",";
json += "\"humidity\":" + String(case_humidity, 1) + ",";
json += "\"pressure\":" + String(pressure, 2) + ",";
json += "\"pressure_sensor_temp\":" + String(pressure_sensor_temp, 2);
json += "},";
json += "\"accelerometers\":{";
json += "\"acc1\":{\"x\":" + String(acc1_x) + ",\"y\":" + String(acc1_y) + ",\"z\":" + String(acc1_z) + "},";
json += "\"acc2\":{\"x\":" + String(acc2_x) + ",\"y\":" + String(acc2_y) + ",\"z\":" + String(acc2_z) + "}";
json += "},";
json += "\"gps\":{";
json += "\"latitude\":" + String(gps_latitude, 8) + ",";
json += "\"longitude\":" + String(gps_longitude, 8) + ",";
json += "\"speed\":" + String(gps_speed) + ",";
json += "\"altitude\":" + String(gps_altitude) + ",";
json += "\"visible_satellites\":" + String(gps_visible_satellites) + ",";
json += "\"used_satellites\":" + String(gps_used_satellites) + ",";
json += "\"accuracy\":" + String(gps_accuracy);
json += "},";
json += "\"system\":{";
json += "\"wakeup_reason\":" + String(wakeup_reason) + ",";
json += "\"watchdog_counter\":" + String(watchdog_counter);
json += "}";
json += "}";
json += "}";
return json;
}

View File

@@ -1,16 +1,110 @@
float lux = -1;
float batvoltage = 0.0;
float casetemp = 0.0;
float casehum = 0.0;
float pressure = 0.0;
float pressuresensortemp = 0.0;
float acc1x = 0.0;
float acc1y = 0.0;
float acc1z = 0.0;
float acc2x = 0.0;
float acc2y = 0.0;
float acc2z = 0.0;
#include <Arduino.h>
int32_t wakeupreason = 0;
// Sensor data structure to hold all readings
struct SensorData {
// Timestamp
unsigned long timestamp;
// Light sensor
float lux;
// Battery
float battery_voltage;
// Temperature and humidity
float case_temperature;
float case_humidity;
// Pressure sensor
float pressure;
float pressure_sensor_temp;
// Accelerometers
float acc1_x;
float acc1_y;
float acc1_z;
float acc2_x;
float acc2_y;
float acc2_z;
// System info
int32_t wakeup_reason;
int32_t watchdog_counter;
// GPS data (when available)
float gps_latitude;
float gps_longitude;
float gps_speed;
float gps_altitude;
int gps_visible_satellites;
int gps_used_satellites;
float gps_accuracy;
// Modem information
String modem_id;
float modem_temperature;
String sim_card_id;
String network_name;
String network_id;
// Network connection information
String link_type; // LTE, 2G, 3G, etc.
int signal_quality; // Signal quality (0-31, where 31 is best)
int signal_strength; // Signal strength in dBm
int network_registration_status; // Network registration status
String network_band; // Network band (e.g., "LTE BAND 20")
int network_channel; // Network channel number
String network_operator_code; // Network operator code
// Constructor to initialize all values
SensorData() {
timestamp = 0;
lux = -1;
battery_voltage = 0.0;
case_temperature = 0.0;
case_humidity = 0.0;
pressure = 0.0;
pressure_sensor_temp = 0.0;
acc1_x = 0.0;
acc1_y = 0.0;
acc1_z = 0.0;
acc2_x = 0.0;
acc2_y = 0.0;
acc2_z = 0.0;
wakeup_reason = 0;
watchdog_counter = 0;
gps_latitude = 0.0;
gps_longitude = 0.0;
gps_speed = 0.0;
gps_altitude = 0.0;
gps_visible_satellites = 0;
gps_used_satellites = 0;
gps_accuracy = 0.0;
modem_id = "";
modem_temperature = 0.0;
sim_card_id = "";
network_name = "";
network_id = "";
link_type = "";
signal_quality = 0;
signal_strength = 0;
network_registration_status = 0;
network_band = "";
network_channel = 0;
network_operator_code = "";
}
// Method to check if data is fresh (within last 5 minutes)
bool isFresh() const {
return (millis() - timestamp) < 300000; // 5 minutes
}
// Method to get JSON representation for HTTP transmission
String toJSON() const;
};
volatile int32_t wdcounter = 0;
// Global sensor data instance
extern SensorData sensorData;
// Data collection functions
void collectAllSensorData();

View File

@@ -0,0 +1,154 @@
# ESP Communication Test Guide
## Overview
This implementation establishes serial communication between the nRF52 and ESP microcontroller using:
- **ESP_TXD** (Pin 43): nRF52 TX → ESP RX
- **ESP_RXD** (Pin 42): ESP TX → nRF52 RX
- **ESP_PWR** (Pin 45): Power control for ESP
- **ESP_GPIO0** (Pin 47): ESP boot mode control (not used in this implementation)
## Implementation Details
### Bit-Banging UART at 115200 Baud
- Uses direct pin manipulation for UART communication
- Timing: 8.68 microseconds per bit (1/115200)
- 8N1 format: 8 data bits, no parity, 1 stop bit
- LSB first transmission
### Functions Implemented
1. **`initializeESPSerial()`**
- Powers up ESP microcontroller
- Configures pins for UART communication
- Sets up bit-banging timing
2. **`powerupESP()`**
- Powers up ESP/Modem rail if needed
- Activates ESP power pin
- Handles power rail management
3. **`powerdownESP()`**
- Safely powers down ESP
- Manages power rail state
- Cleans up serial state
4. **`uartSendByte(uint8_t byte)`**
- Sends single byte using bit-banging
- Handles start bit, 8 data bits, stop bit
- Precise timing for 115200 baud
5. **`uartReceiveByte()`**
- Receives single byte using bit-banging
- Waits for start bit, samples in middle
- Returns received byte
6. **`sendCommandToESP(const String& command)`**
- Sends AT command to ESP
- Adds CR+LF termination
- Uses bit-banging for transmission
7. **`readResponseFromESP(String& response, unsigned long timeout)`**
- Reads response from ESP
- Handles timeout
- Detects complete responses (OK/ERROR)
8. **`testESPConnection()`**
- Tests basic ESP communication
- Sends "AT" command
- Verifies "OK" response
9. **`testESPCommunication()`**
- Comprehensive ESP communication test
- Tests power up/down
- Tests multiple AT commands
- Tests WiFi functionality
## Testing Commands
The implementation tests these ESP AT commands:
1. **`AT`** - Basic communication test
2. **`AT+GMR`** - Get firmware version
3. **`AT+CWMODE?`** - Query WiFi mode
4. **`AT+CWLAP`** - Scan for WiFi networks
## Expected Behavior
### Successful Communication
```
|----------------------------------|
| Testing ESP Communication |
|----------------------------------|
Powering up ESP microcontroller...
Powering up ESP/Modem power rail...
ESP powered up successfully
Initializing ESP serial communication...
ESP serial initialized (pins 42/43 at 115200 baud)
ESP serial initialization successful
|----------------------------------|
| Testing ESP Connection |
|----------------------------------|
Sending test command to ESP...
Sending to ESP: AT
Command sent successfully
Reading response from ESP...
Received complete response: [OK]
ESP Response: OK
SUCCESS: ESP communication established!
ESP communication test successful!
Testing additional ESP commands...
Sending to ESP: AT+GMR
Command sent successfully
Reading response from ESP...
ESP Version: [version info]
Sending to ESP: AT+CWMODE?
Command sent successfully
Reading response from ESP...
ESP WiFi Mode: [mode info]
Sending to ESP: AT+CWLAP
Command sent successfully
Reading response from ESP...
ESP WiFi Scan: [network list]
Powering down ESP microcontroller...
ESP powered down successfully
|----------------------------------|
```
### Potential Issues
1. **No Response**
- Check ESP power supply
- Verify pin connections
- Check ESP firmware (should respond to AT commands)
2. **Garbled Data**
- Check baud rate timing
- Verify pin assignments
- Check for electrical interference
3. **Timeout Issues**
- ESP may need more boot time
- Check ESP firmware state
- Verify power rail stability
## Hardware Requirements
- ESP microcontroller (ESP8266/ESP32)
- Proper power supply for ESP
- Correct pin connections
- ESP firmware that responds to AT commands
## Next Steps
1. Compile and upload to nRF52
2. Monitor RTT output for communication status
3. Verify ESP responds to AT commands
4. Test WiFi functionality if needed
5. Integrate with sensor data transmission
## Notes
- Bit-banging is used due to nRF52 UART configuration complexity
- Timing is critical for reliable communication
- Power management ensures proper ESP operation
- Error handling includes timeouts and response validation