mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +01:00
7a2beda2a9
By defining ENABLE_LOOP_MEASUREMENT as true in config.h, the loop measurement will be enabled. This measures the time between successive executions of the main CS loop to help identify if something is taking too long and holding up the other loop functions.
165 lines
5.0 KiB
C++
165 lines
5.0 KiB
C++
////////////////////////////////////////////////////////////////////////////////////
|
|
// DCC-EX CommandStation-EX Please see https://DCC-EX.com
|
|
//
|
|
// This file is the main sketch for the Command Station.
|
|
//
|
|
// CONFIGURATION:
|
|
// Configuration is normally performed by editing a file called config.h.
|
|
// This file is NOT shipped with the code so that if you pull a later version
|
|
// of the code, your configuration will not be overwritten.
|
|
//
|
|
// If you used the automatic installer program, config.h will have been created automatically.
|
|
//
|
|
// To obtain a starting copy of config.h please copy the file config.example.h which is
|
|
// shipped with the code and may be updated as new features are added.
|
|
//
|
|
// If config.h is not found, config.example.h will be used with all defaults.
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if __has_include ( "config.h")
|
|
#include "config.h"
|
|
#else
|
|
#warning config.h not found. Using defaults from config.example.h
|
|
#include "config.example.h"
|
|
#endif
|
|
|
|
|
|
/*
|
|
* © 2020,2021 Chris Harlow, Harald Barth, David Cutting,
|
|
* Fred Decker, Gregor Baues, Anthony W - Dayton All rights reserved.
|
|
*
|
|
*
|
|
* This is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* It is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#include "DCCEX.h"
|
|
|
|
// Create a serial command parser for the USB connection,
|
|
// This supports JMRI or manual diagnostics and commands
|
|
// to be issued from the USB serial console.
|
|
DCCEXParser serialParser;
|
|
|
|
void setup()
|
|
{
|
|
// The main sketch has responsibilities during setup()
|
|
|
|
// Responsibility 1: Start the usb connection for diagnostics
|
|
// This is normally Serial but uses SerialUSB on a SAMD processor
|
|
Serial.begin(115200);
|
|
|
|
CONDITIONAL_LCD_START {
|
|
// This block is still executed for DIAGS if LCD not in use
|
|
LCD(0,F("DCC++ EX v%S"),F(VERSION));
|
|
LCD(1,F("Starting"));
|
|
}
|
|
|
|
// Start the WiFi interface on a MEGA, Uno cannot currently handle WiFi
|
|
|
|
#if WIFI_ON
|
|
WifiInterface::setup(WIFI_SERIAL_LINK_SPEED, F(WIFI_SSID), F(WIFI_PASSWORD), F(WIFI_HOSTNAME), IP_PORT, WIFI_CHANNEL);
|
|
#endif // WIFI_ON
|
|
|
|
#if ETHERNET_ON
|
|
EthernetInterface::setup();
|
|
#endif // ETHERNET_ON
|
|
|
|
// Responsibility 3: Start the DCC engine.
|
|
// Note: this provides DCC with two motor drivers, main and prog, which handle the motor shield(s)
|
|
// Standard supported devices have pre-configured macros but custome hardware installations require
|
|
// detailed pin mappings and may also require modified subclasses of the MotorDriver to implement specialist logic.
|
|
|
|
// STANDARD_MOTOR_SHIELD, POLOLU_MOTOR_SHIELD, FIREBOX_MK1, FIREBOX_MK1S are pre defined in MotorShields.h
|
|
|
|
|
|
DCC::begin(MOTOR_SHIELD_TYPE);
|
|
|
|
#if defined(RMFT_ACTIVE)
|
|
RMFT::begin();
|
|
#endif
|
|
|
|
#if __has_include ( "mySetup.h")
|
|
#define SETUP(cmd) serialParser.parse(F(cmd))
|
|
#include "mySetup.h"
|
|
#undef SETUP
|
|
#endif
|
|
|
|
LCD(1,F("Ready"));
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
// The main sketch has responsibilities during loop()
|
|
|
|
// Responsibility 1: Handle DCC background processes
|
|
// (loco reminders and power checks)
|
|
DCC::loop();
|
|
|
|
// Responsibility 2: handle any incoming commands on USB connection
|
|
serialParser.loop(Serial);
|
|
|
|
// Responsibility 3: Optionally handle any incoming WiFi traffic
|
|
#if WIFI_ON
|
|
WifiInterface::loop();
|
|
#endif
|
|
#if ETHERNET_ON
|
|
EthernetInterface::loop();
|
|
#endif
|
|
|
|
#if defined(RMFT_ACTIVE)
|
|
RMFT::loop();
|
|
#endif
|
|
|
|
LCDDisplay::loop(); // ignored if LCD not in use
|
|
|
|
// Optionally report any decrease in memory (will automatically trigger on first call)
|
|
#if ENABLE_FREE_MEM_WARNING
|
|
static int ramLowWatermark = 32767; // replaced on first loop
|
|
|
|
int freeNow = updateMinimumFreeMemory();
|
|
if (freeNow < ramLowWatermark)
|
|
{
|
|
ramLowWatermark = freeNow;
|
|
LCD(2,F("Free RAM=%5db"), ramLowWatermark);
|
|
}
|
|
#endif
|
|
|
|
// Optionally report average and maximum loop time
|
|
#if ENABLE_LOOP_MEASUREMENT
|
|
static unsigned long startTime = micros();
|
|
static unsigned int maxElapsed = 0;
|
|
static unsigned long totalElapsed = 0;
|
|
static unsigned long count = 0;
|
|
static unsigned long lastOutput = millis();
|
|
|
|
unsigned long endTime = micros();
|
|
unsigned int elapsed = endTime - startTime;
|
|
|
|
if (elapsed > maxElapsed) maxElapsed = elapsed;
|
|
count++;
|
|
totalElapsed += elapsed;
|
|
|
|
unsigned long currentMillis = millis();
|
|
if (currentMillis - lastOutput >= 5000) {
|
|
DIAG(F("\nLoop: max=%dus ave=%dus\n"), maxElapsed, totalElapsed/count);
|
|
maxElapsed = 0;
|
|
totalElapsed = 0;
|
|
count = 0;
|
|
lastOutput = currentMillis;
|
|
}
|
|
startTime = micros();
|
|
#endif
|
|
|
|
}
|