optimizing to allow for pulse train batching

This commit is contained in:
Gregg 2022-01-08 16:18:37 -06:00
parent 9d0c56799c
commit ee6c270de3
4 changed files with 73 additions and 32 deletions

View File

@ -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 nTrain=nPixels;
L0=low0*80; }
H1=high1*80;
L1=low1*80;
LR=lowReset*80;
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) if(!*rf)
return; return;
rf->clear(); uint32_t *pulses = (uint32_t *) malloc(96);
for(int i=0;i<nPixels;i++)
loadColor(getColorRGB(r,g,b)); loadColor(getColorRGB(r,g,b),pulses);
rf->phase(LR,0); // end-marker delay/reset rf->start(pulses,24,nPixels); // start pulse train and repeat for nPixels
rf->start(); delayMicroseconds(resetTime);
free(pulses);
} }
/////////////////// ///////////////////
@ -34,12 +45,24 @@ void Pixel::setColors(color_t *color, int nPixels){
if(!*rf) if(!*rf)
return; return;
uint32_t x0,x1,x2;
rf->clear(); x0=micros();
for(int i=0;i<nPixels;i++)
loadColor(color[i]); uint32_t *pulses = (uint32_t *) malloc(nTrain*96);
rf->phase(LR,0); // end-marker delay/reset
rf->start(); for(int i=0;i<nPixels;i++){
loadColor(color[i],pulses);
rf->start(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){ void Pixel::loadColor(color_t c, uint32_t *p){
for(int i=23;i>=0;i--){ uint32_t count=24;
if((c>>i)&1) p+=23;
rf->add(H1,L1); // 1-bit
else while(count--){
rf->add(H0,L0); // 0-bit *p--=pattern[c&1];
c=c>>1;
} }
} }

View File

@ -12,17 +12,18 @@ typedef uint32_t color_t;
class Pixel { class Pixel {
private: private:
uint32_t H0, L0; // High and Low times for a zero-pulse (in units of 1/80 microseconds) uint32_t pattern[2]; // storage for zero-bit and one-bit pulses
uint32_t H1, L1; // High and Low times for a one-pulse (in units of 1/80 microseconds) uint32_t resetTime; // minimum time (in usec) between pulse trains
uint32_t LR; // Low time for a reset/end-of-data (in units of 1/80 microseconds) uint32_t nTrain; // number of Pixels to transmit per pulse train batch
RFControl *rf; 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: 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, 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
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
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 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 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 void setColors(color_t *color, int nPixels); // sets colors of nPixels from array of Colors

View File

@ -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 // 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)

View File

@ -85,7 +85,23 @@ void setup() {
Serial.println("\n\nHomeSpan Pixel Example\n"); Serial.println("\n\nHomeSpan Pixel Example\n");
Serial.printf("PX on Pin=%d check: %s\n",px.getPin(),px?"OKAY":"BAD"); 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() } // end of setup()
void loop(){ void loop(){