// 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. // // The #if directive prevent compile errors for Uno and Nano by excluding the // HAL directives from the build. #if !defined(IO_NO_HAL) // Include devices you need. #include "IODevice.h" //#include "IO_HALDisplay.h" // Auxiliary display devices (LCD/OLED) //#include "IO_HCSR04.h" // Ultrasonic range sensor //#include "IO_VL53L0X.h" // Laser time-of-flight sensor //#include "IO_DFPlayer.h" // MP3 sound player //#include "IO_TouchKeypad.h // Touch keypad with 16 keys //#include "IO_EXTurntable.h" // Turntable-EX turntable controller //#include "IO_EXFastClock.h" // FastClock driver //#include "IO_PCA9555.h" // 16-bit I/O expander (NXP & Texas Instruments). //#include "IO_I2CDFPlayer.h" // DFPlayer over I2C //========================================================================== // 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 directives define auxiliary display devices. // These can be defined in addition to the system display (display // number 0) that is defined in config.h. // A write to a line which is beyond the length of the screen will overwrite // the bottom line, unless the line number is 255 in which case the // screen contents will scroll up before the text is written to the // bottom line. //======================================================================= // // Create a 128x32 OLED display device as display number 1 // (line 0 is written by EX-RAIL 'SCREEN(1, 0, "text")'). //HALDisplay::create(1, 0x3d, 128, 32); // Create a 20x4 LCD display device as display number 2 // (line 0 is written by EX-RAIL 'SCREEN(2, 0, "text")'). // HALDisplay::create(2, 0x27, 20, 4); //======================================================================= // User Add-ins //======================================================================= // User add-ins can be created when you want to do something that // can't be done in EX-RAIL but does not merit a HAL driver. The // user add-in is a C++ function that is executed periodically by the // HAL subsystem. // Example: The function will be executed once per second and will display, // on screen #3, the first eight entries (assuming an 8-line display) // from the loco speed table. // Put the following block of code in myHal.cpp OUTSIDE of the // halSetup() function: // // void updateLocoScreen() { // for (int i=0; i<8; i++) { // if (DCC::speedTable[i].loco > 0) { // int speed = DCC::speedTable[i].speedCode; // char direction = (speed & 0x80) ? 'R' : 'F'; // speed = speed & 0x7f; // if (speed > 0) speed = speed - 1; // SCREEN(3, i, F("Loco:%4d %3d %c"), DCC::speedTable[i].loco, // speed, direction); // } // } // } // // Put the following line INSIDE the halSetup() function: // // UserAddin::create(updateLocoScreen, 1000); // //======================================================================= // 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 a PCF8575 16-port I2C GPIO Extender module. //======================================================================= // The parameters are: // First Vpin=200 // Number of VPINs=16 (numbered 200-215) // I2C address of module=0x23 //PCF8575::create(200, 16, 0x23); // Alternative form using INT pin (see above) //PCF8575::create(200, 16, 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. ANOUT(10000,23,0,0) will play the 23rd mp3 file. // ANOUT(10000,23,30,0) 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. ANOUT(10001,30,0,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); //======================================================================= // Play mp3 files from a Micro-SD card, using a DFPlayer MP3 Module on a SC16IS750/SC16IS752 I2C UART //======================================================================= // DFPlayer via NXP SC16IS752 I2C Dual UART. Each device has 2 UARTs on a single I2C address // Total nr of devices on an I2C bus is 16, with 2 UARTs on each address making a total of 32 UARTs per I2C bus // I2C address range 0x48 - 0x57 // // audioMixer can be 1 when connected to audio mixer 1, 2 when connected to audio mixer 2, 0 will default to 1 // Generic format: // I2CDFPlayer::create(1st vPin, vPins, I2C address, xtal); // Parameters: // 1st vPin : First virtual pin that EX-Rail can control to play a sound, use PLAYSOUND command (alias of ANOUT) // vPins : Total number of virtual pins allocated (1 vPin is supported currently) // 1st vPin for UART 0 // I2C Address : I2C address of the serial controller, in 0x format // xtal : 0 for 1.8432Mhz, 1 for 14.7456Mhz // // The vPin is also a pin that can be read with the WAITFOR(vPin) command indicating if the DFPlayer has finished playing a track // // I2CDFPlayer::create(10000, 1, 0x48, 1); // // Configuration example on a multiplexer // I2CDFPlayer::create(10000, 1, {I2CMux_0, SubBus_0, 0x48}, 1); //======================================================================= // 16-pad capacitative touch key pad based on TP229 IC. //======================================================================= // Parameters below: // 11000 = first VPIN allocated // 16 = number of VPINs allocated // 25 = local GPIO pin number for clock signal // 24 = local GPIO pin number for data signal // // Pressing the key pads numbered 1-16 cause each of the nominated digital VPINs // (11000-11015 in this case) to be activated. // TouchKeypad::create(11000, 16, 25, 24); //======================================================================= // The following directive defines an EX-Turntable turntable instance. //======================================================================= // EXTurntable::create(VPIN, Number of VPINs, I2C Address) // // The parameters are: // VPIN=600 // Number of VPINs=1 (Note there is no reason to change this) // I2C address=0x60 // // Note that the I2C address is defined in the EX-Turntable code, and 0x60 is the default. //EXTurntable::create(600, 1, 0x60); //======================================================================= // The following directive defines an EX-IOExpander instance. //======================================================================= // EXIOExpander::create(VPIN, Number of VPINs, I2C Address) // // The parameters are: // VPIN=an available Vpin // Number of VPINs=pin count (must match device in use as per documentation) // I2C address=an available I2C address (default 0x65) // // Note that the I2C address is defined in the EX-IOExpander code, and 0x65 is the default. // The example is for an Arduino Nano. //EXIOExpander::create(800, 18, 0x65); //======================================================================= // The following directive defines a rotary encoder instance. //======================================================================= // The parameters are: // firstVpin = First available Vpin to allocate // numPins= Number of Vpins to allocate, can be either 1 or 2 // i2cAddress = Available I2C address (default 0x70) //RotaryEncoder::create(firstVpin, numPins, i2cAddress); //RotaryEncoder::create(700, 1, 0x70); //RotaryEncoder::create(701, 2, 0x71); //======================================================================= // The following directive defines an EX-FastClock instance. //======================================================================= // EXFastCLock::create(I2C Address) // // The parameters are: // // I2C address=0x55 (decimal 85) // // Note that the I2C address is defined in the EX-FastClock code, and 0x55 is the default. // EXFastClock::create(0x55); } #endif