Hi
Gibt es eigentlich eine Möglichkeit, eine Serielle Schnittstelle über den WLan zu übertragen und dann wieder in eine Serielle Schnittstelle zurück ? Also
Seriell1 -- esp-Link1 -- WLan -- esp-Link2 -- Seriell2
Hintergrund :
Ich möchte meine Smartmeter-Erfassung von Innogy weghaben und die Erfassung über Openhab machen. Das Binding benötigt dafür aber eine "Richtige" Serielle Schnittstelle. Da mein Zählerkasten im Keller ist und der Rasberry fürs Openhab im Dachgescoss, ist der Weg für eine Kabelverbindung zu weit und zu aufwändig. Mit dem esp-Link habe ich gute Erfahrung gemacht ( Benutze ich für den eBus )
Danke im Vorraus
guinnes
Mit esp-link für die esp-12 (wemos d1 oder node mcu) hast du doch schon alles was du brauchst.
Die Software esplink ist halt eine Umsetzung von seriell auf wlan und zurück
Gruß Sascha
Danke für die Antwort, aber wir reden scheinbar aneinander vorbei.
Ich brauche 2 Physikalische Serielle Schnittstellen, die über den WLan verbunden sind, und ich kann beim esp-link keine IP-Adresse eintragen mit der sich dieser esp-Link mit einem anderen esp-Link verbindet.
Das brauche ich :
Seriell1 -- esp-Link1 ( IP-1 ) -- WLan --( IP-2 ) esp-Link2 -- Seriell2
und ich finde keine Möglichkeit, daß sich der esp-Link2 mit dem esp-Link1 verbindet.
Ich bräuchte entweder eine Bridge, die an beiden IP-Adressen lauscht und in beide IP-Adressen schreibt, natürlich über Kreuz. Um das selber zu schreiben ( und dann auch noch für den Raspberry ), stecke ich nicht tief genug drin.
Oder aber eine Möglichkeit, dem esp-Link eine 2. IP-Adresse anzugeben, mit der er sich verbinden soll.
Glückauf
guinnes
Hallo guinnes,
wenn ich recht verstehe, ein "eigenes" WLan-Netz zwischen den Seriellen-Schnittstellen ?
LG
Papa Romeo
Antwort vom Autor:
ZitatThorsten von Eicken
@tve
déc. 30 2019 07:50
esp-link is really not designed to be a transparent serial-to-serial-over-wifi bridge in this way
I believe there are other projects that are better suited to that.
no, there is no option for a gpio output, wouldn't be hard to add, but it's not there as-is
Zitat
Satya Gupta
@satyagupta
déc. 30 2019 07:54
Ahh well in that case i need to change the codes
Thanks @tve for quick reply :)
much appreciate it :)
ZitatThorsten von Eicken
@tve
déc. 30 2019 07:56
sure, just a warning: there is no support to make one esp-link connect to the other. it only accepts incoming connections. so you have to write the outbound part yourself. that's the biggest missing piece for your use-case
https://gitter.im/jeelabs/esp-link?at=5e1569fde409da486ce3839e
Zitat von: Papa Romeo am 21 Juli 2020, 21:04:41
wenn ich recht verstehe, ein "eigenes" WLan-Netz zwischen den Seriellen-Schnittstellen ?
Das soll schon über mein normales WLan gehen, nur eben eine Verbindung zwischen esp-Link1 und esp-Link2. Aber das scheint ja laut amenomade nicht vorgesehen zu sein, Schade eigentlich.
Jemand noch ne Idee ?
Vielleicht kennt ja jemand ne Software für den Raspberry, die ne virtuelle Serielle Schnittstelle aus TCP macht ?
Wenn nicht sehe ich nur 3 Möglichkeiten :
- Ein serielles Kabel durch die ganze Hütte ziehen ( wenig attraktiv )
- Das Binding umschreiben ( Java ist nicht meine Muttersprache, von daher nicht attraktiver )
- Den Raspberry in den Keller packen, was ich auch vermeiden möchte
Danke aber für eure Antworten
Glückauf
guinnes
nRF24 ?
wenn C/C++ deine Sprache ist, dann kannst du dich an der Erweiterung meiner EspSerialBridge (https://github.com/habeIchVergessen/EspSerialBridge) versuchen. Es fehlt lediglich der Teil der Bridge, der den Kontakt zum zweiten ESP aufnimmt.
Zitat von: Papa Romeo am 22 Juli 2020, 06:49:46
nRF24 ?
Sieht erst mal nicht schlecht aus. Wenn ich fertige Software finde, ist das wohl einen Versuch wert, Danke
Zitat von: habeIchVergessen am 22 Juli 2020, 09:52:22
wenn C/C++ deine Sprache ist, dann kannst du dich an der Erweiterung meiner EspSerialBridge (https://github.com/habeIchVergessen/EspSerialBridge) versuchen. Es fehlt lediglich der Teil der Bridge, der den Kontakt zum zweiten ESP aufnimmt.
Leider nicht, meine Sprache ist Object Pascal. Ich kann C/C++ zwar etwas lesen, aber bestimmt nicht schreiben. Ich kucks mir trotzdem mal an, Danke
Zitat von: Papa Romeo am 22 Juli 2020, 06:49:46
nRF24 ?
Das sieht erst mal richtig gut aus, werde ich probieren :)
Knapp 18.00 € für 2 Arduino mit 2 Spannungsreglern und 2 Sender/Empfängern ist die Sache wert.
Die Arduinos sind bestellt, der Schreib/Lesekopf ist bestellt, die Arduino-IDE ist runtergeladen, einem Versuch steht nichts meh im Wege :D
Nochmal vielen Dank auch an alle, die sich beteiligt haben
Glückauf
guinnes
So, was lange währt...
Alles OK, Die Daten vom Lesekopf werden jetzt über 2.4 GHz vom Keller bis ins Dach übertragen, der Tip mit dem nRF24 war Gold wert, nochmal vielen Dank.
Die Software war ( weil C++ ) für mich nicht ganz so einfach, ich hab die Bibliotheken anpassen müssen, aber nun tuts. Wenn gewünscht, kann ich die Codes hier einstellen
Glückauf
guinnes
Zitat von: guinnes am 22 August 2020, 17:08:11
Wenn gewünscht, kann ich die Codes hier einstellen
klar wird das gewünscht ;D
Gruß Peter
Moin
Ich benutze die vom Hersteller des nRF24 empfolene Mirf-Bibliothek. Folgende erweiterungen habe ich gemacht :
nRF24L01.h :
#define DYNPD 0x1C
#define FEATURE 0x1D
#define DPL_P5 5
#define DPL_P4 4
#define DPL_P3 3
#define DPL_P2 2
#define DPL_P1 1
#define DPL_P0 0
#define EN_DPL 2 // Enable Dynamic Payload
#define EN_ACK_PAY 1
#define EN_DYN_ACK 0
#define R_RX_PL_WID 0x60 // Read Payload Länge
Mirf.h :
typedef enum {
RF24_PA_MIN = 0, // -18 dBM
RF24_PA_LOW, // -12 dBM
RF24_PA_HIGH, // -6 dBM
RF24_PA_MAX, // 0 dBM
RF24_PA_ERROR
} rf24_pa_dbm_e;
typedef enum {
RF24_1MBPS = 0,
RF24_2MBPS,
RF24_250KBPS
} rf24_datarate_e;
typedef enum {
RF24_CRC_DISABLED = 0,
RF24_CRC_8,
RF24_CRC_16
} rf24_crclength_e;
//#define mirf_CONFIG ((1<<EN_CRC) | (0<<CRCO) ) // Enable CRC und CRC = 1 Byte
#define mirf_CONFIG ((1<<EN_CRC) | (1<<CRCO) ) // Enable CRC und CRC = 2 Byte
void getDynData(uint8_t * data,uint8_t len);
void sendDyn(uint8_t *value,uint8_t len);
void getDynaPayloadLen(uint8_t * data);
void enableDynPayload();
Mirf.cpp :
void Nrf24l::sendDyn(uint8_t * value,uint8_t len)
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
{
uint8_t status;
status = getStatus();
while (PTX) {
status = getStatus();
if((status & ((1 << TX_DS) | (1 << MAX_RT)))){
PTX = 0;
break;
}
} // Wait until last paket is send
ceLow();
powerUpTx(); // Set to transmitter mode , Power up
csnLow(); // Pull down chip select
spi->transfer( FLUSH_TX ); // Write cmd to flush tx fifo
csnHi(); // Pull up chip select
csnLow(); // Pull down chip select
spi->transfer( W_TX_PAYLOAD ); // Write cmd to write payload
transmitSync(value,len); // Write payload
csnHi(); // Pull up chip select
ceHi(); // Start transmission
}
extern void Nrf24l::enableDynPayload()
// Dynamische Payloadlänge einschalten
{
// Enable dynamically sized packets on the 2 RX pipes we use, 0 and 1.
// RX pipe address 1 is used to for normal packets from radios that send us data.
// RX pipe address 0 is used to for auto-acknowledgment packets from radios we transmit to.
configRegister(DYNPD, (1 << DPL_P0) | (1 << DPL_P1));
// Enable dynamically sized payloads, ACK payloads, and TX support with or without an ACK request.
configRegister(FEATURE, (1 << EN_DPL));
}
extern void Nrf24l::getDynaPayloadLen(uint8_t * data)
// ließt die Dynamische Payloadlänge aus
{
csnLow(); // Pull down chip select
spi->transfer( R_RX_PL_WID ); // Send cmd to read rx payload
transferSync(data,data,1); // Read payloadlen
csnHi(); // Pull up chip select
}
extern void Nrf24l::getDynData(uint8_t * data,uint8_t len)
// ließt len Bytes aus dem Radio aus
{
csnLow(); // Pull down chip select
spi->transfer( R_RX_PAYLOAD ); // Send cmd to read rx payload
transferSync(data,data,len); // Read payload
csnHi(); // Pull up chip select
configRegister(STATUS,(1<<RX_DR)); // Reset status register
}
Der Sketch des Senders :
/*
Die Daten, die über die Serielle Schnittstelle reinkommen, werde 1:1 in bis zu 32-Byte-Päckchen gesendet
Dabei wird zuerst gewartet, bis ein SML-Telegramm zu ende ist
und dann auf den Anfang eines neuen geprüft
*/
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
byte payload[32];
const int Maxpayloadsize = 32;
void setup() {
Serial.begin(9600); // Serielle Schnittstelle 9600 Baud
Serial.setTimeout(100); // Maximal 100 Milisekunden warten 32 Bytes brauchen ca. 34 MiliSekunden
/*
* Setup pins / SPI.
*/
/* To change CE / CSN Pins:
*
* Mirf.csnPin = 9;
* Mirf.cePin = 7;
*/
Mirf.cePin = 9;
Mirf.csnPin = 10;
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
/*
* Configure addresses.
*/
Mirf.setRADDR((byte *)"clie1");
Mirf.setTADDR((byte *)"serv1");
/*
* Write channel and payload config then power up reciver.
*/
/*
* To change channel:
*
* Mirf.channel = 10;
*
* NB: Make sure channel is legal in your area.
*/
Mirf.channel = 90;
Mirf.config();
Mirf.enableDynPayload(); // Dynamischr Payloadlänge einschalten
// show_Regs();
Sync(); // Der Loop darf erst nach einem TimeOut der Seriellen Schnittstelle anspringen
// Serial.print("Start");
}
void loop() {
byte noTimeOut = 1;
Serial.readBytes((byte *) &payload[0],1); // Erstes 1B einlesen
if (payload[0] == 0x1B){
Serial.readBytes((byte *) &payload[1],1); // Zweites 1B einlesen
if (payload[1] == 0x1B){
Serial.readBytes((byte *) &payload[2],1); // Drittes 1B einlesen
if (payload[2] == 0x1B){
Serial.readBytes((byte *) &payload[3],1); // Viertes 1B einlesen
if (payload[3] == 0x1B){
Serial.readBytes((byte *) &payload[4],1); // 01 Einlesen
if ( payload[4]== 0x01){
Serial.readBytes((byte *) &payload[5],1); // 01 Einlesen
if ( payload[5]== 0x01){
Serial.readBytes((byte *) &payload[6],1); // 01 Einlesen
if ( payload[6] == 0x01){
Serial.readBytes((byte *) &payload[7],1); // 01 Einlesen
if ( payload[7] == 0x01) {
while(Mirf.isSending()){} // Mirf schon fertig ?
Mirf.sendDyn((byte *)&payload,8); // Dann den Telegrammanfang raus
while (noTimeOut) { // In noTimeOut steht die Anzahl der gelesenen Bytes
noTimeOut = Serial.readBytes((byte *) &payload,Maxpayloadsize);
if (noTimeOut){ // noch was gelesen ?
while(Mirf.isSending()){}
Mirf.sendDyn((byte *) &payload,noTimeOut); // Die gelesenen Bytes raus
}
}
}
}
}
}
}
}
}
}
}
void Sync(){ // Warten auf die Ende-Signatur ( 1B 1B 1B 1B 1A XX XX XX) und nachfolgendem TimeOut des vorherigen Telegramms
byte myChar = 0;
byte noTimeOut = 1;
while (noTimeOut) {
Serial.readBytes((byte *) &myChar,1); // Erstes 1B einlesen
if (myChar == 0x1B){
Serial.readBytes((byte *) &myChar,1); // Zweites 1B einlesen
if (myChar == 0x1B){
Serial.readBytes((byte *) &myChar,1); // Drittes 1B einlesen
if (myChar == 0x1B){
Serial.readBytes((byte *) &myChar,1); // Viertes 1B einlesen
if (myChar == 0x1B){
Serial.readBytes((byte *) &myChar,1); // 1A einlesen
if (myChar == 0x1A){
Serial.readBytes((byte *) &myChar,1); // Anzahl der Füllbytes einlesen
Serial.readBytes((byte *) &myChar,1); // CRC 1. Byte einlesen
Serial.readBytes((byte *) &myChar,1); // CRC 2. Byte einlesen
noTimeOut = Serial.readBytes((byte *) &myChar,1); // Hier gibts nix mehr innerhalb des Timeouts zu lesen
}
}
}
}
}
}
}
void show_Regs(){
byte Reg_Result = 0;
Mirf.readRegister( CONFIG, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "config = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( EN_AA, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "EN_AA = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( EN_RXADDR, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "EN_RXADDR = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( SETUP_AW, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "SETUP_AW = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( SETUP_RETR, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "SETUP_RETR = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( RF_CH, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "RF_CH = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( RF_SETUP, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "RF_SETUP = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( STATUS, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "STATUS = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( OBSERVE_TX, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "OBSERVE_TX = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( CD, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "CD = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( FIFO_STATUS, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "FIFO_STATUS = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( DYNPD, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "DYNPD = " );
Serial.println( Reg_Result, BIN );
Mirf.readRegister( FEATURE, &Reg_Result, sizeof(Reg_Result) );
Serial.print( "FEATURE = " );
Serial.println( Reg_Result, BIN );
}
Und der des Empfängers :
/*
Die Daten, die über Funk kommen, werden als Hex ausgegeben
*/
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
byte payload[32];
void setup() {
Serial.begin(9600);
/*
* Setup pins / SPI.
*/
Mirf.cePin = 9;
Mirf.csnPin = 10;
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
/*
* Configure addresses.
*/
Mirf.setRADDR((byte *)"serv1");
Mirf.setTADDR((byte *)"clie1");
/*
* Set the payload length to sizeof(byte)
*
* NB: payload on client and server must be the same.
*/
/*
* Write channel and payload config then power up reciver.
*/
/*
* To change channel:
*
* Mirf.channel = 10;
*
* NB: Make sure channel is legal in your area.
*/
Mirf.channel = 90;
Mirf.config();
Mirf.enableDynPayload();
}
void loop() {
byte DynPayload; // Payloadlänge
while(!Mirf.dataReady()){} // Warten bis beim Mirf ein Paket angekommen ist
// Serial.println("Mirf Fertig");
Mirf.getDynaPayloadLen((byte *) &DynPayload); // Payloadlänge auslesen
Mirf.getDynData((byte *) &payload,DynPayload); // Das Paket lesen
Serial.write(payload,DynPayload); // und aus der seriellen Schnittstelle raus
// Serial.print(' ');
// Serial.println(DynPayload,DEC); // Dynamische Payloadlänge ausgeben
}
Es sind noch ein paar Zeilen drin, die ich zum Debuggen gebraucht habe, aber da die auskommentiert sind stören sie auch nicht
Es ist sicherlich nicht besonders elegant, aber C ist nun mal nicht meine Welt.
Es gibt immer noch ein paar CRC-Fehler, aber damit kann ich leben. Ich werde noch versuchen, die Übertragungsgeschwindigkeit runterzusetzen, vielleicht hilf das
Glückauf
guinnes