Arbeiten mit dem Cayenne Dashboard - LoRa zu MQTT Gateway (Teil 3) - AZ-Delivery

Na een paar mislukte pogingen om een ​​universele LoRa-gateway met de ESP32 te bouwen, werd de volgende eigen gateway gemaakt, waarmee op LoRa gebaseerde IoT-apparaten via MQTT met het Cayenne Dashboard kunnen worden verbonden. In een uitgebreide versie beheert de gateway ook IoT-apparaten op basis van het ESP-Now-protocol.

We hebben er maar één nodig voor de gateway ESP32 met LoRa en OLED-displayverdere componenten zijn niet nodig. De voeding kan worden gedaan met elke USB-voeding.

Functie beschrijving:

De gateway kan 32 apparaten beheren met elk maximaal 8 kanalen. De gegevensoverdracht is asynchroon. Wanneer de gateway een LoRa-gegevenspakket ontvangt, worden de eerste zes bytes geïnterpreteerd als apparaat-ID (meestal het MAC-adres). De gateway controleert vervolgens in een apparatenlijst of dit apparaat al is geregistreerd. Als dit niet het geval is, wordt de apparaat-ID opgeslagen en weergegeven voor registratie via de webinterface.

Als het apparaat al is geregistreerd, worden de gegevens uitgelezen en opgeslagen in een berichtenbuffer voor elk kanaal. Het kanaalnummer wordt bepaald op basis van het apparaatnummer (index in de apparatenlijst) * 8 + kanaalnummer van de ontvangen gegevens. Apparaat 0 heeft dus kanalen 0 tot 7, apparaat 1 heeft kanalen 8 tot 15 etc.

Een gegevensrecord begint met een byte voor het kanaalnummer gevolgd door een byte met het type en vervolgens 1 tot 6 gegevensbytes, afhankelijk van het type. Nadat alle gegevens in de berichtenbuffer zijn opgeslagen en als nieuw zijn gemarkeerd, wordt het responspakket op het Lora-apparaat samengesteld. Het begint opnieuw met de zes bytes apparaat-ID. De kanalen voor dit apparaat worden vervolgens in de berichtenbuffer gecontroleerd om te bepalen of er een uitgaand gegevenspakket van Cayenne naar het apparaat is dat is gemarkeerd met Nieuw. Als een dergelijk datapakket wordt gevonden, wordt het toegevoegd aan het antwoordpakket, waarbij het relatieve kanaalnummer 0 tot 7 opnieuw wordt gebruikt. Als laatste stap wordt het responspakket overgedragen naar het LoRa-apparaat.

De functie Cayenne.loop (1) neemt de communicatie met de IoT-server over. In de callback-functie CAYENNE_OUT_DEFAULT () worden alle kanalen gezocht in de berichtenbuffer die zijn gemarkeerd met Nieuw en die een invoergegevenspakket voor het type Cayenne bevatten. Deze pakketten worden nu geconverteerd, afhankelijk van het type en verzonden naar de IoT-server. Na een succesvolle overdracht wordt de nieuwe vlag gereset.

Een tweede callback-functie CAYENNE_IN_DEFAULT () wordt aangeroepen wanneer er gegevens van Cayenne zijn voor een actiekanaal. De gegevens van de IoT-server worden afhankelijk van het type geconverteerd en opgeslagen in de berichtenbuffer. Ze zijn gemarkeerd met Nieuw zodat ze naar het apparaat worden verzonden de volgende keer dat LoRa communiceert met het antwoordpakket.

Weer te geven:

Naast de naam toont het display de huidige datum en tijd. Daaronder het IP-adres.
De regel MQTT: toont het aantal succesvolle overdrachten naar de IoT-server, LoRa de succesvolle overdrachten naar LoRa-apparaten en NU het aantal succesvolle overdrachten naar ESP-Now-apparaten. De laatste is momenteel altijd 0 omdat deze functie nog niet is geïmplementeerd.

Apparatenlijst en registratie:

De apparatenlijst wordt opgeslagen als een CSV-bestand in het flash-bestandssysteem (SPIFFS) zodat het wordt bewaard, zelfs als er geen voeding is. Deze lijst kan worden bijgehouden via de webserver die in de gateway is geïntegreerd. Apparaten kunnen worden verwijderd en nieuwe apparaten kunnen worden geregistreerd.

Datapakketten:

Voor het type zijn de codes volgens de IPSO Alliance Smart Objects-richtlijnen, maar 3200 wordt afgetrokken.

Type IPSO TypNr. Bytes Ontbinding
Digitale ingang 3200 0 1 1
Digitale uitgang 3201 1 1 1
Analoge ingang 3202 2 2 0,01 met teken
Analoge uitgang 3203 3 2 0,01 met teken
Verlichting sensor 3301 101 2 1 lux
Aanwezigheidssensor 3302 102 1 1
Temperatuur sensor 3303 103 2 0.1°C met het teken van de
luchtvochtigheid Sensor, 3304 104 1 0.5%
de acceleratie Sensor 3313 113 6 0.001 G met het teken
voor elk van de assen X, Y en Z
druk Sensor 3315 115 2 0.1 hPa
Gyrometer 3334 134 6 0.01%/s, met het teken
, afhankelijk van de X-as, Y -, en Z -
GPS-Positie 3336 136 9 breedtegraad in graden 0.0001°
met het teken
lengtegraad 0.0001°
, met het teken
van de hoogte van 0,01 m
met het teken

 

Schets:

De registratie van de gateway in het geval van de Cayenne is op dezelfde manier gedaan als in deel 1 van deze Blog-serie beschreven. De toegang tot de gegevens dienen te worden in de Schets is ingevoerd (gele markering), en de toegang tot gegevens om in te Loggen op het lokale Wi-Fi. De Cayenne Dashboard geeft de Widgets, nog geen apparaat is aangesloten op de Gateway.

Raad voor de Arduino IDE = TTGO LoRa32-OLED-V1

/* * De MQTT Gateway is een Interface tussen de LoRa apparaten of ESP Nowe apparaten 
 * en Cayenne MQTT Dashboards. Het draait op ESP32 met LoRa en OLED-Display
 * De configuratie van de Browser
 */
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
#include<Arduino.h>
#include <CayenneMQTTESP32.h>
#include <CayenneLPP.h>
#include <WiFi.h>
#include <de webserver.h>
#include <tijd.h>
#include "FS.h"
#include "SPIFFS.h"


//De gegevens voor deze instelling krijgen we van de Cayenne Dashboard
#define MQTT_USER ""
#define MQTT_PASSWORD ""
#define MQTT_CLIENTID ""

// toegang tot de gegevens voor de lokale Wi-Fi -
#define WIFI_SSID ""
#define WIFI_PASSWORD ""

//NTP-Server voor tijdsynchronisatie
.#definiëren NTP_SERVER "de.pool.ntp.org"
#define GMT_OFFSET_SEC 3600
#define DAYLIGHT_OFFSET_SEC 0

//Pennen voor de LoRa Chip
#define SS      18
#define EERSTE     14
#define DI0     26
//- Frequentie voor de LoRa Chip
#define BAND -    433175000

//
#define MAXCHANNELS 256 //maximum aantal beheerde kanalen
#define MAXDEVICE 32 //maximum aantal van beheerde apparaten MAXCHANNELS/MAXDEVICE = 8 het maximum aantal kanalen

//Formatteren van het Flash-Bestandssysteem als het nog niet klaar
#define FORMAT_SPIFFS_IF_FAILED true

#define DEBUG 1

//bouwstenen voor de Web-Server,
const char HTML_HEADER[] =
"<!DOCTYPE HTML>"
"<html>"
"<head>"
"<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-schaalbare=0>\">"
"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">"
"<title>MQTT Gateway</title>"
"<script language=\"javascript\">"
"function laden() {"
"document.locatie=\"http://%s\";}"
"</script>"
"<style>"
"body { background-color: #d2f3eb; font-family: Arial, Helvetica, Sans-Serif; Color: #000000;font-size:12pt; }"
"th { background-color: #b6c0db; color: #050ed2;font-weight:lichter;font-size:10pt;}"
"table, th, td {border: 1px solid black;}"
".title {font-size:18pt;font-weight:bold;text-align:center;}"
"</style>"
"</head>"
"<body><div style='margin-left:30 met een afwijkende;'>";
const char HTML_END[] =
"</div><script language=\"javascript\">setTimeout(reload, 10000);</script></body>"
"</html>";
const char HTML_TAB_GERAETE[] =
"<table style=\"width:100%\"><tr><th style=\"width:20%\">ID</th><th style=\"width:10%\">nr.</th>"
"<th style=\"width:20% off\">Kanalen</th><th style=\"width:20%\">Naam</th>"
"<th style=\"width:20%\">laatste</th><th style=\"width:10%\">Action</th></tr>";
const char HTML_TAB_END[] =
"</table>";
const char HTML_NEWDEVICE[] =
"<div style=\"margin-top:20px;\">%s Naam: <input type=\"text\" style=\"width:200px\" name=\"apparaatnaam\" maxlength=\"10\" value=\"\"> <button name=\"aanmelden\" value=\"%s\">Register</button></div>";
const char HTML_TAB_ZEILE[] =
"<tr><td>%s</td><td>%h</td><td>%i %i</td><td>%s</td><td>%s</td><td><button name=\"verwijderen\" value=\"%i\">Verwijderen</button></td></tr>";

//data structuren,
//bericht Buffer
struct MSG_BUF {   uint8_t type,;   uint8_t nieuwe;   uint8_t gegevens[10];
};

//eenheid definitie van
struct APPARAAT, {   uint8_t actieve;   uint8_t service; //0=LoRa, 1=ESP-Nu   uint8_t id[6];   String naam,;   String laden;
};

//Globale Variabele
//de web server
web server server(80);

//OLED Display
SSD1306  display(0x3c, 4, 15);

//Buffer voor het opslaan van de berichten voor elk kanaal
MSG_BUF berichten[MAXCHANNELS];

//lijst van gedefinieerde apparaten,
APPARAAT, apparaten[MAXDEVICE];

//Id van een niet-geregistreerd apparaat,
uint8_t onbekend[6];
//Vlag is altijd het geval wanneer een nieuw apparaat werd ontdekt
boolean nieuwe eenheid = false;
//het type van het nieuwe apparaat, 0=LöRa 1 =ESPNow
uint8_t neuesGeraetTyp = 0;

//tellers en Activiteit de Status van het Display
uint32_t loraCnt = 0; //aantal ontvangen LoRa bericht
String loraLast = ""; //datum en tijd van de laatste ontvangen LoRa bericht
uint32_t nowCnt = 0; //aantal ontvangen ESP Nu bericht
String nowLast = ""; //datum en tijd van de laatste ontvangen LoRa bericht
uint32_t cayCnt = 0; //aantal verzonden MQTT berichten
String cayLast = ""; //datum en tijd van de laatste verzonden MQTT bericht


//Functie geeft de datum en de tijd in de Notatie jjjj-mm-dd hh:mm:ss-als een Tekenreeks
Tekenreeks getLocalTime()
{   char sttime[20] = "";   struct tm tijd info;   als(!getLocalTime(&tijd info)){     Seriële.println("Failed to verkrijgen tijd");     terug sttime;   }   strftime(sttime, sizeof(sttime), "%Y-%m-%d %H:%M:%S", &tijd info);   terug sttime;
}

//functie geeft als resultaat een 6-Byte apparaat-Id in de notatie xx:xx:xx:xx:xx:xx als String
String getId(uint8_t id[6])
{   String stid;   char tmp[4];   sprintf(tmp,,"%02x",id[0]);   stid=tmp;   voor (uint8_t j = 1; j<6; j++) {     sprintf(tmp,":%02x",, id[j]);     stid = stid += tmp ;   }   terug stid;
}

//stelt het bericht buffer vóór
//zet alle berichten voltooid
void init bericht buffer() {   voor (int i = 0;i<MAXCHANNELS;ik++) berichten die[ik].her - = 0;
}

//functie om de configuratie op te Slaan
void schrijf configuratie(const char *fn -) {   Bestand f = SPIFFS.open(fn,, FILE_WRITE);   als (!f) {     Seriële.println(F("FOUT: SPIFFS Kan de configuratie niet opslaan"));     return;   }   voor (uint8_t ik, = 0; ik<MAXDEVICE; i++) {     f.afdrukken(apparaten[ik].actief);f.print(",");     f.afdrukken(apparaten[ik].de service);f -.print(",");     f.print(getId(apparaten[i].id));f.print(",");     f.afdrukken(apparaten[ik].de naam);f.print(",");     f.println(apparaten[ik].laad);   }
}

//Functie voor het Registreren van een nieuw apparaat
ongeldig apparaat registreren() {   uint8_t ik = 0;   //het vinden van een gratis vermelding   terwijl ((ik<MAXDEVICE) && apparaten[ik].actief) i++;   //er is geen nieuwe inschrijving doen we niets   als (ik < MAXDEVICE) {     //anders wordt de eenheid registreren Naam = Naam ingevoerd      //of onbekend of er niemand was ingevoerd     als (de server.hasArg("apparaatnaam")) {       apparaten[i].- naam van de = server -.arg("apparaatnaam");     } anders {       apparaten die[ik].de naam = "onbekend";     }     voor (uint8_t j = 0; j<6; j++) apparaten[i].- id[j]=onbekende[j];     - apparaten[ik].actief = 1;     apparaten[ik].service= neuesGeraetTyp;     apparaten[ik].belasting = "";     schrijven configuratie("/de configuratie.csv");     nieuwe eenheid = false;   }
}

//Dienst functie van de Web server
void handvat wortel,() {   char htmlbuf[1024];   char tmp1[20];   char tmp2[20];   char tmp3[20];   int index,;   //is de delete-knop is geklikt ?   als (de server.hasArg("verwijderen")) {     index = server -.arg("verwijderen").toInt();
#ifdef DEGUG     Seriële.printf("apparaat Wissen %i = ",index van);     Seriële.println(apparaten[index].naam);
#endif     apparaten[index].actieve=0;     schrijven configuratie("/de configuratie.csv");   }   //de 'Register' knop wordt geklikt ?   als (de server.hasArg("registreren")) {     eenheid registreren();   }   //Huidige HTML-pagina naar de Browser verzenden naar de   server.setContent lengte(CONTENT_LENGTH_UNKNOWN);   //Header   WiFi.localIP().toString().toCharArray(tmp1,20);   sprintf(htmlbuf,HTML_HEADER,tmp1);   server te.sturen(200, "text/html",htmlbuf);   //vorm van het begin van   de server.sendContent("<div class=\"titel\">MQTT - Gateway</div><form>");   //Tabel van actieve apparaten   server.sendContent(HTML_TAB_GERAETE);   voor (uint8_t ik, = 0; ik<MAXDEVICE; ik++) {      als (apparaten[ik].actief == 1) {        getId(apparaten[i].- id).toCharArray(tmp1,20);       apparaten[ik].de naam.toCharArray(tmp2,20);       apparaten[ik].belasting.toCharArray(tmp3,20);       sprintf(htmlbuf,HTML_TAB_ZEILE,tmp1,ik,ik*8,ik*8+7,tmp2,tmp3,ik);       server.sendContent(htmlbuf);     }   }   server.sendContent(HTML_TAB_END);   //Als er een nieuw apparaat is gevonden zijn ID en een invoerveld voor de naam   // en een knop voor het Registreren van de nieuwe eenheid   als (een nieuwe eenheid) {     getId(onbekend).toCharArray(tmp1,20);     sprintf(htmlbuf,HTML_NEWDEVICE,tmp1,tmp1);     server.sendContent(htmlbuf);   }   server.sendContent(HTML_END);
}

//functie om te Zoeken naar een apparaat in de lijst
//de Terugkeer van de Index van het apparaat of -1 als deze niet gevonden
int vinden apparaat(uint8_t dev,[6]) {   uint8_t j,;   uint8_t ik, = 0;   boolean gevonden = op false;   doen {     j = 0;     als (apparaten[ik].actief == 0) {       ik++;     } anders {       terwijl ((j < 6) && (dev[j] == apparaten[i].- id[j])) {j++;}       gevonden = (j == 6);       als (!vond) ik++;      }    } terwijl ((ik<MAXDEVICE) && (!gevonden));   als (gevonden) {terug ik;} anders {terug -1;}
}

//Functie om de Status op het OLED-Display
void display() {   display.duidelijk();   display.koord(0,0,"MQTT Gateway");   display.koord(0,10,getLocalTime());   display.koord(0,20,WiFi.localIP().toString());   display.koord(0,34,"MQTT: ");   display.koord(60,34,String(cayCnt));   display.koord(0,44,"LoRa: ");   display.koord(60,44,String(loraCnt));   display.koord(0,54,"NU: ");   display.koord(60,54,String(nowCnt));   display.display();
}


//een bericht afkomstig is van Een LoRa Client proces
nietig readLoRa() {   int typen devnr;   uint8_t devid,[6];   uint8_t kanaal,;   uint8_t type,;   uint8_t len,;   uint8_t dat;   boolean - uitgang;   //ophalen van gegevens als het bestaat   int packetSize = LoRa.parsePacket();   //we hebben ontvangen van gegevens ?   als (packet-grootte > 5) {
#ifdef DEBUG         Serial.. println(getLocalTime());     Serieel.afdrukken(" RX ");     Serieel.afdrukken(packet grootte);     van de Seriële.println(" Bytes");     Serieel.afdrukken("Device ID");
#endif      //stel eerst de apparaat-Id om te lezen     voor (uint8_t ik,=0; ik,<6;ik,++){       devid[ik]=LoRa.read();
#ifdef DEBUG       Seriële.printf("-%02x",devid[ik,]);
#endif     }
#ifdef DEBUG     Serial.. println();
#endif     //rest van het pakket voor het berekenen van     de pakket grootte -= 6;     //controleer of het apparaat is geregistreerd, wordt     het typen van devnr = vinden apparaat(devid);     als (typen devnr >= 0)  {       //indien Ja, we instellen van de tijd-stempel voor het laatste bericht en       /lees/de gegevens       apparaten[typen devnr].laden = getLocalTime();       schrijven configuratie("/de configuratie.csv");       terwijl (pakket grootte > 0) {         //kanaal nummer = nummer van het apparaat * 16 + apparaat, kanaal         kanaal, = LoRa.lees() + typen devnr*16;
#ifdef DEBUG         Seriële.printf("kanaal: %02x ",, kanaal);
#endif         //type van het kanaal         type = LoRa.read();
#ifdef DEBUG         Seriële.printf("typt u: %02x ",type);
#endif         //bepalen van de lengte van het data pakket en als het kanaal is een actuator         output = false,;         switch(type) {           case LPP_DIGITAL_INPUT : len = LPP_DIGITAL_INPUT_SIZE - 2; breken;           geval LPP_DIGITAL_OUTPUT : len = LPP_DIGITAL_OUTPUT_SIZE - 2; uitgang = waar; breken;           geval LPP_ANALOG_INPUT : len = LPP_ANALOG_INPUT_SIZE - 2; breken;           geval LPP_ANALOG_OUTPUT : len = LPP_ANALOG_OUTPUT_SIZE - 2; uitgang = waar; breken;           geval LPP_LUMINOSITY : len = LPP_LUMINOSITY_SIZE - 2; breken;           geval LPP_PRESENCE : len = LPP_PRESENCE_SIZE - 2; breken;           geval LPP_TEMPERATURE : len = LPP_TEMPERATURE_SIZE - 2; breken;           geval LPP_RELATIVE_HUMIDITY : len = LPP_RELATIVE_HUMIDITY_SIZE - 2; breken;           geval LPP_ACCELEROMETER : len = LPP_ACCELEROMETER_SIZE - 2; breken;           geval LPP_BAROMETRIC_PRESSURE : len = LPP_BAROMETRIC_PRESSURE_SIZE - 2; breken;           geval LPP_GYROMETER : len = LPP_GYROMETER_SIZE - 2; breken;           geval LPP_GPS : len = LPP_GPS_SIZE - 2; breken;           standaard: len =  0;         }         // ist der Kanal kein Aktuator, setzen wir im Nachrichtenbuffer neu auf 1         // damit die Daten bei nächster Gelegenheit an den MQTT Server gesendet werden         als (!uitgang) berichten[kanaal].neu =1;         berichten[kanaal].typ = typ;         // Restpaket = 2 weniger da Kanal und Typ gelesen wurden         pakketgrootte -= 2;
#ifdef DEBUG         Serie.afdrukken("Daten:");
#stop als         // non lesen wir die empfangenen Daten mit der ermittelten Länge         voor (uint8_t ik=0; ik<len; ik++) {           dat = LoRa.lezen();           // für Aktuatoren merken wir uns keine Daten           als (! uitgang) berichten[kanaal].daten[ik] = dat;
#ifdef DEBUG           Serie.printf("-% 02x",dat);
#stop als           // Restpaket um eins vermeldn           pakketgrootte --;         }
#ifdef DEBUG         Serie.println();
#stop als       }       // Status aktualisieren       loraCnt++;       loraLast = getLocalTime();       anzeige();     } anders {       // Das Gerät ist nicht registriert        // wir merken uns die Geräte-Id um sie für die Registriuerung anzuzeigen       voor (uint8_t ik = 0; ik<6; ik++) onbetekenend[ik] = devid[ik];       neuesGeraet = waar;       neuesGeraetTyp = 0; // LoRa Gerät     }     // Teil zwei Antwort an das LoRa Gerät senden     vertraging(100);     LoRa.beginPakket();     // ben Anfang die Geräte-Id     LoRa.schrijven(devid,6);     // wir prüfen ob wir Output Daten für das aktuelle LoRa-Gerät haben     int devbase = devnr*16;     voor (int ik = devbase; ik<devbase+8; ik++) {       // je nach typ Digital oder Analogdaten       schakelaar (berichten[ik].typ) {           geval LPP_DIGITAL_OUTPUT : LoRa.schrijven(ik-devbase);             LoRa.schrijven(berichten[ik].typ);             LoRa.schrijven(berichten[ik].daten,1);
#ifdef DEBUG             Serie.println("Digital Ausgang");
#stop als             breken;           geval LPP_ANALOG_OUTPUT :  LoRa.schrijven(ik-devbase);             LoRa.schrijven(berichten[ik].typ);             LoRa.schrijven(berichten[ik].daten,2);
#ifdef DEBUG             Serie.println("Analoge Ausgang");
#stop als             breken;       }     }          int lstatus = LoRa.endPacket();
#ifdef DEBUG     Serie.afdrukken("Sendestatus =");     Serie.println(lstatus);
#stop als   }
}

// Funktion zum lesen der Konfiguration
nietig configuratie configuratie(const char *fn) {   uint8_t ik = 0;   Draad tmp;   char hex[3];   als (!SPIFFS.bestaat(fn)) {     // existiert noch nicht dann erzeugen     schreibe Configuratie(fn);     terug;   }   het dossier f = SPIFFS.Open(fn, "r");   als (!f) {     Serie.println(F("FOUT :: SPIFFS Kann Konfiguration nicht öffnen"));     terug;   }   terwijl (f.beschikbaar() && (ik<MAXDEVICE)) {     tmp = f.readStringUntil(',');     apparaten[ik].aktiv = (tmp == "1");     tmp = f.readStringUntil(',');     apparaten[ik].dienst = tmp.toInt();     tmp = f.readStringUntil(',');     voor (uint8_t j=0; j<6; j++){       hex[0]=tmp[j*3];       hex[1]=tmp[j*3+1];       hex[2]=0;       apparaten[ik].ID kaart[j]= (byte) strtol(hex,NUL,16);     }     tmp = f.readStringUntil(',');     apparaten[ik].naam = tmp;     tmp = f.readStringUntil(',');     apparaten[ik].laatste = tmp;     ik++;   }    }

nietig opstelling() {   // gerätespeicher initialisieren   voor (uint8_t ik =0; ik<MAXDEVICE; ik++) apparaten[ik].aktiv = 0;   // OLED Display initialisieren   pinMode(16,UITGANG);   digitalWrite(16, LAAG);   vertraging(50);    digitalWrite(16, HIGH);   Scherm.in het();   Scherm.flipScreenVertically();   Scherm.setFont(ArialMT_Plain_10);   Scherm.setText lijn ment(TEXT_ALIGN_LEFT);   //Seriële interface start   Seriële.beginnen(115200);   terwijl (!Seriële);    Seriële.println("Start",);   //Flash-Bestand syastem   als (SPIFFS.beginnen(FORMAT_SPIFFS_IF_FAILED)) Seriële.println(F("SPIFFS loaded"));   //Lees configuratie   lees configuratie("/de configuratie.csv");     init bericht buffer();   //SPI en LoRa initialiseren   SPI.beginnen(5,19,27,18);   LoRa.setPins(SS,EERSTE,DI0);   Seriële.println("LoRa TRX");   als (!LoRa.beginnen(BAND)) {     Seriële.println("Starten van LoRa is mislukt!");     terwijl (1);   }   LoRa.enableCrc();   Seriële.println("LoRa Eerste OK!");   vertraging(2000);   //Met de Wi-Fi-en MQTT connect to Server   Serial.. println("Wi-Fi");   Cayenne.beginnen(MQTT_USER, MQTT_PASSWORD, MQTT_CLIENTID, WIFI_SSID, WIFI_PASSWORD);   Serieel.afdrukken("IP-adres: ");   Seriële.println(WiFi.localIP());   //Web-Server initialiseren   server.op("/", handvat root);   server.starten();   //klok met tijd-server synchroniseren   config tijd(GMT_OFFSET_SEC, DAYLIGHT_OFFSET_SEC, NTP_SERVER);   //de Stroom van de tijd-uitgang   Seriële.println(getLocalTime());


}


void loop() {   display();   //LoRa Interface te controleren gegevens   readLoRa();   //met Cayenne MQTT Server, en communiceren   Cayenne.lus(1);   //de Web Server, gebruik   de server.het afhandelen van de client();

}

//Gegevens van het bericht buffer om de MQTT Server te sturen
CAYENNE_OUT_DEFAULT()
{   boolean - uitgang = op false;   boolean sentData = , false;
#ifdef DEBUG   Serial.. println(getLocalTime());   Seriële.println("Cayenne verzenden");
#endif   voor (int i = 0; i<MAXCHANNELS; ik++) {     //alleen nieuwe berichten meer verzenden     als (berichten die[ik].her - == 1) {
#ifdef DEBUG       Seriële.printf("Verzenden MQTT typt u %i\n",,berichten[ik].typ);
#endif       //afhankelijk van het type gegevens om te verzenden       wisselen (berichten[ik].typ) {           geval LPP_DIGITAL_INPUT : Cayenne.digitale sensor schrijf(ik,berichten[heb ik].gegevens[0]); breken;           geval LPP_DIGITAL_OUTPUT : output = true; breken;           //geval LPP_ANALOG_INPUT : Cayenne.virtuele schrijven(ik,(berichten[i].data[0]*256 + berichten[i].data[1])/100,"analog_sensor",UNIT_UNDEFINED); break; break;           geval LPP_ANALOG_OUTPUT : output = true; breken;           geval LPP_LUMINOSITY : Cayenne.luxWrite(ik,berichten[heb ik].de gegevens[0]*256 + van berichten[ik].gegevens[1]); breken;           geval LPP_PRESENCE : Cayenne.digitale sensor schrijf(ik,berichten[heb ik].gegevens[0]); breken;           geval LPP_TEMPERATURE : Cayenne.Celsius schrijf(ik,(berichten[heb ik].de gegevens[0]*256 + van berichten[ik].gegevens[1])/10); breken;           geval LPP_RELATIVE_HUMIDITY : Cayenne.virtuele schrijf(ik,berichten[heb ik].gegevens[0]/2,TYPE_RELATIVE_HUMIDITY,UNIT_PERCENT); breken;           geval LPP_ACCELEROMETER : Cayenne.virtuele schrijf(ik,(berichten[heb ik].de gegevens[0]*256 + van berichten[ik].gegevens[1])/1000,"gx","g"); break;           geval LPP_BAROMETRIC_PRESSURE : Cayenne.hectopascal schrijf(ik,(berichten[heb ik].de gegevens[0]*256 + van berichten[ik].gegevens[1])/10); breken;           //geval LPP_GYROMETER : len = LPP_GYROMETER_SIZE - 2; break;           //geval LPP_GPS : len = LPP_GPS_SIZE - 2; break;       }       als (!output) {         berichten[ik].opnieuw = 0;         sentData = ware;       }            }   }   als (sentData) {     //bijwerken Status     cayCnt++;     cayLast = getLocalTime();     display();   }

}

CAYENNE_IN_DEFAULT()
{   uint8_t * pData;   , int val;   , int ch, = aanvraag.kanaal;
#ifdef DEBUG   Serial.. println("Cayenne recive");   Seriële.printf("MQTT data voor kanaal %i = %d\n",,ch,getValue.asString());
#endif   schakelaar (berichten[ch].type) {       case LPP_DIGITAL_OUTPUT : berichten,[ch].gegevens[0] = getValue.asInt();         berichten[ch].nieuwe = 1;         breken;       geval LPP_ANALOG_OUTPUT :  val = ronde(getValue.asDouble()*100);         berichten,[ch].data -[0] = val / 256;         berichten[ch].data -[1] = val % 256;         berichten[ch].nieuw = 1;         - einde;   }    }

 

 

DisplaysEsp-32Projekte für fortgeschrittene

3 Reacties

moi

moi

für was genau ist der cayenne server zuständig?

kann ich auch einfach eine lokale ip eines mqtt servers eingeben und die pakete werden an diesen weiter geleitet?

Gerald Lechner

Gerald Lechner

Hallo Marco
Ja du brauchst dafür einen zweiter ESP32 mit LoRa und im nächsten Teil folgt der notwendige Code.
Gruß Gerald

Marco

Marco

Hallo,
toller Artikel der Lust aufs Ausprobieren macht. Noch eine Frage. Ihr beschreibt hier das Gateway. Das “spricht” auf der einen Seite LoRa und auf der anderen Seite (via WLan) mit einem Netzwerk.
Ich bräuchte dann für die Kommunikation mittels LoRa dann noch einen zweiten ESP als Client, richtig? Könnt Ihr darüber vielleicht einen 4. Teil machen und erklären wie man dann damit ein Ende-Ende Szenario aufbaut?

Viele Grüße
Marco

Laat een reactie achter

Alle opmerkingen worden voor publicatie gecontroleerd door een moderator

Aanbevolen blogberichten

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery