2020-09-22 20:57:11 +02:00
////////////////////////////////////////////////////////////////////////////////////
// © 2020, Chris Harlow. All rights reserved.
//
// This file is a demonstattion of setting up a DCC-EX
2020-09-26 17:29:11 +02:00
// Command station with optional support for direct connection of WiThrottle devices
2020-09-22 20:57:11 +02:00
// such as "Engine Driver". If you contriol your layout through JMRI
// then DON'T connect throttles to this wifi, connect them to JMRI.
//
2020-09-26 17:29:11 +02:00
// THE WIFI FEATURE IS NOT SUPPORTED ON ARDUINO DEVICES WITH ONLY 2KB RAM.
2020-09-22 20:57:11 +02:00
////////////////////////////////////////////////////////////////////////////////////
# include "config.h"
2020-09-26 09:49:51 +02:00
# include "DCCEX.h"
2020-09-25 19:51:08 +02:00
2020-09-26 17:29:11 +02:00
// 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.
2020-09-22 20:57:11 +02:00
DCCEXParser serialParser ;
2020-09-12 00:27:46 +02:00
2020-10-22 21:41:56 +02:00
// (1) Start NetworkInterface - HTTP callback
void httpRequestHandler ( ParsedRequest * req , Client * client ) {
DIAG ( F ( " \n Parsed Request: " ) ) ;
DIAG ( F ( " \n Method: [%s] " ) , req - > method ) ;
DIAG ( F ( " \n URI: [%s] " ) , req - > uri ) ;
DIAG ( F ( " \n HTTP version: [%s] " ) , req - > version ) ;
DIAG ( F ( " \n Parameter count:[%d] \n " ) , * req - > paramCount ) ;
}
// (1) End NetworkInterface - HTTP callback
2020-09-22 20:57:11 +02:00
void setup ( )
{
2020-09-12 00:27:46 +02:00
// The main sketch has responsibilities during setup()
2020-09-22 20:57:11 +02:00
// Responsibility 1: Start the usb connection for diagnostics
2020-09-12 00:27:46 +02:00
// This is normally Serial but uses SerialUSB on a SAMD processor
Serial . begin ( 115200 ) ;
2020-10-12 20:32:47 +02:00
DIAG ( F ( " DCC++ EX v%S " ) , F ( VERSION ) ) ;
CONDITIONAL_LCD_START {
// This block is ignored if LCD not in use
LCD ( 0 , F ( " DCC++ EX v%S " ) , F ( VERSION ) ) ;
LCD ( 1 , F ( " Starting " ) ) ;
}
2020-09-19 01:40:18 +02:00
2020-09-22 20:57:11 +02:00
// Start the WiFi interface on a MEGA, Uno cannot currently handle WiFi
2020-10-12 20:32:47 +02:00
# if WIFI_ON
2020-10-05 19:42:31 +02:00
WifiInterface : : setup ( WIFI_SERIAL_LINK_SPEED , F ( WIFI_SSID ) , F ( WIFI_PASSWORD ) , F ( WIFI_HOSTNAME ) , IP_PORT ) ;
2020-09-25 22:49:53 +02:00
# endif // WIFI_ON
2020-09-12 00:27:46 +02:00
2020-09-22 20:57:11 +02:00
// 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
// Optionally a Timer number (1..4) may be passed to DCC::begin to override the default Timer1 used for the
// waveform generation. e.g. DCC::begin(STANDARD_MOTOR_SHIELD,2); to use timer 2
2020-10-12 20:32:47 +02:00
DCC : : begin ( MOTOR_SHIELD_TYPE ) ;
2020-10-22 21:41:56 +02:00
// (2) Start NetworkInterface - The original WifiInterface is still there but disabled
DIAG ( F ( " \n Free RAM before network init: [%d] \n " ) , freeMemory ( ) ) ;
DIAG ( F ( " \n Network Setup In Progress ... \n " ) ) ;
2020-10-23 21:30:56 +02:00
NetworkInterface : : setup ( ETHERNET , TCP , 8888 ) ; // specify WIFI or ETHERNET depending on if you have Wifi or an EthernetShield; Wifi has to be on Serial1 UDP or TCP for the protocol
2020-10-22 21:41:56 +02:00
NetworkInterface : : setHttpCallback ( httpRequestHandler ) ; // The network interface will provide and HTTP request object which can be used as well to send the reply. cf. example above
// NetworkInterface::setup(WIFI, UDP, 8888); // Setup without port will use the by default port 2560 :: Wifi+UDP IS NOT YET SUPPORTED
// NetworkInterface::setup(WIFI); // setup without port and protocol will use by default TCP on port 2560
// NetworkInterface::setup(); // all defaults ETHERNET, TCP on port 2560
DIAG ( F ( " \n Network Setup done ... " ) ) ;
DIAG ( F ( " \n Free RAM after network init: [%d] \n " ) , freeMemory ( ) ) ;
// (2) End starting NetworkInterface
2020-10-12 20:32:47 +02:00
LCD ( 1 , F ( " Ready " ) ) ;
2020-09-12 00:27:46 +02:00
}
2020-09-22 20:57:11 +02:00
void loop ( )
{
2020-09-12 00:27:46 +02:00
// The main sketch has responsibilities during loop()
2020-09-22 20:57:11 +02:00
2020-09-12 00:27:46 +02:00
// Responsibility 1: Handle DCC background processes
// (loco reminders and power checks)
2020-09-22 20:57:11 +02:00
DCC : : loop ( ) ;
2020-09-12 00:27:46 +02:00
// Responsibility 2: handle any incoming commands on USB connection
serialParser . loop ( Serial ) ;
2020-09-22 20:57:11 +02:00
// Responsibility 3: Optionally handle any incoming WiFi traffic
2020-10-04 17:29:48 +02:00
# if WIFI_ON
2020-09-12 00:27:46 +02:00
WifiInterface : : loop ( ) ;
2020-09-22 20:57:11 +02:00
# endif
2020-10-22 21:41:56 +02:00
// (3) Start Loop NetworkInterface
NetworkInterface : : loop ( ) ;
// (3) End Loop NetworkInterface
2020-10-12 20:32:47 +02:00
LCDDisplay : : loop ( ) ; // ignored if LCD not in use
2020-09-22 20:57:11 +02:00
// Optionally report any decrease in memory (will automatically trigger on first call)
# if ENABLE_FREE_MEM_WARNING
2020-09-26 09:42:24 +02:00
static int ramLowWatermark = 32767 ; // replaced on first loop
2020-09-22 20:57:11 +02:00
int freeNow = freeMemory ( ) ;
if ( freeNow < ramLowWatermark )
{
ramLowWatermark = freeNow ;
2020-10-12 20:32:47 +02:00
LCD ( 2 , F ( " Free RAM=%5db " ) , ramLowWatermark ) ;
2020-09-22 20:57:11 +02:00
}
# endif
2020-09-12 00:27:46 +02:00
}