Implemented LoRa
This commit is contained in:
parent
6971275630
commit
576b481c13
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -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"
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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>;
|
||||
};
|
||||
};*/
|
||||
};
|
@ -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_
|
@ -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
110
src/lora/lora.c
Normal 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));
|
||||
}
|
23
src/main.c
23
src/main.c
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user