diff --git a/src/extras/Pixel.cpp b/src/extras/Pixel.cpp index f1c190e..4c40f24 100644 --- a/src/extras/Pixel.cpp +++ b/src/extras/Pixel.cpp @@ -3,15 +3,24 @@ /////////////////// -Pixel::Pixel(int pin, float high0, float low0, float high1, float low1, float lowReset){ +Pixel::Pixel(int pin, uint32_t nPixels){ + + rf=new RFControl(pin,false); // set clock to 1/80 usec + setTiming(0.32, 0.88, 0.64, 0.56, 80.0); // set default timing parameters (suitable for most SK68 and WS28 RGB pixels) + + if(nPixels==0) // must reserve at least enough memory for one pixel per transmission batch + nPixels=1; - H0=high0*80; // high0, low0, etc. are all in microseconds and must be multiplied by 80 to match 80MHz RFControl clock - L0=low0*80; - H1=high1*80; - L1=low1*80; - LR=lowReset*80; + nTrain=nPixels; +} - rf=new RFControl(pin,false); // set clock to 1/80 usec +/////////////////// + +void Pixel::setTiming(float high0, float low0, float high1, float low1, uint32_t lowReset){ + + pattern[0]=RF_PULSE(high0*80+0.5,low0*80+0.5); + pattern[1]=RF_PULSE(high1*80+0.5,low1*80+0.5); + resetTime=lowReset; } /////////////////// @@ -20,12 +29,14 @@ void Pixel::setRGB(uint8_t r, uint8_t g, uint8_t b, int nPixels){ if(!*rf) return; - - rf->clear(); - for(int i=0;iphase(LR,0); // end-marker delay/reset - rf->start(); + + uint32_t *pulses = (uint32_t *) malloc(96); + + loadColor(getColorRGB(r,g,b),pulses); + rf->start(pulses,24,nPixels); // start pulse train and repeat for nPixels + delayMicroseconds(resetTime); + + free(pulses); } /////////////////// @@ -34,12 +45,24 @@ void Pixel::setColors(color_t *color, int nPixels){ if(!*rf) return; + + uint32_t x0,x1,x2; - rf->clear(); - for(int i=0;iphase(LR,0); // end-marker delay/reset - rf->start(); + x0=micros(); + + uint32_t *pulses = (uint32_t *) malloc(nTrain*96); + + for(int i=0;istart(pulses,24); // start pulse train + } + + x1=micros(); + Serial.printf("%d\n",x1-x0); + + while(1); + delayMicroseconds(resetTime); + free(pulses); } /////////////////// @@ -52,13 +75,14 @@ void Pixel::setHSV(float h, float s, float v, int nPixels){ /////////////////// -void Pixel::loadColor(color_t c){ - - for(int i=23;i>=0;i--){ - if((c>>i)&1) - rf->add(H1,L1); // 1-bit - else - rf->add(H0,L0); // 0-bit +void Pixel::loadColor(color_t c, uint32_t *p){ + + uint32_t count=24; + p+=23; + + while(count--){ + *p--=pattern[c&1]; + c=c>>1; } } diff --git a/src/extras/Pixel.h b/src/extras/Pixel.h index 8de4220..01053f3 100644 --- a/src/extras/Pixel.h +++ b/src/extras/Pixel.h @@ -12,17 +12,18 @@ typedef uint32_t color_t; class Pixel { private: - uint32_t H0, L0; // High and Low times for a zero-pulse (in units of 1/80 microseconds) - uint32_t H1, L1; // High and Low times for a one-pulse (in units of 1/80 microseconds) - uint32_t LR; // Low time for a reset/end-of-data (in units of 1/80 microseconds) + uint32_t pattern[2]; // storage for zero-bit and one-bit pulses + uint32_t resetTime; // minimum time (in usec) between pulse trains + uint32_t nTrain; // number of Pixels to transmit per pulse train batch RFControl *rf; - void loadColor(color_t c); // creates pulse pattern for pixel color (encoded as RGB in low 24-bits) + void loadColor(color_t c, uint32_t *p); // creates pulse pattern for pixel color (encoded as RGB in low 24-bits of *p) public: - Pixel(int pin, float high0, float low0, float high1, float low1, float lowReset); // creates addressable single-wire RGB LED on pin (such as the SK68 or WS28); parameters are in MICROSECONDS! - Pixel(int pin) : Pixel(pin, 0.32, 0.88, 0.64, 0.56, 80.0) {}; // default parameters for SK68XXMINI-HS LEDs, though will likely work with many other variations as well + Pixel(int pin, uint32_t nPixels=1); // creates addressable single-wire RGB LED on pin (such as the SK68 or WS28), with OPTIONAL reserve of memory for nPixels + void setTiming(float high0, float low0, float high1, float low1, uint32_t lowReset); // changes default timings for bit pulse - note parameters are in MICROSECONDS + void setRGB(uint8_t r, uint8_t g, uint8_t b, int nPixels=1); // sets color of nPixels to RGB values (0-255) void setHSV(float h, float s, float v, int nPixels=1); // sets color of nPixels to HSV values where h=[0,360], s=[0,100], v=[0,100] void setColors(color_t *color, int nPixels); // sets colors of nPixels from array of Colors diff --git a/src/extras/RFControl.h b/src/extras/RFControl.h index 8c17212..e07851d 100644 --- a/src/extras/RFControl.h +++ b/src/extras/RFControl.h @@ -41,5 +41,5 @@ class RFControl { // Helper macro for creating your own storage of uint32_t data array elements - used with first variation of start() above -#define RF_PULSE(highTicks,lowTicks) (1 << 15 | highTicks | lowTicks << 16) +#define RF_PULSE(highTicks,lowTicks) (1 << 15 | uint32_t(highTicks) | uint32_t(lowTicks) << 16) diff --git a/src/extras/extras.ino b/src/extras/extras.ino index 832396e..5045f1b 100644 --- a/src/extras/extras.ino +++ b/src/extras/extras.ino @@ -85,7 +85,23 @@ void setup() { Serial.println("\n\nHomeSpan Pixel Example\n"); Serial.printf("PX on Pin=%d check: %s\n",px.getPin(),px?"OKAY":"BAD"); + + px.setRGB(0,0,0,8); + px.setRGB(255,0,0,1); + delay(500); + px.setRGB(0,255,0,2); + delay(500); + px.setRGB(0,255,0,4); + delay(500); + px.setRGB(0,255,255,6); + delay(500); + px.setRGB(0,0,255,8); + delay(500); + +// while(1); + + } // end of setup() void loop(){