Arbeiten mit dem Cayenne Dashboard - Gateway als Access-Point und Netzwerk-Client(Teil 5) - AZ-Delivery

En la Parte 3 , tenemos una Pasarela construida como Cliente en una Red WI-fi funciona. Era necesario, por tanto los datos de Acceso correspondientes Constantes en la Memoria del programa de inmersión. Ya tenemos la puerta de enlace también para ESP-Now desea utilizar, sería conveniente si la puerta de enlace también como Punto de Acceso podría trabajar.

Ahora la ESP32 puede. Si tenemos el WiFi de Moda WIFI_AP_STA tasas funciona el ESP, tanto como Access Point y también como Estación. Sin embargo, sólo un Canal. La Conexión en Routernetzwerk en la selección del Canal de Prioridad. Es decir, el Punto de Acceso utiliza siempre el mismo Canal, como la Conexión en Routernetzwerk.

Ahora, vamos a este Doppelmode utilizar nuestro Gateway a través de un Navegador para configurarlo. La información de Acceso necesaria, como el SSID y la Contraseña, pero los datos de Acceso a Cayenne simplemente en Leerstrings. La puerta de enlace se inicia lo que no puede tener Conexión en Routernetzwerk construir, ya que los datos que faltan. Después de que el Intento de conexión en tiempo de espera se ha ido, el Punto de Acceso con el SSID MQTTGateway se inicia. La Dirección IP de la puerta de enlace es en esta web, siempre 192.168.4.1

Para la puerta de enlace para configurar informar de un Ordenador o un Smartphone, en esta Red (sin Contraseña) e iniciar el Navegador con la Dirección http://192.168.4.1 Debemos entonces la siguiente página de Configuración ver.

Si las Credenciales se almacenan, tratando de puerta de enlace se conecta con el Routernetz de fabricar. Es la conexión se realiza correctamente, la Pantalla muestra la Dirección IP de la puerta de enlace en el Routernetz se puede lograr.

Después de una Conexión con el Routernetz compuesto se obtiene en el Navegador siempre la Lista de Dispositivos registrados. A través de la Ruta de acceso /conf se puede mirar en la página de Configuración para acceder y cambiar los datos de Acceso.

Sketch:

 

/* El MQTT Gateway proporciona una Interfaz entre LoRa Dispositivos o ESP Nowe Dispositivos 
 * y la Cayena MQTT cuadro de Mandos. Se ejecuta en ESP32 con LoRa y Pantalla OLED
 * La Configuración se realiza desde el Navegador
 */
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
#include<Arduino.h>
#include <CayenneMQTTESP32.h>
#include <CayenneLPP.h>
#include <WiFi.h>
#include <Servidor web.h>
#include <time.h>
#include "FS.h"
#include "SPIFFS.h"


//Servidor NTP para sincronizar la hora
#define NTP_SERVER "de.pool.ntp.org"
#define GMT_OFFSET_SEC 3600
#define DAYLIGHT_OFFSET_SEC 0

//pin de la LoRa Chip
#define SS      18
#define RST     14
#define DI0     26
//Frecuencia de la LoRa Chip
#define BANDA    433175000

//
#define MAXCHANNELS 256 //Número máximo de los Canales
#define MAXDEVICE 32 //Número máximo de Dispositivos administrados MAXCHANNELS/MAXDEVICE = 8 da como resultado el Número máximo de Canales por Unidad

//Formato Flash Filesystem si aún no lo ha hecho
#define FORMAT_SPIFFS_IF_FAILED true

#define DEBUG 1

//Bloques de construcción para el Servidor Web
const PROGMEM char HTML_HEADER[] =
"<!DOCTYPE HTML>"
"<html>"
"<head>"
"<meta name = \"ventanilla\" content = \"width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0>\">"
"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">"
"<title>MQTT puerta de enlace</title>"
"<style>"
"body { background-color: #d2f3eb; font-family: Arial, Helvetica, Sans-Serif; Color: #000000;font-size:12pt; }"
"th { background-color: #b6c0db; color: #050ed2;font-weight:lighter;font-size:10pt;}"
"table, th, td {border: 1px solid black;}"
".título {font-size:18 pto;font-weight:bold;text-align:center;} "
"</style>";

const PROGMEM char HTML_HEADER_END[] = 
"</head>"
"<body><div style='margin-left:30px;'>";

const PROGMEM char HTML_SCRIPT[] =
"<script language=\"javascript\">"
"function reload() {"
"document.location=\"http://%s\";}"
"</script>";

const PROGMEM char HTML_END_RELOAD[] =
"</div><script language=\"javascript\">setTimeout(reload, 10000);</script></body>"
"</html>";
const PROGMEM char HTML_END[] =
"</body></html>";
const PROGMEM char HTML_TAB_GERAETE[] =
"<table style=\"width:100%\"><tr><th style=\"width:20%\">ID</th><th style=\"width:10%\">Número</th>"
"<th style=\"width:20%\">Kanäle</th><th style=\"width:20%\">Nombre</th>"
"<th style=\"width:20%\">Letzte Daten</th><th style=\"width:10%\">Acción</th></tr>";
const PROGMEM char HTML_TAB_END[] =
"</table>";
const PROGMEM char HTML_NEWDEVICE[] =
"<div style=\"margin-top:20px;\">%s Nombre: <input type=\"text\" style=\"width:200px\" name=\"devname\" maxlength=\"10\" value=\"\"> <button name=\"registrieren\" value=\"%s\">Registrieren</button></div>";
const PROGMEM char HTML_TAB_ZEILE[] =
"<tr><td>%s</td><td>%i</td><td>%i bis %i</td><td>%s</td><td>%s</td><td><button name=\"delete\" value=\"%i\">Löschen</button></td></tr>";
const PROGMEM char HTML_CONFIG[] = 
"<form method=\"post\"><h1>Zugangsdaten</h1><table>"
"<tr><td>WLAN SSID</td><td><input type=\"text\" name=\"ssid\" value=\"%s\" size=50 maxlen=30/></td></tr>"
"<tr><td>WLAN Contraseña</td><td><input type=\"text\" name=\"pwd\" value=\"%s\" size=50 maxlen=30/></td></tr>"
"<tr><td>Cayenne Benutzername</td><td><input type=\"text\" name=\"mquser\" value=\"%s\" size=50 maxlen=40/></td></tr>"
"<tr><td>Cayenne Contraseña</td><td><input type=\"text\" name=\"mqpwd\" value=\"%s\" size=50 maxlen=50/></td></tr>"
"<tr><td>Cayenne Cliente Id</td><td><input type=\"text\" name=\"mqid\" value=\"%s\" size=50 maxlen=40/></td></tr>"
"<tr><td>&nbsp;</td><td><button name=\"guardar\" value=>Speichern</button></td></tr>"
"</table></form></body></html>";

//Datenstrukturen
//Nachrichten Búfer
struct MSG_BUF {   uint8_t typ;   uint8_t neu;   uint8_t daten[10];
};

//Gerätedefinition
struct DISPOSITIVO {   uint8_t aktiv;   uint8_t dienst; //0=LoRa, 1=ESP-Ahora   uint8_t id[6];   String nombre;   String última;
};

//Globale Variable
//Zugangsdaten diese können über den Servidor Web eingegeben werden
Cadena wlanssid = "Lechner LAN";
Cadena de wlanpwd = "Guadalquivir2711";
Cadena de mqttuser = "";
Cadena mqttpwd = "";
Cadena mqttid = "";

//Webserver Instanz
servidor Web servidor(80);

//Pantalla OLED
SSD1306  pantalla(0x3c, 4, 15);

//Búfer zum Zwischenspeichern der Nachrichten je Kanal
MSG_BUF mensajes[MAXCHANNELS];

//Liste der definierten Geräte
DISPOSITIVO dispositivos[MAXDEVICE];

//Id eines nicht registrierten Gerätes
uint8_t unbekannt[6];
//Bandera immer dann wahr wenn ein neues Gerät entdeckt wurde
booleano neuesGeraet = false;
//Typ des neuen Gerätes 0=LöRa 1 =ESPNow
uint8_t neuesGeraetTyp = 0;

//Zähler und Aktivitaets Estado für das Pantalla
uint32_t loraCnt = 0; //Anzahl der empfangenen LoRa Nachrichten
Cadena loraLast = ""; //Datum und Zeit der letzten empfangenen LoRa que el mensaje
uint32_t nowCnt = 0; //Anzahl der empfangenen ESP Ahora Nachrichten
Cadena nowLast = ""; //Datum und Zeit der letzten empfangenen LoRa que el mensaje
uint32_t cayCnt = 0; //Anzahl der gesendeten MQTT Nachrichten
Cadena cayLast = ""; //Datum und Zeit der letzten gesendeten MQTT que el mensaje


//Funktion liefert Dato und Uhrzeit im Formato aaaa-mm-dd hh:mm:ss ela Cadena
Cadena getLocalTime()
{   char sttime[20] = "";   struct tm timeinfo;   si (WiFi.de estado() == WL_CONNECTED) {     si(!getLocalTime(&timeinfo)){       Serie.println("Error al obtener el tiempo de");       volver sttime;     }     strftime(sttime, sizeof(sttime), "%Y-%m-%d %H:%M:%S", &timeinfo);   }   volver sttime;
}

//Funktion liefert eine 6 Bytes Geräte-Id im formato xx:xx:xx:xx:xx:xx ela Cadena
String getId(uint8_t id de[6])
{   Cadena stid;   char tmp[4];   sprintf(tmp,"%02x",id[0]);   stid=tmp;   para (uint8_t j = 1; j<6; j++) {     sprintf(tmp,":%02x",id[j]);     stid = stid += tmp ;   }   volver stid;
}

//bereitet den Nachrichtenbuffer vor
//setzt alle Nachrichten auf erledigt
vacío initMessageBuffer() {   para (int i = 0;i<MAXCHANNELS;i++) de los mensajes de la[i].neu = 0;
}

//Funktion zum Speichern der Konfiguration
vacío schreibeKonfiguration(const char *fn) {   de Archivo f = SPIFFS.open(fn, FILE_WRITE);   if (!f) {     Serial.println(F("ERROR: SPIFFS Configuración Puede no guardar"));     return;   }   for (uint8_t i = 0; i<MAXDEVICE; i++) {     f.print(devices[i].activo);f.print(",");     f.print(devices[i].servicio);f.print(",");     f.print(getId(devices[i].id));f.print(",");     f.print(devices[i].nombre);f.print(",");     f.println(devices[i].carga);   }
}

//Para Guardar los datos de Acceso
void schreibeZugang(const char *fn) {   File f = SPIFFS.open(fn, FILE_WRITE);   if (!f) {     Serial.println(F("ERROR: SPIFFS Puede Credenciales no guardar"));     return;   }   f.print("WLANSSID=");f.print(wlanssid);f.print('\n');   f.print("WLANPWD=");f.print(wlanpwd);f.print('\n');   f.print("MQTTUSER=");f.print(mqttuser);f.print('\n');   f.print("MQTTPWD=");f.print(mqttpwd);f.print('\n');   f.print("MQTTID=");f.print(mqttid);f.print('\n');    }

;//Función para Registrar un nuevo Dispositivo
void geraetRegistrieren() {   uint8_t i = 0;   //búsqueda libre Entrada   while ((i<MAXDEVICE) && devices[i].activo) i++;   //no hay nueva Entrada en la que no hacemos nada   if (i < MAXDEVICE) {     //de lo contrario Dispositivo registrar Nombre = Nombre introducido      //o desconocido si alguna se ha introducido     if (server.hasArg("devname")) {       devices[i].nombre del = server.arg("devname");     } else {       devices[i].nombre de = "desconocido";     }     for (uint8_t j = 0; j<6; j++) devices[i].id[j]=desconocido[j];     devices[i].activo = 1;     devices[i].servicio= neuesGeraetTyp;     devices[i].carga = "";     schreibeKonfiguration("/configuración.csv");     neuesGeraet = false;   }
}

//La página de Configuración del Servidor Web muestra
void handleConfig(){   char htmlbuf[1024];   boolean restart = false;   int índice;   //la Speicherknopf el botón ?   if (server.hasArg("save")) {     //Datos de la POST request     wlanssid = server.arg("ssid");     //si el SSID contiene un Espacio en blanco, obtenemos un "+"     //el necesario para iniciar la Sesión de nuevo en un Espacio transformado, se     wlanssid.replace("+"," ");     wlanpwd = server.arg("pwd");     mqttuser = server.arg("mquser");     mqttpwd = server.arg("mqpwd");     mqttid = server.arg("mqid");     Serial.println("Nueva Configuración:");     Serial.print("SSID: ");Serial.println(wlanssid);     Serial.print("Contraseña: ");Serial.println(wlanpwd);     Serial.print("Usuario: ");Serial.println(mqttuser);     Serial.print("Contraseña: ");Serial.println(mqttpwd);     Serial.print("ID: ");Serial.println(mqttid);     //La nueva Configuración en SPIFFS guardar     schreibeZugang("/zugang.txt");     //vamos a controlar que la Conexión WiFi se debe reiniciar     //primero, pero el servidor web de la Página de HTML entregar     restart = true;   }   //Salida de la página de Configuración   //hacemos el Puntero a la memoria interna de la Zugangsstrings   //para sprintf y para Iniciar la CONEXIÓN wi-fi y Cayenne enlace   char* txtSSID = const_cast<char*>(wlanssid.c_str());   char* txtPassword = const_cast<char*>(wlanpwd.c_str());      char* txtUser = const_cast<char*>(mqttuser.c_str());   char* txtPwd = const_cast<char*>(mqttpwd.c_str());   char* txtId = const_cast<char*>(mqttid.c_str());   //Actual de la Página de HTML en el Navegador   servidor.setContentLength(CONTENT_LENGTH_UNKNOWN);   //Cabecera   server.send(200, "text/html",HTML_HEADER);   server.sendContent(HTML_HEADER_END);   //El Formulario con los Campos de entrada con los Valores actuales llena   sprintf(htmlbuf,HTML_CONFIG,txtSSID,txtPassword,txtUser,txtPwd,txtId);   //y en el Browsewr enviado   server.sendContent(htmlbuf);   server.sendContent(HTML_END);   if (restart) {     //Era el restart bandera tiene el WiFi desconectado y conectado de nuevo     //construir     Serial.println("Reiniciar");     uint8_t tiempo de espera = 0;     Serial.println("desconectar");     WiFi.disconnect();     while ((WiFi.estado() == WL_CONNECTED) && (tiempo de espera de < 10))     {       retardo(1000);       de tiempo de espera++;     }     Serial.println("Volver a conectar");     WiFi.begin(txtSSID,txtPassword);     while ((WiFi.estado() != WL_CONNECTED) && (tiempo de espera de < 10))     {       retardo(1000);       de tiempo de espera++;     }     Serial.print("IP address: ");     Serial.println(WiFi.localIP());     if (WiFi.estado() == WL_CONNECTED) {       //la Neustrart éxito también se debe a que la Conexión Cayenne que ser reconstruido.       Serial.println("Cayenne conectar");       Cayenne.begin(txtUser, txtPwd, txtId);     //Reloj con un servidor de tiempo para sincronizar     configTime(GMT_OFFSET_SEC, DAYLIGHT_OFFSET_SEC, NTP_SERVER);     //Hora Actual gastar     Serial.println(getLocalTime());     }   }
}

//El reset Página fue solicitada desde el Servidor web
void handleReset() {   //ponemos los datos de Acceso de nuevo    wlanssid= "";    wlanpwd = "";    mqttuser = "";    mqttpwd="";    mqttid="";    //y mostrar los datos de Configuración en    //sólo si en la página de Configuración, el Botón    //Guardar los datos de Acceso     //también en SPIFFS eliminado.    handleConfig();
}

//La Página con la lista de Dispositivos del Servidor web para consultar
void handleWLANRequest(){   char htmlbuf[512];   char tmp1[20];   char tmp2[20];   char tmp3[20];   int índice;   //se ha Borrado Botón ?   if (server.hasArg("delete")) {     index = server.arg("delete").toInt();
#ifdef DEGUG     Serial.printf("Borrar device %i = ",index);     Serial.println(devices[índice].nombre);
#endif     devices[índice].activo=0;     schreibeKonfiguration("/configuración.csv");   }   //se ha de Registrar el Botón ?   if (server.hasArg("registrar")) {     geraetRegistrieren();   }   //Actual de la Página de HTML en el Navegador   servidor.setContentLength(CONTENT_LENGTH_UNKNOWN);   //Cabecera   server.send(200, "text/html",HTML_HEADER);   //Dirección IP de recarga script   WiFi.localIP().toString().toCharArray(tmp1,20);   sprintf(htmlbuf,HTML_SCRIPT,tmp1);   server.sendContent(htmlbuf);   server.sendContent(HTML_HEADER_END);   //Formulario Principio   server.sendContent("<div class=\"nombre\">MQTT puerta de enlace</div><form method=\"post\">");   //Tabla de Dispositivos activos   server.sendContent(HTML_TAB_GERAETE);   for (uint8_t i = 0; i<MAXDEVICE; i++) {      if (devices[i].activo == 1) {        getId(devices[i].id).toCharArray(tmp1,20);       devices[i].nombre.toCharArray(tmp2,20);       devices[i].carga.toCharArray(tmp3,20);       sprintf(htmlbuf,HTML_TAB_ZEILE,tmp1,i,i*8,i*8+7,tmp2,tmp3,i);       servidor.sendContent(htmlbuf);     }   }   server.sendContent(HTML_TAB_END);   //Si se encuentra un nuevo Dispositivo, su ID y un Campo de entrada para el Nombre   // y un Botón para Registrar el nuevo Aparato   if (neuesGeraet) {     getId(desconocido).toCharArray(tmp1,20);     sprintf(htmlbuf,HTML_NEWDEVICE,tmp1,tmp1);     server.sendContent(htmlbuf);   }   server.sendContent(HTML_END_RELOAD);
}

//Servicio de Función de Servidor Web para el Directorio Raíz
void handleRoot() {   if (WiFi.estado() != WL_CONNECTED) {     //si no tiene Conexión a Routernetz tienen     //si la página de Configuración muestra de modo que los datos se pueden introducir     handleConfig();   } else {     handleWLANRequest();   }
}


//Función para Buscar un Dispositivo en la lista de Dispositivos
//Devolución Índice de la Unidad o -1 si no se encuentra
int findDevice(uint8_t dev[6]) {   uint8_t j;   uint8_t i = 0;   boolean found = false;   do {     j = 0;     if (devices[i].activo == 0) {       i++;     } else {       while ((j < 6) && (dev[j] == devices[i].id[j])) {j++;}       found = (j == 6);       if (!found) i++;      }    } while ((i<MAXDEVICE) && (!found));   if (found) {return i;} else {return -1;}
}

//Función para Mostrar el Estado de la Pantalla OLED
void mostrar() {   la pantalla.clear();   display.lazo(0,0,"MQTT puerta de enlace");   pantalla.de cordón(0,10,getLocalTime());   pantalla.cordón(0,20,WiFi.localIP().toString());   de la pantalla.de cordel(0,34,"MQTT: ");   mostrar.el lazo(60,34,de la Cadena de(cayCnt));   pantalla.de cordel(0,44,"LoRa: ");   mostrar.el lazo(60,44,de la Cadena de(loraCnt));   pantalla.de cordel(0,54,"AHORA: ");   mostrar.el lazo(60,54,de la Cadena de(nowCnt));   de visualización.de la pantalla();
}


//Eine que el mensaje von einem LoRa Cliente verarbeiten
vacío readLoRa() {   int devnr;   uint8_t devid[6];   uint8_t canal;   uint8_t typ;   uint8_t len;   uint8_t dat;   booleano de salida;   //Daten holen cae vorhanden   int packetSize = LoRa.parsePacket();   //haben wir Daten erhalten ?   si (packetSize > 5) {
#ifdef DEBUG         Serial.println(getLocalTime());     Serie.de impresión(" RX ");     de Serie.impresión(packetSize);     Serie.println(" Bytes");     de Serie.impresión("Device ID");
#endif      //zuerst morir Geräte-Id lesen     para (uint8_t i=0; i<6;i++){       devid[me]=LoRa.leer();
#ifdef DEBUG       Serial.printf("-%02x",devid[i]);
#endif     }
#ifdef DEBUG     Serial.println();
#endif     //Restpaket berechnen     packetSize -= 6;     //nachschauen ob das Gerät registriert ist     devnr = findDevice(devid);     si (devnr >= 0)  {       //wenn ja setzen wir den Zeitstempel für die letzte Meldung und       //lesen morir Daten       dispositivos[devnr].última = getLocalTime();       schreibeKonfiguration("/konfiguration.csv");       mientras (packetSize > 0) {         //Kanalnummer = Gerätenummer * 16 + Gerätekanal         canal = LoRa.leer() + devnr*16;
#ifdef DEBUG         Serial.printf("Kanal: %02x ",canal);
#endif         //typ des Kanals         typ = LoRa.leer();
#ifdef DEBUG         Serial.printf("Typ: %02x ",typ);
#endif         //ermitteln der Länge des Datenpakets und ob der Kanal ein Aktuator ist         salida = falsa;         interruptor de(tipo) {           caso LPP_DIGITAL_INPUT : len = LPP_DIGITAL_INPUT_SIZE - 2; romper;           caso LPP_DIGITAL_OUTPUT : len = LPP_DIGITAL_OUTPUT_SIZE - 2; salida = verdadero; salto;           caso LPP_ANALOG_INPUT : len = LPP_ANALOG_INPUT_SIZE - 2; romper;           caso LPP_ANALOG_OUTPUT : len = LPP_ANALOG_OUTPUT_SIZE - 2; salida = verdadero; salto;           caso LPP_LUMINOSITY : len = LPP_LUMINOSITY_SIZE - 2; romper;           caso LPP_PRESENCE : len = LPP_PRESENCE_SIZE - 2; romper;           caso LPP_TEMPERATURE : len = LPP_TEMPERATURE_SIZE - 2; romper;           caso LPP_RELATIVE_HUMIDITY : len = LPP_RELATIVE_HUMIDITY_SIZE - 2; romper;           caso LPP_ACCELEROMETER : len = LPP_ACCELEROMETER_SIZE - 2; romper;           caso LPP_BAROMETRIC_PRESSURE : len = LPP_BAROMETRIC_PRESSURE_SIZE - 2; romper;           caso LPP_GYROMETER : len = LPP_GYROMETER_SIZE - 2; romper;           caso LPP_GPS : len = LPP_GPS_SIZE - 2; romper;           defecto: len =  0;         }         //ist der Kanal kein Aktuator, setzen wir im Nachrichtenbuffer neu auf 1         //damit morir Daten bei nächster Gelegenheit un den MQTT Servidor gesendet werden         si (!la salida de) los mensajes de[canal de].neu =1;         mensajes de[canal].tipo = typ;         //Restpaket = 2 weniger da Kanal und Typ gelesen atacados         packetSize -= 2;
#ifdef DEBUG         Serial.de impresión("Daten:");
#endif         //monja lesen wir die empfangenen Daten mit der ermittelten Länge         para (uint8_t i=0; i<len; me++) {           dat = LoRa.leer();           //für Aktuatoren merken wir uns keine Daten           si (! la salida de) los mensajes de[canal de].daten[me] = dat;
#ifdef DEBUG           Serial.printf("-%02x",dat);
#endif           //Restpaket um eins vermindern           packetSize --;         }
#ifdef DEBUG         Serial.println();
#endif       }       //Estado aktualisieren       loraCnt++;       loraLast = getLocalTime();       anzeige();     } else {       //Das Gerät ist nicht registriert        //wir merken uns die Geräte-Id um sie für die Registriuerung anzuzeigen       para (uint8_t i = 0; i<6; i++) unbekannt[me] = devid[me];       neuesGeraet = verdadero;       neuesGeraetTyp = 0; //LoRa Gerät     }     //Teil zwei Antwort un das LoRa Gerät senden     retraso(100);     LoRa.beginPacket();     //am Anfang morir Geräte-Id     LoRa.escribir(devid,6);     // wir prüfen ob wir Salida Daten für das aktuelle LoRa-Gerät haben     int devbase = devnr*16;     para (int i = devbase; me<devbase+8; yo++) {       //je nach typ Digital oder Analogdaten       interruptor de (mensajes[i].typ) {           caso LPP_DIGITAL_OUTPUT : LoRa.escribir(me-devbase);             LoRa.escribir(mensajes[me].typ);             LoRa.escribir(mensajes[me].daten,1);
#ifdef DEBUG             Serial.println("Digital Ausgang");
#endif             romper;           caso LPP_ANALOG_OUTPUT :  LoRa.escribir(me-devbase);             LoRa.escribir(mensajes[me].typ);             LoRa.escribir(mensajes[me].daten,2);
#ifdef DEBUG             Serial.println("Analógico Ausgang");
#endif             romper;       }     }          int lstatus = LoRa.endPacket();
#ifdef DEBUG     Serial.de impresión("Sendestatus = ");     Serie.println(lstatus);
#endif   }
}

//Funktion zum Lesen der Konfiguration
vacío leseKonfiguration(const char *fn) {   uint8_t i = 0;   de la Cadena de tmp;   char hex[3];   si (!SPIFFS.existe(fn)) {     //existiert noch nicht dann erzeugen     schreibeKonfiguration(fn);     de retorno;   }   Archivo f = SPIFFS.abrir(fn, "r");   si (!f) {     Serie.println(F("ERROR:: SPIFFS Kann Konfiguration nicht öffnen"));     de regreso;   }   , mientras que (f.disponible() && (me<MAXDEVICE)) {     tmp = f.readStringUntil(',');     dispositivos[me].aktiv = (tmp == "1");     tmp = f.readStringUntil(',');     dispositivos[me].dienst = tmp.toInt();     tmp = f.readStringUntil(',');     para (uint8_t j=0; j<6; j++){       hex[0]=tmp[j*3];       hex[1]=tmp[j*3+1];       hex[2]=0;       dispositivos[i].id[j]= (byte) strtol(hex,NULL,16);     }     tmp = f.readStringUntil(',');     dispositivos[i].nombre = tmp;     tmp = f.readStringUntil(',');     dispositivos[me].últimos = tmp;     i++;   }    }
//Funktion zum Lesen der Zugangsdaten
vacío leseZugang(const char *fn) {   uint8_t me = 0;   String clave;   de la Cadena de val;   char hex[3];   si (!SPIFFS.existe(fn)) {     //existiert noch nicht dann erzeugen     schreibeZugang(fn);     de retorno;   }   Archivo f = SPIFFS.abrir(fn, "r");   si (!f) {     Serie.println(F("ERROR:: SPIFFS Kann Zugangsdaten nicht öffnen"));     retorno;   }   mientras que (f.disponible() && (me<MAXDEVICE)) {     clave = f.readStringUntil('=');     val = f.readStringUntil('\n');     si (la tecla == "WLANSSID") wlanssid = val;     si (la clave == "WLANPWD") wlanpwd = val;      si (la clave == "MQTTUSER") mqttuser = val;      si (la clave == "MQTTPWD") mqttpwd = val;      si (la clave == "MQTTID") mqttid = val;    }    }

void setup() {   //gerätespeicher initialisieren   para (uint8_t yo =0; me<MAXDEVICE; yo++) dispositivos[me].aktiv = 0;   // Pantalla OLED initialisieren   pinMode(16,SALIDA);   digitalWrite(16, de BAJO);   retardo(50);    digitalWrite(16, ALTA);   de la pantalla.de inicialización();   de la pantalla.flipScreenVertically();   pantalla.setFont(ArialMT_Plain_10);   pantalla.setTextAlignment(TEXT_ALIGN_LEFT);   //Serielle Schnittstelle starten   Serie.de comenzar(115200);   mientras que el (!de Serie);    de Serie.println("Inicio");   //Sistema de Archivos Flash   si (SPIFFS.comenzar(FORMAT_SPIFFS_IF_FAILED)) Serie.println(F("SPIFFS geladen"));   //Konfiguration und Zugangsdaten einlesen   leseKonfiguration("/konfiguration.csv");   leseZugang("/zugang.txt");   initMessageBuffer();   //SPI und LoRa initialisieren   SPI.comenzar(5,19,27,18);   LoRa.setPins(SS,PRIMERA,DI0);   Serie.println("LoRa TRX");   si (!LoRa.comenzar(BANDA)) {     de Serie.println("a Partir de LoRa ha fallado!");     mientras que (1);   }   LoRa.enableCrc();   Serie.println("LoRa Inicial OK!");   retraso(2000);   //Ausgabe der gelesenen Zugangsdaten zur Kontrolle   Serie.de impresión("SSID: ");de Serie.println(wlanssid);   Serie.de impresión("Contraseña: ");de Serie.println(wlanpwd);   Serie.de impresión("Usuario: ");de Serie.println(mqttuser);   Serie.de impresión("Contraseña: ");de Serie.println(mqttpwd);   Serie.de impresión("ID.: ");De serie.println(mqttid);   //Mit dem WLAN und MQTT Servidor verbinden   Serie.println("WLAN verbinden");   //wir benutzen den ESP32 ela Access Poin aber auch als Cliente im Routernetz   WiFi.en modo(WIFI_AP_STA);   //wir benötigen Zeiger auf den Zeichenspeicher innerhalb der Cadenas   char* txtSSID = const_cast<char*>(wlanssid.c_str());   char* txtPassword = const_cast<char*>(wlanpwd.c_str());      char* txtUser = const_cast<char*>(mqttuser.c_str());   char* txtPwd = const_cast<char*>(mqttpwd.c_str());   char* txtId = const_cast<char*>(mqttid.c_str());   WiFi.begin(txtSSID, txtPassword);   //Conexión en Routernetz se establece   uint8_t tiempo de espera = 0;   while ((WiFi.estado() != WL_CONNECTED) && (tiempo de espera<10)) {     tiempo de espera++;     delay(1000);   }   //estamos a la espera de un máximo de 10 Segundos hasta que la Conexión está   //Independientemente de la Conexión en la Routernetz comenzar el Punto de acceso   //permite la Configuración a través de un Navegador, es que si    //en el Punto de acceso para iniciar sesión   WiFi.softAP("MQTTGateway");   if (WiFi.estado() == WL_CONNECTED) {     //Fue la Conexión en Routernetz con éxito, vamos a empezar MQTT a Cayenne     //y sincronizar el Reloj interno con el Time-Servidor     Serial.print("IP address: ");     Serial.println(WiFi.localIP());     Cayenne.begin(txtUser, txtPwd, txtId);     Serial.println("Cayenne Conexión");     //el Reloj con un servidor de tiempo para sincronizar     configTime(GMT_OFFSET_SEC, DAYLIGHT_OFFSET_SEC, NTP_SERVER);     //Hora Actual gastar     Serial.println(getLocalTime());   }   //Web Server inicializar el   servidor.on("/", handleRoot);   server.on("/conf,handleConfig);   server.on("/reset",handleReset);   server.begin();   Serial.println("*********************************************");


}


void loop() {   pantalla();   if (WiFi.estado() == WL_CONNECTED) {     //LoRa Interfaz de Datos para comprobar     readLoRa();     //con Cayena MQTT comunicarse con un Servidor de     Cayena.loop(1);   }   //Web Server usar   el servidor de.handleClient();

}

//Datos de la Nachrichtenbuffer en el MQTT Servidor enviar
CAYENNE_OUT_DEFAULT()
{   boolean salida = false;   boolean sentData = false;
#ifdef DEBUG   Serial.println(getLocalTime());   Serial.println("Cayenne send");
#endif   for (int i = 0; i<MAXCHANNELS; i++) {     //sólo enviar Mensajes nuevos     if (messages[i].nuevo == 1) {
#ifdef DEBUG       Serial.printf("Enviar MQTT Tipo %i\n",messages[i].tipo);
#endif       //dependiendo del Tipo de envío de Datos       conmutador de (mensajes[i].tipo) {           case LPP_DIGITAL_INPUT : Cayenne.digitalSensorWrite(i,messages[i].datos[0]); break;           case LPP_DIGITAL_OUTPUT : salida = true; break;           //case LPP_ANALOG_INPUT : Cayenne.virtualWrite(i), (mensajes[i].datos[0]*256 + mensajes[i].datos[1])/100,"analog_sensor",UNIT_UNDEFINED); break; break;           case LPP_ANALOG_OUTPUT : salida = true; break;           case LPP_LUMINOSITY : Cayenne.luxWrite(i,messages[i].datos[0]*256 + messages[i].datos[1]); break;           case LPP_PRESENCE : Cayenne.digitalSensorWrite(i,messages[i].datos[0]); break;           case LPP_TEMPERATURE : Cayenne.celsiusWrite(i,(messages[i].datos[0]*256 + messages[i].datos[1])/10); break;           case LPP_RELATIVE_HUMIDITY : Cayenne.virtualWrite(i,messages[i].datos[0]/2,TYPE_RELATIVE_HUMIDITY,UNIT_PERCENT); break;           case LPP_ACCELEROMETER : Cayenne.virtualWrite(i,(messages[i].datos[0]*256 + messages[i].datos[1])/1000,"gx","g"); break;           case LPP_BAROMETRIC_PRESSURE : Cayenne.hectoPascalWrite(i,(messages[i].datos[0]*256 + messages[i].datos[1])/10); break;           //case LPP_GYROMETER : len = LPP_GYROMETER_SIZE - 2; break;           //case LPP_GPS : len = LPP_GPS_SIZE - 2; break;       }       if (!salida) {         messages[i].nuevo = 0;         sentData = true;       }            }   }   if (sentData) {     //actualizar el Estado     cayCnt++;     cayLast = getLocalTime();     pantalla();   }

}

CAYENNE_IN_DEFAULT()
{   uint8_t * pData;   int val;   , int ch = request.canal;
#ifdef DEBUG   Serial.println("Cayenne recive");   Serial.printf("MQTT Datos de Canal %i = %s\n",ch,getValue.asString());
#endif   conmutador de (mensajes de[ch].tipo) {       case LPP_DIGITAL_OUTPUT : mensajes de[ch].datos[0] = getValue.asInt();         mensajes de[ch].nuevo = 1;         break;       case LPP_ANALOG_OUTPUT :  val = round(getValue.asDouble()*100);         messages[ch].daten[0] = val / 256;         mensajes de[ch].daten[1] = val % 256;         mensajes de[ch].neu = 1;         romper;   }   CAYENNE_LOG("de Canal %u, el valor %s", solicitud de.canal, getValue.asString());   //mensaje de Proceso aquí. Si hay un conjunto de error un mensaje de error usando getValue.setError(), e.g getValue.setError("mensaje de Error");    }

 

Viel Spaß beim Testen.

Esp-32Projekte für fortgeschrittene

Deja un comentario

Todos los comentarios son moderados antes de ser publicados