diff --git a/.gitignore b/.gitignore index b0b8666..61eedc4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ config.h .vscode/extensions.json mySetup.h mySetup.cpp +myHal.cpp myAutomation.h myFilter.cpp myAutomation.h diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 674c2ef..7cf2ed1 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "ee5db61" +#define GITHUB_SHA "a2f8a8e" diff --git a/I2CManager.h b/I2CManager.h index 25ab004..1163261 100644 --- a/I2CManager.h +++ b/I2CManager.h @@ -107,11 +107,16 @@ * the loop() function is called, and may be adequate under some circumstances. * The advantage of NOT using interrupts is that the impact of I2C upon the DCC waveform (when accurate timing mode isn't in use) * becomes almost zero. - * This mechanism is under evaluation and should not be relied upon as yet. * */ +// Uncomment following line to enable Wire library instead of native I2C drivers //#define I2C_USE_WIRE + +// Uncomment following line to disable the use of interrupts by the native I2C drivers. +//#define I2C_NO_INTERRUPTS + +// Default to use interrupts within the native I2C drivers. #ifndef I2C_NO_INTERRUPTS #define I2C_USE_INTERRUPTS #endif diff --git a/I2CManager_NonBlocking.h b/I2CManager_NonBlocking.h index 3bdfc38..112e51e 100644 --- a/I2CManager_NonBlocking.h +++ b/I2CManager_NonBlocking.h @@ -129,6 +129,10 @@ uint8_t I2CManagerClass::read(uint8_t i2cAddress, uint8_t *readBuffer, uint8_t r /*************************************************************************** * checkForTimeout() function, called from isBusy() and wait() to cancel * requests that are taking too long to complete. + * This function doesn't fully work as intended so is not currently called. + * Instead we check for an I2C hang-up and report an error from + * I2CRB::wait(), but we aren't able to recover from the hang-up. Such faults + * may be caused by an I2C wire short for example. ***************************************************************************/ void I2CManagerClass::checkForTimeout() { unsigned long currentMicros = micros(); @@ -163,7 +167,10 @@ void I2CManagerClass::loop() { #if !defined(I2C_USE_INTERRUPTS) handleInterrupt(); #endif - checkForTimeout(); + // Timeout is now reported in I2CRB::wait(), not here. + // I've left the code, commented out, as a reminder to look at this again + // in the future. + //checkForTimeout(); } /*************************************************************************** @@ -175,6 +182,9 @@ void I2CManagerClass::handleInterrupt() { // Update hardware state machine I2C_handleInterrupt(); + // Enable interrupts to minimise effect on other interrupt code + interrupts(); + // Check if current request has completed. If there's a current request // and state isn't active then state contains the completion status of the request. if (state != I2C_STATE_ACTIVE && currentRequest != NULL) { diff --git a/IODevice.cpp b/IODevice.cpp index c7ab7c0..b61ecf8 100644 --- a/IODevice.cpp +++ b/IODevice.cpp @@ -28,8 +28,9 @@ #define USE_FAST_IO #endif -// Link to mySetup function. If not defined, the function reference will be NULL. -extern __attribute__((weak)) void mySetup(); +// Link to halSetup function. If not defined, the function reference will be NULL. +extern __attribute__((weak)) void halSetup(); +extern __attribute__((weak)) void mySetup(); // Deprecated function name, output warning if it's declared //================================================================================================================== // Static methods @@ -61,12 +62,15 @@ void IODevice::begin() { } _initPhase = false; - // Call user's mySetup() function (if defined in the build in mySetup.cpp). + // Check for presence of deprecated mySetup() function, and output warning. + if (mySetup) + DIAG(F("WARNING: mySetup() function should be renamed to halSetup()")); + + // Call user's halSetup() function (if defined in the build in myHal.cpp). // The contents will depend on the user's system hardware configuration. - // The mySetup.cpp file is a standard C++ module so has access to all of the DCC++EX APIs. - if (mySetup) { - mySetup(); - } + // The myHal.cpp file is a standard C++ module so has access to all of the DCC++EX APIs. + if (halSetup) + halSetup(); } // Overarching static loop() method for the IODevice subsystem. Works through the @@ -301,18 +305,16 @@ bool IODevice::owns(VPIN id) { // Minimal implementations of public HAL interface, to support Arduino pin I/O and nothing more. void IODevice::begin() { DIAG(F("NO HAL CONFIGURED!")); } -bool IODevice::configure(VPIN pin, ConfigTypeEnum, int, int p[]) { +bool IODevice::configure(VPIN pin, ConfigTypeEnum configType, int nParams, int p[]) { + if (configType!=CONFIGURE_INPUT || nParams!=1 || pin >= NUM_DIGITAL_PINS) return false; #ifdef DIAG_IO DIAG(F("Arduino _configurePullup Pin:%d Val:%d"), pin, p[0]); #endif - if (p[0]) { - pinMode(pin, INPUT_PULLUP); - } else { - pinMode(pin, INPUT); - } + pinMode(pin, p[0] ? INPUT_PULLUP : INPUT); return true; } void IODevice::write(VPIN vpin, int value) { + if (vpin >= NUM_DIGITAL_PINS) return; digitalWrite(vpin, value); pinMode(vpin, OUTPUT); } @@ -320,6 +322,7 @@ void IODevice::writeAnalogue(VPIN, int, uint8_t, uint16_t) {} bool IODevice::isBusy(VPIN) { return false; } bool IODevice::hasCallback(VPIN) { return false; } int IODevice::read(VPIN vpin) { + if (vpin >= NUM_DIGITAL_PINS) return 0; return !digitalRead(vpin); // Return inverted state (5v=0, 0v=1) } int IODevice::readAnalogue(VPIN vpin) { diff --git a/IO_PCF8574.h b/IO_PCF8574.h index dea5e2c..58c4654 100644 --- a/IO_PCF8574.h +++ b/IO_PCF8574.h @@ -75,7 +75,7 @@ private: if (immediate) { uint8_t buffer[1]; I2CManager.read(_I2CAddress, buffer, 1); - _portInputState = ((uint16_t)buffer) & 0xff; + _portInputState = buffer[0]; } else { requestBlock.wait(); // Wait for preceding operation to complete // Issue new request to read GPIO register @@ -86,7 +86,7 @@ private: // This function is invoked when an I/O operation on the requestBlock completes. void _processCompletion(uint8_t status) override { if (status == I2C_STATUS_OK) - _portInputState = ((uint16_t)inputBuffer[0]) & 0xff; + _portInputState = inputBuffer[0]; else _portInputState = 0xff; } diff --git a/RMFT2.cpp b/RMFT2.cpp index 5a91541..c2a99d3 100644 --- a/RMFT2.cpp +++ b/RMFT2.cpp @@ -720,10 +720,10 @@ void RMFT2::kill(const FSH * reason, int operand) { byte opcode=GET_OPCODE; if (opcode==OPCODE_ENDEXRAIL) return; if (opcode!=OPCODE_SIGNAL) continue; - byte redpin=GET_OPERAND(0); + VPIN redpin=GET_OPERAND(0); if (redpin!=id)continue; - byte amberpin=GET_OPERAND(1); - byte greenpin=GET_OPERAND(2); + VPIN amberpin=GET_OPERAND(1); + VPIN greenpin=GET_OPERAND(2); // If amberpin is zero, synthesise amber from red+green IODevice::write(redpin,red || (amber && (amberpin==0))); if (amberpin) IODevice::write(amberpin,amber); diff --git a/SSD1306Ascii.cpp b/SSD1306Ascii.cpp index 17fd5a2..2fc23c2 100644 --- a/SSD1306Ascii.cpp +++ b/SSD1306Ascii.cpp @@ -89,28 +89,93 @@ const uint8_t FLASH SSD1306AsciiWire::blankPixels[30] = {0x40, // First byte specifies data mode 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +//============================================================================== +// this section is based on https://github.com/adafruit/Adafruit_SSD1306 + +/** Initialization commands for a 128x32 or 128x64 SSD1306 oled display. */ +const uint8_t FLASH SSD1306AsciiWire::Adafruit128xXXinit[] = { + // Init sequence for Adafruit 128x32/64 OLED module + 0x00, // Set to command mode + SSD1306_DISPLAYOFF, + SSD1306_SETDISPLAYCLOCKDIV, 0x80, // the suggested ratio 0x80 + SSD1306_SETMULTIPLEX, 0x3F, // ratio 64 (initially) + SSD1306_SETDISPLAYOFFSET, 0x0, // no offset + SSD1306_SETSTARTLINE | 0x0, // line #0 + SSD1306_CHARGEPUMP, 0x14, // internal vcc + SSD1306_MEMORYMODE, 0x02, // page mode + SSD1306_SEGREMAP | 0x1, // column 127 mapped to SEG0 + SSD1306_COMSCANDEC, // column scan direction reversed + SSD1306_SETCOMPINS, 0X12, // set COM pins + SSD1306_SETCONTRAST, 0x7F, // contrast level 127 + SSD1306_SETPRECHARGE, 0xF1, // pre-charge period (1, 15) + SSD1306_SETVCOMDETECT, 0x40, // vcomh regulator level + SSD1306_DISPLAYALLON_RESUME, + SSD1306_NORMALDISPLAY, + SSD1306_DISPLAYON +}; + +//------------------------------------------------------------------------------ +// This section is based on https://github.com/stanleyhuangyc/MultiLCD + +/** Initialization commands for a 128x64 SH1106 oled display. */ +const uint8_t FLASH SSD1306AsciiWire::SH1106_132x64init[] = { + 0x00, // Set to command mode + SSD1306_DISPLAYOFF, + SSD1306_SETDISPLAYCLOCKDIV, 0X80, // set osc division + SSD1306_SETMULTIPLEX, 0x3F, // ratio 64 + SSD1306_SETDISPLAYOFFSET, 0X00, // set display offset + SSD1306_SETSTARTPAGE | 0X0, // set page address + SSD1306_SETSTARTLINE | 0x0, // set start line + SH1106_SET_PUMP_MODE, SH1106_PUMP_ON, // set charge pump enable + SSD1306_SEGREMAP | 0X1, // set segment remap + SSD1306_COMSCANDEC, // Com scan direction + SSD1306_SETCOMPINS, 0X12, // set COM pins + SSD1306_SETCONTRAST, 0x80, // 128 + SSD1306_SETPRECHARGE, 0X1F, // set pre-charge period + SSD1306_SETVCOMDETECT, 0x40, // set vcomh + SH1106_SET_PUMP_VOLTAGE | 0X2, // 8.0 volts + SSD1306_NORMALDISPLAY, // normal / reverse + SSD1306_DISPLAYON +}; + //============================================================================== // SSD1306AsciiWire Method Definitions //------------------------------------------------------------------------------ // Constructor SSD1306AsciiWire::SSD1306AsciiWire(int width, int height) { + m_displayWidth = width; + m_displayHeight = height; // Set size in characters in base class lcdRows = height / 8; lcdCols = width / 6; + m_col = 0; + m_row = 0; + m_colOffset = 0; I2CManager.begin(); I2CManager.setClock(400000L); // Set max supported I2C speed for (byte address = 0x3c; address <= 0x3d; address++) { if (I2CManager.exists(address)) { + m_i2cAddr = address; + if (m_displayWidth==132 && m_displayHeight==64) { + // SH1106 display. This uses 128x64 centered within a 132x64 OLED. + m_colOffset = 2; + I2CManager.write_P(address, SH1106_132x64init, sizeof(SH1106_132x64init)); + } else if (m_displayWidth==128 && (m_displayHeight==64 || m_displayHeight==32)) { + // SSD1306 128x64 or 128x32 + I2CManager.write_P(address, Adafruit128xXXinit, sizeof(Adafruit128xXXinit)); + if (m_displayHeight == 32) + I2CManager.write(address, 5, 0, // Set command mode + SSD1306_SETMULTIPLEX, 0x1F, // ratio 32 + SSD1306_SETCOMPINS, 0x02); // sequential COM pins, disable remap + } else { + DIAG(F("OLED configuration option not recognised")); + return; + } // Device found DIAG(F("%dx%d OLED display configured on I2C:x%x"), width, height, address); - if (width == 132) - begin(&SH1106_132x64, address); - else if (height == 32) - begin(&Adafruit128x32, address); - else - begin(&Adafruit128x64, address); // Set singleton address lcdDisplay = this; clear(); @@ -132,23 +197,6 @@ void SSD1306AsciiWire::clearNative() { } } -// Initialise device -void SSD1306AsciiWire::begin(const DevType* dev, uint8_t i2cAddr) { - m_i2cAddr = i2cAddr; - m_col = 0; - m_row = 0; - const uint8_t* table = (const uint8_t*)GETFLASHW(&dev->initcmds); - uint8_t size = GETFLASH(&dev->initSize); - m_displayWidth = GETFLASH(&dev->lcdWidth); - m_displayHeight = GETFLASH(&dev->lcdHeight); - m_colOffset = GETFLASH(&dev->colOffset); - I2CManager.write_P(m_i2cAddr, table, size); - if (m_displayHeight == 32) - I2CManager.write(m_i2cAddr, 5, 0, // Set command mode - SSD1306_SETMULTIPLEX, 0x1F, // ratio 32 - SSD1306_SETCOMPINS, 0x02); // sequential COM pins, disable remap -} - //------------------------------------------------------------------------------ // Set cursor position (by text line) @@ -209,82 +257,6 @@ size_t SSD1306AsciiWire::writeNative(uint8_t ch) { return 1; } -//============================================================================== -// this section is based on https://github.com/adafruit/Adafruit_SSD1306 - -/** Initialization commands for a 128x32 or 128x64 SSD1306 oled display. */ -const uint8_t FLASH SSD1306AsciiWire::Adafruit128xXXinit[] = { - // Init sequence for Adafruit 128x32/64 OLED module - 0x00, // Set to command mode - SSD1306_DISPLAYOFF, - SSD1306_SETDISPLAYCLOCKDIV, 0x80, // the suggested ratio 0x80 - SSD1306_SETMULTIPLEX, 0x3F, // ratio 64 (initially) - SSD1306_SETDISPLAYOFFSET, 0x0, // no offset - SSD1306_SETSTARTLINE | 0x0, // line #0 - SSD1306_CHARGEPUMP, 0x14, // internal vcc - SSD1306_MEMORYMODE, 0x02, // page mode - SSD1306_SEGREMAP | 0x1, // column 127 mapped to SEG0 - SSD1306_COMSCANDEC, // column scan direction reversed - SSD1306_SETCOMPINS, 0X12, // set COM pins - SSD1306_SETCONTRAST, 0x7F, // contrast level 127 - SSD1306_SETPRECHARGE, 0xF1, // pre-charge period (1, 15) - SSD1306_SETVCOMDETECT, 0x40, // vcomh regulator level - SSD1306_DISPLAYALLON_RESUME, - SSD1306_NORMALDISPLAY, - SSD1306_DISPLAYON -}; - -/** Initialize a 128x32 SSD1306 oled display. */ -const DevType FLASH SSD1306AsciiWire::Adafruit128x32 = { - Adafruit128xXXinit, - sizeof(Adafruit128xXXinit), - 128, - 32, - 0 -}; - -/** Initialize a 128x64 oled display. */ -const DevType FLASH SSD1306AsciiWire::Adafruit128x64 = { - Adafruit128xXXinit, - sizeof(Adafruit128xXXinit), - 128, - 64, - 0 -}; -//------------------------------------------------------------------------------ -// This section is based on https://github.com/stanleyhuangyc/MultiLCD - -/** Initialization commands for a 128x64 SH1106 oled display. */ -const uint8_t FLASH SSD1306AsciiWire::SH1106_132x64init[] = { - 0x00, // Set to command mode - SSD1306_DISPLAYOFF, - SSD1306_SETDISPLAYCLOCKDIV, 0X80, // set osc division - SSD1306_SETMULTIPLEX, 0x3F, // ratio 64 - SSD1306_SETDISPLAYOFFSET, 0X00, // set display offset - SSD1306_SETSTARTPAGE | 0X0, // set page address - SSD1306_SETSTARTLINE | 0x0, // set start line - SH1106_SET_PUMP_MODE, SH1106_PUMP_ON, // set charge pump enable - SSD1306_SEGREMAP | 0X1, // set segment remap - SSD1306_COMSCANDEC, // Com scan direction - SSD1306_SETCOMPINS, 0X12, // set COM pins - SSD1306_SETCONTRAST, 0x80, // 128 - SSD1306_SETPRECHARGE, 0X1F, // set pre-charge period - SSD1306_SETVCOMDETECT, 0x40, // set vcomh - SH1106_SET_PUMP_VOLTAGE | 0X2, // 8.0 volts - SSD1306_NORMALDISPLAY, // normal / reverse - SSD1306_DISPLAYON -}; - -/** Initialize a 132x64 oled SH1106 display. */ -const DevType FLASH SSD1306AsciiWire::SH1106_132x64 = { - SH1106_132x64init, - sizeof(SH1106_132x64init), - 128, - 64, - 2 // SH1106 is a 132x64 controller but most OLEDs are only attached - // to columns 2-129. -}; - //------------------------------------------------------------------------------ diff --git a/SSD1306Ascii.h b/SSD1306Ascii.h index 90a7e7e..312a62f 100644 --- a/SSD1306Ascii.h +++ b/SSD1306Ascii.h @@ -32,21 +32,6 @@ //#define NOLOWERCASE //------------------------------------------------------------------------------ -// Device initialization structure. - -struct DevType { - /* Pointer to initialization command bytes. */ - const uint8_t* initcmds; - /* Number of initialization bytes */ - const uint8_t initSize; - /* Width of the display in pixels */ - const uint8_t lcdWidth; - /** Height of the display in pixels. */ - const uint8_t lcdHeight; - /* Column offset RAM to display. Used to pick start column of SH1106. */ - const uint8_t colOffset; -}; - // Constructor class SSD1306AsciiWire : public LCDDisplay { public: @@ -55,25 +40,17 @@ class SSD1306AsciiWire : public LCDDisplay { SSD1306AsciiWire(int width, int height); // Initialize the display controller. - void begin(const DevType* dev, uint8_t i2cAddr); + void begin(uint8_t i2cAddr); // Clear the display and set the cursor to (0, 0). void clearNative() override; // Set cursor to start of specified text line void setRowNative(byte line) override; - - // Initialize the display controller. - void init(const DevType* dev); // Write one character to OLED size_t writeNative(uint8_t c) override; - // Display characteristics / initialisation - static const DevType FLASH Adafruit128x32; - static const DevType FLASH Adafruit128x64; - static const DevType FLASH SH1106_132x64; - bool isBusy() override { return requestBlock.isBusy(); } private: diff --git a/myHal.cpp_example.txt b/myHal.cpp_example.txt new file mode 100644 index 0000000..13a6b4b --- /dev/null +++ b/myHal.cpp_example.txt @@ -0,0 +1,161 @@ +// Sample myHal.cpp file. +// +// To use this file, copy it to myHal.cpp and uncomment the directives and/or +// edit them to satisfy your requirements. If you only want to use up to +// two MCP23017 GPIO Expander modules and/or up to two PCA9685 Servo modules, +// then you don't need this file as DCC++EX configures these for free! + +// Note that if the file has a .cpp extension it WILL be compiled into the build +// and the halSetup() function WILL be invoked. +// +// To prevent this, temporarily rename the file to myHal.txt or similar. +// + +// Include devices you need. +#include "IODevice.h" +#include "IO_HCSR04.h" // Ultrasonic range sensor +#include "IO_VL53L0X.h" // Laser time-of-flight sensor +#include "IO_DFPlayer.h" // MP3 sound player + + +//========================================================================== +// The function halSetup() is invoked from CS if it exists within the build. +// The setup calls are included between the open and close braces "{ ... }". +// Comments (lines preceded by "//") are optional. +//========================================================================== + +void halSetup() { + + //======================================================================= + // The following directive defines a PCA9685 PWM Servo driver module. + //======================================================================= + // The parameters are: + // First Vpin=100 + // Number of VPINs=16 (numbered 100-115) + // I2C address of module=0x40 + + //PCA9685::create(100, 16, 0x40); + + + //======================================================================= + // The following directive defines an MCP23017 16-port I2C GPIO Extender module. + //======================================================================= + // The parameters are: + // First Vpin=196 + // Number of VPINs=16 (numbered 196-211) + // I2C address of module=0x22 + + //MCP23017::create(196, 16, 0x22); + + + // Alternative form, which allows the INT pin of the module to request a scan + // by pulling Arduino pin 40 to ground. Means that the I2C isn't being polled + // all the time, only when a change takes place. Multiple modules' INT pins + // may be connected to the same Arduino pin. + + //MCP23017::create(196, 16, 0x22, 40); + + + //======================================================================= + // The following directive defines an MCP23008 8-port I2C GPIO Extender module. + //======================================================================= + // The parameters are: + // First Vpin=300 + // Number of VPINs=8 (numbered 300-307) + // I2C address of module=0x22 + + //MCP23008::create(300, 8, 0x22); + + + //======================================================================= + // The following directive defines a PCF8574 8-port I2C GPIO Extender module. + //======================================================================= + // The parameters are: + // First Vpin=200 + // Number of VPINs=8 (numbered 200-207) + // I2C address of module=0x23 + + //PCF8574::create(200, 8, 0x23); + + + // Alternative form using INT pin (see above) + + //PCF8574::create(200, 8, 0x23, 40); + + + //======================================================================= + // The following directive defines an HCSR04 ultrasonic ranging module. + //======================================================================= + // The parameters are: + // Vpin=2000 (only one VPIN per directive) + // Number of VPINs=1 + // Arduino pin connected to TRIG=30 + // Arduino pin connected to ECHO=31 + // Minimum trigger range=20cm (VPIN goes to 1 when <20cm) + // Maximum trigger range=25cm (VPIN goes to 0 when >25cm) + // Note: Multiple devices can be configured by using a different ECHO pin + // for each one. The TRIG pin can be shared between multiple devices. + // Be aware that the 'ping' of one device may be received by another + // device and position them accordingly! + + //HCSR04::create(2000, 30, 31, 20, 25); + //HCSR04::create(2001, 30, 32, 20, 25); + + + //======================================================================= + // The following directive defines a single VL53L0X Time-of-Flight range sensor. + //======================================================================= + // The parameters are: + // VPIN=5000 + // Number of VPINs=1 + // I2C address=0x29 (default for this chip) + // Minimum trigger range=200mm (VPIN goes to 1 when <20cm) + // Maximum trigger range=250mm (VPIN goes to 0 when >25cm) + + //VL53L0X::create(5000, 1, 0x29, 200, 250); + + // For multiple VL53L0X modules, add another parameter which is a VPIN connected to the + // module's XSHUT pin. This allows the modules to be configured, at start, + // with distinct I2C addresses. In this case, the address 0x29 is only used during + // initialisation to configure each device in turn with the desired unique I2C address. + // The examples below have the modules' XSHUT pins connected to the first two pins of + // the first MCP23017 module (164 and 165), but Arduino pins may be used instead. + // The first module here is given I2C address 0x30 and the second is 0x31. + + //VL53L0X::create(5000, 1, 0x30, 200, 250, 164); + //VL53L0X::create(5001, 1, 0x31, 200, 250, 165); + + + //======================================================================= + // Play mp3 files from a Micro-SD card, using a DFPlayer MP3 Module. + //======================================================================= + // Parameters: + // 10000 = first VPIN allocated. + // 10 = number of VPINs allocated. + // Serial1 = name of serial port (usually Serial1 or Serial2). + // With these parameters, up to 10 files may be played on pins 10000-10009. + // Play is started from EX-RAIL with SET(10000) for first mp3 file, SET(10001) + // for second file, etc. Play may also be initiated by writing an analogue + // value to the first pin, e.g. SERVO(10000,23,0) will play the 23rd mp3 file. + // SERVO(10000,23,30) will do the same thing, as well as setting the volume to + // 30 (maximum value). + // Play is stopped by RESET(10000) (or any other allocated VPIN). + // Volume may also be set by writing an analogue value to the second pin for the player, + // e.g. SERVO(10001,30,0) sets volume to maximum (30). + // The EX-RAIL script may check for completion of play by calling WAITFOR(pin), which will only proceed to the + // following line when the player is no longer busy. + // E.g. + // SEQUENCE(1) + // AT(164) // Wait for sensor attached to pin 164 to activate + // SET(10003) // Play fourth MP3 file + // LCD(4, "Playing") // Display message on LCD/OLED + // WAITFOR(10003) // Wait for playing to finish + // LCD(4, " ") // Clear LCD/OLED line + // FOLLOW(1) // Go back to start + + // DFPlayer::create(10000, 10, Serial1); + + +} + +#endif diff --git a/mySetup.cpp_example.txt b/mySetup.cpp_example.txt deleted file mode 100644 index 0ce511a..0000000 --- a/mySetup.cpp_example.txt +++ /dev/null @@ -1,217 +0,0 @@ -// Sample mySetup.cpp file. -// -// To use this file, copy it to mySetup.cpp and uncomment the directives and/or -// edit them to satisfy your requirements. - -// Note that if the file has a .cpp extension it WILL be compiled into the build -// and the mySetup() function WILL be invoked. -// -// To prevent this, temporarily rename it to mySetup.txt or similar. -// - -// Only the #include directives relating to the devices in use need be included here. -#include "IODevice.h" -#include "IO_HCSR04.h" -#include "IO_VL53L0X.h" -#include "DFPlayer.h" -#include "IO_Network.h" -#include "Net_RF24" -#include "Net_ENC28J60" -#include "Net_Ethernet" - - -// Examples of statically defined HAL directives (alternative to the create() call). -// These have to be outside of the mySetup() function. - -//======================================================================= -// The following directive defines a PCA9685 PWM Servo driver module. -//======================================================================= -// The parameters are: -// First Vpin=100 -// Number of VPINs=16 (numbered 100-115) -// I2C address of module=0x40 - -//PCA9685 pwmModule1(100, 16, 0x40); - - -//======================================================================= -// The following directive defines an MCP23017 16-port I2C GPIO Extender module. -//======================================================================= -// The parameters are: -// First Vpin=196 -// Number of VPINs=16 (numbered 196-211) -// I2C address of module=0x22 - -//MCP23017 gpioModule2(196, 16, 0x22); - - -// Alternative form, which allows the INT pin of the module to request a scan -// by pulling Arduino pin 40 to ground. Means that the I2C isn't being polled -// all the time, only when a change takes place. Multiple modules' INT pins -// may be connected to the same Arduino pin. - -//MCP23017 gpioModule2(196, 16, 0x22, 40); - - -//======================================================================= -// The following directive defines an MCP23008 8-port I2C GPIO Extender module. -//======================================================================= -// The parameters are: -// First Vpin=300 -// Number of VPINs=8 (numbered 300-307) -// I2C address of module=0x22 - -//MCP23008 gpioModule3(300, 8, 0x22); - - -//======================================================================= -// The following directive defines a PCF8574 8-port I2C GPIO Extender module. -//======================================================================= -// The parameters are: -// First Vpin=200 -// Number of VPINs=8 (numbered 200-207) -// I2C address of module=0x23 - -//PCF8574 gpioModule4(200, 8, 0x23); - - -// Alternative form using INT pin (see above) - -//PCF8574 gpioModule4(200, 8, 0x23, 40); - - -//======================================================================= -// The function mySetup() is invoked from CS if it exists within the build. -// It is called just before mysetup.h is executed, so things set up within here can be -// referenced by commands in mySetup.h. -//======================================================================= - -void mySetup() { - - // Alternative way of creating a module driver, which has to be within the mySetup() function - // The other devices can also be created in this way. The parameter lists for the - // create() function are identical to the parameter lists for the declarations. - - //MCP23017::create(196, 16, 0x22); - - - //======================================================================= - // Play mp3 files from a Micro-SD card, using a DFPlayer MP3 Module. - //======================================================================= - // Parameters: - // 10000 = first VPIN allocated. - // 10 = number of VPINs allocated. - // Serial1 = name of serial port (usually Serial1 or Serial2). - // With these parameters, up to 10 files may be played on pins 10000-10009. - // Play is started from EX-RAIL with SET(10000) for first mp3 file, SET(10001) - // for second file, etc. Play may also be initiated by writing an analogue - // value to the first pin, e.g. SERVO(10000,23,0) will play the 23rd mp3 file. - // SERVO(10000,23,30) will do the same thing, as well as setting the volume to - // 30 (maximum value). - // Play is stopped by RESET(10000) (or any other allocated VPIN). - // Volume may also be set by writing an analogue value to the second pin for the player, - // e.g. SERVO(10001,30,0) sets volume to maximum (30). - // The EX-RAIL script may check for completion of play by calling WAITFOR(pin), which will only proceed to the - // following line when the player is no longer busy. - // E.g. - // SEQUENCE(1) - // AT(164) // Wait for sensor attached to pin 164 to activate - // SET(10003) // Play fourth MP3 file - // LCD(4, "Playing") // Display message on LCD/OLED - // WAITFOR(10003) // Wait for playing to finish - // LCD(4, " ") // Clear LCD/OLED line - // FOLLOW(1) // Go back to start - - // DFPlayer::create(10000, 10, Serial1); - - - //======================================================================= - // Remote (networked) VPIN Configuration - //======================================================================= - // Define remote pins to be used. The range of remote pins is like a common data area shared - // between all nodes. - // For outputs, a write to a remote VPIN causes a message to be sent to another node, which then performs - // the write operation on the device VPIN that is local to that node. - // For inputs, the state of remote input VPIN is read on the node where it is connected, and then - // sent to other nodes in the system where the state is saved and processed. Updates are sent on change, and - // also periodically if no changes. - // - // Currently, analogue inputs are not enabled for remote access. - // - // Each definition is a triple of remote node, remote pin, type, indexed by relative pin. - // Each pin may be an input whose value is to be read before being transmitted (RPIN_IN), - // an output which is to be triggered when written to (RPIN_OUT) or both (RPIN_INPUT), - // such as a servo or DFPlayer device pin. Unused pins (e.g. spares to reserve contiguous - // pin sequences) should be defined sd VPIN_NONE with 0 as the type. - // Where possible, align the input and inout pins on an offset which is a multiple of 8 - // from the start of the remote pins, as in the example below. - // - // There is a limit of 224 in the number of pin states per node that are sent - // over the network (to keep the number of sent messages to 1 x 32 bytes). This restriction - // may be lifted in future. - // - // In the example below with two nodes 30 and 31, - // a turnout object set to operate pin 4004 will operate the servo connected to - // VPIN 100 on node 30; - // a sensor object monitoring pin 4024 will trigger if pin D24 on node - // 31 activates; - // an output object associated with pin 4002 will, when set on, activate - // pin 166 (MCP23017 pin 3) on node 30. - // - // All nodes on the same network should use the same REMOTEPINS setup, and the - // node number of each node should be set to a different number. - // - // REMOTEPINS rpins[] = { - // {30,164,RPIN_IN} , //4000 Node 30, first MCP23017 pin, input - // {30,165,RPIN_IN}, //4001 Node 30, second MCP23017 pin, input - // {30,166,RPIN_OUT}, //4002 Node 30, third MCP23017 pin, output - // {30,166,RPIN_OUT}, //4003 Node 30, fourth MCP23017 pin, output - // {30,100,RPIN_INOUT}, //4004 Node 30, first PCA9685 servo pin - // {30,101,RPIN_INOUT}, //4005 Node 30, second PCA9685 servo pin - // {30,102,RPIN_INOUT}, //4006 Node 30, third PCA9685 servo pin - // {30,103,RPIN_INOUT}, //4007 Node 30, fourth PCA9685 servo pin - // {30,24,RPIN_IN}, //4008 Node 30, Arduino pin D24 - // {30,25,RPIN_IN}, //4009 Node 30, Arduino pin D25 - // {30,26,RPIN_IN}, //4010 Node 30, Arduino pin D26 - // {30,27,RPIN_IN}, //4011 Node 30, Arduino pin D27 - // {30,VPIN_NONE,0}, //4012 Node 30, spare - // {30,VPIN_NONE,0}, //4013 Node 30, spare - // {30,VPIN_NONE,0}, //4014 Node 30, spare - // {30,VPIN_NONE,0}, //4015 Node 30, spare - // - // {31,164,RPIN_IN} , //4016 Node 31, first MCP23017 pin, input - // {31,165,RPIN_IN}, //4017 Node 31, second MCP23017 pin, input - // {31,166,RPIN_OUT}, //4018 Node 31, third MCP23017 pin, output - // {31,166,RPIN_OUT}, //4019 Node 31, fourth MCP23017 pin, output - // {31,100,RPIN_INOUT}, //4020 Node 31, first PCA9685 servo pin - // {31,101,RPIN_INOUT}, //4021 Node 31, second PCA9685 servo pin - // {31,102,RPIN_INOUT}, //4022 Node 31, third PCA9685 servo pin - // {31,103,RPIN_INOUT}, //4023 Node 31, fourth PCA9685 servo pin - // {31,24,RPIN_IN}, //4024 Node 31, Arduino pin D24 - // {31,25,RPIN_IN}, //4025 Node 31, Arduino pin D25 - // {31,26,RPIN_IN}, //4026 Node 31, Arduino pin D26 - // {31,27,RPIN_IN}, //4027 Node 31, Arduino pin D27 - // {31,VPIN_NONE,0}, //4028 Node 31, spare - // {31,VPIN_NONE,0}, //4029 Node 31, spare - // {31,VPIN_NONE,0}, //4030 Node 31, spare - // {31,VPIN_NONE,0} //4031 Node 31, spare - // }; - - // Network using RF24 wireless module, with CE on pin 48 and CS on pin 49 and node=30 - - // Net_RF24 *rf24Driver = new Net_RF24(48, 49); - // Network::create(4000, NUMREMOTEPINS(rpins), 30, rpins, rf24Driver); - - // Network using ENC28J60 ethernet module, with CS on pin 49 and node=30 - - // Net_ENC28J60 *encDriver = new Net_ENC28J60(49); - // Network::create(4000, NUMREMOTEPINS(rpins), 30, rpins, encDriver); - - // Network using Arduino Ethernet library, with CS on default pin (10) and node=30 - // This would be the option selected if you already use ethernet for DCC++EX - // commands. - - // Net_Ethernet *etherDriver = new Net_Ethernet(); - // Network::create(4000, NUMREMOTEPINS(rpins), 30, rpins, etherDriver); - -} diff --git a/version.h b/version.h index ca3fc4e..3089db9 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,7 @@ #include "StringFormatter.h" -#define VERSION "3.2.0 rc3" +#define VERSION "3.2.0 rc5" // 3.2.0 Major functional and non-functional changes. // New HAL added for I/O (digital and analogue inputs and outputs, servos etc). // Support for MCP23008, MCP23017 and PCF9584 I2C GPIO Extender modules.