mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-25 00:56:13 +01:00
311 lines
12 KiB
Plaintext
311 lines
12 KiB
Plaintext
// 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
|
|
|
|
//==========================================================================
|
|
// 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<OLED>::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<LiquidCrystal>(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);
|
|
|
|
|
|
//=======================================================================
|
|
// 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
|