Added "invert" option to LedPin()

If invert=true, PWM output will be phase-inverted.  This is useful when creating a pair of PWM pins that need to be out of phase by 180 degrees (e.g driving a piezo-electric buzzer via two PWM pins).
This commit is contained in:
Gregg 2023-01-07 20:44:19 -06:00
parent a8271c8724
commit 6d18d5a3dc
3 changed files with 9 additions and 15 deletions

View File

@ -29,7 +29,7 @@
///////////////////
LedC::LedC(uint8_t pin, uint16_t freq){
LedC::LedC(uint8_t pin, uint16_t freq, boolean invert){
if(freq==0)
freq=DEFAULT_PWM_FREQ;
@ -44,10 +44,7 @@ LedC::LedC(uint8_t pin, uint16_t freq){
timerList[nTimer][nMode]->speed_mode=(ledc_mode_t)nMode;
timerList[nTimer][nMode]->timer_num=(ledc_timer_t)nTimer;
timerList[nTimer][nMode]->freq_hz=freq;
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
timerList[nTimer][nMode]->clk_cfg=LEDC_USE_APB_CLK;
#endif
int res=LEDC_TIMER_BIT_MAX-1; // find the maximum possible resolution
while(getApbFrequency()/(freq*pow(2,res))<1)
@ -68,9 +65,7 @@ LedC::LedC(uint8_t pin, uint16_t freq){
channelList[nChannel][nMode]->channel=(ledc_channel_t)nChannel;
channelList[nChannel][nMode]->timer_sel=(ledc_timer_t)nTimer;
channelList[nChannel][nMode]->intr_type=LEDC_INTR_DISABLE;
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
channelList[nChannel][nMode]->flags.output_invert=0;
#endif
channelList[nChannel][nMode]->flags.output_invert=invert;
channelList[nChannel][nMode]->hpoint=0;
channelList[nChannel][nMode]->gpio_num=pin;
timer=timerList[nTimer][nMode];
@ -85,18 +80,19 @@ LedC::LedC(uint8_t pin, uint16_t freq){
///////////////////
LedPin::LedPin(uint8_t pin, float level, uint16_t freq) : LedC(pin, freq){
LedPin::LedPin(uint8_t pin, float level, uint16_t freq, boolean invert) : LedC(pin, freq, invert){
if(!channel)
Serial.printf("\n*** ERROR: Can't create LedPin(%d) - no open PWM channels and/or Timers ***\n\n",pin);
else
Serial.printf("LedPin=%d: mode=%d channel=%d, timer=%d, freq=%d Hz, resolution=%d bits\n",
Serial.printf("LedPin=%d: mode=%d channel=%d, timer=%d, freq=%d Hz, resolution=%d bits %s\n",
channel->gpio_num,
channel->speed_mode,
channel->channel,
channel->timer_sel,
timer->freq_hz,
timer->duty_resolution
timer->duty_resolution,
channel->flags.output_invert?"(inverted)":""
);
set(level);

View File

@ -59,7 +59,7 @@ class LedC {
ledc_channel_config_t *channel=NULL;
ledc_timer_config_t *timer;
LedC(uint8_t pin, uint16_t freq);
LedC(uint8_t pin, uint16_t freq, boolean invert=false);
public:
int getPin(){return(channel?channel->gpio_num:-1);} // returns the pin number
@ -75,7 +75,7 @@ class LedC {
class LedPin : public LedC {
public:
LedPin(uint8_t pin, float level=0, uint16_t freq=DEFAULT_PWM_FREQ); // assigns pin to be output of one of 16 PWM channels initial level and frequency
LedPin(uint8_t pin, float level=0, uint16_t freq=DEFAULT_PWM_FREQ, boolean invert=false); // assigns pin to be output of one of 16 PWM channels initial level and frequency
void set(float level); // sets the PWM duty to level (0-100)
static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ); // converts Hue/Saturation/Brightness to R/G/B

View File

@ -45,9 +45,7 @@ RFControl::RFControl(uint8_t pin, boolean refClock, boolean installDriver){
config->rmt_mode=RMT_MODE_TX;
config->tx_config.carrier_en=false;
config->channel=(rmt_channel_t)nChannels;
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
config->flags=0;
#endif
config->clk_div = 1;
config->mem_block_num=1;
config->gpio_num=(gpio_num_t)pin;