Completed LedPin() and ServoPin()
Both classes check that total number of combined instantiations does not exceed 16. ServoPin() has additional limit of only 8 instantiations. DEPRECATED: PwmPin(). Keep for backwards compatibility only. TO DO: Update Tutorial Examples to replace PwmPin with LedPin, and update Extras.h documentations with LedPin and ServoPin.
This commit is contained in:
parent
a8dff0a7de
commit
d49bca9bbe
|
|
@ -1,97 +1,10 @@
|
|||
|
||||
#include "PwmPin.h"
|
||||
|
||||
PwmPin::PwmPin(uint8_t channel, uint8_t pin){
|
||||
this->channel=channel & 0x0F;
|
||||
this->pin=pin;
|
||||
|
||||
ledc_timer_config_t ledTimer;
|
||||
ledTimer.timer_num=LEDC_TIMER_0;
|
||||
ledTimer.speed_mode=(this->channel)<8?LEDC_HIGH_SPEED_MODE:LEDC_LOW_SPEED_MODE;
|
||||
ledTimer.duty_resolution=LEDC_TIMER_10_BIT;
|
||||
ledTimer.freq_hz=5000;
|
||||
ledc_timer_config(&ledTimer);
|
||||
|
||||
ledChannel.gpio_num=pin;
|
||||
ledChannel.speed_mode=(this->channel)<8?LEDC_HIGH_SPEED_MODE:LEDC_LOW_SPEED_MODE;
|
||||
ledChannel.channel=(ledc_channel_t)(this->channel&0x07);
|
||||
ledChannel.intr_type=LEDC_INTR_DISABLE;
|
||||
ledChannel.timer_sel=LEDC_TIMER_0;
|
||||
ledChannel.duty=0;
|
||||
ledChannel.hpoint=0;
|
||||
ledc_channel_config(&ledChannel);
|
||||
|
||||
}
|
||||
|
||||
void PwmPin::set(uint8_t level){
|
||||
ledChannel.duty=level*1023;
|
||||
ledChannel.duty/=100;
|
||||
ledChannel.duty&=0x03FF;
|
||||
ledc_channel_config(&ledChannel);
|
||||
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void PwmPin::HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ){
|
||||
|
||||
// The algorithm below was provided on the web at https://www.cs.rit.edu/~ncs/color/t_convert.html
|
||||
// h = [0,360]
|
||||
// s = [0,1]
|
||||
// v = [0,1]
|
||||
|
||||
int i;
|
||||
float f, p, q, t;
|
||||
|
||||
if( s == 0 ){
|
||||
*r = *g = *b = v;
|
||||
return;
|
||||
}
|
||||
|
||||
h /= 60;
|
||||
i = floor( h ) ;
|
||||
f = h - i;
|
||||
p = v * ( 1 - s );
|
||||
q = v * ( 1 - s * f );
|
||||
t = v * ( 1 - s * ( 1 - f ) );
|
||||
switch( i % 6 ) {
|
||||
case 0:
|
||||
*r = v;
|
||||
*g = t;
|
||||
*b = p;
|
||||
break;
|
||||
case 1:
|
||||
*r = q;
|
||||
*g = v;
|
||||
*b = p;
|
||||
break;
|
||||
case 2:
|
||||
*r = p;
|
||||
*g = v;
|
||||
*b = t;
|
||||
break;
|
||||
case 3:
|
||||
*r = p;
|
||||
*g = q;
|
||||
*b = v;
|
||||
break;
|
||||
case 4:
|
||||
*r = t;
|
||||
*g = p;
|
||||
*b = v;
|
||||
break;
|
||||
case 5:
|
||||
*r = v;
|
||||
*g = p;
|
||||
*b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
LedPin::LedPin(uint8_t pin, uint8_t level){
|
||||
if(numChannels>15){
|
||||
if(numChannels+ServoPin::numChannels>15){
|
||||
Serial.printf("\n*** ERROR: Can't create LedPin(%d) - no open PWM channels ***\n\n",pin);
|
||||
return;
|
||||
}
|
||||
|
|
@ -127,6 +40,7 @@ LedPin::LedPin(uint8_t pin, uint8_t level){
|
|||
ledChannel.hpoint=0;
|
||||
ledc_channel_config(&ledChannel);
|
||||
set(level);
|
||||
//Serial.printf("Configured LED on Pin %d using Channel %d in Speed Mode %d\n",ledChannel.gpio_num,ledChannel.channel,ledChannel.speed_mode);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
|
@ -201,9 +115,14 @@ void LedPin::HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ){
|
|||
|
||||
////////////////////////////
|
||||
|
||||
ServoPin::ServoPin(uint8_t channel, uint8_t pin, double initDegrees, uint16_t minMicros, uint16_t maxMicros, double minDegrees, double maxDegrees){
|
||||
this->channel=channel & 0x07;
|
||||
this->pin=pin;
|
||||
ServoPin::ServoPin(uint8_t pin, double initDegrees, uint16_t minMicros, uint16_t maxMicros, double minDegrees, double maxDegrees){
|
||||
if(numChannels>7 || numChannels>(15-LedPin::numChannels)){
|
||||
Serial.printf("\n*** ERROR: Can't create ServoPin(%d) - no open PWM channels ***\n\n",pin);
|
||||
return;
|
||||
}
|
||||
|
||||
enabled=true;
|
||||
|
||||
this->minMicros=minMicros;
|
||||
this->maxMicros=maxMicros;
|
||||
this->minDegrees=minDegrees;
|
||||
|
|
@ -216,27 +135,129 @@ ServoPin::ServoPin(uint8_t channel, uint8_t pin, double initDegrees, uint16_t mi
|
|||
ledTimer.freq_hz=50;
|
||||
ledc_timer_config(&ledTimer);
|
||||
|
||||
ledChannel.gpio_num=pin;
|
||||
ledChannel.speed_mode=LEDC_HIGH_SPEED_MODE;
|
||||
ledChannel.channel=(ledc_channel_t)(this->channel);
|
||||
ledChannel.intr_type=LEDC_INTR_DISABLE;
|
||||
ledChannel.timer_sel=LEDC_TIMER_1;
|
||||
ledChannel.hpoint=0;
|
||||
ledChannel.duty*=micros2duty;
|
||||
servoChannel.gpio_num=pin;
|
||||
servoChannel.speed_mode=LEDC_HIGH_SPEED_MODE;
|
||||
servoChannel.channel=(ledc_channel_t)numChannels++;
|
||||
servoChannel.intr_type=LEDC_INTR_DISABLE;
|
||||
servoChannel.timer_sel=LEDC_TIMER_1;
|
||||
servoChannel.hpoint=0;
|
||||
servoChannel.duty*=micros2duty;
|
||||
set(initDegrees);
|
||||
//Serial.printf("Configured Servo on Pin %d using Channel %d in Speed Mode %d\n",servoChannel.gpio_num,servoChannel.channel,servoChannel.speed_mode);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void ServoPin::set(double degrees){
|
||||
ledChannel.duty=(degrees-minDegrees)*microsPerDegree+minMicros;
|
||||
if(!enabled)
|
||||
return;
|
||||
|
||||
if(ledChannel.duty<minMicros)
|
||||
ledChannel.duty=minMicros;
|
||||
else if(ledChannel.duty>maxMicros)
|
||||
ledChannel.duty=maxMicros;
|
||||
servoChannel.duty=(degrees-minDegrees)*microsPerDegree+minMicros;
|
||||
|
||||
ledChannel.duty*=micros2duty;
|
||||
ledc_channel_config(&ledChannel);
|
||||
if(servoChannel.duty<minMicros)
|
||||
servoChannel.duty=minMicros;
|
||||
else if(servoChannel.duty>maxMicros)
|
||||
servoChannel.duty=maxMicros;
|
||||
|
||||
servoChannel.duty*=micros2duty;
|
||||
ledc_channel_config(&servoChannel);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
const double ServoPin::micros2duty=65535.0/20000.0;
|
||||
uint8_t LedPin::numChannels=0;
|
||||
uint8_t ServoPin::numChannels=0;
|
||||
|
||||
//*******************************************************
|
||||
// DEPRECATED - INCLUDED FOR BACKWARDS COMPATIBILITY ONLY
|
||||
//*******************************************************
|
||||
|
||||
PwmPin::PwmPin(uint8_t channel, uint8_t pin){
|
||||
this->channel=channel & 0x0F;
|
||||
this->pin=pin;
|
||||
|
||||
ledc_timer_config_t ledTimer;
|
||||
ledTimer.timer_num=LEDC_TIMER_0;
|
||||
ledTimer.speed_mode=(this->channel)<8?LEDC_HIGH_SPEED_MODE:LEDC_LOW_SPEED_MODE;
|
||||
ledTimer.duty_resolution=LEDC_TIMER_10_BIT;
|
||||
ledTimer.freq_hz=5000;
|
||||
ledc_timer_config(&ledTimer);
|
||||
|
||||
ledChannel.gpio_num=pin;
|
||||
ledChannel.speed_mode=(this->channel)<8?LEDC_HIGH_SPEED_MODE:LEDC_LOW_SPEED_MODE;
|
||||
ledChannel.channel=(ledc_channel_t)(this->channel&0x07);
|
||||
ledChannel.intr_type=LEDC_INTR_DISABLE;
|
||||
ledChannel.timer_sel=LEDC_TIMER_0;
|
||||
ledChannel.duty=0;
|
||||
ledChannel.hpoint=0;
|
||||
ledc_channel_config(&ledChannel);
|
||||
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void PwmPin::set(uint8_t channel, uint8_t level){
|
||||
ledChannel.duty=level*1023;
|
||||
ledChannel.duty/=100;
|
||||
ledChannel.duty&=0x03FF;
|
||||
ledc_channel_config(&ledChannel);
|
||||
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void PwmPin::HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ){
|
||||
|
||||
// The algorithm below was provided on the web at https://www.cs.rit.edu/~ncs/color/t_convert.html
|
||||
// h = [0,360]
|
||||
// s = [0,1]
|
||||
// v = [0,1]
|
||||
|
||||
int i;
|
||||
float f, p, q, t;
|
||||
|
||||
if( s == 0 ){
|
||||
*r = *g = *b = v;
|
||||
return;
|
||||
}
|
||||
|
||||
h /= 60;
|
||||
i = floor( h ) ;
|
||||
f = h - i;
|
||||
p = v * ( 1 - s );
|
||||
q = v * ( 1 - s * f );
|
||||
t = v * ( 1 - s * ( 1 - f ) );
|
||||
switch( i % 6 ) {
|
||||
case 0:
|
||||
*r = v;
|
||||
*g = t;
|
||||
*b = p;
|
||||
break;
|
||||
case 1:
|
||||
*r = q;
|
||||
*g = v;
|
||||
*b = p;
|
||||
break;
|
||||
case 2:
|
||||
*r = p;
|
||||
*g = v;
|
||||
*b = t;
|
||||
break;
|
||||
case 3:
|
||||
*r = p;
|
||||
*g = q;
|
||||
*b = v;
|
||||
break;
|
||||
case 4:
|
||||
*r = t;
|
||||
*g = p;
|
||||
*b = v;
|
||||
break;
|
||||
case 5:
|
||||
*r = v;
|
||||
*g = p;
|
||||
*b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,69 @@
|
|||
|
||||
/////////////////////////////////////
|
||||
// PWM Pin Control //
|
||||
/////////////////////////////////////
|
||||
|
||||
// A wrapper around the ESP-IDF ledc library to easily set the brightness of an LED from 0-100%.
|
||||
// Can be used for any device requiring a PWM output (not just an LED). Frequency of PWM
|
||||
// is hardcoded to 5000 Hz and either High-Speed Timer-0 (for channels 0-7) or Low-Speed Timer-0
|
||||
// for channels (8-15) is configured and selected automatically.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ----- PWM Pin Control -----
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Wrappers around the ESP-IDF ledc library to control PWM-based devices:
|
||||
//
|
||||
// LedPin(pin) - controls a Dimmable LED on specified pin with frequency=5000 Hz
|
||||
// - use set(level) to set brightness from 0-100%
|
||||
//
|
||||
// ServoPin(pin) - controls a Servo Motor on specified pin with frequency=50 Hz
|
||||
// - use set(degrees) to set position to degrees
|
||||
//
|
||||
// Max number of LedPin instantiations: 16
|
||||
// Max number of ServoPin instantiatons: 8
|
||||
// Max combined limit (LedPins+ServoPins): 16
|
||||
//
|
||||
// Instantiation of an LedPin or ServoPin that causes any of the maximums above to be exceeded throws
|
||||
// an error message. The object will still be created, but calls to set(level) or set(degrees) are ignored.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <driver/ledc.h>
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
class LedPin {
|
||||
boolean enabled=false;
|
||||
ledc_channel_config_t ledChannel;
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
class ServoPin {
|
||||
boolean enabled=false;
|
||||
uint16_t minMicros;
|
||||
uint16_t maxMicros;
|
||||
double minDegrees;
|
||||
double microsPerDegree;
|
||||
ledc_channel_config_t servoChannel;
|
||||
|
||||
static const double micros2duty;
|
||||
|
||||
public:
|
||||
ServoPin(uint8_t pin, double initDegrees, uint16_t minMicros, uint16_t maxMicros, double minDegrees, double maxDegrees);
|
||||
ServoPin(uint8_t pin, double initDegrees=0) : ServoPin(pin,initDegrees,1000,2000,-90,90) {};
|
||||
|
||||
void set(double degrees); // sets the Servo to degrees, where degrees is bounded by [minDegrees,maxDegrees]
|
||||
int getPin(){return servoChannel.gpio_num;} // returns the pin number
|
||||
|
||||
static uint8_t numChannels;
|
||||
};
|
||||
|
||||
//*******************************************************
|
||||
// DEPRECATED - INCLUDED FOR BACKWARDS COMPATIBILITY ONLY
|
||||
//*******************************************************
|
||||
|
||||
class PwmPin {
|
||||
uint8_t channel;
|
||||
uint8_t pin;
|
||||
|
|
@ -18,48 +71,8 @@ class PwmPin {
|
|||
|
||||
public:
|
||||
PwmPin(uint8_t channel, uint8_t pin); // assigns pin to be output of one of 16 PWM channels (0-15)
|
||||
void set(uint8_t level); // sets the PWM duty to level (0-100)
|
||||
void set(uint8_t channel, uint8_t level){set(level);} // sets the PWM duty to level (0-100) - deprecated, but defined for backwards compatibility
|
||||
void set(uint8_t channel, uint8_t level); // sets the PWM duty to level (0-100)
|
||||
int getPin(){return pin;} // returns the pin number
|
||||
|
||||
static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ); // converts Hue/Saturation/Brightness to R/G/B
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
class LedPin {
|
||||
boolean enabled=false;
|
||||
ledc_channel_config_t ledChannel;
|
||||
static uint8_t numChannels;
|
||||
|
||||
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
|
||||
|
||||
static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ); // converts Hue/Saturation/Brightness to R/G/B
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
class ServoPin {
|
||||
uint8_t channel; // channel must be in range [0,7] (only HighSpeed Channels will be used)
|
||||
uint8_t pin;
|
||||
uint16_t minMicros;
|
||||
uint16_t maxMicros;
|
||||
double minDegrees;
|
||||
double microsPerDegree;
|
||||
ledc_channel_config_t ledChannel;
|
||||
|
||||
static const double micros2duty;
|
||||
|
||||
public:
|
||||
ServoPin(uint8_t channel, uint8_t pin, double initDegrees, uint16_t minMicros, uint16_t maxMicros, double minDegrees, double maxDegrees);
|
||||
ServoPin(uint8_t channel, uint8_t pin, double initDegrees=0) : ServoPin(channel,pin,initDegrees,1000,2000,-90,90) {};
|
||||
|
||||
void set(double degrees); // sets the Servo to degrees, where degrees is bounded by [minDegrees,maxDegrees]
|
||||
int getPin(){return pin;} // returns the pin number
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "PwmPin.h"
|
||||
|
||||
//ServoPin servo(3,18,-90);
|
||||
ServoPin servo(3,18,0,500,2200,-90,90);
|
||||
//ServoPin servo(18,0,500,2200,-90,90);
|
||||
|
||||
void setup(){
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ void setup(){
|
|||
Serial.println("Starting...");
|
||||
|
||||
|
||||
LedPin yellow(16);
|
||||
LedPin yellow(16,10);
|
||||
LedPin d1(19);
|
||||
LedPin d2(19);
|
||||
LedPin d3(19);
|
||||
|
|
@ -30,13 +30,14 @@ void setup(){
|
|||
LedPin d10(19);
|
||||
LedPin d11(19);
|
||||
LedPin d12(19);
|
||||
LedPin d13(19);
|
||||
LedPin d14(19);
|
||||
LedPin d15(19);
|
||||
LedPin d16(19);
|
||||
LedPin red(17);
|
||||
LedPin red(17,100);
|
||||
|
||||
while(1){
|
||||
// ServoPin servo(18,0,500,2200,-90,90);
|
||||
ServoPin s0(19);
|
||||
ServoPin servo(18,45);
|
||||
ServoPin s1(19);
|
||||
|
||||
while(0){
|
||||
for(int i=0;i<100;i++){
|
||||
yellow.set(i);
|
||||
delay(10);
|
||||
|
|
@ -48,24 +49,21 @@ void setup(){
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop(){
|
||||
|
||||
|
||||
// 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);
|
||||
// }
|
||||
|
||||
// return;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue