sensor_main/source/main.cpp
tobid7 7b79c20b8f # Changes
- Fix Visual glitch in Clear Screen
- Add Long Time Screenshot
- Try fix sd card issue (still not working)
2025-06-12 15:20:40 +02:00

335 lines
8.0 KiB
C++
Executable File

#include <stdio.h>
#include <string.h>
#include "hardware/i2c.h"
extern "C" {
#include "hardware/watchdog.h"
#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
}
#include <bme280.h>
#include <server.h>
#include <font.hpp>
#include <format>
#include <string>
#include <tft.hpp>
// #define MOBILE_WIFI
#include "boot.h"
#include "wifi.hpp"
// FatFS
extern "C" {
#include "f_util.h"
#include "ff.h"
#include "hw_config.h"
}
////////
void BSOD(const char *);
void msg(const char *msg) { printf("[INFO] %s\n", msg); }
void err(const char *msg) {
printf("[ERROR] %s\n", msg);
BSOD(msg);
}
////////// CONFIG //////////
#define I2C_PORT i2c0
#define I2C_SDA 4
#define I2C_SCL 5
constexpr int PinReboot = 13;
constexpr int PinNoWifi = 14;
constexpr int WifiError = 15;
constexpr uint PinCs = 22;
constexpr uint PinDc = 21;
constexpr uint PinRst = 20;
constexpr uint PinSck = 18;
constexpr uint PinSda = 19;
////////////////////////////
TFT tft(PinCs, PinDc, PinRst, PinSck, PinSda);
#define ClearScreen(c) tft.DrawRect(0, 0, 128, 160, c)
void DrawChar(uint8_t x, uint8_t y, char c, uint16_t fg, uint16_t bg) {
if (c < 0 || c > 255) return;
const uint8_t *chr = &font[c * FONT_HEIGHT];
for (uint8_t row = 0; row < FONT_HEIGHT; ++row) {
uint8_t bits = chr[row];
for (uint8_t col = 0; col < FONT_WIDTH; ++col) {
uint16_t color = (bits & (1 << (7 - col))) ? fg : bg;
tft.DrawPixel(x + col, y + row, color);
}
}
}
void DrawText(uint8_t x, uint8_t y, const char *text, uint16_t fg,
uint16_t bg) {
while (*text) {
if (*text == '\n') {
y += FONT_HEIGHT;
x = 1;
*text++;
continue;
} else if (*text == '\0') {
break;
}
if (x + FONT_WIDTH > 127) {
y += FONT_HEIGHT;
x = 1;
}
DrawChar(x, y, *text++, fg, bg);
x += FONT_WIDTH;
}
}
// Blue Screen of Death
void BSOD(const char *what) {
ClearScreen(0xF800);
DrawText(1, 5, "ERROR", 0xffff, 0xf800);
DrawText(1, 7 + FONT_HEIGHT, what, 0xffff, 0xf800);
for (int i = 0; i < 10; i++) {
DrawText(1, 140, "Rebooting in\n10 seconds...", 0xffff, 0xf800);
sleep_ms(1000);
}
watchdog_reboot(0, 0, 0);
}
void ScreenMsg(const char *what, uint16_t fg_col, uint16_t bg_col) {
ClearScreen(bg_col);
DrawText(1, 5 + FONT_HEIGHT, what, fg_col, bg_col);
}
static size_t get_mac_ascii(int idx, size_t chr_off, size_t chr_len,
char *dest_in) {
static const char *hexchr = "0123456789ABCDEF";
uint8_t mac[6];
char *dest = dest_in;
assert(chr_off + chr_len <= (2 * sizeof(mac)));
cyw43_hal_get_mac(idx, mac);
for (; chr_len && (chr_off >> 1) < sizeof(mac); ++chr_off, --chr_len) {
*dest++ = hexchr[mac[chr_off >> 1] >> (4 * (1 - (chr_off & 1))) & 0xf];
}
return dest - dest_in;
}
int init_wifi() {
msg("Init Wifi");
// Initialise the Wi-Fi chip
if (cyw43_arch_init()) {
err("Wi-Fi init failed");
return -1;
}
msg("Enable STA");
cyw43_arch_enable_sta_mode();
msg("Get Hostname / Mac Address");
char hostname[sizeof(CYW43_HOST_NAME) + 4];
memcpy(&hostname[0], CYW43_HOST_NAME, sizeof(CYW43_HOST_NAME) - 1);
get_mac_ascii(CYW43_HAL_MAC_WLAN0, 8, 4,
&hostname[sizeof(CYW43_HOST_NAME) - 1]);
hostname[sizeof(hostname) - 1] = '\0';
netif_set_hostname(&cyw43_state.netif[CYW43_ITF_STA], hostname);
msg("Connect Wifi");
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD,
CYW43_AUTH_WPA2_AES_PSK, 30000)) {
err("Wi-Fi connect failed");
return -1;
}
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
msg("Connected to Wi-Fi!");
return 0;
}
// #define I2C_PORT i2c0
data _list[1000];
int list_index = 0;
int list_count = 0; // Total stored, max 1000
void list_update(float temp, float humidity) {
_list[list_index].t = temp;
_list[list_index].h = humidity;
list_index = (list_index + 1) % 1000;
if (list_count < 1000) {
list_count++;
}
}
void list_average(float *avg_temp, float *avg_humidity) {
if (list_count == 0) {
*avg_temp = 0.0f;
*avg_humidity = 0.0f;
return;
}
float sum_t = 0.0f;
float sum_h = 0.0f;
for (int i = 0; i < list_count; i++) {
sum_t += _list[i].t;
sum_h += _list[i].h;
}
*avg_temp = sum_t / list_count;
*avg_humidity = sum_h / list_count;
}
bme280_ctx *ctx;
int init_fs() {
if (!sd_init_driver()) {
err("SD driver init failed.");
return 1;
}
sd_card_t *sd = sd_get_by_num(0);
if (!sd) {
err("sd_get_by_num returned NULL");
return 1;
}
if (!sd_card_detect(sd)) {
err("SD card detect failed.");
return 1;
}
const char *drive_prefix = sd_get_drive_prefix(sd);
if (!drive_prefix) {
err("sd_get_drive_prefix returned NULL");
return 1;
}
sleep_ms(1000);
FRESULT res = f_mount(&sd->state.fatfs, "0:", 1);
if (res != FR_OK) {
err(std::format("f_mount failed\nerror code: {}", (int)res).c_str());
return 1;
}
FIL fil;
const char *fn = "test.txt";
FRESULT fr = f_open(&fil, fn, FA_OPEN_APPEND | FA_WRITE);
if (fr != FR_OK) {
err("f_open failed");
return 1;
}
if (f_printf(&fil, "Hello World!\n") < 0) {
err("Failed to write to file");
f_close(&fil);
return 1;
}
fr = f_close(&fil);
if (fr != FR_OK) {
err("f_close failed");
return 1;
}
f_unmount(drive_prefix);
return 0;
}
float __a_te = 0.0f;
float __a_hu = 0.0f;
float __temp = 0.f;
float __humidity = 0.f;
int main() {
stdio_init_all();
tft.Init();
ClearScreen(0xffff);
tft.SetWindow(0, 16, 127, 127);
for (int i = 0; i < 16384; i++) {
tft.WriteData16(boot_image[i]);
}
/// NO WIFI CHECK ///
gpio_init(PinNoWifi);
gpio_pull_down(PinNoWifi);
gpio_set_dir(PinNoWifi, GPIO_IN);
gpio_init(PinReboot);
gpio_pull_down(PinReboot);
gpio_set_dir(PinReboot, GPIO_IN);
bool use_wifi = !gpio_get(PinNoWifi);
/////////////////////
if (use_wifi) {
gpio_init(WifiError);
gpio_set_dir(WifiError, GPIO_OUT);
gpio_put(WifiError, 0);
if (init_wifi() != 0) {
gpio_put(WifiError, 1);
return -1;
}
} else {
DrawText(1, 1, "WIFI Disabled...", 0x00ff, 0xffff);
sleep_ms(2000);
}
ClearScreen(0xffff);
// if (init_fs() != 0) {
// err("FS Init Error");
// }
ctx = bme280_init(I2C_PORT, I2C_SDA, I2C_SCL);
if (use_wifi) {
DrawText(1, 150, ip4addr_ntoa(netif_ip4_addr(netif_list)), 0x0000, 0xffff);
} else {
DrawText(1, 150, "WIFI disabled...", 0x00ff, 0xffff);
}
int __i = 0;
while (true) {
__temp = ctx->read_temp(ctx);
__humidity = ctx->read_humidity(ctx);
if (gpio_get(PinReboot)) {
ScreenMsg(
"D7-System:\nReboot initiated!\n\nYou have 3\nseconds to remove\nthe "
"wire!",
0xffff, 0x00df);
sleep_ms(3000);
watchdog_reboot(0, 0, 0);
}
if (use_wifi) {
DrawText(1, 120,
std::format("TCP Errors:\n - {:016X}", __tcp_errors).c_str(),
0x0000, 0xffff);
if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) ==
CYW43_LINK_UP) {
// Space to keep the string the same len
DrawText(1, 140, "Conected: true ", 0x0000, 0xffff);
} else {
DrawText(1, 140, "Conected: false", 0x0000, 0xffff);
}
}
ctx->update(ctx);
list_average(&__a_te, &__a_hu);
std::string text = std::format(
"Temp: {:.1f} C\nHumidity: {:.2f}%\nAVG Temp: {:.1f} C\nAVG Hum: "
"{:.2f}%",
__temp, __humidity, __a_te, __a_hu);
DrawText(1, 1, text.c_str(), 0x0000, 0xffff);
if (__i >= 10) {
list_update(__temp, __humidity);
__i = 0;
}
__i++;
printf("Temperatur=%.2f °C, Luftfeuchtigkeit=%.2f %\n", __temp, __humidity);
if (use_wifi) {
run_http_server();
}
sleep_ms(1000);
}
if (ctx) {
bme280_deinit(ctx);
}
}