mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 23:56:13 +01:00
Compare commits
2 Commits
d3d6cc97fb
...
dd16e0da97
Author | SHA1 | Date | |
---|---|---|---|
|
dd16e0da97 | ||
|
e823db3d24 |
|
@ -405,16 +405,18 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (params==2) { // <o [-]vpin count>
|
if (params==2) { // <o [-]vpin count>
|
||||||
for (auto pix=vpin;pix<=vpin+p[1];pix++) IODevice::write(pix,setON);
|
for (auto pix=vpin;pix<vpin+p[1];pix++) IODevice::write(pix,setON);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (params==4 || params==5) { // <z [-]vpin r g b [count]>
|
if (params==4 || params==5) { // <z [-]vpin r g b [count]>
|
||||||
uint16_t colourcode=((p[1] & 0x1F)<<11) |
|
auto count=p[4]?p[4]:1;
|
||||||
((p[2] & 0x1F)<<6) |
|
if (p[1]<0 || p[1]>0xFF) break;
|
||||||
((p[3] & 0x1F)<<1);
|
if (p[2]<0 || p[2]>0xFF) break;
|
||||||
if (setON) colourcode |= 0x0001;
|
if (p[3]<0 || p[3]>0xFF) break;
|
||||||
// driver treats count 0 as 1
|
// strange parameter mangling... see IO_NeoPixel.h NeoPixel::_writeAnalogue
|
||||||
for (auto pix=vpin;pix<=vpin+p[4];pix++) IODevice::writeAnalogue(pix,colourcode,0,0);
|
int colour_RG=(p[1]<<8) | p[2];
|
||||||
|
uint16_t colour_B=p[3];
|
||||||
|
for (auto pix=vpin;pix<vpin+count;pix++) IODevice::writeAnalogue(pix,colour_RG,setON,colour_B);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
EXRAIL2.cpp
20
EXRAIL2.cpp
|
@ -998,8 +998,14 @@ void RMFT2::loop2() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_NEOPIXEL: // OPCODE_NEOPIXEL,V(vpin),OPCODE_PAD,V(rgbcolour)
|
case OPCODE_NEOPIXEL:
|
||||||
IODevice::writeAnalogue(operand,getOperand(1));
|
// OPCODE_NEOPIXEL,V([-]vpin),OPCODE_PAD,V(colour_RG),OPCODE_PAD,V(colour_B),OPCODE_PAD,V(count)
|
||||||
|
{
|
||||||
|
VPIN vpin=operand>0?operand:-operand;
|
||||||
|
auto count=getOperand(3);
|
||||||
|
for (auto pix=vpin;pix<vpin+count;pix++)
|
||||||
|
IODevice::writeAnalogue(pix,getOperand(1),operand>0,getOperand(2));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
|
@ -1199,11 +1205,11 @@ int16_t RMFT2::getSignalSlot(int16_t id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sigtype== NEOPIXEL_SIGNAL_FLAG) {
|
if (sigtype== NEOPIXEL_SIGNAL_FLAG) {
|
||||||
// redpin,amberpin,greenpin are the 3 rgbs
|
// redpin,amberpin,greenpin are the 3 RG values but with no blue permitted. . (code limitation hack)
|
||||||
VPIN colour=redpin;
|
int colour_RG=redpin;
|
||||||
if (rag==SIGNAL_AMBER) colour=amberpin;
|
if (rag==SIGNAL_AMBER) colour_RG=amberpin;
|
||||||
if (rag==SIGNAL_GREEN) colour=greenpin;
|
if (rag==SIGNAL_GREEN) colour_RG=greenpin;
|
||||||
IODevice::writeAnalogue(sigid, colour);
|
IODevice::writeAnalogue(sigid, colour_RG,true,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,8 +272,7 @@
|
||||||
#define LCN(msg)
|
#define LCN(msg)
|
||||||
#define MESSAGE(msg)
|
#define MESSAGE(msg)
|
||||||
#define MOVETT(id,steps,activity)
|
#define MOVETT(id,steps,activity)
|
||||||
#define NEOPIXEL(id,colour)
|
#define NEOPIXEL(id,r,g,b,count...)
|
||||||
#define NEOPIXEL_OFF(id,colour)
|
|
||||||
#define NEOPIXEL_SIGNAL(sigid,redcolour,ambercolour,greencolour)
|
#define NEOPIXEL_SIGNAL(sigid,redcolour,ambercolour,greencolour)
|
||||||
#define ACON(eventid)
|
#define ACON(eventid)
|
||||||
#define ACOF(eventid)
|
#define ACOF(eventid)
|
||||||
|
|
|
@ -71,8 +71,8 @@
|
||||||
//const byte TRACK_POWER_0=0, TRACK_POWER_OFF=0;
|
//const byte TRACK_POWER_0=0, TRACK_POWER_OFF=0;
|
||||||
//const byte TRACK_POWER_1=1, TRACK_POWER_ON=1;
|
//const byte TRACK_POWER_1=1, TRACK_POWER_ON=1;
|
||||||
|
|
||||||
// NEOPIXEL RGB generator
|
// NEOPIXEL RG generator for NEOPIXEL_SIGNAL
|
||||||
#define NeoRGB(red,green,blue) (((red & 0x1F)<<11) | ((green & 0x1F)<<6) | ((blue & 0x1F)<<1) )
|
#define NeoRG(red,green) ((red & 0xff)<<8) | (green & 0xff)
|
||||||
|
|
||||||
// Pass 1 Implements aliases
|
// Pass 1 Implements aliases
|
||||||
#include "EXRAIL2MacroReset.h"
|
#include "EXRAIL2MacroReset.h"
|
||||||
|
@ -435,7 +435,7 @@ const FSH * RMFT2::getRosterFunctions(int16_t id) {
|
||||||
#undef DCCX_SIGNAL
|
#undef DCCX_SIGNAL
|
||||||
#define DCCX_SIGNAL(id,redAspect,amberAspect,greenAspect) id | RMFT2::DCCX_SIGNAL_FLAG,redAspect,amberAspect,greenAspect,
|
#define DCCX_SIGNAL(id,redAspect,amberAspect,greenAspect) id | RMFT2::DCCX_SIGNAL_FLAG,redAspect,amberAspect,greenAspect,
|
||||||
#undef NEOPIXEL_SIGNAL
|
#undef NEOPIXEL_SIGNAL
|
||||||
#define NEOPIXEL_SIGNAL(id,redcolour,ambercolour,greencolour) id | RMFT2::NEOPIXEL_SIGNAL_FLAG,redcolour | NEOPIXEL_FLAG_ON, ambercolour | NEOPIXEL_FLAG_ON, greencolour | NEOPIXEL_FLAG_ON,
|
#define NEOPIXEL_SIGNAL(id,redcolour,ambercolour,greencolour) id | RMFT2::NEOPIXEL_SIGNAL_FLAG,redcolour, ambercolour, greencolour,
|
||||||
#undef VIRTUAL_SIGNAL
|
#undef VIRTUAL_SIGNAL
|
||||||
#define VIRTUAL_SIGNAL(id) id,0,0,0,
|
#define VIRTUAL_SIGNAL(id) id,0,0,0,
|
||||||
|
|
||||||
|
@ -558,8 +558,11 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
|
||||||
#define LCN(msg) PRINT(msg)
|
#define LCN(msg) PRINT(msg)
|
||||||
#define MESSAGE(msg) PRINT(msg)
|
#define MESSAGE(msg) PRINT(msg)
|
||||||
#define MOVETT(id,steps,activity) OPCODE_SERVO,V(id),OPCODE_PAD,V(steps),OPCODE_PAD,V(EXTurntable::activity),OPCODE_PAD,V(0),
|
#define MOVETT(id,steps,activity) OPCODE_SERVO,V(id),OPCODE_PAD,V(steps),OPCODE_PAD,V(EXTurntable::activity),OPCODE_PAD,V(0),
|
||||||
#define NEOPIXEL(id,colour) OPCODE_NEOPIXEL,V(id),OPCODE_PAD,V(colour| NEOPIXEL_FLAG_ON),
|
#define NEOPIXEL(id,r,g,b,count...) OPCODE_NEOPIXEL,V(id),\
|
||||||
#define NEOPIXEL_OFF(id,colour) OPCODE_NEOPIXEL,V(id),OPCODE_PAD,V(colour& ^NEOPIXEL_FLAG_ON),
|
OPCODE_PAD,V(((r & 0xff)<<8) | (g & 0xff)),\
|
||||||
|
OPCODE_PAD,V((b & 0xff)),\
|
||||||
|
OPCODE_PAD,V(#count[0]?(count+0):1),
|
||||||
|
|
||||||
#define NEOPIXEL_SIGNAL(sigid,redcolour,ambercolour,greencolour)
|
#define NEOPIXEL_SIGNAL(sigid,redcolour,ambercolour,greencolour)
|
||||||
#define ONACTIVATE(addr,subaddr) OPCODE_ONACTIVATE,V(addr<<2|subaddr),
|
#define ONACTIVATE(addr,subaddr) OPCODE_ONACTIVATE,V(addr<<2|subaddr),
|
||||||
#define ONACTIVATEL(linear) OPCODE_ONACTIVATE,V(linear+3),
|
#define ONACTIVATEL(linear) OPCODE_ONACTIVATE,V(linear+3),
|
||||||
|
|
106
IO_NeoPixel.h
106
IO_NeoPixel.h
|
@ -133,7 +133,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint16_t NEOPIXEL_ON_FLAG=0x0001;
|
|
||||||
|
|
||||||
static const byte SEESAW_NEOPIXEL_BASE=0x0E;
|
static const byte SEESAW_NEOPIXEL_BASE=0x0E;
|
||||||
static const byte SEESAW_NEOPIXEL_STATUS = 0x00;
|
static const byte SEESAW_NEOPIXEL_STATUS = 0x00;
|
||||||
|
@ -152,20 +151,35 @@ private:
|
||||||
_firstVpin = firstVpin;
|
_firstVpin = firstVpin;
|
||||||
_nPins=nPins;
|
_nPins=nPins;
|
||||||
_I2CAddress = i2cAddress;
|
_I2CAddress = i2cAddress;
|
||||||
_brightness=2; // TODO 0,1,2,3
|
|
||||||
|
// calculate the offsets into the seesaw buffer for each colour depending
|
||||||
|
// on the pixel strip type passed in mode.
|
||||||
|
|
||||||
_redOffset=4+(mode >> 4 & 0x03);
|
_redOffset=4+(mode >> 4 & 0x03);
|
||||||
_greenOffset=4+(mode >> 2 & 0x03);
|
_greenOffset=4+(mode >> 2 & 0x03);
|
||||||
_blueOffset=4+(mode & 0x03);
|
_blueOffset=4+(mode & 0x03);
|
||||||
if (4+(mode >>6 & 0x03) == _redOffset) _bytesPerPixel=3;
|
if (4+(mode >>6 & 0x03) == _redOffset) _bytesPerPixel=3;
|
||||||
else _bytesPerPixel=4; // string has a white byte.
|
else _bytesPerPixel=4; // string has a white byte.
|
||||||
|
|
||||||
_kHz800=(mode & NEO_KHZ400)==0;
|
_kHz800=(mode & NEO_KHZ400)==0;
|
||||||
_showPendimg=false;
|
_showPendimg=false;
|
||||||
// In dccex there are only 2 bytes per pixel
|
|
||||||
pixelBuffer=(uint16_t *) calloc(_nPins,sizeof(uint16_t)); // all pixels off
|
// Each pixel requires 3 bytes RGB memory.
|
||||||
|
// Although the driver device can remember this, it cant do off/on without
|
||||||
|
// forgetting what the on colour was!
|
||||||
|
pixelBuffer=(RGB *) malloc(_nPins*sizeof(RGB));
|
||||||
|
stateBuffer=(byte *) calloc((_nPins+7)/8,sizeof(byte)); // all pixels off
|
||||||
|
if (pixelBuffer==nullptr || stateBuffer==nullptr) {
|
||||||
|
DIAG(F("NeoPixel I2C:%s not enough RAM"), _I2CAddress.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// preset all pins to white so a digital on/off will do something even if no colour set.
|
||||||
|
memset(pixelBuffer,0xFF,_nPins*sizeof(RGB));
|
||||||
addDevice(this);
|
addDevice(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _begin() {
|
void _begin() {
|
||||||
|
|
||||||
// Initialise Neopixel device
|
// Initialise Neopixel device
|
||||||
I2CManager.begin();
|
I2CManager.begin();
|
||||||
if (!I2CManager.exists(_I2CAddress)) {
|
if (!I2CManager.exists(_I2CAddress)) {
|
||||||
|
@ -198,45 +212,41 @@ private:
|
||||||
_showPendimg=false;
|
_showPendimg=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read back pixel colour (rarely needed I suspect)
|
|
||||||
int _readAnalogue(VPIN vpin) override {
|
|
||||||
if (_deviceState == DEVSTATE_FAILED) return 0;
|
|
||||||
auto pin=vpin-_firstVpin;
|
|
||||||
return pixelBuffer[pin];
|
|
||||||
}
|
|
||||||
|
|
||||||
// read back pixel on/off
|
// read back pixel on/off
|
||||||
int _read(VPIN vpin) override {
|
int _read(VPIN vpin) override {
|
||||||
if (_deviceState == DEVSTATE_FAILED) return 0;
|
if (_deviceState == DEVSTATE_FAILED) return 0;
|
||||||
auto pin=vpin-_firstVpin;
|
return isPixelOn(vpin-_firstVpin);
|
||||||
return pixelBuffer[pin] & NEOPIXEL_ON_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write digital value. Sets pixel on or off
|
// Write digital value. Sets pixel on or off
|
||||||
void _write(VPIN vpin, int value) override {
|
void _write(VPIN vpin, int value) override {
|
||||||
if (_deviceState == DEVSTATE_FAILED) return;
|
if (_deviceState == DEVSTATE_FAILED) return;
|
||||||
auto pin=vpin-_firstVpin;
|
auto pixel=vpin-_firstVpin;
|
||||||
if (value) {
|
if (value) {
|
||||||
if (pixelBuffer[pin] & NEOPIXEL_ON_FLAG) return;
|
if (isPixelOn(pixel)) return;
|
||||||
pixelBuffer[pin] |= NEOPIXEL_ON_FLAG;
|
setPixelOn(pixel);
|
||||||
}
|
}
|
||||||
else { // set off
|
else { // set off
|
||||||
if (!(pixelBuffer[pin] & NEOPIXEL_ON_FLAG)) return;
|
if (!isPixelOn(pixel)) return;
|
||||||
pixelBuffer[pin] &= (~NEOPIXEL_ON_FLAG);
|
setPixelOff(pixel);
|
||||||
}
|
}
|
||||||
transmit(pin);
|
transmit(pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write analogue (integer) value
|
// Write analogue value.
|
||||||
void _writeAnalogue(VPIN vpin, int colour, uint8_t ignore1, uint16_t ignore2) override {
|
// The convoluted parameter mashing here is to allow passing the RGB and on/off
|
||||||
(void) ignore1;
|
// information through the generic HAL _writeAnalog interface which was originally
|
||||||
(void) ignore2;
|
// designed for servos and short integers
|
||||||
|
void _writeAnalogue(VPIN vpin, int colour_RG, uint8_t onoff, uint16_t colour_B) override {
|
||||||
if (_deviceState == DEVSTATE_FAILED) return;
|
if (_deviceState == DEVSTATE_FAILED) return;
|
||||||
auto newColour=(uint16_t)colour;
|
RGB newColour={(byte)((colour_RG>>8) & 0xFF), (byte)(colour_RG & 0xFF), (byte)(colour_B & 0xFF)};
|
||||||
auto pin=vpin-_firstVpin;
|
auto pixel=vpin-_firstVpin;
|
||||||
if (pixelBuffer[pin]==newColour) return;
|
if (pixelBuffer[pixel]==newColour && isPixelOn(pixel)==(bool)onoff) return; // no change
|
||||||
pixelBuffer[pin]=newColour;
|
|
||||||
transmit(pin);
|
if (onoff) setPixelOn(pixel); else setPixelOff(pixel);
|
||||||
|
pixelBuffer[pixel]=newColour;
|
||||||
|
transmit(pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display device information and status.
|
// Display device information and status.
|
||||||
|
@ -247,6 +257,12 @@ private:
|
||||||
_deviceState == DEVSTATE_FAILED ? F("OFFLINE") : F(""));
|
_deviceState == DEVSTATE_FAILED ? F("OFFLINE") : F(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool isPixelOn(int16_t pixel) {return stateBuffer[pixel/8] & (0x80>>(pixel%8));}
|
||||||
|
void setPixelOn(int16_t pixel) {stateBuffer[pixel/8] |= (0x80>>(pixel%8));}
|
||||||
|
void setPixelOff(int16_t pixel) {stateBuffer[pixel/8] &= ~(0x80>>(pixel%8));}
|
||||||
|
|
||||||
// Helper function for error handling
|
// Helper function for error handling
|
||||||
void reportError(uint8_t status, bool fail=true) {
|
void reportError(uint8_t status, bool fail=true) {
|
||||||
DIAG(F("NeoPixel I2C:%s Error:%d (%S)"), _I2CAddress.toString(),
|
DIAG(F("NeoPixel I2C:%s Error:%d (%S)"), _I2CAddress.toString(),
|
||||||
|
@ -256,30 +272,42 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void transmit(uint16_t pin, bool show=true) {
|
void transmit(uint16_t pixel, bool show=true) {
|
||||||
byte buffer[]={SEESAW_NEOPIXEL_BASE,SEESAW_NEOPIXEL_BUF,0x00,0x00,0x00,0x00,0x00};
|
byte buffer[]={SEESAW_NEOPIXEL_BASE,SEESAW_NEOPIXEL_BUF,0x00,0x00,0x00,0x00,0x00};
|
||||||
uint16_t offset= pin * _bytesPerPixel;
|
uint16_t offset= pixel * _bytesPerPixel;
|
||||||
buffer[2]=(byte)(offset>>8);
|
buffer[2]=(byte)(offset>>8);
|
||||||
buffer[3]=(byte)(offset & 0xFF);
|
buffer[3]=(byte)(offset & 0xFF);
|
||||||
auto colour=pixelBuffer[pin];
|
|
||||||
if (colour & NEOPIXEL_ON_FLAG) {
|
if (isPixelOn(pixel)) {
|
||||||
buffer[_redOffset]=(colour>>11 & 0x1F) <<_brightness;
|
auto colour=pixelBuffer[pixel];
|
||||||
buffer[_greenOffset]=(colour>>6 & 0x1F) <<_brightness;
|
buffer[_redOffset]=colour.red;
|
||||||
buffer[_blueOffset]=(colour>>1 & 0x1F) <<_brightness;
|
buffer[_greenOffset]=colour.green;
|
||||||
} // else leave buffer black
|
buffer[_blueOffset]=colour.blue;
|
||||||
|
} // else leave buffer black (in buffer preset to zeros above)
|
||||||
|
|
||||||
// Transmit pixel to driver
|
// Transmit pixel to driver
|
||||||
I2CManager.write(_I2CAddress,buffer,4 +_bytesPerPixel);
|
I2CManager.write(_I2CAddress,buffer,4 +_bytesPerPixel);
|
||||||
_showPendimg=true;
|
_showPendimg=true;
|
||||||
|
|
||||||
}
|
}
|
||||||
uint16_t* pixelBuffer = nullptr;
|
struct RGB {
|
||||||
byte _brightness;
|
byte red;
|
||||||
|
byte green;
|
||||||
|
byte blue;
|
||||||
|
bool operator==(const RGB& other) const {
|
||||||
|
return red == other.red && green == other.green && blue == other.blue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RGB* pixelBuffer = nullptr;
|
||||||
|
byte* stateBuffer = nullptr; // 1 bit per pixel
|
||||||
|
bool _showPendimg;
|
||||||
|
|
||||||
|
// mapping of RGB onto pixel buffer for seesaw.
|
||||||
byte _bytesPerPixel;
|
byte _bytesPerPixel;
|
||||||
byte _redOffset;
|
byte _redOffset;
|
||||||
byte _greenOffset;
|
byte _greenOffset;
|
||||||
byte _blueOffset;
|
byte _blueOffset;
|
||||||
bool _showPendimg;
|
|
||||||
bool _kHz800;
|
bool _kHz800;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
61
Release_Notes/NeoPixel.md
Normal file
61
Release_Notes/NeoPixel.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
NeoPixel support
|
||||||
|
|
||||||
|
The IO_NeoPixel.h driver supports the adafruit neopixel seesaw board. It turns each pixel into an individual VPIN which can be given a colour and turned on or off using the new <o> command or the NEOPIXEL Exrail macro. Exrail SIGNALS can also drive a single pixel signal or multiple separate pixels.
|
||||||
|
|
||||||
|
|
||||||
|
1. Defining the hardware driver:
|
||||||
|
Add a driver definition in myAutomation.h for each adafruit I2C driver.
|
||||||
|
|
||||||
|
HAL(neoPixel, firstVpin, numberOfPixels [, mode [, i2caddress])
|
||||||
|
Where mode is selected from the various pixel string types which have varying
|
||||||
|
colour order or refresh frequency. For MOST strings this mode will be NEO_GRB but for others refer to the comments in IO_NeoPixel.h
|
||||||
|
If omitted the node and i2caddress default to NEO_GRB, 0x60.
|
||||||
|
|
||||||
|
HAL(NeoPixel,1000,20)
|
||||||
|
This is a NeoPixel driver defaulting to I2C aqddress 0x60 for a GRB pixel string. Pixels are given vpin numbers from 1000 to 1019.
|
||||||
|
HAL(NeoPixel,1020,20,NEO_GRB,0x61)
|
||||||
|
This is a NeoPixel driver on i2c address 0x61
|
||||||
|
|
||||||
|
2. Setting pixels from the < > commands.
|
||||||
|
By default, each pixel in the string is created as white but switched off.
|
||||||
|
Each pixel has a vpin starting from the first vpin in the HAL definitions.
|
||||||
|
|
||||||
|
<o vpin> switches pixel on (same as <z vpin>) e.g. <o 1005>
|
||||||
|
<o -vpin> switches pixel off (same as <z -vpin>) e.g. <o -1003>
|
||||||
|
(the z commands work on pixels the same as other gpio pins.)
|
||||||
|
|
||||||
|
<o [-]vpin count> switches on/off count pixels starting at vpin. e.g <o 1000 5>
|
||||||
|
Note: it IS acceptable to switch across 2 strings of pixels if they are contiguous vpin ranges. It is also interesting that this command doesnt care if the vpins are NeoPixel or any other type, so it can be used to switch a range of other pin types.
|
||||||
|
|
||||||
|
<o [-]vpin red green blue [count]> sets the colour and on/off status of a pin or pins. Each colour is 0..255 e.g. <o 1005 255 255 0> sets pin 1005 to bright yellow and ON, <0 -1006 0 0 255 10> sets pins 1006 to 1015 (10 pins) to bright blue but OFF.
|
||||||
|
Note: If you set a pin to a colour, you can turn it on and off without having to reset the colour every time. This is something the adafruit seesaw library can't do and is just one of several reasons why we dont use it.
|
||||||
|
|
||||||
|
3. Setting pixels from EXRAIL
|
||||||
|
The new NEOPIXEL macro provides the same functionality as the <o [-]vpin red green blue [count]> command above.
|
||||||
|
NEOPIXEL([-]vpin, red, green, blue [,count])
|
||||||
|
|
||||||
|
Setting pixels on or off (without colour change) can be done with SET/RESET [currently there is no set range facility but that may be added as a general exrail thing... watch this space]
|
||||||
|
|
||||||
|
Because the pixels obey set/reset, the BLINK command can also be used to control blinking a pixel.
|
||||||
|
|
||||||
|
4. EXRAIL pixel signals.
|
||||||
|
There are two types possible, a mast with separate fixed colour pixels for each aspect, or a mast with one multiple colour pixel for all aspects.
|
||||||
|
|
||||||
|
For separate pixels, the colours should be established at startup and a normal SIGNALH macro used.
|
||||||
|
|
||||||
|
AUTOSTART
|
||||||
|
SIGNALH(1010,1011,1012)
|
||||||
|
NEOPIXEL(1010,255,0,0)
|
||||||
|
NEOPIXEL(1011,128,128,0)
|
||||||
|
NEOPIXEL(1012,0,255,0)
|
||||||
|
RED(1010) // force signal state otherwise all 3 lights will be on
|
||||||
|
DONE
|
||||||
|
|
||||||
|
For signals with 1 pixel, the NEOPIXEL_SIGNAL macro will create a signal
|
||||||
|
NEOPIXEL_SIGNAL(vpin,redfx,amberfx,greenfx)
|
||||||
|
|
||||||
|
*** This is experimental and may change****
|
||||||
|
In order to fit the existing signal code, the fx colours above are restricted to the red and green pixel values (ie no blue channel)
|
||||||
|
The fx values above can be created by the NeoRG macro so a bright red would be NeoRG(255,0) bright green Ng(0,255) and amber something like NeoRG(128,128)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user