/* * © 2020, Chris Harlow. All rights reserved. * * This file is a demonstattion of calling the DCC-EX API */ #include "DCC.h" #include "DIAG.h" #include "DCCEXParser.h" #include "WifiInterface.h" #ifdef ARDUINO_AVR_UNO #include SoftwareSerial Serial1(15,16); // YOU must get thee pins correct to use Wifi on a UNO #define WIFI_BAUD 9600 #else #define WIFI_BAUD 115200 #endif // this code is here to demonstrate use of the DCC API and other techniques // myFilter is an example of an OPTIONAL command filter used to intercept < > commands from // the usb or wifi streamm. It demonstrates how a command may be intercepted // or even a new command created without having to break open the API library code. // The filter is permitted to use or modify the parameter list before passing it on to // the standard parser. By setting the opcode to 0, the standard parser will // just ignore the command on the assumption that you have already handled it. // // The filter must be enabled by calling the DCC EXParser::setFilter method, see use in setup(). void myComandFilter(Print * stream, byte & opcode, byte & paramCount, int p[]) { (void)stream; // avoid compiler warning if we don't access this parameter switch (opcode) { case '!': // Create a bespoke new command to clear all loco reminders or specific locos e.g if (paramCount==0) DCC::forgetAllLocos(); else for (int i=0;iThis is my HTTP filter responding.
")); } // Callback functions are necessary if you call any API that must wait for a response from the // programming track. The API must return immediately otherwise other loop() functions would be blocked. // Your callback function will be invoked when the data arrives from the prog track. // See the DCC:getLocoId example in the setup function. void myCallback(int result) { DIAG(F("\n getting Loco Id callback result=%d"),result); } // Create a serial command parser... This is OPTIONAL if you don't need to handle JMRI type commands // from the Serial port. DCCEXParser serialParser; // Try monitoring the memory #include "freeMemory.h" int ramLowWatermark=32767; // This figure gets overwritten dynamically in loop() void setup() { // The main sketch has responsibilities during setup() // Responsibility 1: Start the usb connection for diagnostics and possible JMRI input // DIAGSERAL is normally Serial but uses SerialUSB on a SAMD processor DIAGSERIAL.begin(115200); while(!DIAGSERIAL); // Responsibility 2: 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(STANDARD_MOTOR_SHIELD); // Responsibility 3: **Optionally** Start the WiFi interface if required. // NOTE: On a Uno you will have to provide a SoftwareSerial // configured for the pins connected to the Wifi card // and a 9600 baud rate. // setup(serial, F(router name) or NULL, F(router password), F(hostname), F(AcessPoint name) or NULL , port) // (port 3532 is 0xDCC decimal.) Serial1.begin(WIFI_BAUD); WifiInterface::setup(Serial1, F("BTHub5-M6PT"), F("49de8d4862"),F("DCCEX"),3532); // Optionally tell the Wifi parser to use my http filter. // This will intercept http commands from Wifi. WifiInterface::setHTTPCallback(myHttpFilter); // This is just for demonstration purposes DIAG(F("\n===== CVReader demonstrating DCC::getLocoId() call ==========\n")); DCC::getLocoId(myCallback); // myCallback will be called with the result DIAG(F("\n===== DCC::getLocoId has returned, but the callback wont be executed until we are in loop() ======\n")); // Optionally tell the command parser to use my example filter. // This will intercept JMRI commands from both USB and Wifi DCCEXParser::setFilter(myComandFilter); DIAG(F("\nReady for JMRI commands\n")); } 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(DIAGSERIAL); // Responsibility 3: Optionally handle any incoming WiFi traffic WifiInterface::loop(); // Your additional loop code // Optionally report any decrease in memory (will automatically trigger on first call) int freeNow=freeMemory(); if (freeNow