Re-working PWM routines
This commit is contained in:
parent
8d45e20671
commit
a5d31b1ea5
Binary file not shown.
|
|
@ -3,56 +3,75 @@
|
|||
|
||||
///////////////////
|
||||
|
||||
LedPin::LedPin(uint8_t pin, uint8_t level){
|
||||
if(numChannels+ServoPin::numChannels>15){
|
||||
Serial.printf("\n*** ERROR: Can't create LedPin(%d) - no open PWM channels ***\n\n",pin);
|
||||
ledChannel.gpio_num=0;
|
||||
return;
|
||||
LedPin::LedPin(uint8_t pin, uint8_t level, uint16_t freq){
|
||||
|
||||
if(freq==0)
|
||||
freq=DEFAULT_PWM_FREQ;
|
||||
|
||||
for(int nMode=0;nMode<LEDC_SPEED_MODE_MAX;nMode++){
|
||||
for(int nChannel=0;nChannel<LEDC_CHANNEL_MAX;nChannel++){
|
||||
for(int nTimer=0;nTimer<LEDC_TIMER_MAX;nTimer++){
|
||||
if(!channelList[nChannel][nMode]){
|
||||
|
||||
if(!timerList[nTimer][nMode]){ // if this timer slot is free, use it
|
||||
timerList[nTimer][nMode]=new ledc_timer_config_t; // create new timer instance
|
||||
timerList[nTimer][nMode]->speed_mode=(ledc_mode_t)nMode;
|
||||
timerList[nTimer][nMode]->timer_num=(ledc_timer_t)nTimer;
|
||||
timerList[nTimer][nMode]->freq_hz=freq;
|
||||
|
||||
int res=20; // find the maximum possible resolution
|
||||
while(getApbFrequency()/(freq*pow(2,res))<1)
|
||||
res--;
|
||||
|
||||
timerList[nTimer][nMode]->duty_resolution=(ledc_timer_bit_t)res;
|
||||
ledc_timer_config(timerList[nTimer][nMode]);
|
||||
}
|
||||
|
||||
if(timerList[nTimer][nMode]->freq_hz==freq){ // if timer matches desired frequency (always true if newly-created above)
|
||||
channelList[nChannel][nMode]=new ledc_channel_config_t; // create new channel instance
|
||||
channelList[nChannel][nMode]->speed_mode=(ledc_mode_t)nMode;
|
||||
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;
|
||||
channelList[nChannel][nMode]->hpoint=0;
|
||||
channelList[nChannel][nMode]->gpio_num=pin;
|
||||
ledTimer=timerList[nTimer][nMode];
|
||||
ledChannel=channelList[nChannel][nMode];
|
||||
set(level);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enabled=true;
|
||||
|
||||
if(numChannels==0){ // first instantiation of an LedPin
|
||||
ledc_timer_config_t ledTimer;
|
||||
ledTimer.timer_num=LEDC_TIMER_0;
|
||||
ledTimer.duty_resolution=LEDC_TIMER_10_BIT;
|
||||
ledTimer.freq_hz=5000;
|
||||
Serial.printf("\n*** ERROR: Can't create LedPin(%d) - no open PWM channels and/or Timers ***\n\n",pin);
|
||||
|
||||
ledTimer.speed_mode=LEDC_HIGH_SPEED_MODE; // configure both the HIGH-Speed Timer 0 and Low-Speed Timer 0
|
||||
ledc_timer_config(&ledTimer);
|
||||
|
||||
ledTimer.speed_mode=LEDC_LOW_SPEED_MODE;
|
||||
ledc_timer_config(&ledTimer);
|
||||
}
|
||||
|
||||
ledChannel.gpio_num=pin;
|
||||
if(numChannels<8){
|
||||
ledChannel.speed_mode=LEDC_LOW_SPEED_MODE;
|
||||
ledChannel.channel=(ledc_channel_t)(7-numChannels);
|
||||
} else {
|
||||
ledChannel.speed_mode=LEDC_HIGH_SPEED_MODE;
|
||||
ledChannel.channel=(ledc_channel_t)(15-numChannels);
|
||||
}
|
||||
|
||||
numChannels++;
|
||||
|
||||
ledChannel.intr_type=LEDC_INTR_DISABLE;
|
||||
ledChannel.timer_sel=LEDC_TIMER_0;
|
||||
ledChannel.hpoint=0;
|
||||
ledc_channel_config(&ledChannel);
|
||||
set(level);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void LedPin::set(uint8_t level){
|
||||
if(!enabled)
|
||||
|
||||
if(!ledChannel)
|
||||
return;
|
||||
|
||||
Serial.printf("pin=%d, ch=%d, mode=%d, timer=%d, freq=%d, res=%d\n",
|
||||
ledChannel->gpio_num,
|
||||
ledChannel->channel,
|
||||
ledChannel->speed_mode,
|
||||
ledChannel->timer_sel,
|
||||
ledTimer->freq_hz,
|
||||
ledTimer->duty_resolution
|
||||
);
|
||||
|
||||
if(level>100)
|
||||
level=100;
|
||||
|
||||
ledChannel.duty=level*1023;
|
||||
ledChannel.duty/=100;
|
||||
ledChannel.duty&=0x03FF;
|
||||
ledc_channel_config(&ledChannel);
|
||||
ledChannel->duty=level*(pow(2,ledTimer->duty_resolution)-1);
|
||||
ledChannel->duty/=100;
|
||||
ledc_channel_config(ledChannel);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +189,10 @@ void ServoPin::set(double degrees){
|
|||
const double ServoPin::micros2duty=65535.0/20000.0;
|
||||
uint8_t LedPin::numChannels=0;
|
||||
uint8_t ServoPin::numChannels=0;
|
||||
uint8_t LedC::nChannels=0;
|
||||
vector<ledc_timer_config_t> LedC::timers;
|
||||
ledc_channel_config_t *LedC::channelList[LEDC_CHANNEL_MAX][LEDC_SPEED_MODE_MAX]={};
|
||||
ledc_timer_config_t *LedC::timerList[LEDC_TIMER_MAX][LEDC_SPEED_MODE_MAX]={};
|
||||
|
||||
//*******************************************************
|
||||
// DEPRECATED - INCLUDED FOR BACKWARDS COMPATIBILITY ONLY
|
||||
|
|
|
|||
|
|
@ -22,17 +22,33 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
#include <driver/ledc.h>
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
#define DEFAULT_PWM_FREQ 5000
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
class LedPin {
|
||||
boolean enabled=false;
|
||||
ledc_channel_config_t ledChannel;
|
||||
class LedC {
|
||||
|
||||
protected:
|
||||
static uint8_t nChannels;
|
||||
static vector<ledc_timer_config_t> timers;
|
||||
static ledc_channel_config_t *channelList[LEDC_CHANNEL_MAX][LEDC_SPEED_MODE_MAX];
|
||||
static ledc_timer_config_t *timerList[LEDC_TIMER_MAX][LEDC_SPEED_MODE_MAX];
|
||||
};
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
class LedPin : LedC {
|
||||
ledc_channel_config_t *ledChannel=NULL;
|
||||
ledc_timer_config_t *ledTimer;
|
||||
|
||||
public:
|
||||
LedPin(uint8_t pin, uint8_t level=0); // assigns pin to be output of one of 16 PWM channels within initial level
|
||||
void set(uint8_t level); // sets the PWM duty to level (0-100)
|
||||
int getPin(){return ledChannel.gpio_num;} // returns the pin number
|
||||
LedPin(uint8_t pin, uint8_t level=0, uint16_t freq=DEFAULT_PWM_FREQ); // assigns pin to be output of one of 16 PWM channels initial level and frequency
|
||||
void set(uint8_t level); // sets the PWM duty to level (0-100)
|
||||
int getPin(){return(ledChannel?ledChannel->gpio_num:-1);} // returns the pin number
|
||||
|
||||
static uint8_t numChannels;
|
||||
static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ); // converts Hue/Saturation/Brightness to R/G/B
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
// as well as compile and test from this point. This file is ignored when the library is included in other sketches.
|
||||
|
||||
#include "PwmPin.h"
|
||||
|
||||
#include <soc/ledc_reg.h>
|
||||
|
||||
void setup(){
|
||||
|
||||
Serial.begin(115200);
|
||||
|
|
@ -13,53 +14,37 @@ void setup(){
|
|||
|
||||
Serial.println("Starting...");
|
||||
|
||||
LedPin led0(18,100,0);
|
||||
LedPin led1(19,100,2000);
|
||||
LedPin led2(16,10,80000);
|
||||
LedPin led3(17,100,2000);
|
||||
LedPin led4(23);
|
||||
LedPin led5(22,0,3000);
|
||||
LedPin led6(14,0,1);
|
||||
LedPin led7(32,0,1850);
|
||||
LedPin led8(15);
|
||||
LedPin led9(33);
|
||||
LedPin led10(27);
|
||||
LedPin led11(12,100,23);
|
||||
LedPin led12(13,100);
|
||||
LedPin led13(26);
|
||||
LedPin led14(25,0);
|
||||
LedPin led15(4,0);
|
||||
LedPin led16(5,0);
|
||||
|
||||
LedPin yellow(16,10);
|
||||
LedPin d1(19);
|
||||
LedPin d2(19);
|
||||
LedPin d3(19);
|
||||
LedPin d4(19);
|
||||
LedPin d5(19);
|
||||
LedPin d6(19);
|
||||
LedPin d7(19);
|
||||
LedPin d8(19);
|
||||
LedPin d9(19);
|
||||
LedPin d10(19);
|
||||
LedPin d11(19);
|
||||
LedPin d12(19);
|
||||
LedPin red(17);
|
||||
led16.set(20);
|
||||
led0.set(5);
|
||||
led2.set(100);
|
||||
|
||||
// ServoPin servo(18,0,500,2200,-90,90);
|
||||
ServoPin s0(19);
|
||||
ServoPin servo(18,45);
|
||||
ServoPin s1(19);
|
||||
uint32_t v=REG_READ(LEDC_HSTIMER0_CONF_REG);
|
||||
Serial.printf("HS %d %d %d %d\n",(v>>25)&1,v&0x1f,(v>>13)&0x3FF,(v>>5)&0xFF);
|
||||
|
||||
v=REG_READ(LEDC_LSTIMER0_CONF_REG);
|
||||
Serial.printf("LS %d %d %d %d %d\n",(v>>25)&1,v&0x1f,(v>>13)&0x3FF,(v>>5)&0xFF,REG_READ(LEDC_CONF_REG));
|
||||
|
||||
while(1){
|
||||
for(int i=0;i<100;i++){
|
||||
yellow.set(i);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
for(int i=100;i>=0;i--){
|
||||
red.set(i);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
while(1){
|
||||
double STEP=1;
|
||||
|
||||
for(int i=-100*STEP;i<=100*STEP;i++){
|
||||
servo.set((double)i/STEP);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
for(int i=100*STEP;i>=-100*STEP;i--){
|
||||
servo.set((double)i/STEP);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
|
|
|
|||
Loading…
Reference in New Issue