funktioniert.
This commit is contained in:
@@ -32,6 +32,7 @@ add_custom_command(
|
|||||||
|
|
||||||
add_executable(sensor-pico
|
add_executable(sensor-pico
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
src/time_sync.c
|
||||||
src/webserver.c
|
src/webserver.c
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ target_link_libraries(sensor-pico
|
|||||||
pico_lwip
|
pico_lwip
|
||||||
pico_lwip_http
|
pico_lwip_http
|
||||||
pico_lwip_mqtt
|
pico_lwip_mqtt
|
||||||
|
pico_lwip_sntp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Erzeugt .uf2 Datei zum Flashen
|
# Erzeugt .uf2 Datei zum Flashen
|
||||||
|
|||||||
16
lwipopts.h
16
lwipopts.h
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _LWIPOPTS_H
|
#ifndef _LWIPOPTS_H
|
||||||
#define _LWIPOPTS_H
|
#define _LWIPOPTS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define HTTPD_FSDATA_FILE "src/fsdata.c"
|
#define HTTPD_FSDATA_FILE "src/fsdata.c"
|
||||||
|
|
||||||
#define NO_SYS 1
|
#define NO_SYS 1
|
||||||
@@ -31,6 +33,20 @@
|
|||||||
#define PBUF_POOL_SIZE 24
|
#define PBUF_POOL_SIZE 24
|
||||||
#define MEMP_NUM_SYS_TIMEOUT 20
|
#define MEMP_NUM_SYS_TIMEOUT 20
|
||||||
|
|
||||||
|
#define MQTT_OUTPUT_RINGBUF_SIZE 2048
|
||||||
|
|
||||||
|
#define SNTP_SERVER_DNS 1
|
||||||
|
#define SNTP_SERVER_ADDRESS "de.pool.ntp.org"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void sntp_set_system_time_us(uint32_t sec, uint32_t us);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#define SNTP_SET_SYSTEM_TIME_US(sec, us) sntp_set_system_time_us((sec), (us))
|
||||||
|
|
||||||
#define TCP_MSS 1460
|
#define TCP_MSS 1460
|
||||||
#define TCP_WND (8 * TCP_MSS)
|
#define TCP_WND (8 * TCP_MSS)
|
||||||
#define TCP_SND_BUF (8 * TCP_MSS)
|
#define TCP_SND_BUF (8 * TCP_MSS)
|
||||||
|
|||||||
141
src/main.cpp
141
src/main.cpp
@@ -3,12 +3,15 @@
|
|||||||
#include "hardware/i2c.h"
|
#include "hardware/i2c.h"
|
||||||
#include "lwip/apps/httpd.h"
|
#include "lwip/apps/httpd.h"
|
||||||
#include "lwip/apps/mqtt.h"
|
#include "lwip/apps/mqtt.h"
|
||||||
|
#include "lwip/apps/sntp.h"
|
||||||
#include "pico/cyw43_arch.h"
|
#include "pico/cyw43_arch.h"
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static dhcp_server_t dhcp_server{};
|
static dhcp_server_t dhcp_server{};
|
||||||
|
|
||||||
@@ -61,14 +64,14 @@ void mqtt_cb(mqtt_client_t *client, void *arg,
|
|||||||
*mqtt_status = (status == MQTT_CONNECT_ACCEPTED) ? 0 : 1;
|
*mqtt_status = (status == MQTT_CONNECT_ACCEPTED) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int connect_to_mqtt() {
|
mqtt_client_t *connect_to_mqtt() {
|
||||||
static int mqtt_status{-1};
|
static int mqtt_status{-1};
|
||||||
ip_addr_t broker_ip;
|
ip_addr_t broker_ip;
|
||||||
static mqtt_client_t *client{};
|
static mqtt_client_t *client{};
|
||||||
static mqtt_connect_client_info_t info{};
|
static mqtt_connect_client_info_t info{};
|
||||||
|
|
||||||
if (!ipaddr_aton(saved_mqtt_address, &broker_ip)) {
|
if (!ipaddr_aton(saved_mqtt_address, &broker_ip)) {
|
||||||
return -1;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!client) {
|
if (!client) {
|
||||||
client = mqtt_client_new();
|
client = mqtt_client_new();
|
||||||
@@ -84,11 +87,14 @@ int connect_to_mqtt() {
|
|||||||
cyw43_arch_poll();
|
cyw43_arch_poll();
|
||||||
sleep_ms(100);
|
sleep_ms(100);
|
||||||
}
|
}
|
||||||
return mqtt_status;
|
if (mqtt_status == 0) {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BME280_READING_INTERVALS_MS convert_Interval(int interval) {
|
BME280_READING_INTERVALS_MS convert_Interval(int interval) {
|
||||||
if (interval < 1 && interval > 0) {
|
if (interval < 1) {
|
||||||
return INTERVAL_0_5MS;
|
return INTERVAL_0_5MS;
|
||||||
} else if (interval < 20 && interval > 1) {
|
} else if (interval < 20 && interval > 1) {
|
||||||
return INTERVAL_10MS;
|
return INTERVAL_10MS;
|
||||||
@@ -109,12 +115,100 @@ BME280_READING_INTERVALS_MS convert_Interval(int interval) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void publish_cb(void *arg, err_t err) { printf("Publish succesfull!\n"); }
|
||||||
|
|
||||||
|
void publish_mqtt(mqtt_client_t *client, const char *payload) {
|
||||||
|
uint payload_len{strlen(payload)};
|
||||||
|
mqtt_publish(client, "tele/sensor-pico/SENSOR", payload, payload_len, 1, 1,
|
||||||
|
publish_cb, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_json(const char *raw, float &temperature, float &humidity,
|
||||||
|
float &pressure) {
|
||||||
|
if (!raw)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const char *t_ptr = std::strstr(raw, "\"temperature\":");
|
||||||
|
const char *h_ptr = std::strstr(raw, "\"humidity\":");
|
||||||
|
const char *p_ptr = std::strstr(raw, "\"pressure\":");
|
||||||
|
|
||||||
|
if (!t_ptr || !h_ptr || !p_ptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
long t_raw = std::strtol(t_ptr + 14, nullptr, 10);
|
||||||
|
long h_raw = std::strtol(h_ptr + 11, nullptr, 10);
|
||||||
|
long p_raw = std::strtol(p_ptr + 11, nullptr, 10);
|
||||||
|
|
||||||
|
temperature = t_raw / 100.0f;
|
||||||
|
humidity = h_raw / 1024.0f;
|
||||||
|
pressure = p_raw / 25600.0f;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_sensor_payload(char *buffer, size_t size, bme280_handle_t handle,
|
||||||
|
const char *sensor_name) {
|
||||||
|
bme280_read_data(handle);
|
||||||
|
const char *raw = bme280_get_json(handle);
|
||||||
|
|
||||||
|
if (!raw) {
|
||||||
|
snprintf(buffer, size, "{\"error\":\"no data\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float temperature, humidity, pressure;
|
||||||
|
parse_json(raw, temperature, humidity, pressure);
|
||||||
|
|
||||||
|
time_t now;
|
||||||
|
time(&now);
|
||||||
|
struct tm *timeinfo = localtime(&now);
|
||||||
|
|
||||||
|
char time_str[32];
|
||||||
|
strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%S", timeinfo);
|
||||||
|
|
||||||
|
snprintf(buffer, size,
|
||||||
|
"{"
|
||||||
|
"\"Time\":\"%s\","
|
||||||
|
"\"%s\":{"
|
||||||
|
"\"Temperature\":%.2f,"
|
||||||
|
"\"Humidity\":%.2f,"
|
||||||
|
"\"Pressure\":%.2f"
|
||||||
|
"},"
|
||||||
|
"\"TempUnit\":\"C\""
|
||||||
|
"}",
|
||||||
|
time_str, sensor_name, temperature, humidity, pressure);
|
||||||
|
}
|
||||||
|
bool is_time_synced() {
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm *timeinfo = localtime(&now);
|
||||||
|
return timeinfo->tm_year > 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_sntp() {
|
||||||
|
cyw43_arch_lwip_begin();
|
||||||
|
if (sntp_enabled()) {
|
||||||
|
sntp_stop();
|
||||||
|
}
|
||||||
|
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
sntp_setservername(0, "de.pool.ntp.org");
|
||||||
|
#endif
|
||||||
|
sntp_init();
|
||||||
|
cyw43_arch_lwip_end();
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
uint32_t last_publish{};
|
||||||
|
uint32_t last_sntp_retry_ms{};
|
||||||
int mqtt_ret{-1};
|
int mqtt_ret{-1};
|
||||||
int wifi_status{1};
|
int wifi_status{1};
|
||||||
int bme_status{-1};
|
int bme_status{-1};
|
||||||
|
char payload[256];
|
||||||
|
mqtt_client_t *client{};
|
||||||
bme280_handle_t handle{};
|
bme280_handle_t handle{};
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0", 1);
|
||||||
|
tzset();
|
||||||
sleep_ms(3000);
|
sleep_ms(3000);
|
||||||
cyw43_arch_init();
|
cyw43_arch_init();
|
||||||
httpd_init();
|
httpd_init();
|
||||||
@@ -125,30 +219,49 @@ int main() {
|
|||||||
}
|
}
|
||||||
printf("Connected to wifi!\n");
|
printf("Connected to wifi!\n");
|
||||||
printf("IP: %s\n", ip4addr_ntoa(netif_ip4_addr(netif_default)));
|
printf("IP: %s\n", ip4addr_ntoa(netif_ip4_addr(netif_default)));
|
||||||
|
start_sntp();
|
||||||
|
last_sntp_retry_ms = to_ms_since_boot(get_absolute_time());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
while (saved_mqtt_address[0] == '\0') {
|
while (saved_mqtt_address[0] == '\0') {
|
||||||
cyw43_arch_poll();
|
cyw43_arch_poll();
|
||||||
sleep_ms(200);
|
sleep_ms(200);
|
||||||
}
|
}
|
||||||
mqtt_ret = connect_to_mqtt();
|
client = connect_to_mqtt();
|
||||||
if (!mqtt_ret) {
|
if (client == nullptr) {
|
||||||
printf("Connected to mqtt!\n");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
printf("Mqtt Status: %d\n", mqtt_ret);
|
printf("Mqtt Status: %d\n", mqtt_ret);
|
||||||
reset_mqtt_config();
|
reset_mqtt_config();
|
||||||
|
} else {
|
||||||
|
printf("Connected to mqtt!\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bme_status =
|
bme_status =
|
||||||
bme280_init(&handle, 0x76, convert_Interval(saved_measure_frequency));
|
bme280_init(&handle, 0x76, convert_Interval(saved_measure_frequency));
|
||||||
if (!bme_status) {
|
if (!bme_status) {
|
||||||
|
last_publish = to_ms_since_boot(get_absolute_time());
|
||||||
while (true) {
|
while (true) {
|
||||||
bme280_read_data(handle);
|
if ((to_ms_since_boot(get_absolute_time()) - last_publish) >=
|
||||||
printf("Messwerte: %s\n", bme280_get_json(handle));
|
saved_post_frequency * 1000) {
|
||||||
// publish_mqtt();
|
if (is_time_synced()) {
|
||||||
|
build_sensor_payload(payload, sizeof(payload), handle, "BME280");
|
||||||
|
publish_mqtt(client, payload);
|
||||||
|
printf("Payload: %s\n", payload);
|
||||||
|
last_publish = to_ms_since_boot(get_absolute_time());
|
||||||
|
} else {
|
||||||
|
printf("Waiting for SNTP sync (Current year: 1970)...\n");
|
||||||
|
uint32_t now_ms = to_ms_since_boot(get_absolute_time());
|
||||||
|
if (now_ms - last_sntp_retry_ms > 30000) {
|
||||||
|
printf("Retrying SNTP...\n");
|
||||||
|
start_sntp();
|
||||||
|
last_sntp_retry_ms = now_ms;
|
||||||
|
}
|
||||||
|
last_publish = to_ms_since_boot(get_absolute_time()) -
|
||||||
|
(saved_post_frequency * 1000) + 5000;
|
||||||
|
}
|
||||||
|
}
|
||||||
cyw43_arch_poll();
|
cyw43_arch_poll();
|
||||||
sleep_ms(500);
|
sleep_ms(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/time_sync.c
Normal file
10
src/time_sync.c
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
void sntp_set_system_time_us(uint32_t sec, uint32_t us) {
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = (time_t)sec;
|
||||||
|
tv.tv_usec = (suseconds_t)us;
|
||||||
|
settimeofday(&tv, NULL);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user