Arduino-esp32: analogWrite() not implemented

Created on 7 Oct 2016  Â·  105Comments  Â·  Source: espressif/arduino-esp32

to be implemented

Most helpful comment

Hi @me-no-dev

I have create a small library that provide the classic analogWrite for ESP32, please test it and give me your feedback

Repository https://github.com/ERROPiX/ESP32_AnalogWrite

All 105 comments

will be when the driver is ready

two types of analogWrite are now implemented through SigmaDelta and LEDC.
Headers for the relevant drivers are here and here

Just found some examples!
AnalogOut

The led stuff worked for me.

Will you provide an Arduino-compatible analogWrite based on one of these functions? Really convenient for compatibility with existing code examples

Is there any news about this? It's labed as 'to be implemented' but what is the priority of this? It would really helpful to have this function so it can be compatible with some libs that use it.

Just tried to move some code over from a ESP8266 to my shiny new ESP32 and had the same issue with analogWrite not being implemented. Will this be fixed any time soon?

any update? Just hit this problem as well

There are work arounds using ledC. I uploaded a example into the GitHub repo:

https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino

You attached a pin to ledc, set it up, then you can call commands with ledc to update the output.

Over two years, and no fix? Seriously?

@Sod-Almighty different hardware. a direct equivalent implementation is impossible. There are other methods to achieve the same functionality, but they are not exactly compatible.

You have to adjust your code to use either SigmaDelta or LEDC. Both work but they are not drop in. You as the programmer have to decide how to handle the differences.

Chuck.

As posted see my example. If you are programming for both say both a ESP8266 and a ESP32 you can use some if then statements to determine which to use. For example a RGB LED strip control program I have attaches the pin to use in the setup:

        #if defined(ARDUINO_ARCH_ESP32)
            ledcAttachPin(m_nPinR, m_nChannelR);
            ledcSetup(m_nChannelR, 5000, 8);
        #else
            pinMode(m_nPinR, OUTPUT);
        #endif

Then when I need to write to the output:

        #if defined(ARDUINO_ARCH_ESP32)
            ledcWrite(m_nChannelR, subStringR);
        #else
            analogWrite(m_nPinR, subStringR);
        #endif

Although I will disagree with @stickbreaker - nothing is impossible. There has to be a way to add a wrapper for analogWrite that just does the LedC stuff for you but it doesn't look like that's going to happen.

@vseven so,
If I use your defines, I can get a 490hz pwm signal on 4 different pins, each one with a different 8bit duration? (Arduino Uno 3, 9, 10, and 11) and a 980hz PWM signal on 2 different pins (Arduino Uno 5,6) Also with different duration's?

I do not see how the following Arduino Uno commands analogWrite(3,25); analogWrite(5,26); could be directly translated.

To directly translate from analogWrite() to ledcWrite() every interaction of of the Arduino timers would have to be emulated:

TCCR2B = (TCCR2B & 0b11111000) | 6;

I have only used analog Write for one motor controller; a brushed 8 Amp gear motor. I had to adjust the PWM freq way down before the motor could operate. So I reconfigured the base PWM to 122hz with this TCCR2B value. This allowed me to use analogWrite(3,x) to successfully operate this motor. But, I cannot expect this same command to set the ESP32's pin 3 PWM freq to 122hz.

I believe that making a partial translation would be more of a hindrance than benefit.

I know that the ESP32 is different, so to successfully set a PWM freq to 122hz I must Learn how to configure the ESP32 to achieve this goal.

Chuck.

Although I made the ledC example sketch for the ESP32 it was more of a learning thing then anything. I've never programmed a Uno controller, I've never actually used the analogWrite command for that matter. I've only used the ESP32 and then I modified my code to also support ESP8266 chips (using analogWrite) so I don't know the detailed ins and outs. I just know that for a ESP32 you have to add in the ledC PWM "channel" and tie it to your output. You can then modify the channel for your frequency and resolution.

Like I said I'm just using it for relatively simple analog RGB LED control and my code works for both the ESP32 and 8266 without having to modify anything. Check out the sketch above. It might help (or not).

@vseven Like you have experienced, the ESP32 hardware is not equivalent to the AtMega328p. So to effectively use it you have to Learn the differences and exploit them. Your example is a good reference of how to achieve a similar result. My harping that the programmer must discover/learn the ESP32 hardware to maximize his effectiveness is my hardware background showing through.

Thank you for your assistance. I have not needed analogWrite() yet on the ESP32 so I am ignorant on the work-a-rounds.

Chuck.

I have just had an issue with the LiquidCrystal which wouldn't compile because it was missing the analogWrite function.

I added to #define analogWrite ledcWrite the top of the library to replace it with the ledc version and it works without issues now.

Might be a quick fix for anyone wanting to use existing arduino code on their esp32

Note: This was using PlatformIO. In the arduino IDE it just worked without any special defines

Wow, it looks like this is the oldest opened issue on espressif/arduino-esp32.
analogWrite() is really important. How and when may we solve this issue?

it's a very important function ,is there anyone can rerewrite the lib?

Hi @me-no-dev

I have create a small library that provide the classic analogWrite for ESP32, please test it and give me your feedback

Repository https://github.com/ERROPiX/ESP32_AnalogWrite

Bump.

Hi @me-no-dev

I have create a small library that provide the classic analogWrite for ESP32, please test it and give me your feedback

Repository https://github.com/ERROPiX/ESP32_AnalogWrite

It's working perfectly! Thank you very much!

I have create a small library that provide the classic analogWrite for ESP32

Excellent. I will have to give it a try.

@ERROPiX Do you have a plan to integrate your library codes into esp32/cores/ ?

This has gone far too long. Thanks @ERROPiX for providing us with a good wrapper.

this will not go into master. It is not the only PWM (or analogWrite) on the ESP32. There are far more reasons, but I think no point going into them. If anything goes in the master that is analogWrite, that would be MWPWM which does not have Arduino hal yet.

It seems like we have time to hear the reasons, because I'm here to say:

Please implement analogWrite so I can write cross-platform code for these microcontrollers.

(updated, 2019 request)

FastLed is awesome for everything. Analog write is nice for anyone
transitioning from the arduino world to esp32. Analog write would make a
lot more examples carry over. But for all it’s worth. There are plenty of
libraries that take car of PWM.

On Mon, May 20, 2019 at 7:35 PM Skickar notifications@github.com wrote:

It seems like we have time to hear the reasons, because I'm here to say:

Please implement analogWrite so I can write cross-platform code for these
microcontrollers.

(updated, 2019 request)

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4?email_source=notifications&email_token=AFAW7LWSPLUTAJK5ULJTXGLPWNNWPA5CNFSM4CSCDMFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV2SNYY#issuecomment-494216931,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFAW7LXETU4L467EEUV3YZ3PWNNWPANCNFSM4CSCDMFA
.

@jandolina FastLED uses the RMT to send commands out on the esp32 and not analogWrite to create a PWM signal.

Damn, my bad

On Mon, May 20, 2019 at 8:33 PM Mike Dunston notifications@github.com
wrote:

@jandolina https://github.com/jandolina FastLED uses the RMT to send
commands out on the esp32 and not analogWrite to create a PWM signal.

—
You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4?email_source=notifications&email_token=AFAW7LQ3CHZO47TSXQQMQXDPWNUP5A5CNFSM4CSCDMFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV2UY2A#issuecomment-494226536,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFAW7LRT2GJKIM5N7VZUI53PWNUP5ANCNFSM4CSCDMFA
.

There are a few implementation proposals within the list of issues.

Why is that not implemented for 3 years? Does nobody use AnalogWrite? As @skickar pointed out: we need that for cross-platform development. :-/

@exocode It seems that you have an interest in it, why don't you implement one of the proposals that will be compatible with analogWrite().

Chuck.

Hi @stickbreaker, I tried that, but without success. I wanna reuse the same codebase for different ESPs (ESP32 and ESP8266). It seems, that in my build process the ifdef statement is not working properly: You can see it here: (with example code) https://github.com/platformio/platformio-core/issues/2597

Ok. It seems that the platform I use (platformio) had a problem within it's latest stable release. I installed the development version and itn (https://github.com/espressif/arduino-esp32/issues/4#issuecomment-433720705) worked.

The error in my case relied on #ifef which was not compiled properly

This is my solution for compatibility issue with this function. I hope it becomes a builtin function
////////////////////////////////////////////////////////////////////////////////////

int _adc = 0;
int ADC_MAP[48]={
-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1
};

define PWM_FREQ 32000

//change this to set PWM output resolution. 8--> 0~255 values

define PWM_RESOLUTION 8

//#define USE_SIGMADELTA

void setupPWM(int pin)
{
pinMode(pin, OUTPUT);

ifdef USE_SIGMADELTA

sigmaDeltaSetup(_adc, PWM_FREQ);
sigmaDeltaAttachPin(pin, _adc);

else

ledcSetup(_adc, PWM_FREQ, PWM_RESOLUTION);
ledcAttachPin(pin, _adc);

endif

ADC_MAP[pin] = _adc;

_adc = _adc + 1;
}

void analogWrite(int pin, uint8_t val)
{
if(ADC_MAP[pin]==-1)
setupPWM(pin);

ifndef USE_SIGMADELTA

ledcWrite(ADC_MAP[pin], val);

else

sigmaDeltaWrite(ADC_MAP[pin], val);

endif

}

// the setup routine runs once when you press reset:
void setup() {
}

void loop()
{
analogWrite(9,128);
}

@mrayy I think my solution is better, check this repository https://github.com/ERROPiX/ESP32_AnalogWrite

Unless this became internally supported by ESP32, it will be very difficult to manage the channels when using third party libraries.
For example, I recently used ESP32_AnalogWrite library and ESP32_Servo library, which each library was using its own internal ledc channels management, resulting in a conflict that the same ledc channel being allocated by both libraries.

Hello! Just expressing continued interest in adding analogWrite.

I had a same problem recently: I needed to control a servo and two motors and since the libraries were different (there's no single library to control both) they had their own conflicting implementations of analog write.

@me-no-dev Do you have any better suggestions?

Can you please add this? It should be really easy to do.
It's a major inconvenience for lots of people.

Whoever downvoted Harvie's comment should just go implement AnalogWrite.

Whoever downvoted Harvie's comment should just go implement AnalogWrite.

@ERROPiX already did a brilliant job.

analogWrite() is actually a crucial Arduino command (like e.g. analogRead() and digitalWrite() ) and thus should be available for ESP by default.

alternatively and to delimit from "analogWrite DAC values" it might be helpful to implement both a function
softPwmWrite() for pwm pins (see: wiringPi for Raspberry Pi)
additionally to
analogWrite() for DAC pins.

@ERROPiX already did a brilliant job.

So what is the problem with merging it upstream?

I ran into the same problem as @extesy and @mrayy did.
This is such a core Arduino feature I was more than surprised to find it not there when I first went to use it.

@ERROPiX already did a brilliant job.

So what is the problem with merging it upstream?

According to @me-no-dev , only MWPWM can be used for analogWrite, however I am about to object that and say: Implement it with whatever wrapper possible and worry about perfecting it later.

@igrr @kedars @mahavirj @me-no-dev @projectgus @Spritetm
Can you PLEASE push this bit harder? :-)

Oh wow 😲, didn't realise this was missing! I might look into some other boards then 😕...

The ESP32 is an amazing platform. I have been a big fan of this hardware for years. The analogWirte no native is not a dealbreaker. There are many PWM libraries to help you get you where you need to be. Yes it would be cool to have this function, but the platform offers so much that it is a non issue.

Start here:
https://randomnerdtutorials.com/esp32-pwm-arduino-ide/

@wouterds @jandolina I have created a good wrapper library to work with analogWrite
https://github.com/ERROPiX/ESP32_AnalogWrite you can install it on both Arduino IDE and PlatformIO

If you love the esp32 so much, why don't you go write an analog write love
poem to it so everyone else can enjoy it too.

On Sun, Jan 12, 2020, 6:50 PM Joe Andolina notifications@github.com wrote:

The ESP32 is an amazing platform. I have been a big fan of this hardware
for years. The analogWirte no native is not a dealbreaker. There are many
PWM libraries to help you get you where you need to be. Yes it would be
cool to have this function, but the platform offers so much that it is a
non issue.

Start here:
https://randomnerdtutorials.com/esp32-pwm-arduino-ide/

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4?email_source=notifications&email_token=AJTC7HIO7OI5QBMTMXYMDCLQ5PJHRA5CNFSM4CSCDMFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIXMNMQ#issuecomment-573490866,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AJTC7HIHJMSHAM4RV4RJPH3Q5PJHRANCNFSM4CSCDMFA
.

Power is red
Radio is blue
But I can’t dim my LED
So AnalogWrite, I miss you

@wouterds @jandolina I have created a good wrapper library to work with analogWrite
https://github.com/ERROPiX/ESP32_AnalogWrite you can install it on both Arduino IDE and PlatformIO

Thanks, that does seem to work! For a bit. I'm not sure but it looks like there's a memory leak? I'm writing to 4 pins an analog value every loop and I see free memory draining rapidly until it crashes and reboots.

Edit: also can't your port it / make a PR here so it's included by default for everyone? @ERROPiX

as stated, analogWrite() is crucial in the Arduino API world for cross-platform-compatibility, so please provide it for ESP32, too, ASAP. As usual, pwm frq should be somehow between 500Hz...1kHz preferably.

Is there something unusually difficult/on hold about implementing this? Not being facetious, just trying to understand the issue.

thank you for this, I've been receiving emails from this thread for the
last several months and this is the only one that's made me any less angry.
Also, if it wasn't clear, my vote is for implementing analog write.

On Tue, Jan 14, 2020, 1:50 AM Wayne Keenan notifications@github.com wrote:

Power is red
Radio is blue
I can’t dim the LED
Analogwrite, I miss you

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4?email_source=notifications&email_token=AJTC7HO3HD76NST6V3F2RE3Q5WDFHA5CNFSM4CSCDMFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEI37GFY#issuecomment-574092055,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AJTC7HOR35JBFWWIPANHBU3Q5WDFHANCNFSM4CSCDMFA
.

I briefly looked into this to see if I could copy it from @ERROPiX his repository but I have too little C/C++ knowledge (and this repository looks quite complex). But there is an open PR (https://github.com/espressif/arduino-esp32/pull/3110). Would be cool if @magicblocks & @me-no-dev could finish this up or if someone else could pick it up.

it needs to work in the following way:

  1. find available PWM peripheral (LEDC, MCPWM, SigmaDelta, RMT, Soft?)
  2. Make sure that the clock requirements will not interfere with other used ports on the same peripheral (LEDC and others share some clocks)
  3. Mark the selected port as used and save it's usage type
  4. Do not forget to free the port if a call to some other pin function is made. Now this is the big issue here... means that any time you call pinMode and others, have to check if that pin is attached to port and so on.
  5. All of that functionality must be tracked by each peripheral as well (so you can use LEDC or other and still use analogWrite)

The lib above does not take any of those considerations. It's just not that simple :) But I already have some code written towards that goal.

for Arduino IDE there is a library and it worked for me perfectly for motor controller project.
https://www.arduinolibraries.info/libraries/esp32-analog-write

perhaps someone of the devs could test it and make a fork to integrate it to the common ESP32 standard Arduino core libs?

Ok, so I just ran into this issue today.
Not having an analogWrite() function breaks my LCD library. (hd44780)
The hd44780 library currently works on EVERY other Arduino platform/core except this one.
This includes the esp8266 library.
While the hd44780 library code is smart enough to use digitalPinHasPWM() to detect if PWM support exists on the pin,
the code still doesn't work (won't even compile) on this platform because of a call to analogWrite() which does not exist.
Users should not have to muck up their code with platform/core specific conditionals to work around a missing Arduino core library function.

Given that analogWrite() is a core API function, it should always exist in this platform.
Until analogWrite() is properly implemented, which I believe is possible,
my suggestion would be to add an analogWrite() function but not support PWM.
The Arduino.cc analogWrite() function already handles this for pins that do not support PWM.

For the esp32 analogWrite() with PWM support disabled, it would mean
treating all pins as if they do not support PWM, which technically would be correct since they don't have PWM capability using analogWrite() since the underlying code for PWM is not yet implemented.
To do this:

  • change the digitalPinHasPWM() in all variants pins_arduino.h header file to return false
  • create a minimal analogWrite() function that mimicks the Arduino analogWrite() behavior when PWM is not supported on a pin.
    When PWM is not supported on a pin, the official Arduino core code will set the pin low if the value is less than half way to max and high if the value is over half way to max.

In each variant's pins_arduino.h header file change the digitalPinHasPWM() macro to something like this:

define digitalPinHasPWM(p) (0) // analogWrite() does not yet support PWM

And for the matching analogWrite() function:

void analogWrite(uint8_t pin, int val)
{
        if(val < 128)
                digitalWrite(pin, LOW);
        else
                digitalWrite(pin, HIGH);
}

Making these changes/updates will allow existing code that calls analogWrite() to function as it does on all the other platforms.
It also allows the code to use digitalPinHasPWM() to detect if PWM is supported on the specified pin.

IMO, this is a very small/simple change that resolves the main issue of analogWrite() not existing which causes any code that attempts to use analogWrite() to fail to compile.

At some point a proper analogWrite() that supports PWM when possible, should be added to the core

Ok, so I just ran into this issue today.
Not having an analogWrite() function breaks my LCD library. (hd44780)

You're wasting your breath. This core has been broken for almost four years, and the maintainers clearly have no intention of fixing it. They have ignored every attempt to address this problem, holding out for some mythical "perfect solution" that does not exist; instead of just damn well choosing one of the available options, which would be infinitely better than the absolute lack of functionality we currently have.

All I can suggest is that you fork your own, and recommend that your users switch to using that.

Pretty much the only joy that exists in this thread is irritating the cowards responsible for not implementing analogwrite and attracting thumbs downs from nerds who like excuses better than making cross-platform code.

There is a basic implementation of analogWrite available in the Arduino IDE: simply install the ESP32Servo library (the one in the Arduino IDE is the correct one, it is https://github.com/madhephaestus/ESP32Servo ), and add

#include <analogWrite.h>

It has another approach then other libraries: it has in one implementation the Servo library, analogWrite and the Tone library. This makes it possible to have a shared channel management for the 3 different things (servo, analogWrite and tone). A user doesn't need to take care of all this (as long as you don't use timers for other purposes, such as a camera).

Remarkt that you have to use values 0 .. 255 in analogWrite. In case you want to develop cross-platform with ESP8266, use PWMRANGE.

It demonstrates that it is possible to have an implementation of PWM functions compatible with other Arduino's, you just need a common channel manager, which is not yet available.

thanks for your link! Looks really awesome!

four years later....
sponge bob

@FedericoBusero you saved life

@deadoralive023 hey! please don't use words like "finaly" in this thread unless this is merged upstream. i almost fainted of overexcitement... in vain.

@deadoralive023 hey! please don't use words like "finaly" in this thread unless this is merged upstream. i almost fainted of overexcitement... in vain.

I'm new so Thanks for letting me know.

I think after few more years in this (still unresolved) thread you will understand :-D

@developers:
what the heck is the problem to merge this lib https://github.com/madhephaestus/ESP32Servo into the standard esp32 core libs?

@dsyleixa Basicaly the developers:

image

Meanwhile the users:

image

what the heck is the problem to merge this lib https://github.com/madhephaestus/ESP32Servo into the standard esp32 core libs?

@dsyleixa The problem with analogWrite() is almost all usages center around using the LEDC peripheral. There is no problem if you are using just analogWrite() and none of the libraries are using the LEDC peripheral. If you allocate LEDC channel 1 for analogWrite(32, XXX) and a library also uses LEDC channel 1 for a different pin you will now have conflicts between the two usages. That is where the problem is coming from on why this has not been resolved yet.

@me-no-dev had mentioned a reservation like system for the LEDC channels at one point but that has not been exposed in the public API as of now.

atanisoft:
WHAT?
analogWrite is an elementary common standard Arduino command and so it has to be expectedly available in the standard core libs, just like on all other Arduino boards!

analogWrite is an elementary common standard Arduino command

Fully agree with you there, it is part of the standard API.

The problem as I mentioned above is which peripheral should be used for generating the output signal that doesn't impact the usability of the peripherals in a negative manner. That is the problem that needs to be resolved before analogWrite() can be included in the base repository.

The problem as I mentioned above is which peripheral should be used for generating the output signal that doesn't impact the usability of the peripherals in a negative manner. That is the problem that needs to be resolved before analogWrite() can be included in the base repository.

@atanisoft how is that really a problem?
There will often be issues when code needs to use certain resources to implement something.
That isn't a valid reason to not implement something. You just pick something reasonable and move on and if necessary document the limitations and/or how it can be configured.
These same types of issues exist on the AVR platform when using analogWrite() and I'm sure other platforms as well.
How did they handle this on the esp8266?

As I said before, analogWrite() and digitalPinHasPWM(p) should ALWAYS exist.
Worst case if the developers don't want to implement pwm (which I'm still not seeing a reason why they can't), or need more time, then they could do as I showed before.
Simply have digitalPinHasPWM(p) be defined at 0 and then do what other implementations do when a pin does not support pwm. It sets the pin output to LOW when the value is below 128 and HIGH otherwise.
While that implementation choice of analogWrite() would not provide pwm, it does ensure that analogWrite() exists and technically "works" as documented.

To just not implement anything, is total BS, IMO.

how is that really a problem?

If analogWrite() is provided by the core library then every solution proposed in this issue so far would become broken, similarly any other library that happens to implement/export a function named analogWrite() will be broken as well. Perhaps it is not as much of an issue for some developers but it will cause a number of new issues to be filed which all have the same solution: upgrade/downgrade your version. It isn't ideal but maybe it is the only solution.

Simply have digitalPinHasPWM(p) be defined at 0 and then do what other implementations do when a pin does not support pwm. It sets the pin output to LOW when the value is below 128 and HIGH otherwise.

Technically all pins can have PWM except 34-39 which are input only. So the problem will then be, which eight pins should be selected for output (assuming LEDC as the analogWrite implementation)? No matter which ones are selected it will be the wrong choice.

If analogWrite() is provided by the core library then every solution proposed in this issue so far would become broken, similarly any other library that happens to implement/export a function named analogWrite() will be broken as well. Perhaps it is not as much of an issue for some developers but it will cause a number of new issues to be filed which all have the same solution: upgrade/downgrade your version. It isn't ideal but maybe it is the only solution.

But that is really a backward compatibility issue, not an implementation issue.
True, it can still be just as much of a problem, but when you have a platform/core that totally failed to implement API functions, there is no way to keep from having issues once the platform does finally implement those missing API functions.
I see no way around having issues if analogWrite() is expected to "just exist" in the core library like it does in all the other platforms with no need for including a header file or a constructor.

It would have been nice the original pwm output API had been done with a separate library and used a separate object for each pin, so you could configure the pin including for things like using pwm or true analog output, but unfortunately it wasn't done that way.

Technically all pins can have PWM except 34-39 which are input only. So the problem will then be, which eight pins should be selected for output (assuming LEDC as the analogWrite implementation)? No matter which ones are selected it will be the wrong choice

Perhaps there can be a way to configure which pins are used through an API extension or adding a constructor.
Kind of similar to what can done for the pins used for i2c.
I.e. you have defaults that can be reconfigured.

I agree, also on Uno or Nano or Mega not all digi Pins provide pwm - some do, some don't. IIRC, not even the Due has them all everywhere.
But it eventually must be available there somewhere.

At the most basic, you could just have a #define that specifies which pins should have PWM capability. This is elementary, people!

At the absolute bare minimum, you should provide an analogWrite() that does nothing. To omit it entirely from the API is simply inexcusable, and you should be ashamed of yourselves.

You are right new guy. They should be ashamed.

I hope every other angry person on this thread is doing okay in these
ghastly times, I think of you all at least once per night before I go to
sleep.

Let's all hope that one win we can get out of this year is holding someone
responsible for ruining our electronics project.

On Fri, Sep 25, 2020, 9:44 PM infinity-computers-dot-net <
[email protected]> wrote:

At the most basic, you could just have a #define that specifies which
pins should have PWM capability. This is elementary, people!

At the absolute bare minimum, you should provide an analogWrite() that
does nothing. To omit it entirely from the API is simply inexcusable, and
you should be ashamed of yourselves.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4#issuecomment-699324844,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AJTC7HK6X7QC7AHQK33ZLCDSHVPSVANCNFSM4CSCDMFA
.

Sarcasm is the lowest form of wit. In addition, you have just committed the fallacy of relative privation.

If you implement an API, you are obliged to implement the whole API, or else you break compatibility with everything.

This issue has remained unresolved for four years - most of which time was covid-free - when at the very least, they could have bare-minimum "solved" it with a dummy function. And if the number of posts in this thread are any indication, this omission affects a large number of users. So yes, they should be ashamed.

I was agreeing with you nerd, we're all a little tense on this thread.

On Sat, Sep 26, 2020, 8:46 AM infinity-computers-dot-net <
[email protected]> wrote:

Sarcasm is the lowest form of wit. In addition, you have just committed
the fallacy of relative privation.

If you implement an API, you are obliged to implement the whole API, or
else you break compatibility with everything.

This issue has remained unresolved for four years - most of which time was
covid-free - when at the very least, they could have bare-minimum "solved"
it with a dummy function. So yes, they should be ashamed.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4#issuecomment-699505051,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AJTC7HJV6Q4R5EGUMYLKTXTSHX5F3ANCNFSM4CSCDMFA
.

Can we all calm TF down? @me-no-dev already said he's working on a proper implementation and, as he pointed out, is not as simple as creating a wrapper around Arduino functions. @ERROPiX already made something like that for y'all impatient pricks.

Yes, this is far from a simple solution as thought and there are a number of factors that play into the implementation that must be considered.

impatient pricks

This offensive remark contravenes the code of conduct.

impatient pricks

This offensive remark contravenes the code of conduct.

Agreed, this issue is rife with comments that would potentially fall afoul of the code of conduct.

Can we go back to on-topic civilized discussion of the issue(s) at hand?

Mike
Can you please explain what issues are complicating the solution? Is it
management of allocation of resources, eg pins and channels etc?
David

On Mon., Sep. 28, 2020, 04:35 Mike Dunston, notifications@github.com
wrote:

Yes, this is far from a simple solution as thought and there are a number
of factors that play into the implementation that must be considered.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4#issuecomment-699951814,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAEDQSRWP4BUDF36SVHHDVDSIBYIVANCNFSM4CSCDMFA
.

Is it management of allocation of resources, eg pins and channels etc?

That would be one of the two big issues:

  1. There are a total of 16 possible analog signal sources (LEDC has eight, Sigma-delta has another eight).
  2. These two peripherals can be controlled directly via the ESP-IDF API which will bypass the Arduino HAL APIs.

Managing the first one as part of calling pinMode(..) or analogWrite(...) is doable but the second one will invariably result in a lot of frustration and issues filed for the output on an analog pin being "wrong" due to a third-party library using the peripheral in a different manner.

There are also likely other issues which have resulted in this issue unfortunately sitting for so long.

Every time I think about it, I find new issues that can arise. There is no global solution for this. Locally in sketches it's rather simple to do. You can ifdef ESP32 and define a macro. Then you need to pay attention at what libraries in your project are using (if they need one of the peripherals that can do PWM) and make sure you do not overlap.

PWM can be provided by LEDC (HS and LS), MCPWM, RMT and SigmaDelta. DAC is also analogWrite (maybe even more than PWM).

Each of those peripherals can provide other functionality as well.

How did they handle this on the esp8266?

ESP8266 does not have PWM capable peripherals. I wrote a software PWM lib for it.

I'm not sure what you mean by "PWM capable peripherals" here. The ESP8266 has hardware PWM.

ESP8266 does not have PWM capable peripherals.

It seems to have the Sigma-delta peripheral but it is not being used for analogWrite.

The ESP8266 has hardware PWM.

It's not being used for PWM though, https://github.com/esp8266/Arduino/blob/5b767a37eb983a475fe29a8be6b489d62e833251/doc/reference.rst#analog-output

SigmaDelta is not really PWM @atanisoft :) but can be used to drive motors and such. It was not documented and had few channels (not that I remember much).

@infinity-computers-dot-net it does not. PWM is done in software, using one of the hardware timers.

Oh, it's done using an interrupt!?

We need a generalized method of indicating reservation of resources. The
same problems arise with timers, many libs use them, and one has to try to
not have collisions.

Could we not have an initializer that indicates the resource, and return a
success/failure flag?

Eg: if( err = analogInit(pin, LEDC) ) { Serial.print("\nPin assignment
failed:"); Serial.print(err);
where err might indicate 'no peripheral is available' etc

Another problem is that the peripherals share the same clock base, so
interactions between the peripherals.

Still, we should be able to come up with some common solution.

If you build it, they will come. Ie, future code will reap the benefit.

David

On Mon, Sep 28, 2020 at 9:05 AM Me No Dev notifications@github.com wrote:

Every time I think about it, I find new issues that can arise. There is no
global solution for this. Locally in sketches it's rather simple to do. You
can ifdef ESP32 and define a macro. Then you need to pay attention at what
libraries in your project are using (if they need one of the peripherals
that can do PWM) and make sure you do not overlap.

PWM can be provided by LEDC (HS and LS), MCPWM, RMT and SigmaDelta. DAC is
also analogWrite (maybe even more than PWM).

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/4#issuecomment-700129932,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAEDQSWHRRJN5QBPTDTBQV3SICX3PANCNFSM4CSCDMFA
.

The ESP8266 has hardware PWM

No it doesn't, at least not for analogWrite().

At the ESP8266 Arduino repo we implemented a sw waveform generator as a centralized engine of pulse output channels of (mostly) arbitrary shape, and then reimplemented sw pwm, i. e. analogWrite(), on top of that.

The reason we did that is because with the prior code you couldn't mix certain libs, e. g. Servo and pwm wouldn't play nice together, or pwm would fail if you output a Tone. With the waveform generator you can mix.

There are now new versions of the waveform generator proposed, each with pros and cons. They have both undergone rather tough testing. Both PRs are viable, we'll likely keep both.

@me-no-dev I don't know if our waveform generator implementation applies to a FreeRTOS-based platform like the esp32, but if you would like to discuss, you know where to find me :)

This thread has been amazing. Thank you all for keeping the ESP community alive. As a starter chip the ESP family is probably not the right choice. Once you understand things on the Arduino hardware and in the IDE, then you can branch out to unlimited controllers out there. My current favorite combo is VSCode + TTGO Lora 32 v2 with OLED.

Back to the topic.
Do you think it would make sense to take a LED PWM library and just call it PWM so there is no confusion with the LED names? Not out of the box, but still a low bar to entry.

The resource allocation argument is IMO invalid. This is just something that happens with ANY arduino library. If you've ever coded for Arduino UNO (atmega), you know that in such cases you have to manage resources yourself. at least to some extent, but definitely when using 3rd party libraries or directly accessing the peripherals without using the arduino wrappers.

If 3rd party code manages timers directly on atmega, it will screw arduino PWM. It's not a big concern for me. As a developer you should choose if

1.) You are beginner and want to use arduino wrappers (and therefore have to use them almost exclusively).
2.) You are advanced and want to unleash full performance of hardware by using ESP-IDF directly, but then you have to understand the consequences and possibly might loose the ability to use beginner friendly arduino layer.

No need for some magic "solve it all" layer... You will never be able to fix all edge cases anyway...

Just choose some sensible default peripheral to provide 2 to 8 pins with PWM and add option to manualy select different peripheral if needed. Similary to the way we have multiple UARTs or SPIs and stuff like that piggybacked to the original single UART API that we had in early days of arduino. This is not perfect solution, but good enough for anyone who is willing to use Arduino API, which is not perfect anyways... If you need more than few PWM outputs, just use esp-idf OR wait 10 years before someone comes with perfect solution.

Arduino API is mostly usefull for learning, prototyping, etc... Anyone serious will use esp-idf anyways... We just need to have enough API to make all analogwrite examples shipped with arduino IDE to compile and run.

People who use the Arduino IDE for either boards are 99% beginners and hobby users and mostly do not even understand neither real C++ coding nor RTOS coding, but they have the benefit that Arduino API code on a Uno also runs on a Due, Zero, SAMD51, or (hopefully) ESPs. Finally that's also basically the Arduino/Wiring philosophy. So a Arduino-API-compatibility also for the ESPs are crucial.

omg. I have to unsub from this now... but what dsyleixa just said is 100% true.

People who use the Arduino IDE for either boards are 99% beginners and hobby users and mostly do not even understand neither real C++ coding nor RTOS coding

That's what i was saying. Then they don't need all the advanced optimizations, because they will not get 100% performance with that attitude anyways... You will not get that with Arduino UNO / atmegas either. analogWrite() does not have to be 100% perfect.

It is very long issue, but i see some confusion here about signals.
Analog signal is when you can control peak to peak, and with PWM or LEDC we cant do that. It still will be digital signal.
esp32 has only 2 analog out pins and i believe only those pins can be used for analogWrite.
To prove my point try to connect LEDS or PWM driven "analog" signal to scope or to analog IN pin on esp32 and try to get readings. What will be the result?

Why has that issue topic been closed?
It is not resolved yet and thus has to be kept open UNTIL it will be solved!
So please reopen this issue!

Where do you see it has been closed?
Screenshot from 2020-09-30 11-44-17

analogWrite() generally works on Arduino DIGITAL pins, where a pwm signal is generated, and the argument is an integer value for the pwm value. In this respect the Arduino API function name is misleading, it better had been named "pwmWrite" instead, but it wasn't, so it is as it is.
Additionally, there is kind of overloaded functionality for Arduinos which provide also analog voltage output on DAC pins (e.g., like the Arduino Due): on those DAC pins analogWrite creates a "real" analog voltage level from a passed integer value within a defined range.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

merlinschumacher picture merlinschumacher  Â·  4Comments

ComputerLag picture ComputerLag  Â·  3Comments

maxgerhardt picture maxgerhardt  Â·  3Comments

Darkhub picture Darkhub  Â·  3Comments

zuqualla picture zuqualla  Â·  4Comments