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",
|
"04_diagonal.h": "c",
|
||||||
"epaper.h": "c",
|
"epaper.h": "c",
|
||||||
"font.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
|
target_sources(app PRIVATE
|
||||||
src/main.c
|
src/main.c
|
||||||
src/lora/encryption.c
|
src/lora/encryption.c
|
||||||
src/lora/synch.c
|
src/lora/lora.c
|
||||||
src/oled/oled.c
|
#src/lora/synch.c
|
||||||
|
src/epaper/epaper.c
|
||||||
src/utils/constAndVars.c
|
src/utils/constAndVars.c
|
||||||
src/utils/buttons.c
|
src/utils/buttons.c
|
||||||
src/utils/leds.c
|
src/utils/leds.c
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Finale, funktionierende Konfiguration: Wir weichen dem LED-Konflikt
|
* Finale, funktionierende Konfiguration: Wir weichen dem LED-Konflikt
|
||||||
* auf Port B aus, indem wir den sauberen SPI1-Port auf Port A verwenden.
|
* auf Port B aus, indem wir den sauberen SPI1-Port auf Port A verwenden.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
/ {
|
/ {
|
||||||
aliases {
|
aliases {
|
||||||
oled = &oled;
|
oled = &oled;
|
||||||
@ -35,10 +35,10 @@
|
|||||||
cs-gpios = <&gpiob 10 GPIO_ACTIVE_LOW>;
|
cs-gpios = <&gpiob 10 GPIO_ACTIVE_LOW>;
|
||||||
label = "OLED";
|
label = "OLED";
|
||||||
};
|
};
|
||||||
};
|
};*/
|
||||||
|
|
||||||
|
|
||||||
/*&spi1{
|
&spi1{
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-0 = < &spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7 >;
|
pinctrl-0 = < &spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7 >;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
@ -56,4 +56,4 @@
|
|||||||
busy-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
|
busy-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
|
||||||
cs-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
|
cs-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
|
||||||
};
|
};
|
||||||
};*/
|
};
|
@ -1,18 +1,24 @@
|
|||||||
#ifndef LORA_H
|
#ifndef LORA_H
|
||||||
#define 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 = {
|
// Empfangssteuerung
|
||||||
.frequency = 868100000,
|
int enable_lora_receive(void);
|
||||||
.bandwidth = BW_125_KHZ,
|
int disable_lora_receive(void);
|
||||||
.datarate = SF_7,
|
void lora_check_fn(struct k_work *work);
|
||||||
.preamble_len = 8,
|
|
||||||
.coding_rate = CR_4_5,
|
|
||||||
.tx_power = 14,
|
|
||||||
.tx = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
#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();
|
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) {
|
void EPD_Update(void) {
|
||||||
Epaper_Write_Command(0x22);
|
Epaper_Write_Command(0x22);
|
||||||
Epaper_Write_Data(0xFF);
|
Epaper_Write_Data(0xFF);
|
||||||
@ -243,52 +273,13 @@ void EPD_Clear(void) {
|
|||||||
Epaper_READBUSY(); // Warten, bis der Clear-Vorgang abgeschlossen ist
|
Epaper_READBUSY(); // Warten, bis der Clear-Vorgang abgeschlossen ist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void draw_something(char toDraw) {
|
void draw_something(char toDraw) {
|
||||||
printk("Starte finalen Display-Test...\n");
|
|
||||||
|
|
||||||
// --- GPIOs und Geräte-Checks (wie gehabt) ---
|
// Muster in den Display-RAM schreiben
|
||||||
if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port) /*...usw.*/) {
|
printk("Schreibe Bild in den Display-RAM...\n");
|
||||||
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");
|
|
||||||
EPD_W21_CS_0;
|
EPD_W21_CS_0;
|
||||||
Epaper_Write_Command(0x24);
|
Epaper_Write_Command(0x24);
|
||||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||||
@ -296,8 +287,8 @@ void draw_something(char toDraw) {
|
|||||||
}
|
}
|
||||||
EPD_W21_CS_1;
|
EPD_W21_CS_1;
|
||||||
|
|
||||||
// 5. Physisches Update mit dem finalen Bild
|
// Physisches Update
|
||||||
printk("🖼️ Aktualisiere Display...\n");
|
printk("Aktualisiere Display...\n");
|
||||||
EPD_W21_CS_0;
|
EPD_W21_CS_0;
|
||||||
EPD_Update();
|
EPD_Update();
|
||||||
EPD_W21_CS_1;
|
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/kernel.h>
|
||||||
#include <zephyr/sys/printk.h>
|
#include <zephyr/sys/printk.h>
|
||||||
|
|
||||||
//#include "epaper/epaper.h"
|
#include "epaper/epaper.h"
|
||||||
#include "oled/oled.h"
|
//#include "oled/oled.h"
|
||||||
|
|
||||||
|
#include "lora/lora.h"
|
||||||
|
|
||||||
#include "utils/buttons.h"
|
#include "utils/buttons.h"
|
||||||
#include "utils/leds.h"
|
#include "utils/leds.h"
|
||||||
#include "utils/constAndVars.h"
|
#include "utils/constAndVars.h"
|
||||||
|
|
||||||
|
struct k_work_delayable lora_check_work;
|
||||||
|
|
||||||
|
|
||||||
uint8_t init_led_and_button(void) {
|
uint8_t init_led_and_button(void) {
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
|
|
||||||
@ -44,6 +49,16 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
char toDraw = '4';
|
initialise();
|
||||||
oled_draw_something(toDraw);
|
|
||||||
|
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