Merge pull request #10 from jonasniesner/jonasniesner-patch-5

Add BLE
This commit is contained in:
Jonas Niesner
2025-06-29 10:45:02 +02:00
committed by GitHub
7 changed files with 1325 additions and 329 deletions

View File

@@ -1,51 +1,75 @@
{
"build": {
"arduino":{
"ldscript": "nrf52_xxaa.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52_DK",
"f_cpu": "64000000L",
"mcu": "nrf52840",
"variant": "nRF52DK",
"zephyr": {
"variant": "nrf52840dk_nrf52840"
}
"build": {
"arduino":{
"ldscript": "nrf52840_s140_v6.ld"
},
"connectivity": [
"bluetooth"
],
"debug": {
"default_tools": [
"jlink"
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
[
"0x239A",
"0x8029"
],
"jlink_device": "nRF52840_xxAA",
"onboard_tools": [
"cmsis-dap",
"jlink"
[
"0x239A",
"0x0029"
],
"svd_path": "nrf52840.svd"
},
"frameworks": [
"arduino",
"mbed",
"zephyr"
],
"name": "HGD6 nRF52840",
"upload": {
"maximum_ram_size": 262144,
"maximum_size": 1048576,
"protocol": "jlink",
"protocols": [
"jlink",
"nrfjprog",
"stlink",
"blackmagic",
"cmsis-dap",
"mbed"
[
"0x239A",
"0x002A"
],
[
"0x239A",
"0x802A"
]
],
"usb_product": "Feather nRF52840 Express",
"mcu": "nrf52840",
"variant": "feather_nrf52840_express",
"bsp": {
"name": "adafruit"
},
"url": "https://unknown.org",
"vendor": "Unknown"
}
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": [
"bluetooth"
],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": [
"arduino",
"zephyr"
],
"name": "Adafruit Feather nRF52840 Express",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink",
"cmsis-dap",
"blackmagic"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.adafruit.com/product/4062",
"vendor": "Adafruit"
}

View File

@@ -14,7 +14,8 @@ lib_deps =
arduino-libraries/ArduinoHttpClient@^0.6.1
bblanchon/ArduinoJson@^6.21.4
build_unflags = -DNRF52 -DUSE_LFXO
build_flags = -DNRF52840_XXAA -DUSE_LFRC
build_flags = -DNRF52840_XXAA -DUSE_LFRC -DNRF52_S140
lib_compat_mode = soft
upload_protocol = jlink
debug_tool = jlink
monitor_port = socket://localhost:19021

View File

@@ -1,45 +1,110 @@
<?php
// Sensor Data Receiver - POST JSON Version
// This script receives sensor data via POST with JSON payload
// This script receives sensor data via POST with JSON payload and returns structured JSON response
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
// Get JSON input
$json_input = file_get_contents('php://input');
$data = json_decode($json_input, true);
// Create response array
// Create compact response array with Unix timestamp
$response = array(
'status' => 'success',
'message' => 'Data received successfully',
'timestamp' => time(),
'received_data' => $data
'ts' => time(),
'processed' => false
);
// Check if JSON was parsed successfully
if ($data === null) {
$response['status'] = 'error';
$response['message'] = 'Invalid JSON data received';
$response['raw_input'] = $json_input;
$response['error'] = 'Invalid JSON';
http_response_code(400);
} else {
// Log the received data to a JSON file
// Parse and expand short field names to longer descriptive names
$processed_data = array();
// Map short field names to longer descriptive names
$field_mapping = array(
// Timestamp and system data
'ts' => 'timestamp',
'wkr' => 'wakeup_reason',
'wdc' => 'watchdog_counter',
// Sensor data
'lx' => 'light_lux',
'bat' => 'battery_voltage',
'tmp' => 'temperature_celsius',
'hum' => 'humidity_percent',
'prs' => 'pressure_hpa',
'pt' => 'pressure_sensor_temperature',
// Accelerometer data
'a1x' => 'accelerometer1_x',
'a1y' => 'accelerometer1_y',
'a1z' => 'accelerometer1_z',
'a2x' => 'accelerometer2_x',
'a2y' => 'accelerometer2_y',
'a2z' => 'accelerometer2_z',
// GPS data
'glt' => 'gps_latitude',
'gln' => 'gps_longitude',
'gsp' => 'gps_speed',
'gal' => 'gps_altitude',
'gsv' => 'gps_visible_satellites',
'gsu' => 'gps_used_satellites',
'gac' => 'gps_accuracy',
// Modem data
'mid' => 'modem_id',
'mt' => 'modem_temperature',
'sid' => 'sim_card_id',
'nn' => 'network_name',
'nid' => 'network_id',
'lt' => 'link_type',
'sq' => 'signal_quality',
'ss' => 'signal_strength',
'nrs' => 'network_registration_status',
'nb' => 'network_band',
'nc' => 'network_channel',
'noc' => 'network_operator_code',
// Scan data
'wifi' => 'wifi_scan_data',
'ble' => 'ble_scan_data'
);
// Process each field in the received data
foreach ($data as $key => $value) {
if (isset($field_mapping[$key])) {
// Use the longer descriptive name
$processed_data[$field_mapping[$key]] = $value;
} else {
// Keep original name if no mapping exists
$processed_data[$key] = $value;
}
}
// Log the processed data to a JSON file (minimal logging)
$log_filename = 'sensor_data_' . date('Y-m-d') . '.json';
$log_entry = array(
'timestamp' => date('Y-m-d H:i:s'),
'data' => $data
'ts' => time(),
'data' => $processed_data
);
// Append to daily log file
file_put_contents($log_filename, json_encode($log_entry, JSON_PRETTY_PRINT) . "\n", FILE_APPEND | LOCK_EX);
file_put_contents($log_filename, json_encode($log_entry) . "\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;
// Update response with minimal info
$response['processed'] = true;
$response['fields'] = count($processed_data);
$response['log'] = $log_filename;
}
// Output response as JSON
echo json_encode($response, JSON_PRETTY_PRINT);
// Output compact response as JSON
echo json_encode($response);
?>

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
#include <RTTStream.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>
#include <bluefruit.h>
#include "ens210.h"
#include "SparkFun_VEML6030_Ambient_Light_Sensor.h"
#include "sensors.h"
@@ -22,9 +23,68 @@ Adafruit_LIS3DH acc2 = Adafruit_LIS3DH(ACCL2_CS);
RTTStream rtt;
TinyGsm modem(SerialAT);
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
BLEDfu bledfu; // OTA DFU service
BLEDis bledis; // device information
BLEUart bleuart; // uart over ble
BLEBas blebas; // battery
// 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;
bool wifi_scan_enabled;
int wifi_scan_max_networks;
bool ble_scan_enabled;
int ble_scan_max_beacons;
unsigned long ble_scan_duration;
bool modem_shutdown_between_loops;
ModemConfig() {
device_name = "Dev 1";
transmission_interval = 30000;
enable_gps = false;
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;
wifi_scan_enabled = true;
wifi_scan_max_networks = 8;
ble_scan_enabled = true;
ble_scan_max_beacons = 9;
ble_scan_duration = 10000;
modem_shutdown_between_loops = false;
}
};
// BLE scanning variables
DynamicJsonDocument bleScanDoc(8000);
JsonArray bleBeacons;
bool bleScanning = false;
unsigned long bleScanStartTime = 0;
int bleBeaconsFound = 0;
void ble_scan_callback(ble_gap_evt_adv_report_t* report);
void scanforbeacons();
bool initializeBLE();
bool espmodemrail = 0;
bool espon = 0;
bool modemon = 0;
@@ -36,13 +96,14 @@ volatile int32_t wdcounter = 0;
unsigned long lastTransmissionTime = 0;
bool modemInitialized = false;
unsigned long lastWaitCheck = 0;
// Power management functions
void wd_handler();
void gpioinit();
void softpwrup();
// Sensor data management functions
void sampleallsensors();
void sensorpwr(bool onoff);
void collectAllSensorData();
@@ -51,10 +112,8 @@ 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 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();
@@ -76,6 +135,8 @@ bool sendSensorDataToServer(const SensorData& data, const ServerConfig& config);
bool sendSensorDataToServer(const SensorData& data);
void testModemAndNetwork();
void manageModemLifecycle();
void shutdownModem();
bool initializeModemIfNeeded();
// Data transmission scheduling
extern unsigned long lastTransmissionTime;
@@ -99,37 +160,6 @@ 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;
@@ -146,13 +176,23 @@ bool initializeESPSerial();
void powerupESP();
void powerdownESP();
bool sendCommandToESP(const String& command);
bool readESPResponseDebug(String& response, unsigned long timeout = 5000);
void testESPCommunication();
bool readESPResponse(String& response, unsigned long timeout = 5000);
void ScanForWiFiNetworks();
// 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();
// WiFi scan data parser
String parseCWLAPData(const String& cwlapResponse);
bool sendLargeJsonData(HttpClient& http, const DynamicJsonDocument& doc, const String& endpoint);
void optimizeScanData(DynamicJsonDocument& doc, size_t maxSize);
// HTTP response parsing functions
bool parseServerResponse(const String& response, JsonDocument& doc);
String readCompleteHttpResponse(HttpClient& http, unsigned long timeout);
// Non-blocking wait functions
bool waitForNextTransmission(unsigned long interval);
void performBackgroundTasks();

View File

@@ -56,6 +56,12 @@ struct SensorData {
int network_channel; // Network channel number
String network_operator_code; // Network operator code
// WiFi scan data
String wifi_scan_data; // JSON string of WiFi scan results
// BLE scan data
String ble_scan_data; // JSON string of BLE beacon scan results
// Constructor to initialize all values
SensorData() {
timestamp = 0;
@@ -92,6 +98,8 @@ struct SensorData {
network_band = "";
network_channel = 0;
network_operator_code = "";
wifi_scan_data = "";
ble_scan_data = "";
}
// Method to check if data is fresh (within last 5 minutes)

View File

@@ -53,6 +53,17 @@ extern "C"
#define PIN_SERIAL_RX MODEM_RXD
#define PIN_SERIAL_TX MODEM_TXD
#define PIN_SERIAL1_RX MODEM_RXD
#define PIN_SERIAL1_TX MODEM_TXD
#define LED_STATE_ON -1
#define LED_BLUE -1
#define HAVE_HWSERIAL2
#define PIN_SERIAL2_RX ESP_RXD
#define PIN_SERIAL2_TX ESP_TXD
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO SPI_MISO
@@ -73,7 +84,7 @@ static const uint8_t SCL = PIN_WIRE_SCL;
#define AL_ADDR 0x29
#define TINY_GSM_MODEM_BG95
#define SerialAT Serial
#define SerialAT Serial1
#ifdef __cplusplus
}