1455 Zeilen
45 KiB
C
1455 Zeilen
45 KiB
C
//Z21 LAN and WiFi
|
|
//Kommunikation mit der Z21 Library!
|
|
//
|
|
//Copyright (c) by Philipp Gahtow, year 2021
|
|
/*
|
|
* Changes:
|
|
* - Add change für WLAN für multi Paket - meherer Abfragen vom Client
|
|
* - Add change via LAN für multi Paket
|
|
* - Add store for source IP
|
|
* - Change State Report of Volt, mA and temp
|
|
* - Change Ethernet Big UDP handel at packet length = 0
|
|
* - Update ESP Wifi setup
|
|
* - add new function to request WiFi conf data
|
|
* - remove while in Serial read for WiFi
|
|
*/
|
|
//----------------------------------------------
|
|
#if defined(LAN) || defined(WIFI) || defined(ESP_WIFI)
|
|
|
|
extern void Z21LANreceive();
|
|
|
|
// buffers for receiving and sending data
|
|
#define Z21_UDP_TX_MAX_SIZE 20 //--> Z21 LocoNet tunnel DATA has 20 Byte!
|
|
#define Z21_BIG_UDP_MIN_SIZE 4 //--> smallest packet length in a BIG UDP Packet that we can handle
|
|
|
|
//----------------------------------------------
|
|
#if defined(Z21DISPLAY) && defined(BOOSTER_INT_MAINCURRENT)
|
|
extern void DisplayUpdateRailData(uint16_t inAm, float volt, float temp);
|
|
#endif
|
|
#if defined(Z21DISPLAY)
|
|
extern boolean DisplayReady;
|
|
extern void DisplayConfigData();
|
|
extern uint8_t DisplayCounter; //for animation
|
|
extern void DisplayDataTransmission(bool active);
|
|
#if defined(ESP_WIFI)
|
|
uint8_t ESPLastConnetionState;
|
|
#endif
|
|
#endif
|
|
|
|
//----------------------------------------------
|
|
//Wenn zwei Kommunikationsschnittstellen aktiv sind wird LAN hinten angestellt:
|
|
#if defined(LAN) && defined(WIFI)
|
|
#define Z21_Eth_offset WLANmaxIP //shift LAN client behind WiFi client
|
|
#else
|
|
#define Z21_Eth_offset 0
|
|
#endif
|
|
|
|
//----------------------------------------------
|
|
#if defined(BOOSTER_INT_MAINCURRENT)
|
|
float temp = 0;
|
|
#ifdef DALLASTEMPSENSE
|
|
#define DALLAS_Temp_Int 10000 //Intervall to request the temperatur
|
|
unsigned long temp_timer = 0;
|
|
#endif
|
|
#endif
|
|
|
|
//----------------------------------------------
|
|
#if defined(ESP_WIFI)
|
|
/*
|
|
IPAddress Ip(192,168,0,111);
|
|
IPAddress Gw(192,168,0,111);
|
|
IPAddress Sb(255,255,255,0);
|
|
*/
|
|
//client ssid and pw stored in EEPROM!
|
|
String ssid = "";
|
|
String pass = "";
|
|
//AP ssid and pw read out from EEPROM:
|
|
String ssidAP = "";
|
|
String passAP = "";
|
|
byte kanalAP = 3;
|
|
#endif
|
|
|
|
//----------------------------------------------
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
typedef struct //Rückmeldung des Status der Programmierung
|
|
{
|
|
byte IP0; //client IP-Adresse
|
|
byte IP1;
|
|
byte IP2;
|
|
byte IP3;
|
|
byte time; //aktive Zeit
|
|
unsigned int port; //source Port
|
|
} listofIP;
|
|
listofIP mem[LANmaxIP];
|
|
byte storedIP = 0; //speicher für IPs
|
|
#endif
|
|
|
|
//----------------------------------------------
|
|
unsigned long IPpreviousMillis = 0; // will store last time of IP decount updated and SystemInfo update
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
#if defined(WIFI)
|
|
byte outData[Z21_UDP_TX_MAX_SIZE]; //store received Serial to send via UDP
|
|
byte outDcount = 0; //position writing out data
|
|
byte sendTOO = 0xFF; //memIP to whom to send the data
|
|
byte listofWLANHash[WLANmaxIP+LANmaxIP];
|
|
|
|
#define WLAN_Config_Size 10 //num of config data that we can request from the ESP Modul
|
|
#if defined(Z21DISPLAY)
|
|
extern void DisplayUpdateRailPower(bool clear);
|
|
IPAddress WLANlocalIP; //0xE4 = Client IP
|
|
String WLANssid = "[not defined]"; //0xE5 = Client SSID Name
|
|
float ESPSwVer = 0.0; //0xE8 = ESP Sw Version
|
|
uint8_t ESPsoftAPStationNum = 0; //0xE9 = AP Client Connected
|
|
int WLAN_Signal = 0xFF; //0xEA = WLAN client Signal - 31 = "not connected"
|
|
#endif
|
|
//--------------------------------------------------------------------------------------------
|
|
#if defined(DEBUG_WLAN_CONFIG) || defined(Z21DATADEBUG)
|
|
void WLANConfDebug(uint8_t id, String s) {
|
|
//Report ESP config data: ---------------------------------------------------
|
|
String list[WLAN_Config_Size] = {F("WiFi-AP"),F("SSIP-AP"),F("PASS-AP"),F("CHAN-AP"),F("WiFi-CL"),F("SSIP-CL"),F("PASS-CL"),F("ESP-S88"),F("ESP-Ver"),F("AP-CLNum")};
|
|
//request each singel value:
|
|
if (id < WLAN_Config_Size) {
|
|
Debug.print(list[id]);
|
|
Debug.print(": ");
|
|
Debug.println(s);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//Request init data from ESP Modul
|
|
void WLANRequest(uint8_t id) {
|
|
WLAN.write(id);
|
|
delay(5); //wait for answer...
|
|
while (WLAN.available() > 0) {
|
|
Z21LANreceive();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//init ESP8266 serial interface
|
|
void WLANSetup() {
|
|
WLAN.begin(WIFISerialBaud); //UDP to Serial Kommunikation
|
|
WLAN.setTimeout(3); //sets the maximum milliseconds to wait for serial data
|
|
byte b1 = 0;
|
|
#if defined(DEBUG)
|
|
Debug.print(F("WiFi "));
|
|
Debug.print(WIFISerialBaud);
|
|
Debug.print(F("b start.."));
|
|
#endif
|
|
byte timeout = 80; //try to init at least
|
|
do {
|
|
#if defined(DEBUG)
|
|
Debug.print(".");
|
|
#endif
|
|
WLAN.println(); //let device Flush old Data!
|
|
delay(50); //wait for ESP8266 to answer a receive!
|
|
while (WLAN.available() > 0) {
|
|
b1 = WLAN.read();
|
|
#if defined(DEBUG)
|
|
if (b1 == 0xFA)
|
|
Debug.print("OK");
|
|
#endif
|
|
}
|
|
timeout--;
|
|
}
|
|
while (b1 != 0xFA && timeout > 0);
|
|
if (timeout == 0 || b1 != 0xFA) { //Error - no ESP module found!
|
|
#if defined(DEBUG)
|
|
Debug.println("FAIL");
|
|
#endif
|
|
}
|
|
else {
|
|
//Continue config setting for ESP
|
|
#if defined(DEBUG)
|
|
Debug.println();
|
|
#endif
|
|
//Setting S88:
|
|
#if defined(DEBUG)
|
|
Debug.print(F("Set ESP S88..."));
|
|
#endif
|
|
WLAN.write(0xFE); //Send start Bit for Initial Settings
|
|
#if defined(S88N)
|
|
WLAN.write(S88Module);
|
|
#else
|
|
WLAN.write(0xFE);
|
|
#endif
|
|
delay(5); //wait for answer...
|
|
if (WLAN.available() > 0) {
|
|
Z21LANreceive();
|
|
}
|
|
#if defined(DEBUG_WLAN_CONFIG)
|
|
//request all values:
|
|
for (byte counter = 0; counter < WLAN_Config_Size; counter++) {
|
|
delay(10); //wait for answer...
|
|
WLANRequest(0xE0 | (counter & 0x0F));
|
|
}
|
|
#else
|
|
//request only used ones:
|
|
#if defined(Z21DISPLAY)
|
|
#if defined(DEBUG)
|
|
Debug.println(F("Request..."));
|
|
#endif
|
|
WLANRequest(0xE8); //ESP Sw Version
|
|
WLANRequest(0xE5); //Client SSID Name
|
|
WLANRequest(0xE4); //Client IP
|
|
#endif
|
|
WLANRequest(0xEB); //Read all client Hash
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
#if defined(ESP_WIFI)
|
|
/**********************************************************************************/
|
|
//s = String that will be saved,
|
|
//laenge = Index to length byte,
|
|
//start = index to the first letter
|
|
void EEPROMwrite (String s, uint16_t laenge, uint16_t start) {
|
|
byte len = s.length();
|
|
FIXSTORAGE.FIXMODE(laenge,len);
|
|
for (uint16_t i = start; i < (start+len); i++) {
|
|
FIXSTORAGE.FIXMODE(i,s[i-start]);
|
|
}
|
|
|
|
FIXSTORAGE.commit();
|
|
}
|
|
/**********************************************************************************/
|
|
//laenge = Index to length byte,
|
|
//start = index to the first letter
|
|
String EEPROMread (uint16_t laenge, uint16_t start) {
|
|
String s = "";
|
|
byte len = FIXSTORAGE.read(laenge);
|
|
if (len < EEStringMaxSize) {
|
|
for (uint16_t i = start; i < (start+len); i++) {
|
|
s += char(FIXSTORAGE.read(i));
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
/**********************************************************************************/
|
|
boolean tryWifiClient() {
|
|
WiFi.disconnect();
|
|
if ( (ssid.length() > 0) && (pass.length() > 7) ) {
|
|
//check first if we see this SSID
|
|
byte available_networks = WiFi.scanNetworks();
|
|
for (int network = 0; network < available_networks; network++) {
|
|
if (WiFi.SSID(network) == ssid.c_str()) {
|
|
|
|
WiFi.begin(ssid.c_str(), pass.c_str());
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
/**********************************************************************************/
|
|
void ESPSetup() {
|
|
#if defined(ESP32)
|
|
WiFi.mode(WIFI_MODE_APSTA);
|
|
#else
|
|
WiFi.mode(WIFI_AP_STA); //AP & client
|
|
#endif
|
|
|
|
// read eeprom for ssid and pass:
|
|
|
|
//--------------WIFI CLIENT---------------
|
|
ssid = EEPROMread(EEssidLength, EEssidBegin);
|
|
pass = EEPROMread(EEpassLength, EEpassBegin);
|
|
//--------------ACCESS POINT-------------
|
|
ssidAP = EEPROMread(EEssidAPLength, EEssidAPBegin);
|
|
passAP = EEPROMread(EEpassAPLength, EEpassAPBegin);
|
|
|
|
if ((ssidAP.length() > 32) || (ssidAP.length() == 0) || (passAP.length() > 32) || (passAP.length() == 0) ) { //request is OK?
|
|
#if defined(DEBUG)
|
|
Debug.println(F("Reset to default!"));
|
|
#endif
|
|
|
|
ssidAP = SssidAP;
|
|
passAP = SpassAP;
|
|
kanalAP = SkanalAP;
|
|
/*
|
|
#if defined(ESP32)
|
|
portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED;
|
|
portENTER_CRITICAL(&myMutex);
|
|
#endif
|
|
*/
|
|
EEPROMwrite (ssidAP, EEssidAPLength, EEssidAPBegin);
|
|
EEPROMwrite (passAP, EEpassAPLength, EEpassAPBegin);
|
|
FIXSTORAGE.FIXMODE(EEkanalAP, kanalAP);
|
|
|
|
FIXSTORAGE.commit();
|
|
/*
|
|
#if defined(ESP32)
|
|
portEXIT_CRITICAL(&myMutex);
|
|
#endif
|
|
*/
|
|
}
|
|
else {
|
|
kanalAP = FIXSTORAGE.read(EEkanalAP);
|
|
if ((kanalAP < 1) || (kanalAP > 13))
|
|
kanalAP = SkanalAP;
|
|
}
|
|
|
|
WiFi.softAPConfig(AP_ip, AP_ip, AP_sb); //set the default IP for Z21
|
|
|
|
#if defined(ESP32_MCU)
|
|
WiFi.softAP(ssidAP.c_str(), passAP.c_str() ); //Start AcessPoint, ignore Channel parameter!
|
|
#else
|
|
WiFi.softAP(ssidAP.c_str(), passAP.c_str(), kanalAP, false, 8); //Start AcessPoint with max 8 number of clients
|
|
#endif
|
|
//don't hide SSID and max simultaneous connected stations set to eight!
|
|
|
|
#if defined(DEBUG)
|
|
Debug.print(F("AP Name: "));
|
|
Debug.println(ssidAP);
|
|
Debug.print(F("Pw: "));
|
|
Debug.println(passAP);
|
|
Debug.print(F("IP: "));
|
|
Debug.println(WiFi.softAPIP());
|
|
#endif
|
|
|
|
#if defined(DEBUG)
|
|
Debug.print("Client: ");
|
|
Debug.println(ssid.c_str());
|
|
Debug.print("PW: ");
|
|
Debug.println(pass.c_str());
|
|
#endif
|
|
|
|
if (tryWifiClient()) { //Try to connect to WiFi
|
|
#if defined(DEBUG)
|
|
Debug.print(ssid);
|
|
Debug.println(F(" gefunden!"));
|
|
//Debug.print(F("IP: "));
|
|
//Debug.println(WiFi.localIP());
|
|
#endif
|
|
}
|
|
else {
|
|
//Change WiFi Mode, to remove blocking OTA handel, when not connected:
|
|
WiFi.mode(WIFI_AP); //AP & client
|
|
#if defined(DEBUG)
|
|
Debug.print(F("Connect fail to "));
|
|
Debug.println(ssid);
|
|
#endif
|
|
}
|
|
|
|
#if defined(Z21DISPLAY)
|
|
if (Railpower == csNormal) {
|
|
DisplayCounter = 0xFF;
|
|
DisplayConfigData(); //rewrite config data to Display
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
#if defined(WIFI)
|
|
void WLANEvent() {
|
|
//receive WLAN data:
|
|
if (WLAN.available() > 0) { //Empfang Z21 UDP Packet over Serial from ESP
|
|
outData[outDcount] = WLAN.read(); //read
|
|
|
|
if (sendTOO == 0xFF) {
|
|
sendTOO = outData[outDcount]; //Ziel IP/client read out
|
|
}
|
|
else {
|
|
outDcount++;
|
|
|
|
if (outData[0] <= outDcount) { //1. Byte gibt länge der Daten an!
|
|
if (sendTOO <= WLANmaxIP) { //Ziel in range?
|
|
//read Data:
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print(sendTOO);
|
|
Debug.print(F(" Z21 RX: "));
|
|
for (byte i = 0; i < outData[0]; i++) {
|
|
Debug.print(outData[i], HEX);
|
|
Debug.print(" ");
|
|
}
|
|
Debug.println(F("WLAN ok")); //Accept
|
|
#endif
|
|
if (outData[0] >= Z21_BIG_UDP_MIN_SIZE) { //Check if there is really Data in?
|
|
z21.receive(sendTOO, outData);
|
|
}
|
|
else if (outData[0] == 0x02) { //length == 2, then ESP report client IP-Hash
|
|
listofWLANHash[sendTOO] = outData[1];
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print(sendTOO + 1);
|
|
Debug.print(F(" Z21 Client Hash: "));
|
|
Debug.println(outData[1], HEX);
|
|
#endif
|
|
}
|
|
else {
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.println("Length ERROR!");
|
|
WLAN.println(); //new sync!
|
|
#endif
|
|
}
|
|
outData[1] = sendTOO; //Store Client that send the DATA
|
|
}
|
|
#if defined(Z21DATADEBUG)
|
|
else {
|
|
Debug.print(F("Z21 EE ")); //Fail
|
|
Debug.println(sendTOO, HEX);
|
|
WLAN.println(); //new sync!
|
|
}
|
|
#endif
|
|
//Reset to read next data:
|
|
outDcount = 0;
|
|
sendTOO = 0xFF;
|
|
} //END of Data received "normal"!
|
|
else if ((outDcount >= Z21_UDP_TX_MAX_SIZE) || (sendTOO == 'E' && outData[0] == 'E') || (outData[outDcount-2] == 'E' && outData[outDcount-1] == 'E')) {
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.write(sendTOO); //Fail?
|
|
for (byte i = 0; i < outDcount; i++)
|
|
Debug.write(outData[i]);
|
|
Debug.print(F(" FLUSH "));
|
|
Debug.print(outDcount);
|
|
Debug.println(" Data!");
|
|
#endif
|
|
WLAN.println(); //new sync!
|
|
//WLAN.flush(); //clear
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
else if ((sendTOO == 'O' && outData[0] == 'K') || (outData[outDcount-2] == 'O' && outData[outDcount-1] == 'K')) { //keine valied Data!
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.println(F("Z21 OK"));
|
|
#endif
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
else if (sendTOO > WLANmaxIP) {
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print(F("Z21 Error: 0x"));
|
|
Debug.println(sendTOO, HEX);
|
|
#endif
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
return; //just count the Data byte that we had read!
|
|
} // ENDE Z21 Data
|
|
//----------------------------------------------
|
|
/*ESP System Config:
|
|
** 0xE0 = AP IP
|
|
** 0xE1 = AP SSID Name
|
|
** 0xE2 = AP Password
|
|
** 0xE3 = AP Channel
|
|
** 0xE4 = Client IP
|
|
** 0xE5 = Client SSID Name
|
|
** 0xE6 = Client Password
|
|
** 0xE7 = S88 Module
|
|
** 0xE8 = ESP Sw Version
|
|
** 0xE9 = AP Client Connected
|
|
* 0xEA = WLAN RSSI
|
|
* 0xEB = IP-HASH clients
|
|
* 0xEC = reserved
|
|
* 0xED = reserved
|
|
* 0xEF = reserved
|
|
* 0xFE = Set S88 Module
|
|
* 0xFA = Z21 "OK"!
|
|
* 0xFB = ERROR "EE" Fail
|
|
*/
|
|
//receive config of Serial WLAN ESP8266:
|
|
if ((sendTOO & 0xF0) == 0xE0) {
|
|
if ((sendTOO & 0x0F) < WLAN_Config_Size) {
|
|
String data = WLAN.readStringUntil('\n');
|
|
#if defined(DEBUG_WLAN_CONFIG) || defined(Z21DATADEBUG)
|
|
WLANConfDebug(sendTOO & 0x0F, data);
|
|
#endif
|
|
#if defined(Z21DISPLAY)
|
|
switch (sendTOO) {
|
|
case 0xE4: WLANlocalIP.fromString(data); //Client IP
|
|
if (Railpower ==csNormal) {
|
|
DisplayCounter = 0xFF;
|
|
DisplayConfigData();
|
|
}
|
|
break;
|
|
case 0xE5: WLANssid = data; //Client SSID Name
|
|
if (Railpower ==csNormal) {
|
|
DisplayCounter = 0xFF;
|
|
DisplayConfigData();
|
|
}
|
|
break;
|
|
case 0xE8: ESPSwVer = data.toFloat(); break; //ESP Sw Version
|
|
case 0xE9: ESPsoftAPStationNum = data.toInt(); //AP Client Connected
|
|
}
|
|
#endif
|
|
}
|
|
else if (sendTOO == 0xEA) { //WLAN RSSI
|
|
if (WLAN.available() > 0) {
|
|
#if defined(Z21DISPLAY)
|
|
//WLAN Signal RSSI is reported:
|
|
WLAN_Signal = WLAN.read();
|
|
if ((WLAN_Signal >> 7) == 1) { // >= 128
|
|
WLAN_Signal = (256 - WLAN_Signal) * -1; //make it negativ (db)
|
|
}
|
|
#if defined(Z21SYSTEMDATADEBUG)
|
|
Debug.print(F(" WLAN-Signal: "));
|
|
Debug.println(WLAN_Signal); //read
|
|
#endif
|
|
IPpreviousMillis = 0; //reset counter to update display now!
|
|
#else
|
|
WLAN.read(); //empty buffer, data not in use!
|
|
#endif
|
|
}
|
|
}
|
|
else if (sendTOO == 0xEB) { //IP-HASH clients
|
|
byte HashData = 0x00;
|
|
byte ClientCount = 0;
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("Report Clients: "));
|
|
#endif
|
|
while (WLAN.available() > 0) {
|
|
HashData = WLAN.read();
|
|
if (HashData != 0x00) {
|
|
listofWLANHash[ClientCount] = HashData;
|
|
ClientCount++;
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(ClientCount);
|
|
Debug.print(F(" IPHash: "));
|
|
Debug.print(HashData, HEX);
|
|
Debug.print(F("; "));
|
|
#endif
|
|
}
|
|
}
|
|
#if defined(Z21DEBUG)
|
|
if (ClientCount == 0)
|
|
Debug.print(F(" none!"));
|
|
Debug.println();
|
|
#endif
|
|
}
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
} //ENDE WLAN Config
|
|
else if (sendTOO == 0xFA) { //Quittung!
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.println(F("Z21 OK"));
|
|
#endif
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
else if (sendTOO == 0xFB) { //ERROR!
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.println(F("Z21 ERROR"));
|
|
#endif
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
//Set S88 Module
|
|
else if (sendTOO == 0xFE) {
|
|
if (WLAN.available() > 0) {
|
|
uint8_t Module = WLAN.read();
|
|
#if defined(S88N)
|
|
if (Module <= S88MAXMODULE) { // && sendTOO >= 0
|
|
S88Module = Module;
|
|
#if defined(REPORT)
|
|
Debug.print(F("Set S88 Module: "));
|
|
Debug.println(S88Module);
|
|
#endif
|
|
if (FIXSTORAGE.read(EES88Moduls) != S88Module) {
|
|
FIXSTORAGE.FIXMODE(EES88Moduls, S88Module);
|
|
SetupS88();
|
|
WLANSetup();
|
|
}
|
|
}
|
|
#else
|
|
WLAN.write(0xFE);
|
|
WLAN.write(0xFE); //kein S88 aktiv!
|
|
#endif
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
}
|
|
} //ENDE if wlan available
|
|
else {
|
|
//no data - stream is over!
|
|
outDcount = 0; //reset read buffer
|
|
sendTOO = 0xFF;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
byte Z21addIP (byte ip0, byte ip1, byte ip2, byte ip3, unsigned int port) {
|
|
//suche ob IP schon vorhanden?
|
|
for (byte i = 0; i < storedIP; i++) {
|
|
if (mem[i].IP0 == ip0 && mem[i].IP1 == ip1 && mem[i].IP2 == ip2 && mem[i].IP3 == ip3) {
|
|
mem[i].time = ActTimeIP; //setzte Zeit
|
|
mem[i].port = port; //update port!
|
|
return i+1;
|
|
}
|
|
}
|
|
if (storedIP >= LANmaxIP) {
|
|
for (byte i = 0; i < storedIP; i++) {
|
|
if (mem[i].time == 0) { //Abgelaufende IP, dort eintragen!
|
|
mem[i].IP0 = ip0;
|
|
mem[i].IP1 = ip1;
|
|
mem[i].IP2 = ip2;
|
|
mem[i].IP3 = ip3;
|
|
mem[i].port = port;
|
|
mem[i].time = ActTimeIP; //setzte Zeit
|
|
return i+1;
|
|
}
|
|
}
|
|
return 0; //keine freien IPs (never reach here!)
|
|
}
|
|
mem[storedIP].IP0 = ip0;
|
|
mem[storedIP].IP1 = ip1;
|
|
mem[storedIP].IP2 = ip2;
|
|
mem[storedIP].IP3 = ip3;
|
|
mem[storedIP].port = port;
|
|
mem[storedIP].time = ActTimeIP; //setzte Zeit
|
|
storedIP++;
|
|
return storedIP;
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void Z21LANreceive() {
|
|
//-------------------------------------------------------------------------------------------
|
|
//receive LAN data or we run on ESP MCU:
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
byte packetSize = Udp.parsePacket();
|
|
if(packetSize) { //packetSize
|
|
IPAddress remote = Udp.remoteIP();
|
|
byte packetBuffer[packetSize];
|
|
Udp.read(packetBuffer,packetSize); // read the packet into packetBufffer
|
|
if (packetSize == packetBuffer[0]) { //normal:
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print(Z21addIP(remote[0], remote[1], remote[2], remote[3], Udp.remotePort()) + Z21_Eth_offset);
|
|
Debug.print(" Z21 RX: ");
|
|
for (byte i = 0; i < packetBuffer[0]; i++) {
|
|
Debug.print(packetBuffer[i], HEX);
|
|
Debug.print(" ");
|
|
}
|
|
Debug.println();
|
|
#endif
|
|
z21.receive(Z21addIP(remote[0], remote[1], remote[2], remote[3], Udp.remotePort()) + Z21_Eth_offset, packetBuffer);
|
|
}
|
|
else { //kombiniertes UDP Paket:
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print(packetSize);
|
|
Debug.print(F(" BIG Z21 RX: "));
|
|
for (byte i = 0; i < packetSize; i++) {
|
|
Debug.print(packetBuffer[i], HEX);
|
|
Debug.print(" ");
|
|
}
|
|
Debug.println();
|
|
#endif
|
|
|
|
byte readpos = 0; //data length position des aktuellen Paket
|
|
//durchlaufe alle Pakete:
|
|
do {
|
|
//check if packet length is not empty and okay?
|
|
if (packetBuffer[readpos] >= Z21_BIG_UDP_MIN_SIZE) {
|
|
byte pBuffer[packetBuffer[readpos]]; //make a array of packet length
|
|
for (byte i = 0; i < packetBuffer[readpos]; i++) //fill up array with packet
|
|
pBuffer[i] = packetBuffer[readpos + i];
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print("#-- "); //Big UDP = in one Packet!
|
|
Debug.print(Z21addIP(remote[0], remote[1], remote[2], remote[3], Udp.remotePort()) + Z21_Eth_offset);
|
|
Debug.print(F(" Z21 RX: "));
|
|
for (byte i = 0; i < pBuffer[0]; i++) {
|
|
Debug.print(pBuffer[i], HEX);
|
|
Debug.print(" ");
|
|
}
|
|
Debug.println();
|
|
#endif
|
|
z21.receive(Z21addIP(remote[0], remote[1], remote[2], remote[3], Udp.remotePort()) + Z21_Eth_offset, pBuffer);
|
|
readpos = packetBuffer[readpos] + readpos; //bestimme position des nächsten Paket
|
|
}
|
|
else {
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print("Length ERROR! ");
|
|
Debug.println(packetBuffer[readpos]);
|
|
#endif
|
|
break; //Stop here!
|
|
}
|
|
}
|
|
while(readpos < packetSize);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(WIFI)
|
|
WLANEvent();
|
|
#endif
|
|
|
|
//----------------------------------------------
|
|
//Nutzungszeit IP's bestimmen und update SystemInfo
|
|
unsigned long currentMillis = millis();
|
|
if((currentMillis - IPpreviousMillis) >= IPinterval) {
|
|
IPpreviousMillis = currentMillis;
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
for (byte i = 0; i < storedIP; i++) {
|
|
if (mem[i].time > 0) {
|
|
mem[i].time--; //Zeit herrunterrechnen
|
|
#if defined(Z21DATADEBUG)
|
|
if (mem[i].time == 0) {
|
|
Debug.print(i + Z21_Eth_offset + 1);
|
|
Debug.println(F(" LAN client timed out"));
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
//interval:
|
|
#if defined(BOOSTER_INT_MAINCURRENT)
|
|
notifyz21getSystemInfo(0); //SysInfo an alle BC Clients senden!
|
|
#endif
|
|
}
|
|
//----------------------------------------------
|
|
#if defined(Z21DISPLAY) && defined(ESP_WIFI)
|
|
if (ESPLastConnetionState != WiFi.status()) {
|
|
ESPLastConnetionState = WiFi.status();
|
|
if (Railpower ==csNormal) { //Update data on Display
|
|
DisplayCounter = 0xFF;
|
|
DisplayConfigData();
|
|
}
|
|
}
|
|
#endif
|
|
//----------------------------------------------
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
#if defined(S88N)
|
|
//Ask for Feedback data of group index:
|
|
void notifyz21S88Data(uint8_t gIndex) {
|
|
//S88sendon = 'i';
|
|
reportS88Data(gIndex);
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21RailPower(uint8_t State)
|
|
{
|
|
if (Railpower != State) {
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("z21 "));
|
|
#endif
|
|
|
|
globalPower(State);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoState(uint16_t Adr, uint8_t data[])
|
|
{
|
|
#if defined(DCC)
|
|
AllLocoData(Adr, data);
|
|
#endif
|
|
|
|
#if defined(LOCONET) && !defined(LnSLOTSRV)
|
|
LNGetSetLocoSlot(Adr, true); //send status to LocoNet
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt(uint16_t Adr, uint8_t state, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setLocoFunc(Adr, state, fkt);
|
|
#endif
|
|
|
|
#if defined(LOCONET) && defined(DCC)
|
|
if (fkt <= 4) {
|
|
byte DIRF = dcc.getFunktion0to4(Adr) | (dcc.getLocoDir(Adr) << 5);
|
|
sendLNDIRF(Adr, DIRF);
|
|
}
|
|
else if (fkt >= 5 && fkt <= 8)
|
|
sendLNSND(Adr, dcc.getFunktion5to8(Adr));
|
|
else if (fkt >= 9 && fkt <= 12)
|
|
sendLNF3 (Adr, dcc.getFunktion9to12(Adr));
|
|
else if (fkt >= 13 && fkt <= 20)
|
|
sendLNF4 (Adr, dcc.getFunktion13to20(Adr));
|
|
else if (fkt >= 21 && fkt <= 28)
|
|
sendLNF5 (Adr, dcc.getFunktion21to28(Adr));
|
|
#endif
|
|
|
|
#if defined(XPRESSNET) && defined(DCC)
|
|
if (fkt <= 4)
|
|
XpressNet.setFunc0to4(Adr, dcc.getFunktion0to4(Adr));
|
|
else if (fkt >= 5 && fkt <= 8)
|
|
XpressNet.setFunc5to8(Adr, dcc.getFunktion5to8(Adr));
|
|
else if (fkt >= 9 && fkt <= 12)
|
|
XpressNet.setFunc9to12(Adr, dcc.getFunktion9to12(Adr));
|
|
else if (fkt >= 13 && fkt <= 20)
|
|
XpressNet.setFunc13to20(Adr, dcc.getFunktion13to20(Adr));
|
|
else if (fkt >= 21 && fkt <= 28)
|
|
XpressNet.setFunc21to28(Adr, dcc.getFunktion21to28(Adr));
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG) && defined(DCC)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(" Dir: ");
|
|
Debug.print(dcc.getLocoDir(Adr), BIN);
|
|
if (fkt <= 4) {
|
|
Debug.print(", F1:");
|
|
Debug.println(dcc.getFunktion0to4(Adr), BIN);
|
|
}
|
|
else if (fkt >= 5 && fkt <= 8) {
|
|
Debug.print(", F2:");
|
|
Debug.println(dcc.getFunktion5to8(Adr), BIN);
|
|
}
|
|
else if (fkt >= 9 && fkt <= 12) {
|
|
Debug.print(", F3:");
|
|
Debug.println(dcc.getFunktion9to12(Adr), BIN);
|
|
}
|
|
else if (fkt >= 13 && fkt <= 20) {
|
|
Debug.print(", F4:");
|
|
Debug.println(dcc.getFunktion13to20(Adr), BIN);
|
|
}
|
|
else if (fkt >= 21 && fkt <= 28) {
|
|
Debug.print(", F5:");
|
|
Debug.println(dcc.getFunktion21to28(Adr), BIN);
|
|
}
|
|
else if (fkt >= 29 && fkt <= 31) {
|
|
Debug.print(", F6:");
|
|
Debug.println(dcc.getFunktion29to31(Adr), BIN);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt0to4(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions0to4(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(LOCONET) && defined(DCC)
|
|
sendLNDIRF(Adr, fkt | (dcc.getLocoDir(Adr) << 5));
|
|
#endif
|
|
|
|
#if defined(XPRESSNET)
|
|
XpressNet.setFunc0to4(Adr, fkt);
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG) && defined(DCC)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F0-4:");
|
|
Debug.println(dcc.getFunktion0to4(Adr), BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt5to8(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions5to8(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(LOCONET)
|
|
sendLNSND(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(XPRESSNET)
|
|
XpressNet.setFunc5to8(Adr, fkt);
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG) && defined(DCC)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F5-8:");
|
|
Debug.println(dcc.getFunktion5to8(Adr), BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt9to12(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions9to12(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(LOCONET)
|
|
sendLNF3 (Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(XPRESSNET)
|
|
XpressNet.setFunc9to12(Adr, fkt);
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG) && defined(DCC)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F9-12:");
|
|
Debug.println(dcc.getFunktion9to12(Adr), BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt13to20(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions13to20(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(LOCONET)
|
|
sendLNF4 (Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(XPRESSNET)
|
|
XpressNet.setFunc13to20(Adr, fkt);
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG) && defined(DCC)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F13-20:");
|
|
Debug.println(dcc.getFunktion13to20(Adr), BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt21to28(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions21to28(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(LOCONET)
|
|
sendLNF5 (Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(XPRESSNET)
|
|
XpressNet.setFunc21to28(Adr, fkt);
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG) && defined(DCC)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F21-28:");
|
|
Debug.println(dcc.getFunktion21to28(Adr), BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt29to36(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions29to36(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F29-36:");
|
|
Debug.println(fkt, BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt37to44(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions37to44(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F37-44:");
|
|
Debug.println(fkt, BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt45to52(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions45to52(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F45-52:");
|
|
Debug.println(fkt, BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt53to60(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions53to60(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F53-60:");
|
|
Debug.println(fkt, BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoFkt61to68(uint16_t Adr, uint8_t fkt)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setFunctions61to68(Adr, fkt);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F61-68:");
|
|
Debug.println(fkt, BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//Binärzustandsadressen von 29 bis 32767
|
|
void notifyz21LocoFktExt(uint16_t Adr, uint8_t low, uint8_t high)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setLocoFuncBinary(Adr, low, high);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 A:");
|
|
Debug.print(Adr);
|
|
Debug.print(", F");
|
|
Debug.print((high << 7) + (low & 0x7F));
|
|
Debug.print(": ");
|
|
Debug.println(low >> 7); //Zustand
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LocoSpeed(uint16_t Adr, uint8_t speed, uint8_t steps)
|
|
{
|
|
if (Adr == 0) {
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("Z21 A:"));
|
|
Debug.print(Adr);
|
|
Debug.println(F(" ERROR not a loco!"));
|
|
#endif
|
|
return;
|
|
}
|
|
#if defined(LOCONET)
|
|
switch (steps) {
|
|
case 14: sendLNSPD(Adr, map(speed, 0, 14, 0, 128)); break;
|
|
case 28: sendLNSPD(Adr, map(speed, 0, 28, 0, 128)); break;
|
|
default: sendLNSPD(Adr, speed);
|
|
}
|
|
#endif
|
|
#if defined(XPRESSNET)
|
|
XpressNet.setSpeed(Adr, steps, speed);
|
|
XpressNet.ReqLocoBusy(Adr); //Lok wird nicht von LokMaus gesteuert!
|
|
#endif
|
|
switch (steps) {
|
|
case 14: dcc.setSpeed14(Adr, speed); break;
|
|
case 28: dcc.setSpeed28(Adr, speed); break;
|
|
default: dcc.setSpeed128(Adr, speed);
|
|
}
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("Z21 A:"));
|
|
Debug.print(Adr);
|
|
Debug.print(", S");
|
|
Debug.print(steps);
|
|
Debug.print(":");
|
|
Debug.println(speed, BIN);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21Accessory(uint16_t Adr, bool state, bool active)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setBasicAccessoryPos(Adr, state, active);
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
uint8_t notifyz21AccessoryInfo(uint16_t Adr)
|
|
//return state of the Address (left/right = true/false)
|
|
{
|
|
#if defined(DCC)
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 GetAccInfo: ");
|
|
Debug.print(Adr);
|
|
Debug.print("-");
|
|
Debug.println(dcc.getBasicAccessoryInfo(Adr));
|
|
#endif
|
|
|
|
return dcc.getBasicAccessoryInfo(Adr);
|
|
#else
|
|
return 0x00;
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21ExtAccessory(uint16_t Adr, byte state)
|
|
{
|
|
#if defined(DCC)
|
|
dcc.setExtAccessoryPos(Adr, state);
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 SetExtAcc: ");
|
|
Debug.print(Adr);
|
|
Debug.print("-");
|
|
Debug.println(state);
|
|
#endif
|
|
}
|
|
|
|
#if defined(LOCONET)
|
|
//--------------------------------------------------------------------------------------------
|
|
uint8_t notifyz21LNdispatch(uint16_t Adr)
|
|
//return the Slot that was dispatched, 0xFF at error!
|
|
{
|
|
#if defined(Z21DEBUG)
|
|
Debug.print("Z21 LNdispatch: ");
|
|
Debug.println(Adr);
|
|
#endif
|
|
return LNdispatch(Adr);
|
|
}
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LNSendPacket(uint8_t *data, uint8_t length)
|
|
{
|
|
#if defined(LnDEB)
|
|
Debug.print(F("LOCONET_FROM_LAN "));
|
|
#endif
|
|
LNSendPacket (data, length, Z21bcLocoNet_s, false); //Report nicht an Z21 Library!
|
|
LNdecode(false); //verarbeite empfangene Daten, aber nicht als Z21 RX!
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21LNdetector(uint8_t client, uint8_t typ, uint16_t Adr) {
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("LAN_LOCONET_DETECTOR 0x"));
|
|
Debug.print(Adr);
|
|
Debug.print("-");
|
|
Debug.print(typ, HEX);
|
|
#endif
|
|
if (typ == 0x80) { //SIC Abfrage
|
|
byte data[4];
|
|
data[0] = 0x01; //Typ
|
|
data[1] = Adr & 0xFF;
|
|
data[2] = Adr >> 8;
|
|
data[3] = dcc.getBasicAccessoryInfo(Adr); //Zustand Rückmelder
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F(" State: "));
|
|
Debug.println(data[3], BIN);
|
|
#endif
|
|
z21.setLNDetector(client, data, 4);
|
|
}
|
|
#if defined(Z21DEBUG)
|
|
else Debug.println();
|
|
#endif
|
|
}
|
|
|
|
#endif //LOCONET
|
|
|
|
/*
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21CANdetector(uint8_t client, uint8_t typ, uint16_t ID) {
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("CAN_DETECTOR "));
|
|
Debug.print(typ);
|
|
Debug.print("=");
|
|
Debug.println(ID);
|
|
#endif
|
|
}
|
|
|
|
//z21.setCANDetector(uint16_t NID, uint16_t Adr, uint8_t port, uint8_t typ, uint16_t v1, uint16_t v2);
|
|
*/
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//read out the current of the booster main
|
|
void notifyz21getSystemInfo(uint8_t client) {
|
|
|
|
|
|
#if defined(BOOSTER_INT_MAINCURRENT)
|
|
uint16_t inAm = getRailmA();
|
|
uint16_t volt = getRailVolt();
|
|
|
|
|
|
#ifdef DALLASTEMPSENSE
|
|
if((millis() - temp_timer) >= DALLAS_Temp_Int) { //á 10 sec.
|
|
temp = sensors.getTempCByIndex(0);
|
|
sensors.requestTemperatures(); // Send the command to get temperatures
|
|
temp_timer = millis();
|
|
}
|
|
|
|
#elif defined(MEGA_MCU)
|
|
temp = analogRead(TempPin);
|
|
#if defined(AREF_1V1)
|
|
temp = (1024-temp) / (temp / 34.5);
|
|
#else
|
|
temp = (1024-temp) / (temp / 11.5);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(Z21SYSTEMDATADEBUG)
|
|
Debug.print("mA: ");
|
|
Debug.print(inAm);
|
|
Debug.print("(");
|
|
Debug.print(VAmpINT); //Volt on VAmpIntPin
|
|
Debug.print(")_V");
|
|
|
|
#if defined(VoltIntPin) //ESP8266 has only one ADC for current sense!
|
|
Debug.print(analogRead(VoltIntPin));
|
|
Debug.print(":");
|
|
#endif
|
|
Debug.print(volt); //Rail Voltage: Rail:100k - Sense - 4,7k - GND
|
|
Debug.print("_T:");
|
|
Debug.println(temp);
|
|
#endif
|
|
|
|
#if defined(Z21DISPLAY)
|
|
DisplayUpdateRailData(inAm,volt,temp);
|
|
#endif
|
|
|
|
z21.sendSystemInfo(client, inAm, volt, temp); //report System State to z21 client
|
|
//(12-22V): 20V=0x4e20, 21V=0x5208, 22V=0x55F0
|
|
#else
|
|
z21.sendSystemInfo(client, 0, 0, 0); //report zero System State to z21 client
|
|
#endif
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21CVREAD(uint8_t cvAdrMSB, uint8_t cvAdrLSB)
|
|
{
|
|
unsigned int cvAdr = cvAdrMSB << 8 | cvAdrLSB;
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("Z21 read CV#"));
|
|
Debug.println(cvAdr+1);
|
|
#endif
|
|
|
|
#if defined(DCC)
|
|
dcc.opsReadDirectCV(cvAdr); //read cv
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21CVWRITE(uint8_t cvAdrMSB, uint8_t cvAdrLSB, uint8_t value)
|
|
{
|
|
unsigned int cvAdr = cvAdrMSB << 8 | cvAdrLSB;
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(F("Z21 set CV#"));
|
|
Debug.print(cvAdr+1);
|
|
Debug.print(" - ");
|
|
Debug.println(value);
|
|
#endif
|
|
|
|
#if defined(DCC)
|
|
dcc.opsProgDirectCV(cvAdr,value); //return value from DCC via 'notifyCVVerify'
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21CVPOMWRITEBYTE(uint16_t Adr, uint16_t cvAdr, uint8_t value)
|
|
{
|
|
#if defined(RCDEB)
|
|
Debug.print(F("Z21 POM Byte A"));
|
|
Debug.print(Adr);
|
|
Debug.print(F(" set CV#"));
|
|
Debug.print(cvAdr+1);
|
|
Debug.print(" - ");
|
|
Debug.println(value);
|
|
#endif
|
|
|
|
#if defined(DCC)
|
|
dcc.opsProgramCV(Adr, cvAdr, value); //set decoder byte
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21CVPOMWRITEBIT(uint16_t Adr, uint16_t cvAdr, uint8_t value)
|
|
{
|
|
#if defined(RCDEB)
|
|
Debug.print(F("Z21 POM Bit A"));
|
|
Debug.print(Adr);
|
|
Debug.print(F(" set CV#"));
|
|
Debug.print(cvAdr+1);
|
|
Debug.print(" - ");
|
|
Debug.println(value);
|
|
#endif
|
|
|
|
#if defined(DCC)
|
|
dcc.opsPOMwriteBit(Adr, cvAdr, value); //set decoder bit
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21CVPOMREADBYTE (uint16_t Adr, uint16_t cvAdr)
|
|
{
|
|
#if defined(DCCGLOBALDETECTOR) && defined(DCC)
|
|
|
|
#if defined(RCDEB)
|
|
Debug.print(F("Z21 POM A"));
|
|
Debug.print(Adr);
|
|
Debug.print(" read CV#");
|
|
Debug.println(cvAdr+1);
|
|
#endif
|
|
|
|
RailcomCVAdr = cvAdr;
|
|
|
|
#if defined(MEGA_MCU)
|
|
RailComStart(); //Start Reading Data!
|
|
#endif
|
|
|
|
#else
|
|
z21.setCVNack(); //Antwort: LAN_X_CV_NACK
|
|
#endif
|
|
|
|
#if defined(DCC)
|
|
dcc.opsPOMreadCV(Adr, cvAdr); //get decoder value
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//Information to DCC Libray via EEPROM (50 to 75) over RailCom, ProgModus, etc.
|
|
void notifyz21UpdateConf() {
|
|
FIXSTORAGE.FIXMODE(EEPROMDCCPROPERTY, (FIXSTORAGE.read(EEPROMDCCPROPERTY) & 0xFC) | 0x02); //Ausgabeformat nur DCC (Ausgabeformat (0x00) DCC+MM, (0x02) nur DCC, (0x03) nur MM)
|
|
#if defined(ESP_WIFI)
|
|
FIXSTORAGE.commit();
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.println("Z21 Conf: ");
|
|
Debug.print(F("RailCom: ")); //RailCom: 0=aus/off, 1=ein/on
|
|
Debug.print(FIXSTORAGE.read(EEPROMRailCom), HEX);
|
|
Debug.print(F(", PWR-B: ")); //Power-Button: 0=Gleisspannung aus, 1=Nothalt
|
|
Debug.print(FIXSTORAGE.read(52), HEX);
|
|
Debug.print(F(", Prog-R: ")); //Auslese-Modus: 0=Nichts, 1=Bit, 2=Byte, 3=Beides
|
|
Debug.print(FIXSTORAGE.read(EEPROMProgReadMode), HEX);
|
|
Debug.print(F(", RstP(s): "));
|
|
Debug.print(FIXSTORAGE.read(EEPROMRSTsRepeat));
|
|
Debug.print(F(", RstP(f): "));
|
|
Debug.print(FIXSTORAGE.read(EEPROMRSTcRepeat));
|
|
Debug.print(F(", ProgP: "));
|
|
Debug.print(FIXSTORAGE.read(EEPROMProgRepeat));
|
|
Debug.print(F(", MainV: "));
|
|
Debug.print(word(FIXSTORAGE.read(73),FIXSTORAGE.read(72)));
|
|
Debug.print(F(", ProgV: "));
|
|
Debug.println(word(FIXSTORAGE.read(75),FIXSTORAGE.read(74)));
|
|
#endif
|
|
|
|
#if defined(DCC)
|
|
dcc.loadEEPROMconfig(); //Update values!
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//Information Abfrage Z21 Library
|
|
uint8_t notifyz21ClientHash(uint8_t client) {
|
|
|
|
byte HashIP = 0x00;
|
|
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
if (client < Z21_Eth_offset) { //Prüfe über Offset ob WiFi or LAN
|
|
#endif
|
|
#if defined(WIFI)
|
|
//get Client IP-Hash from WiFi
|
|
HashIP = listofWLANHash[client - 1];
|
|
#endif
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
}
|
|
else {
|
|
//get Client IP-Hash from Ethernet Interface
|
|
byte cl = client - Z21_Eth_offset - 1; //senden ohne Offset!
|
|
HashIP = mem[cl].IP0 ^ mem[cl].IP1 ^ mem[cl].IP2 ^ mem[cl].IP3; //make Hash from IP
|
|
}
|
|
#endif
|
|
|
|
#if defined(Z21DEBUG)
|
|
Debug.print(client);
|
|
Debug.print(F(" IPHash: "));
|
|
Debug.print(HashIP, HEX);
|
|
Debug.print(F(" BC: "));
|
|
Debug.println(FIXSTORAGE.read(0x200 | HashIP), BIN);
|
|
#endif
|
|
|
|
return HashIP; //not found!
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//bug fix for enc28 Ethernet shield with UIP Library - need to do this after each packet!
|
|
#if defined (LAN) && defined (ENC28)
|
|
void restartENC28() {
|
|
Udp.stop(); // added for enc28
|
|
#if defined(Z21SYSTEMDATADEBUG)
|
|
Debug.print("restart connection: ");// added for enc28
|
|
Debug.println(Udp.begin(z21Port) ? "success" : "failed");// added for enc28
|
|
#else
|
|
Udp.begin(z21Port);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void notifyz21EthSend(uint8_t client, uint8_t *data)
|
|
{
|
|
#if defined(Z21DATADEBUG)
|
|
Debug.print(client);
|
|
Debug.print(F(" Z21 TX: "));
|
|
for (byte i = 0; i < data[0]; i++) {
|
|
Debug.print(data[i], HEX);
|
|
Debug.print(" ");
|
|
}
|
|
Debug.println();
|
|
#endif
|
|
if (client == 0) { //all stored
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
for (byte i = 0; i < storedIP; i++) {
|
|
if (mem[i].time > 0) { //noch aktiv?
|
|
IPAddress ip(mem[i].IP0, mem[i].IP1, mem[i].IP2, mem[i].IP3);
|
|
Udp.beginPacket(ip, mem[i].port); //Broadcast
|
|
Udp.write(data, data[0]);
|
|
Udp.endPacket();
|
|
#if defined (LAN) && defined (ENC28)
|
|
restartENC28(); //fix bug!
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(WIFI)
|
|
WLAN.write(client);
|
|
WLAN.write(data, data[0]);
|
|
#endif
|
|
}
|
|
else {
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
if (client < Z21_Eth_offset) { //Prüfe über Offset ob WiFi or LAN
|
|
#endif
|
|
#if defined(WIFI)
|
|
WLAN.write(client);
|
|
WLAN.write(data, data[0]);
|
|
#endif
|
|
#if defined(LAN) || defined(ESP_WIFI)
|
|
}
|
|
else {
|
|
byte cl = client - Z21_Eth_offset - 1; //senden ohne Offset!
|
|
IPAddress ip(mem[cl].IP0, mem[cl].IP1, mem[cl].IP2, mem[cl].IP3);
|
|
Udp.beginPacket(ip, mem[cl].port); //no Broadcast
|
|
Udp.write(data, data[0]);
|
|
Udp.endPacket();
|
|
}
|
|
#endif
|
|
}
|
|
#if defined (LAN) && defined (ENC28)
|
|
restartENC28(); //fix bug!
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------
|
|
#endif
|