FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: Persuasiv am 28 Juli 2019, 22:07:27

Titel: Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Persuasiv am 28 Juli 2019, 22:07:27
Hallo,

mein Gelände ist weitläufig. Deswegen muss ich Sensordaten über ~100 m verschicken. Eine Glasfaseranbindung der Nebengebäude existiert nicht. Dazu bietet sich LoRa an. Damit können Entfernungen von > 1 km legal überbrückt werden. Mit einer kurzen Drahtantenne sind 100 m inkl. zwei Häuserwänden oder 20 m und drei ca. 30 cm dicke Betondecken realistisch. Laut meiner Simulation gehen unter optimalen Bedingungen auch 35 km @433 MHz.

Grundsätzlich sieht die Idee bei der Umsetzung so aus: Erfassung der Messwerte → Kodieren der Messwerte via Keyvalueprotokoll → Verschicken der Werte → Empfangen der Werte → Übergabe der Messwerte an FHEM → Darstellung der Messwerte

Für den Empfänger nutze ich den leicht abgewandelten Code von Adafruit für den Feather 32u4 LoRa:
#include <SPI.h>
#include <RH_RF95.h>

#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 7
#define LED 13
#define RF95_FREQ 868.0
RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup()
{
  pinMode(LED, OUTPUT);     
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);
  Serial.begin(9600);
  delay(100);
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  while (!rf95.init())
  {
Serial.println("Initialisierung fehlgeschlagen!");
while (1);
  }
  Serial.println("Initialisierung erfolgreich abgeschlossen!");

  if (!rf95.setFrequency(RF95_FREQ))
  {
Serial.println("setFrequency failed");
while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
  rf95.setTxPower(10, false);
}

void loop()
{
  if (rf95.available())
  {
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);

if (rf95.recv(buf, &len))
{
  digitalWrite(LED, LOW);
  Serial.print("OK VALUES ");
  Serial.print((char*)buf);
  Serial.print(",R=");
  Serial.println(rf95.lastRssi(), DEC);
  Serial.println();
}
  }
}


Die Erfassung, die Aufbereitung und der Versand erfolgen dann so (hier wird ein RCWL-0516 ausgewertet):

#include <Adafruit_Sensor.h>
#define LOG_PERIOD 300000

#include <SPI.h>
#include <RH_RF95.h>
#include <Wire.h>                                                                     

#define RFM95_CS 8                                                                   
#define RFM95_RST 4
#define RFM95_INT 7
#define VBATPIN A9
#define RF95_FREQ 868.0                                                             


RH_RF95 rf95(RFM95_CS, RFM95_INT);                                                   


String type = "BW";                                                               
uint8_t SenderID = 1;   
String message = "";                                                                 
unsigned long previousMillis;                         

const int pinradar = 0;                                       

int feindkontakte = 0;
int bewegung = 0;

String Stringkonvertierung0(float Wert) {
  char charBuff[10];
  dtostrf(Wert,2, 0, charBuff);
  return charBuff;
}

void setup()
  {
    pinMode(13, OUTPUT);
    Serial.begin(115200);
    Serial1.begin(115200);
    pinMode(pinradar, INPUT);     
    pinMode(RFM95_RST, OUTPUT);
    digitalWrite(RFM95_RST, HIGH); 
                                                                                   
    delay(100);
                                                                                     
    digitalWrite(RFM95_RST, LOW);                                                     
    delay(10);
    digitalWrite(RFM95_RST, HIGH);
    delay(10);
 
    while (!rf95.init())
{
  Serial.println("Initialisierung fehlgeschlagen!");
  while (1);
}
                                                                                 
    if (!rf95.setFrequency(RF95_FREQ))
{
  Serial.println("Frequenzeinstellung fehlgeschlagen!");
  while (1);
}

    rf95.setTxPower(5, false);                                                           
  }


void loop()
  {
   
    if(digitalRead(pinradar)==LOW)
      {
        digitalWrite(13, LOW);         
      }
   
   
    if(digitalRead(pinradar)==HIGH)
      {
        feindkontakte++;
        bewegung = 1;
        digitalWrite(13, HIGH);
        delay(1000);
      }

 
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > LOG_PERIOD)
    {
        previousMillis = currentMillis;   
       
        message = type+" "+String(SenderID)+" A="+Stringkonvertierung0(bewegung)+",F="+Stringkonvertierung0(feindkontakte);
       
        int messageSize = message.length()+1;
        char radiopacket[messageSize];
        message.toCharArray(radiopacket, messageSize);
           
        rf95.send((uint8_t *)radiopacket, messageSize);
        rf95.waitPacketSent();

        feindkontakte = 0;
        bewegung = 0;
    }
   
}


Die Übergabe der Messwerte erfolgt so:
defmod Empfaenger JeeLink /dev/serial/by-id/usb-Adafruit_Feather_32u4-if00@9600

In Fhem wird direkt ein Nodespezifischer FileLog angelegt. Diesen kann man dann nutzen, um z. B. Plots anfertigen zu können. Die Sensoren werden bei mir zumeist mit vier 18650er Akkus betrieben. Daraus ergibt sich eine Akkulaufzeit von ca. einem Jahr.

Verwendete Hardware:
https://www.adafruit.com/product/3078

Müsste auch gehen (ungetestet):
https://www.ebay.de/itm/2-x-LoRa32u4-II-Development-Board-IOT-LiPo-Atmega328-SX1276-HPD13-868mhz-Antenna/163801909356?hash=item26235ac86c:m:mF6GRPJv6lUBfrKhk6s2aPQ

Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: blueberry63 am 08 August 2019, 16:49:07
Es gibt schon einen Thread zu LoRa:

https://forum.fhem.de/index.php/topic,63856.0.html (https://forum.fhem.de/index.php/topic,63856.0.html)

Ich habe mich noch nicht mit dem Thema beschäftigt, aber vielleicht solltet ihr euch zusammen tun.

Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Persuasiv am 08 August 2019, 21:40:26
Bisher hat niemand eine alternative Lösung gepostet :( Aktuell verzweifel ich an meinem Seismograf. FHEM kommt mit der Datenmenge (1,3 Mrd. Messwerte pro Jahr) nicht klar ...
Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Tobias am 13 August 2019, 08:15:07
super interessant,
du verwendest den Feather sowohl als Sender als auch Empfänger ?
Theoretisch wäre es egal ob man 868 oder 433MHZ verwendet? (natürlich bei Sender und Empfänger identisch)
Wäre eine Batterienutzung auch möglich wenn das Modul permanent aktiviert ist um auf Befehle zu reagieren?
Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Persuasiv am 13 August 2019, 13:50:25
Ich verwende die Feather als Sender und als Empfänger. Die Frequenz spielt schon eine Rolle.


433 MHz868 MHz
Antennenlänge~16,5 cm~8,2 cm
BandISM-Band Region 1SRD-Band Europa
Anzahl Störsenderhochklein
Reichweitehöherhoch

@869,4 MHz sind sogar Sendeleistungen von 500 mW erlaubt. Eine Batterienutzung ist bei permanentem Empfang unmöglich, wenn man einen Feather verwendet. D. h. das hier gezeigte Beispiel eignet sich nur für autonome Sensoren. Man darf auch nicht den Fehler begehen und den deutlich leistungsstärkeren Feather M0 verwenden zu wollen. Es besteht ein Bug in der Sleepydog-Library. Dieser wird auch nicht mehr gefixt. Ich habe den Fehler vor über zwei Jahren gemeldet: https://github.com/adafruit/Adafruit_SleepyDog/issues/13
Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Shojo am 13 August 2019, 13:59:02
Zitat von: Persuasiv am 08 August 2019, 21:40:26
FHEM kommt mit der Datenmenge (1,3 Mrd. Messwerte pro Jahr) nicht klar ...

Sowas würde ich auch in eine InfluxDB oder der gleichen speichern.
Und mit Grafana auswerten.

Hier mal paar Links:
Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Tobias am 13 August 2019, 19:53:03
danke für die Info, was meinst du mit autonome sensoren? Ich habe in deinem Sketch keine explizite (De-)Aktivierung des Sendemoduls wenn der MessageString gesendet werden soll gesehen.
Mein UseCase ist, 1-3mal pro Tag wird eine Message an den LoRaWan BatterieClient gesendet und dieser soll sofort drauf reagieren. Ist aus deiner Sicht eine Batterienutzung möglich?
Titel: Antw:Beliebige Sensoren via LoRa über Entfernugen von > 1 km anbinden
Beitrag von: Persuasiv am 13 August 2019, 21:13:13
Autonome Sensoren erfassen alle x Minuten einen Messwert und schicken diesen zum Server. Dabei wird nicht überprüft, ob der Server die Nachricht erhalten hat. Letzteres macht keinen Sinn, weil Störsender meist zu lange aktiv sind. Dadurch würde die Akkulaufzeit zu stark leiden. Anbei kann man die stark schwankende Signalqualität nachvollziehen. Der Sender + Empfänger wurden dabei zu keinem Zeitpunkt bewegt.

Der obige Node läuft die ganze Zeit am Server und eignet sich nicht für den Akkubetrieb. Dazu muss man die SleepyDog-Library einbinden:

#include "Adafruit_SleepyDog.h"

und den Feather 5 Minuten in den DeepSleep schicken:


  int n = 37;                                                                           //Watchdog sleep max 8 sek je Zyklus
  int i = 1;

  while (i <= n)
    {
      i = i + 1;
      Watchdog.sleep(8000);
    }
  Watchdog.disable();

// mache beliebiges ....

  Watchdog.enable();


ZitatMein UseCase ist, 1-3mal pro Tag wird eine Message an den LoRaWan BatterieClient gesendet und dieser soll sofort drauf reagieren. Ist aus deiner Sicht eine Batterienutzung möglich?

Mit dem Feather auf keinen Fall. Im DeepSleep zieht er ~300 µA. Wenn das Radio aktiv ist, dann sind es ~13 mA. Meine Sensoren brauchen inkl. der Datenübertragung (alle 5 Minuten) im Schnitt ca. 2 mA.