This commit is contained in:
Gregg 2022-01-17 08:25:26 -06:00
parent 79c028c057
commit 5f513c4c34
3 changed files with 55 additions and 97 deletions

View File

@ -3,7 +3,7 @@
/////////////////// ///////////////////
Pixel::Pixel(int pin, uint32_t nPixels){ Pixel::Pixel(int pin){
rf=new RFControl(pin,false,false); // set clock to 1/80 usec, no default driver rf=new RFControl(pin,false,false); // set clock to 1/80 usec, no default driver
setTiming(0.32, 0.88, 0.64, 0.56, 80.0); // set default timing parameters (suitable for most SK68 and WS28 RGB pixels) setTiming(0.32, 0.88, 0.64, 0.56, 80.0); // set default timing parameters (suitable for most SK68 and WS28 RGB pixels)
@ -11,8 +11,7 @@ Pixel::Pixel(int pin, uint32_t nPixels){
rmt_isr_register(loadData,(void *)this,0,NULL); // set custom interrupt handler rmt_isr_register(loadData,(void *)this,0,NULL); // set custom interrupt handler
rmt_set_tx_thr_intr_en(rf->getChannel(),true,8); // enable threshold interrupt (note end-transmission interrupt automatically enabled by rmt_tx_start) rmt_set_tx_thr_intr_en(rf->getChannel(),true,8); // enable threshold interrupt (note end-transmission interrupt automatically enabled by rmt_tx_start)
channelNum=rf->getChannel(); // save integer form of channel number txEndMask=TxEndMask(rf->getChannel()); // create bit mask for end-of-transmission interrupt specific to this channel
txEndMask=TxEndMask(channelNum); // create bit mask for end-of-transmission interrupt specific to this channel
} }
@ -27,23 +26,26 @@ void Pixel::setTiming(float high0, float low0, float high1, float low1, uint32_t
/////////////////// ///////////////////
void Pixel::setRGB(uint8_t r, uint8_t g, uint8_t b, int nPixels){ void Pixel::setRGB(uint8_t r, uint8_t g, uint8_t b, uint32_t nPixels){
if(!*rf) if(!*rf || nPixels==0)
return; return;
uint32_t *pulses = (uint32_t *) malloc(24*sizeof(uint32_t)); uint32_t data=getColorRGB(r,g,b);
setColors(&data,nPixels,false);
loadColor(getColorRGB(r,g,b),pulses);
rf->start(pulses,24,nPixels); // start pulse train and repeat for nPixels
delayMicroseconds(resetTime);
free(pulses);
} }
/////////////////// ///////////////////
void Pixel::setColors(const uint32_t *data, uint32_t nPixels){ void Pixel::setHSV(float h, float s, float v, uint32_t nPixels){
float r,g,b;
LedPin::HSVtoRGB(h,s/100.0,v/100.0,&r,&g,&b);
setRGB(r*255,g*255,b*255,nPixels);
}
///////////////////
void Pixel::setColors(const uint32_t *data, uint32_t nPixels, boolean multiColor){
if(!*rf || nPixels==0) if(!*rf || nPixels==0)
return; return;
@ -53,58 +55,15 @@ void Pixel::setColors(const uint32_t *data, uint32_t nPixels){
status.iMem=0; status.iMem=0;
status.iBit=24; status.iBit=24;
status.started=true; status.started=true;
this->multiColor=multiColor;
// loadData(); // load first 2 bytes loadData(this); // load first two bytes of data to get started
// loadData();
loadData(this);
loadData(this); loadData(this);
rmt_tx_start(rf->getChannel(),true); rmt_tx_start(rf->getChannel(),true);
while(status.started); while(status.started); // wait for transmission to be complete
delayMicroseconds(resetTime); // end-of-marker delay
return;
// uint32_t *pulses = (uint32_t *) malloc(nTrain*24*sizeof(uint32_t));
//
// if(!pulses){
// Serial.printf("*** ERROR: Not enough memory to reserve for %d Pixels per batch transmission\n",nTrain);
// return;
// }
//
// int i,j;
//
// for(i=0;i<nPixels;){
// for(j=0;j<nTrain && i<nPixels;j++,i++)
// loadColor(color[i],pulses+j*24);
// rf->start(pulses,j*24);
// }
//
// free(pulses);
// delayMicroseconds(resetTime);
}
///////////////////
void Pixel::setHSV(float h, float s, float v, int nPixels){
float r,g,b;
LedPin::HSVtoRGB(h,s/100.0,v/100.0,&r,&g,&b);
setRGB(r*255,g*255,b*255,nPixels);
}
///////////////////
void Pixel::loadColor(uint32_t c, uint32_t *p){
uint32_t count=24;
p+=23;
while(count--){
*p--=pattern[c&1];
c=c>>1;
}
} }
/////////////////// ///////////////////
@ -136,16 +95,16 @@ void Pixel::loadData(void *arg){
RMT.int_clr.val=~0; RMT.int_clr.val=~0;
if(status.nPixels==0){ if(status.nPixels==0){
RMTMEM.chan[pix->channelNum].data32[status.iMem].val=0; RMTMEM.chan[pix->rf->getChannel()].data32[status.iMem].val=0;
return; return;
} }
for(int i=0;i<8;i++) for(int i=0;i<8;i++)
RMTMEM.chan[pix->channelNum].data32[status.iMem++].val=pix->pattern[(*status.data>>(--status.iBit))&1]; RMTMEM.chan[pix->rf->getChannel()].data32[status.iMem++].val=pix->pattern[(*status.data>>(--status.iBit))&1];
if(status.iBit==0){ if(status.iBit==0){
status.iBit=24; status.iBit=24;
status.data++; status.data+=pix->multiColor;
status.nPixels--; status.nPixels--;
} }
@ -154,4 +113,4 @@ void Pixel::loadData(void *arg){
/////////////////// ///////////////////
volatile pixel_status_t Pixel::status; volatile Pixel::pixel_status_t Pixel::status;

View File

@ -8,22 +8,22 @@
#include "RFControl.h" #include "RFControl.h"
#include "PwmPin.h" #include "PwmPin.h"
struct pixel_status_t { class Pixel {
struct pixel_status_t {
int nPixels; int nPixels;
const uint32_t *data; const uint32_t *data;
int iBit; int iBit;
int iMem; int iMem;
boolean started; boolean started;
}; };
class Pixel {
private: private:
RFControl *rf; // Pixel utilizes RFControl
uint32_t pattern[2]; // storage for zero-bit and one-bit pulses uint32_t pattern[2]; // storage for zero-bit and one-bit pulses
uint32_t resetTime; // minimum time (in usec) between pulse trains uint32_t resetTime; // minimum time (in usec) between pulse trains
int channelNum; // channel number
uint32_t txEndMask; // mask for end-of-transmission interrupt uint32_t txEndMask; // mask for end-of-transmission interrupt
boolean multiColor; // flag to indicate array contains multiple colors (don't just repeat first color for nPixels)
uint32_t nTrain; // number of Pixels to transmit per pulse train batch
#if defined(CONFIG_IDF_TARGET_ESP32) #if defined(CONFIG_IDF_TARGET_ESP32)
const int memSize=64; const int memSize=64;
@ -38,21 +38,18 @@ class Pixel {
const int memSize=0; const int memSize=0;
#endif #endif
RFControl *rf;
volatile static pixel_status_t status;
static void loadData(void *arg); // interrupt handler static void loadData(void *arg); // interrupt handler
void loadColor(uint32_t c, uint32_t *p); // creates pulse pattern for pixel color (encoded as RGB in low 24-bits of *p) volatile static pixel_status_t status; // storage for volatile information modified in interupt handler
public: public:
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); // 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 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, uint32_t 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, uint32_t nPixels=1); // sets color of nPixels to HSV values where h=[0,360], s=[0,100], v=[0,100]
void setColors(const uint32_t *data, uint32_t nPixels); // sets colors of nPixels from array of Colors void setColors(const uint32_t *data, uint32_t nPixels, bool multiColor=true); // sets colors of nPixels from array of colors stored in data
int getPin(){return(rf->getPin());} // returns pixel pin if valid, else returns -1 int getPin(){return(rf->getPin());} // returns pixel pin if valid, else returns -1
static uint32_t getColorRGB(uint8_t r, uint8_t g, uint8_t b); // return pixel Color from RGB values static uint32_t getColorRGB(uint8_t r, uint8_t g, uint8_t b); // return pixel Color from RGB values

View File

@ -95,11 +95,12 @@ void setup() {
Serial.println("\n\nHomeSpan Pixel Example\n"); Serial.println("\n\nHomeSpan Pixel Example\n");
// Pixel px0(10);
Pixel px(1); Pixel px(1);
uint32_t colors[20]; uint32_t colors[20];
colors[0]=px.getColorRGB(40,0,0); colors[0]=px.getColorRGB(0,40,0);
colors[1]=px.getColorRGB(40,0,0); colors[1]=px.getColorRGB(40,0,0);
colors[2]=px.getColorRGB(40,0,0); colors[2]=px.getColorRGB(40,0,0);
colors[3]=px.getColorRGB(40,40,0); colors[3]=px.getColorRGB(40,40,0);
@ -109,6 +110,7 @@ void setup() {
colors[7]=px.getColorRGB(0,40,0); colors[7]=px.getColorRGB(0,40,0);
px.setColors(colors,8); px.setColors(colors,8);
// px.setHSV(240,80,40,3);
Serial.println("\n\nDone\n\n"); Serial.println("\n\nDone\n\n");
while(1); while(1);