Skip to content

Commit

Permalink
ESPS2 Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlloydev committed Apr 19, 2021
1 parent 13df703 commit 28979ad
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 100 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The use of this function is similar to the Arduino method as its resource manage
### Syntax

```c++
analogWrite(pin, value);
void analogWrite(pin, value);
```
### Parameters
Expand Down Expand Up @@ -58,9 +58,13 @@ void printPinsStatus();

This function prints the available PWM pins to choose from and a formatted output showing the PWM pins that are in use (attached) and the channels that are available (-1). Resource management is handled automatically and transparently. There is no requirement to have any function in the setup loop. PWM resolution and frequency can be changed at any time in the main loop. If you enter a higher duty value than the limit, the status output will show the max value that has effect.

| ESP32 Dev Board | ESP32S2-Saola-1M |
| :----------------------------------------------------------- | ------------------------------------------------------------ |
| ![esp32-pinsStatus-large](https://user-images.githubusercontent.com/63488701/115168460-f9b02880-a088-11eb-8c65-debeee7a7858.png) | ![esp32-s2 pinsStatus-large](https://user-images.githubusercontent.com/63488701/115168504-26644000-a089-11eb-93f1-476fdf1b4418.png) |
| All 8 channels offer independent resolution bits, duty cycle value and frequency . | All 8 channels offer independent resolution bits, duty cycle value. Four independant frequencies on chanels (0,1), (2,3), (4,5) and (6,7) |
| `const uint64_t pinMask = 0x27FE00207FFE;` | `const uint64_t pinMask = 0x308EFF034;` |


![printPinsStatus](https://user-images.githubusercontent.com/63488701/114637054-719bde80-9c96-11eb-972d-49e38b16ec4a.png)
The the available PWM pins are determined by a pinMask constant. It might be necessary to alter the pimMask to match your board or to customize for your design.

### Example Code

Expand Down
139 changes: 80 additions & 59 deletions analogWrite.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
/**********************************************************************************
AnalogWrite Library for ESP32-ESP32S2 Arduino core - Version 1.0.0
AnalogWrite Library for ESP32-ESP32S2 Arduino core - Version 1.1.0
by dlloydev https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite
This Library is licensed under the MIT License
**********************************************************************************/

#include <Arduino.h>
#include "analogWrite.h"

pinStatus_t pinsStatus[16] = {
{ 1, -1, 5000, 13, 0 }, { 3, -1, 5000, 13, 0 },
{ 5, -1, 5000, 13, 0 }, { 7, -1, 5000, 13, 0 },
{ 9, -1, 5000, 13, 0 }, {11, -1, 5000, 13, 0 },
{13, -1, 5000, 13, 0 }, {15, -1, 5000, 13, 0 }
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
pinStatus_t pinsStatus[8] = {
{0, -1, 5000, 13, 0 }, {2, -1, 5000, 13, 0 },
{4, -1, 5000, 13, 0 }, {6, -1, 5000, 13, 0 },
{1, -1, 5000, 13, 0 }, {3, -1, 5000, 13, 0 },
{5, -1, 5000, 13, 0 }, {7, -1, 5000, 13, 0 }
};
const uint8_t chd = 1;
#else //ESP32
pinStatus_t pinsStatus[8] = {
{ 0, -1, 5000, 13, 0 }, { 2, -1, 5000, 13, 0 },
{ 4, -1, 5000, 13, 0 }, { 6, -1, 5000, 13, 0 },
{ 8, -1, 5000, 13, 0 }, {10, -1, 5000, 13, 0 },
{12, -1, 5000, 13, 0 }, {14, -1, 5000, 13, 0 }
};
const uint8_t chd = 2;
#endif

void analogWrite(int8_t pin, int32_t value) {
if (pin == DAC1 || pin == DAC2) { //dac
Expand All @@ -22,23 +33,23 @@ void analogWrite(int8_t pin, int32_t value) {
int8_t ch = getChannel(pin);
if (ch >= 0) {
if (value == -1) { //detach pin
pinsStatus[ch / 2].pin = -1;
pinsStatus[ch / 2].frequency = 5000;
pinsStatus[ch / 2].resolution = 13;
ledcDetachPin(pinsStatus[ch / 2].pin);
pinsStatus[ch / chd].pin = -1;
pinsStatus[ch / chd].frequency = 5000;
pinsStatus[ch / chd].resolution = 13;
ledcDetachPin(pinsStatus[ch / chd].pin);
REG_SET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
} else { // attached
int32_t valueMax = (pow(2, pinsStatus[ch / 2].resolution)) - 1;
int32_t valueMax = (pow(2, pinsStatus[ch / chd].resolution)) - 1;
if (value > valueMax) { // full ON
value = valueMax + 1;
ledcDetachPin(pin);
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
} else { // write PWM
ledcSetup(ch, pinsStatus[ch / 2].frequency, pinsStatus[ch / 2].resolution);
ledcSetup(ch, pinsStatus[ch / chd].frequency, pinsStatus[ch / chd].resolution);
ledcWrite(ch, value);
}
pinsStatus[ch / 2].value = value;
pinsStatus[ch / chd].value = value;
}
}
}
Expand All @@ -47,82 +58,92 @@ void analogWrite(int8_t pin, int32_t value) {
float analogWriteFrequency(int8_t pin, float frequency) {
int8_t ch = getChannel(pin);
if (ch >= 0) {
pinsStatus[ch / 2].frequency = frequency;
pinsStatus[ch / 2].pin = pin;
ledcSetup(ch, frequency, pinsStatus[ch / 2].resolution);
ledcWrite(ch, pinsStatus[ch / 2].value);
if ((pinsStatus[ch / chd].pin) > 47) return -1;
pinsStatus[ch / chd].pin = pin;
pinsStatus[ch / chd].frequency = frequency;
//ledcChangeFrequency(ch, frequency, pinsStatus[ch / chd].resolution);
ledcSetup(ch, frequency, pinsStatus[ch / chd].resolution);
ledcWrite(ch, pinsStatus[ch / chd].value);
}
return ledcReadFreq(ch);
}

int32_t analogWriteResolution(int8_t pin, uint8_t resolution) {
int8_t ch = getChannel(pin);
if (ch >= 0) {
pinsStatus[ch / 2].resolution = resolution;
pinsStatus[ch / 2].pin = pin;
ledcSetup(ch, pinsStatus[ch].frequency, resolution);
ledcWrite(ch, pinsStatus[ch].value);
if ((pinsStatus[ch / chd].pin) > 47) return -1;
pinsStatus[ch / chd].pin = pin;
pinsStatus[ch / chd].resolution = resolution;
ledcSetup(ch, pinsStatus[ch / chd].frequency, resolution);
ledcWrite(ch, pinsStatus[ch / chd].value);
}
return pow(2, resolution);
}

int8_t getChannel(int8_t pin) {
if ((pinMask >> pin) & 1) { //valid pin number?
if (REG_GET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL)) { //gpio pin function?
for (int8_t i = 0; i < 8; i++) { //search channels for the pin
if (pinsStatus[i].pin == pin) { //pin found
return pinsStatus[i].channel;
if (!((pinMask >> pin) & 1)) return -1; //not pwm pin
for (int8_t i = 0; i < 8; i++) {
int8_t ch = pinsStatus[i].channel;
if (pinsStatus[ch / chd].pin == pin) {
return ch;
break;
}
}
for (int8_t i = 0; i < 8; i++) {
int8_t ch = pinsStatus[i].channel;
if ((REG_GET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL)) == 0) { //free pin
if (pinsStatus[ch / chd].pin == -1) { //free channel
if ((ledcRead(ch) < 1) && (ledcReadFreq(ch) < 1)) { //free timer
pinsStatus[ch / chd].pin = pin;
ledcAttachPin(pin, ch);
return ch;
break;
}
}
return -99; //pin is being used externally
} else { //pin is not used
for (int8_t i = 0; i < 8; i++) { //search for free channel
if (pinsStatus[i].pin == -1) { //channel is free
pinsStatus[i].pin = pin;
ledcAttachPin(pin, pinsStatus[i].channel);
return pinsStatus[i].channel;
} else {
pinsStatus[ch / chd].pin = 88; //occupied timer
return -1;
break;
}
}
} else {
return -1; //occupied pin
break;
}
}
return -88; //no available resources
return -1;
}

void printPinsStatus() {
Serial.print("PWM pins: ");
for (int i = 0; i < muxSize; i++) {
if ((pinMask >> i) & 1) {
Serial.print(i); Serial.print(", ");
if (i == 18) Serial.println();
if (i == 18) Serial.print(" ");
}
}
Serial.println();

Serial.println();
for (int i = 0; i < 8; i++) {
Serial.print("ch"); Serial.print(pinsStatus[i].channel); Serial.print(" ");
if (pinsStatus[i].channel < 10) Serial.print(" ");
if (pinsStatus[i].pin == -1) {
Serial.print(pinsStatus[i].pin); Serial.print(" ");
} else {
Serial.print("pin"); Serial.print(pinsStatus[i].pin); Serial.print(" ");
}
if (pinsStatus[i].pin < 10) Serial.print(" ");
if (pinsStatus[i].frequency < 10000) Serial.print(" ");
if (pinsStatus[i].frequency < 1000) Serial.print(" ");
if (pinsStatus[i].frequency < 100) Serial.print(" ");
if (pinsStatus[i].frequency < 10) Serial.print(" ");
Serial.print(pinsStatus[i].frequency); Serial.print(" Hz ");
if (pinsStatus[i].resolution < 10) Serial.print(" ");
Serial.print(pinsStatus[i].resolution); Serial.print("-bit ");
Serial.print("val ");
if (pinsStatus[i].value < 10000) Serial.print(" ");
if (pinsStatus[i].value < 1000) Serial.print(" ");
if (pinsStatus[i].value < 100) Serial.print(" ");
if (pinsStatus[i].value < 10) Serial.print(" ");
Serial.print(pinsStatus[i].value);
int ch = pinsStatus[i].channel;
Serial.print("ch: ");
if (ch < 10) Serial.print(" "); Serial.print(ch); Serial.print(" ");
Serial.print("Pin: ");
if ((pinsStatus[ch / chd].pin >= 0) && (pinsStatus[ch / chd].pin < 10)) Serial.print(" ");
Serial.print(pinsStatus[ch / chd].pin); Serial.print(" ");
Serial.print("Hz: ");
if (ledcReadFreq(ch) < 10000) Serial.print(" ");
if (ledcReadFreq(ch) < 1000) Serial.print(" ");
if (ledcReadFreq(ch) < 100) Serial.print(" ");
if (ledcReadFreq(ch) < 10) Serial.print(" ");
Serial.print(ledcReadFreq(ch)); Serial.print(" ");
Serial.print("Bits: ");
if (pinsStatus[ch / chd].resolution < 10) Serial.print(" ");
Serial.print(pinsStatus[ch / chd].resolution); Serial.print(" ");
Serial.print("Duty: ");
if (pinsStatus[ch / chd].value < 10000) Serial.print(" ");
if (pinsStatus[ch / chd].value < 1000) Serial.print(" ");
if (pinsStatus[ch / chd].value < 100) Serial.print(" ");
if (pinsStatus[ch / chd].value < 10) Serial.print(" ");
Serial.print(pinsStatus[ch / chd].value);
Serial.println();
}
}
8 changes: 6 additions & 2 deletions analogWrite.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#ifndef _ESP32_ESP32S2_ANALOG_WRITE_
#define _ESP32_ESP32S2_ANALOG_WRITE_

#include <Arduino.h>

#if (defined(ESP32) || defined(ARDUINO_ARCH_ESP32))

#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#define NUM_OUTPUT_PINS 45
#define DAC1 17
#define DAC2 18
const uint8_t muxSize = 48;
const uint64_t pinMask = 0x7FE00207FFE; //PWM
const uint64_t pinMask = 0x27FE00207FFE; //PWM
#else
#define NUM_OUTPUT_PINS 34
#define DAC1 25
Expand All @@ -30,4 +33,5 @@ void analogWrite(int8_t pin, int32_t value = 0);
int8_t getChannel(int8_t pin);
void printPinsStatus(void);

#endif
#endif //ESP32 or ARDUINO_ARCH_ESP32
#endif //_ESP32_ESP32S2_ANALOG_WRITE_
61 changes: 27 additions & 34 deletions examples/AnalogWriteTest/AnalogWriteTest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,42 @@
#include "analogWrite.h"

void setup() {
Serial.begin(115200);

analogWriteFrequency(23, 2300);
analogWrite(23, 10);

analogWriteFrequency(22, 125);
analogWriteResolution(22, 3);
analogWrite(22, 6);

analogWriteFrequency(21, 125);
analogWriteResolution(21, 3);
analogWrite(21, 7);
Serial.begin(115200);
Serial.println();

analogWriteFrequency(19, 125);
analogWriteResolution(19, 3);
analogWrite(19, 8);
analogWriteFrequency(5, 4800);
analogWriteResolution(5, 10);
analogWrite(5, 950);

analogWriteFrequency(18, 1800);
analogWriteResolution(18, 8);
analogWrite(18, 4000);
analogWrite(2, 100);
analogWriteFrequency(2, 1);
analogWriteResolution(2, 10);

analogWriteFrequency(5, 500);
analogWriteResolution(5, 12);
analogWrite(5, 5000);
analogWriteFrequency(21, 10000);
analogWriteResolution(21, 8);
analogWrite(21, 31);

analogWriteFrequency(17, 1700);
analogWrite(17, 6000);
analogWriteFrequency(12, 50);
analogWriteResolution(12, 5);
analogWrite(12, 20);

pinMode(16, INPUT); //comment out to allow analogWrite on pin16
analogWriteResolution(16, 10);
analogWriteFrequency(16, 1600);
analogWrite(16, 7000);
analogWriteFrequency(13, 3333);
analogWriteResolution(13, 11);
analogWrite(13, 1000);

pinMode(4, INPUT); //comment out to allow analogWrite on pin4
analogWriteFrequency(4, 400);
analogWriteResolution(4, 11);
analogWrite(4, 8000);
pinMode(19, INPUT);
analogWriteFrequency(19, 100);
analogWriteResolution(19, 6);
analogWrite(19, 44);

pinMode(2, INPUT); //comment out to allow analogWrite on pin2
analogWriteFrequency(2, 200);
analogWrite(2, 8191);
analogWrite(22, 500);
analogWriteFrequency(22, 1200);
analogWriteResolution(22, 11);

Serial.println();
analogWriteFrequency(33, 60);
analogWriteResolution(33, 10);
analogWrite(33, 650);

printPinsStatus();
}
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"keywords": "esp32, analogWrite, LEDC",
"description": "Provides analogWrite for ESP32 and ESP32S2 using the LEDC functions. Controls both PWM and DAC outputs. Smart GPIO resource management.",
"license": "MIT",
"version": "1.0.0",
"version": "1.1.0",
"frameworks": "arduino",
"platforms": "espressif32",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ESP32 ESP32S2 AnalogWrite
version=1.0.0
version=1.1.0
author=David Lloyd
maintainer=David Lloyd <[email protected]>
sentence=ESP32 ESP32 analogWrite functions
Expand Down

0 comments on commit 28979ad

Please sign in to comment.