diff --git a/.gitignore b/.gitignore index 09e6aac..d2edddf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch -CVReader.ino + diff --git a/examples/advanced/CVReader.ino b/examples/advanced/CVReader.ino new file mode 100644 index 0000000..33724fc --- /dev/null +++ b/examples/advanced/CVReader.ino @@ -0,0 +1,152 @@ +/* + * © 2020, Chris Harlow. All rights reserved. + * + * This file is a demonstattion of calling the DCC-EX API + */ + + + +#include "DCCEX.h" + +#ifdef ARDUINO_AVR_UNO + #include + SoftwareSerial Serial1(15,16); // YOU must get these 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 + + // 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 + + 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 commands coming from keyboard or JMRI on thr USB connection. +DCCEXParser serialParser; + +void setup() { + + // Responsibility 1: Start the usb connection for diagnostics and possible JMRI input + Serial.begin(115200); + + // Responsibility 2: Start the DCC engine with information about your Motor Shield. + // STANDARD_MOTOR_SHIELD, POLOLU_MOTOR_SHIELD, FIREBOX_MK1, FIREBOX_MK1S are pre defined in MotorDriverss.h + DCC::begin(STANDARD_MOTOR_SHIELD); +} + +void 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); +} diff --git a/examples/basicWifi/CVReader.ino b/examples/basicWifi/CVReader.ino new file mode 100644 index 0000000..797088f --- /dev/null +++ b/examples/basicWifi/CVReader.ino @@ -0,0 +1,72 @@ +/* + * © 2020, Chris Harlow. All rights reserved. + * + * This file is a demonstattion of setting up a DCC-EX + * Command station to support direct connection of WiThrottle devices + * such as "Engine Driver". If you contriol your layout through JMRI + * then DON'T connect throttles to this wifi, connect them to JMRI. + * + * This is just 3 statements longer than the basic setup. + * + * THIS SETUP DOES NOT APPLY TO ARDUINO UNO WITH ONLY A SINGLE SERIAL PORT. + * REFER TO SEPARATE EXAMPLE. + */ + +#include "DCCEX.h" + + +// Create a serial command parser... Enables certain diagnostics and commands +// to be issued from the USB serial console +// This is NOT intended for JMRI.... + +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); + + // 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 + + DCC::begin(STANDARD_MOTOR_SHIELD); + + // Start the WiFi interface. + // NOTE: References to Serial1 are for the serial port used to connect + // your wifi chip/shield. + + + Serial1.begin(115200); // BAUD rate of your Wifi chip/shield + WifiInterface::setup(Serial1, + F("BTHub5-M6PT"), // Router name + F("49de8d4862"), // Router password + F("DCCEX"), // Hostname (ignored by some wifi chip firmware) + 3532); // port (3532 is 0xDCC) + +} + +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 + WifiInterface::loop(); + +}