Implemented LoRa

This commit is contained in:
maroh94 2025-07-21 22:30:41 +02:00
parent 6971275630
commit 576b481c13
8 changed files with 198 additions and 69 deletions

View File

@ -5,6 +5,12 @@
"04_diagonal.h": "c",
"epaper.h": "c",
"font.h": "c",
"oled.h": "c"
"oled.h": "c",
"leds.h": "c",
"constandvars.h": "c",
"kernel.h": "c",
"lora.h": "c",
"spi.h": "c",
"gpio.h": "c"
}
}

View File

@ -6,8 +6,9 @@ FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE
src/main.c
src/lora/encryption.c
src/lora/synch.c
src/oled/oled.c
src/lora/lora.c
#src/lora/synch.c
src/epaper/epaper.c
src/utils/constAndVars.c
src/utils/buttons.c
src/utils/leds.c

View File

@ -6,7 +6,7 @@
* Finale, funktionierende Konfiguration: Wir weichen dem LED-Konflikt
* auf Port B aus, indem wir den sauberen SPI1-Port auf Port A verwenden.
*/
/*
/ {
aliases {
oled = &oled;
@ -35,10 +35,10 @@
cs-gpios = <&gpiob 10 GPIO_ACTIVE_LOW>;
label = "OLED";
};
};
};*/
/*&spi1{
&spi1{
status = "okay";
pinctrl-0 = < &spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7 >;
pinctrl-names = "default";
@ -56,4 +56,4 @@
busy-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
};
};*/
};

View File

View File

@ -1,18 +1,24 @@
#ifndef LORA_H
#define LORA_H
#define DEFAULT_RADIO_NODE DT_ALIAS(lora0)
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/lora.h>
const struct device *lora_dev = DEVICE_DT_GET(DEFAULT_RADIO_NODE);
// Zugriff auf das LoRa-Device
extern const struct device *lora_dev;
struct lora_modem_config config = {
.frequency = 868100000,
.bandwidth = BW_125_KHZ,
.datarate = SF_7,
.preamble_len = 8,
.coding_rate = CR_4_5,
.tx_power = 14,
.tx = false,
};
// Empfangssteuerung
int enable_lora_receive(void);
int disable_lora_receive(void);
void lora_check_fn(struct k_work *work);
#endif
// Buffer-Zugriff
const char *get_last_msg(void);
void clear_msg_buffer(void);
// Optional: Empfangsdauer definieren
extern struct k_work_delayable lora_check_work;
#define ACTIVE_WINDOW_MS 10000
#endif // LORA_H_

View File

@ -167,6 +167,36 @@ void EPD_HW_Init(void) {
Epaper_READBUSY();
}
void initialise(void){
// GPIOs und Geräte-Checks
if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port)) {
printk("Gerät nicht bereit\n");
return;
}
gpio_pin_configure_dt(&epd_cs, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&epd_dc, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&epd_reset, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&epd_busy, GPIO_INPUT);
// Initialisierungssequent für den Chip
EPD_HW_Init();
// 2. Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen
EPD_Clear(); // Erster Clear-Durchgang
EPD_Clear(); // Zweiter Clear-Durchgang
// vor dem Malen den Cursor auf den Anfang (0,0) setzen
EPD_W21_CS_0;
Epaper_Write_Command(0x4E); // Setze X-Adress-Zähler auf 0
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x4F); // Setze Y-Adress-Zähler auf 0
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
EPD_W21_CS_1;
}
void EPD_Update(void) {
Epaper_Write_Command(0x22);
Epaper_Write_Data(0xFF);
@ -243,52 +273,13 @@ void EPD_Clear(void) {
Epaper_READBUSY(); // Warten, bis der Clear-Vorgang abgeschlossen ist
}
void draw_something(char toDraw) {
printk("Starte finalen Display-Test...\n");
// --- GPIOs und Geräte-Checks (wie gehabt) ---
if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port) /*...usw.*/) {
printk("Gerät nicht bereit\n");
return;
}
gpio_pin_configure_dt(&epd_cs, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&epd_dc, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&epd_reset, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&epd_busy, GPIO_INPUT);
// ------------------------------------------------
EPD_HW_Init();
// 2. Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen
printk("🧹 Führe doppelten Clear-Zyklus für Kaltstart durch...\n");
EPD_Clear(); // Erster Clear-Durchgang
EPD_Clear(); // Zweiter Clear-Durchgang
// 3. VOR dem Malen den Cursor auf den Anfang (0,0) setzen
EPD_W21_CS_0;
Epaper_Write_Command(0x4E); // Setze X-Adress-Zähler auf 0
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x4F); // Setze Y-Adress-Zähler auf 0
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
EPD_W21_CS_1;
// 3. Dein gewünschtes Bild vorbereiten (z.B. alles schwarz)
printk("🎨 Erzeuge finales Bild...\n");
// static uint8_t pattern_buffer[ALLSCREEN_GRAGHBYTES];
// memset(pattern_buffer, 0xFF, ALLSCREEN_GRAGHBYTES); // 0x00 = Schwarz
// static uint8_t pattern_buffer[ALLSCREEN_GRAGHBYTES];
// for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
// Wir erzeugen ein Muster aus 0xFF und 0x00
// Das sollte dicke schwarze und weiße Streifen ergeben
// pattern_buffer[i] = ((i / 32) % 2 == 0) ? 0xFF : 0x00;
// }
// 4. Muster in den Display-RAM schreiben
printk("✍️ Schreibe Bild in den Display-RAM...\n");
// Muster in den Display-RAM schreiben
printk("Schreibe Bild in den Display-RAM...\n");
EPD_W21_CS_0;
Epaper_Write_Command(0x24);
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
@ -296,8 +287,8 @@ void draw_something(char toDraw) {
}
EPD_W21_CS_1;
// 5. Physisches Update mit dem finalen Bild
printk("🖼️ Aktualisiere Display...\n");
// Physisches Update
printk("Aktualisiere Display...\n");
EPD_W21_CS_0;
EPD_Update();
EPD_W21_CS_1;

110
src/lora/lora.c Normal file
View File

@ -0,0 +1,110 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/lora.h>
#include <string.h>
#include "lora/lora.h"
#define SLEEP_INTERVAL_MS 120000
const struct device *lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
static struct lora_modem_config config = {
.frequency = 868100000,
.bandwidth = BW_125_KHZ,
.datarate = SF_7,
.preamble_len = 8,
.coding_rate = CR_4_5,
.tx_power = 14,
.tx = false,
};
static char msg_buffer[8] = {0};
void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
int16_t rssi, int8_t snr, void *user_data)
{
if (size > 0 && size < sizeof(msg_buffer)) {
memcpy(msg_buffer, data, size);
msg_buffer[size] = '\0';
printk("📡 Nachricht empfangen (%d Bytes): %s\n", size, msg_buffer);
}
}
int enable_lora_receive(void)
{
// Empfang sicher neu starten
lora_recv_async(lora_dev, NULL, NULL);
int ret = lora_config(lora_dev, &config);
if (ret != 0) {
printk("❌ LoRa-Konfiguration fehlgeschlagen: %d\n", ret);
return ret;
}
ret = lora_recv_async(lora_dev, lora_receive_cb, NULL);
if (ret != 0) {
printk("❌ Empfang konnte nicht aktiviert werden: %d\n", ret);
return ret;
}
printk("📡 LoRa-Empfang aktiviert\n");
return 0;
}
int disable_lora_receive(void)
{
int ret = lora_recv_async(lora_dev, NULL, NULL);
if (ret != 0) {
printk("❌ Empfang konnte nicht deaktiviert werden: %d\n", ret);
return ret;
}
printk("🔕 LoRa-Empfang deaktiviert\n");
return 0;
}
void lora_check_fn(struct k_work *work)
{
printk("🔔 Starte LoRa-Empfang\n");
clear_msg_buffer();
enable_lora_receive();
if (msg_buffer != ""){
printk("Nachricht gelesen!");
disable_lora_receive();
draw_something('4');
}
k_work_schedule(&lora_check_work, K_MSEC(SLEEP_INTERVAL_MS));
/* if (enable_lora_receive() == 0) {
for (int i = 0; i < ACTIVE_WINDOW_MS / 100; i++) {
k_msleep(100);
}
disable_lora_receive();
}
const char *msg = get_last_msg();
if (msg[0] != '\0') {
printk("📨 Neue Nachricht: %s\n", msg);
draw_something(msg[0]);
} else {
printk("📭 Keine Nachricht empfangen\n");
}
k_work_schedule(&lora_check_work, K_MSEC(SLEEP_INTERVAL_MS));*/
}
const char *get_last_msg(void)
{
return msg_buffer;
}
void clear_msg_buffer(void)
{
memset(msg_buffer, 0, sizeof(msg_buffer));
}

View File

@ -2,13 +2,18 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
//#include "epaper/epaper.h"
#include "oled/oled.h"
#include "epaper/epaper.h"
//#include "oled/oled.h"
#include "lora/lora.h"
#include "utils/buttons.h"
#include "utils/leds.h"
#include "utils/constAndVars.h"
struct k_work_delayable lora_check_work;
uint8_t init_led_and_button(void) {
uint8_t ret;
@ -44,6 +49,16 @@ int main(void)
}
}*/
char toDraw = '4';
oled_draw_something(toDraw);
initialise();
lora_recv_async(lora_dev, NULL, NULL); // sicher deaktivieren
k_work_init_delayable(&lora_check_work, lora_check_fn);
k_work_schedule(&lora_check_work, K_NO_WAIT);
// Event Loop (muss da sein für Timer und Arbeiten im Hintergrund)
while (1) {
k_sleep(K_SECONDS(1)); // Energiesparend schlafen
}
return 0;
}