460 Zeilen
15 KiB
C

//--------------------------------------------------------------------------------------------
#define FIND 0x00 //Display Mode - search for Address!
//**************************************************************
//Setup up PIN-Configuration for different MCU (UNO/MEGA/Sanduino)
#include "MCU_config.h"
//--------------------------------------------------------------------------------------------
//Load everything that is used:
//**************************************************************
//Report Upload Sketch Time:
#if defined(DebugBaud) || defined(Z21DISPLAY) || defined(HTTPCONF) || defined(ESP_WIFI)
const char* comp_date = __DATE__ " " __TIME__; //sketch was compiled
#endif
//**************************************************************
//LocoNet LocoBuffer-USB -> deaktiviere alle DEBUG Funktionen!
#if (defined(LnBufferUSB) && defined(LOCONET)) || (defined(UNO_MCU) && defined(XPRESSNET))
#undef DebugBaud
#undef Debug
#undef DEBUG
#undef DEBUG_WLAN_CONFIG
#undef REPORT
#undef REQEST
#undef LnDEB
#undef XnDEB
#undef Z21DEBUG
#undef Z21DATADEBUG
#undef Z21SYSTEMDATADEBUG
#else
#undef LnBufferUSB //deaktiviere!
#endif
//**************************************************************
//Firmware store in EEPROM:
#define EEPROMSwVerMSB 0
#define EEPROMSwVerLSB 1
/**************************************************************
Serial Debug Output:*/
#ifdef DebugBaud
#ifndef Debug
#define Debug Serial //Interface for Debugging
#endif
#endif
/**************************************************************
XpressNet Library:*/
#ifdef XPRESSNET
#include <XpressNetMaster.h>
#endif
/**************************************************************
LocoNet Library:*/
#ifdef LOCONET
#if defined(ESP32_MCU) //use LocoNet2 Library
#include "LNSerial.h"
LocoNetBus bus;
#include <LocoNetESP32.h>
LocoNetESP32 locoNetPhy(&bus, LNRxPin, LNTxPin, 0);
LocoNetDispatcher parser(&bus);
#elif defined(ESP8266_MCU)
#include "LNHwSerial.h"
#else
#include <LocoNet.h>
#endif
#endif
/**************************************************************
BOOSTER EXT:*/
#ifdef BOOSTER_EXT
#define BOOSTER_EXT_ON HIGH
#define BOOSTER_EXT_OFF LOW
#endif
/**************************************************************
BOOSTER INT:*/
#ifdef BOOSTER_INT
//#define BOOSTER_INT_ON LOW //only for old Mode without RAILCOM support over NDCC!
//#define BOOSTER_INT_OFF HIGH //only for old Mode without RAILCOM support over NDCC!
#define BOOSTER_INT_NDCC //for new RAILCOM Booster3R - GoIntPin activate inverted booster signal
#endif
/**************************************************************
DCC Master to create a DCC Signal:*/
#include <DCCPacketScheduler.h> //DCC Interface Library
//**************************************************************
void AllLocoData(uint16_t adr, uint8_t data[]); //so function can be found!
//Power functions:
static void globalPower (byte state);
static uint16_t getRailmA();
static uint16_t getRailVolt();
//--------------------------------------------------------------
// certain global XPressnet status indicators
#define csNormal 0x00 // Normal Operation Resumed ist eingeschaltet
#define csEmergencyStop 0x01 // Der Nothalt ist eingeschaltet
#define csTrackVoltageOff 0x02 // Die Gleisspannung ist abgeschaltet
#define csShortCircuit 0x04 // Kurzschluss
#define csServiceMode 0x08 // Der Programmiermodus ist aktiv - Service Mode
byte Railpower = csTrackVoltageOff; //State of RailPower at Startup
bool Z21ButtonLastState = false; //store last value of the Push Button for GO/STOP
/**************************************************************
ESP OTA Upload:*/
#if defined(ESP_OTA)
#include <ArduinoOTA.h>
#include "ESP_OTA.h"
#endif
//**************************************************************
#if defined(Z21VIRTUAL)
#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(TXvWiFi, RXvWiFi); // init Soft Serial
#undef LAN //LAN nicht zulassen - Doppelbelegung der Signalleitungen!
#undef HTTPCONF
#undef LOCONET
#endif
//**************************************************************
#if defined(LAN) //W5100 LAN Interface Library
#define HTTPCONF //activate Website to configure DHCP, IP Adress and Number of S88 Bus Module
#if !defined(MEGA_MCU)
#undef ENC28
#endif
#if defined(ENC28) //MEGA MCU only!
#include <UIPEthernet.h>
#else
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library
#endif
#else
//need class for variable type "IPAddress" (WLANlocalIP) what is showing WLAN IP on Display!
#if defined(WIFI) && defined(Z21DISPLAY)
#include <IPAddress.h>
#endif
#endif
#if defined(ESP_WIFI) //ESP8266 or ESP32
#if defined(ESP8266_MCU)
#include <ESP8266WiFi.h>
//#include <ESP8266WebServer.h>
#if defined ESP_OTA
#include <ESP8266mDNS.h> //OTA update
#endif
#elif defined(ESP32_MCU)
#include <WiFi.h>
#include <WiFiAP.h> //optional?
#if defined(ESP_OTA)
#include <ESPmDNS.h> //ESP32 only, OTA update
#endif
#endif
#include <WiFiClient.h>
#include <WiFiUdp.h>
#endif
//**************************************************************
//Configure the analog 1.1V refenence voltage:
#ifndef AREF_1V1
#if defined(EXTERNAL_UREF_1V1)
#define AREF_1V1 EXTERNAL //externe 1.1 Volt
#elif defined(MEGA_MCU)
#define AREF_1V1 INTERNAL1V1 //Arduino MEGA internal 1,1 Volt
#elif defined(UNO_MCU)
#define AREF_1V1 INTERNAL //Arduino UNO (equal to 1.1 volts on the ATmega168 or ATmega328P)
#elif defined(ESP32_MCU) | defined(ESP8266_MCU) //ESP Modul
#define AREF_1V1 //always 1,1 Volt
#endif
//other Arduino's 5,0 Volt internal refence!
#endif
//**************************************************************
//Z21 LAN Protokoll:
#if defined(LAN) || defined (WIFI) || defined(ESP_WIFI)
#include <z21.h>
z21Class z21;
#else
//make LocoNet work when no WLAN and LAN is used!
#if defined(LOCONET)
#include <z21header.h>
#endif
#endif
//**************************************************************
#if defined(DUE_MCU)
#include <DueFlashStorage.h>
DueFlashStorage Flash;
#define FIXSTORAGE Flash
#define FIXMODE write
#elif defined(ESP32_MCU) //use NVS on ESP32!
#include <z21nvs.h>
z21nvsClass NVSEEPROMZ21;
#define FIXSTORAGE NVSEEPROMZ21
#define FIXMODE write
#else
#include <EEPROM.h> //EEPROM - to store number of S88 Module and LAN IP
#define FIXSTORAGE EEPROM
#if defined(ESP8266_MCU) || defined(ESP32_MCU)
#define FIXMODE write
#else
#define FIXMODE update
#endif
#endif
#if defined(ESP8266_MCU) || defined(ESP32_MCU)
//--> EEPROM Konfiguration ESP:
#define EESize 767 //Größe des EEPROM
#define EEStringMaxSize 40 //Länge String im EEPROM
//Client:
#define EEssidLength 200 //Länge der SSID
#define EEssidBegin 201 //Start Wert
#define EEpassLength 232 //Länge des Passwort
#define EEpassBegin 233 //Start Wert
//AP:
#define EEssidAPLength 264 //Länge der SSID AP
#define EEssidAPBegin 265 //Start Wert
#define EEpassAPLength 298 //Länge des Passwort AP
#define EEpassAPBegin 300 //Start Wert
#define EEkanalAP 299 //Kanal AP
#endif
//--> Allgemeine EEPROM Konfiguration:
//S88:
#define EES88Moduls 38 //Adresse EEPROM Anzahl der Module für S88
//LAN:
#define EELANDHCP 39 //aktiviert DHCP auf dem LAN Interface
#define EELANip 40 //Startddress im EEPROM für die IP
//---------------------------------------------------------------
#if defined(LAN) //W5100 LAN Udp Setup:
EthernetUDP Udp; //UDP for communication with APP/Computer (Port 21105)
#if defined(Z21MT)
EthernetUDP UdpMT; //UDP to Z21 Maintenance Tool (Port 21106)
#include "Z21Maintenance.h"
#endif
//---------------------------------------------------------------
boolean LAN_DHCP = false; //LAN DHCP Modus aus
// The IP address will be dependent on your local network:
IPAddress LAN_ip(192, 168, 0, 111); //Werkseinstellung ist: 192.168.0.111
/*LAN MAC configuration: */
#ifndef LANmacB2
#define LANmacB2 0xEF
#endif
#ifndef LANmacB1
#define LANmacB1 0xFE
#endif
#ifndef LANmacB0
#define LANmacB0 0xED
#endif
static byte mac[] = { 0x84, 0x2B, 0xBC, LANmacB2, LANmacB1, LANmacB0 };
/*LAN DHCP configuration: */
#ifndef LANTimeoutDHCP
#define LANTimeoutDHCP 5000 //Timeout to wait for a DHCP respose
#endif
#if defined(HTTPCONF) //W5100 LAN config Website:
EthernetServer server(80); // (port 80 is default for HTTP):
#endif
#endif //LAN end
//---------------------------------------------------------------
#if defined(ESP_WIFI)
#ifndef ESP_HTTPCONF
#define ESP_HTTPCONF
#endif
#ifndef SssidAP
#if defined(ESP32_MCU)
#define SssidAP "Z21_ESP32_Central" // Default Z21 AP (SSID)
#else
#define SssidAP "Z21_ESP_Central" // Default Z21 AP (SSID)
#endif
#endif
#ifndef SpassAP
#define SpassAP "12345678" // Default Z21 network password
#endif
#ifndef SkanalAP
#define SkanalAP 3 // Default Kanal des AP
#endif
//AP default Z21 IP
IPAddress AP_ip(192, 168, 0, 111); //Werkseinstellung ist: 192.168.0.111
IPAddress AP_sb(255, 255, 255, 0); //Werkseinstellung Subnet
WiFiUDP Udp;
#if defined(ESP_HTTPCONF) //Setting Website
WiFiServer ESPWebserver(80); //default port 80 for HTTP
#endif
#endif
//--------------------------------------------------------------
//Z21 Protokoll Typ Spezifikationen
#if defined(LAN) || defined (WIFI) || defined(ESP_WIFI)
#include "Z21type.h" //Z21 Data Information
#endif
//--------------------------------------------------------------
//S88 Singel Bus:
#if defined(S88N)
#include "S88.h"
#endif
//--------------------------------------------------------------
//Dallas Temperatur Sensor:
#if defined(DALLASTEMPSENSE) //&& defined(MEGA_MCU)
#include <OneWire.h>
#include <DallasTemperature.h>
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device address
DeviceAddress insideThermometer;
#define DALLAS_RESOLUTION 9 //Temperatur resolution
#endif
//--------------------------------------------------------------
//INA219 current sensor
#if defined (INA219)
#include <Wire.h>
#include <INA219_WE.h>
INA219_WE ina219 = INA219_WE(INA219); //default Address 0x40
#endif
//--------------------------------------------------------------
//DCC Interface Master Short Detection:
//EXTERNAL BOOSTER:
#define DetectShortCircuit 0x1FF //to detect short circuit (0xFF)
unsigned int ShortTime = 0; //Time Count for Short Detect
unsigned long LEDcount = 0; //Timer for Status LED
//INTERNAL BOOSTER:
#if defined(BOOSTER_INT_MAINCURRENT)
#define BOOSTER_INT_CURRENT_SHORT_DETECT //wenn nicht aktiviert dann hier einschalten!
unsigned long ShortTimeINT = 0; //Time Count for internal short detect
byte ShortTimeINTcounter = 0; //Count the low detection
#if defined(ESP8266_MCU)
//slow down readings on ESP8266 to let WIFI work! Slow down to min. ATTENTION WIFI may stop!
#define VAmpReadTimeNormal 10 //interval of reading normal (ms)
#else //other MCU:
#define VAmpINTMesureCount 10 //Anzahl des Messungen
byte CountVAmpINT = 0; //Zahl des Messung
#endif
uint16_t CalcVAmpINT = 0; //zwischen Messung
uint16_t VAmpINT = 0; //current power on the track
#ifndef DETECT_SHORT_INT_WAIT
#define DETECT_SHORT_INT_WAIT 20 //time in ms to wait before power off
#endif
#ifndef DETECT_SHORT_INT_VALUE //normal operation
#if defined(INA219)
#define DETECT_SHORT_INT_VALUE 3200 //mA for Short Power
#elif defined(ESP8266_MCU)
#define DETECT_SHORT_INT_VALUE 205 //because of WeMos internal voltage devider! á (2A * 0.33 Ohm) / (3,3/1024) = 204.8
#else
#if defined(AREF_1V1)
#define DETECT_SHORT_INT_VALUE 1000 //analogRead value for "mA" that is too much (AREF = 1.1V) á (3,3A * 0.33 Ohm) / (1,1/1024) = 1014
#else
#define DETECT_SHORT_INT_VALUE 250 //analogRead value for "mA" that is too much (AREF = 5.0V)
#endif
#endif
#endif
#endif
//setting for DCC ACK sense Value
#if defined(INA219)
#define DCC_ACK_SENSE_VALUE 60 //WeMos D1 Mini with INA219 connected!
#elif defined(ESP8266) //ESP8266 or WeMos D1 mini
#define DCC_ACK_SENSE_VALUE 4 //WeMos has a voltage divider for 3.1 Volt -> we not want to modify the board!
#else
#define DCC_ACK_SENSE_VALUE 30 //value difference
#endif
//--------------------------------------------------------------
DCCPacketScheduler dcc;
#define DCC //activate DCC Interface (always)
//--------------------------------------------------------------
#if defined(DCCGLOBALDETECTOR) && defined(DCC)
#include "Z21_RailCom.h"
#endif
//--------------------------------------------------------------
#if defined(XPRESSNET)
XpressNetMasterClass XpressNet;
#endif
//--------------------------------------------------------------
//LocoNet-Bus:
#if defined (LOCONET)
#include "LNInterface.h"
#endif
//--------------------------------------------------------------
//XpressNet-Bus:
#if defined(XPRESSNET)
#include "XBusInterface.h"
#endif
//--------------------------------------------------------------
//Z21 Ethernet communication:
#if defined(LAN) || defined(WIFI) || defined(ESP_WIFI)
#include "Z21_LAN.h"
#endif
//--------------------------------------------------------------
//OLED Display
#if defined(Z21DISPLAY)
#include "OLEDdisplay.h"
#endif
//--------------------------------------------------------------
//Power function:
#include "POWER.h" //load Z21 Power functions
//--------------------------------------------------------------
//Webpage
#if defined(HTTPCONF) || defined(ESP_HTTPCONF)
#include "Webpage.h"
#endif
//--------------------------------------------------------------------------------------------
//Z21 Software Reset:
#if defined(SOFT_RESET)
#include <avr/wdt.h>
#define soft_restart() \
do \
{ \
wdt_enable(WDTO_15MS); \
for(;;) \
{ \
} \
} while(0)
#endif
//--------------------------------------------------------------------------------------------
#if defined(DEBUG) && !defined(DUE_MCU) && !defined(ESP8266) && !defined(ESP32)
//ONLY for Atmega, not for Arduino DUE or ESP chip (ARM)!
int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
#endif
//--------------------------------------------------------------------------------------------
//ONLY for ESP
#if defined(DEBUG) && (defined(ESP8266) || defined(ESP32))
int freeRam ()
{
return ESP.getFreeHeap();
}
#endif
//--------------------------------------------------------------