Skip to content

PWM analogWriteRange BUG? #2592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gorec2005 opened this issue Oct 9, 2016 · 31 comments
Closed

PWM analogWriteRange BUG? #2592

gorec2005 opened this issue Oct 9, 2016 · 31 comments

Comments

@gorec2005
Copy link

gorec2005 commented Oct 9, 2016

Hardware

Hardware: ESP-12
Core Version: from GIT 08.10.2016

Description

Bright not changed if change PWM analog Range... and all time bright is maximum!
i don't understand - it's a bug or feature...

Settings in IDE

Module: Nodemcu v1
Flash Size: 4MB
CPU Frequency: 160Mhz
Flash Mode: dio
Flash Frequency: 40Mhz
Upload Using: SERIAL
Reset Method: nodemcu

Sketch

void setup() {
  Serial.begin(9600);
  Serial.println(__FILE__ " " __DATE__ " " __TIME__);
  pinMode( 12, OUTPUT ); 
}

void loop() {
Serial.println("2000");
analogWrite( 12,1 );
analogWriteRange(2000);
delay(1000);

Serial.println("3000");
analogWrite( 12,1 );
analogWriteRange(3000);
delay(1000);

Serial.println("4000");
analogWrite( 12,1 );
analogWriteRange(4000);
delay(1000);
}
@WereCatf
Copy link
Contributor

You do not use analogWriteRange to control an LED's brightness, you use analogWrite for that. Change your loop to, say, the following, and you'll see the LED's brightness change:

void loop() {
Serial.println("255");
analogWrite( 12,255 );
delay(1000);

Serial.println("511");
analogWrite( 12,511 );
delay(1000);

Serial.println("767");
analogWrite( 12,767 );
delay(1000);
}

@gorec2005
Copy link
Author

Than you for you answer!
:-) - yes - i understand it, but it's not enought only 1000 for my task - i need 10000
but if i set
analogWriteRange(10000);
and after that
do
analogWrite(1);
led bright is max! - i think it's a bug....

@me-no-dev
Copy link
Collaborator

yes and no. You are going outside of the range that the hardware can do. Why in the world you need 10000 steps? that is not the frequency ;) it's the resolution. And then setting a value of 1 means that the time between start of the period and the time that you hit the count it will be so small that you will overlap your setting function and things will go to hell.
This is software PWM and not hardware one, so stuff is limited ;)
Again why 10000 steps?

@gorec2005
Copy link
Author

gorec2005 commented Oct 10, 2016

it's need for led bright regulation.... if it's only 1000 and set analogWrite(gpio,1) average current via 1 Amper LED is 1mA but it is very big size :-( - i think if increase resolution to 10000 - at analogWrite(gpio,1) current will be 0.1 mA. I jus need really LED softoff... but now it's can be only decrease bright to some level and than discret off. and i did'nt understand how after
analogWriteRange(10000);
analogWite(1);
will be more brihtly than
analogWrite(10);

@me-no-dev
Copy link
Collaborator

? I'm not positive that you understand what PWM does. Led current is controlled by resistors and not PWM. PWM gives pulses and depending on the width is for how long the LED will stay on from that period (AT FULL BRIGHTNESS). Setting range to 10000 means that you can analogWrite(pin, 0-10000) and not that you will send 1/10000 of the current through

@gorec2005
Copy link
Author

gorec2005 commented Oct 10, 2016

Yes i understand it!
but it's not work as described!!!
i test it on esp-01 with similary results....
more over it's reboot's after set range to 10000 and than analog write 1 and analogwrite 0.....

@WereCatf
Copy link
Contributor

Um, no, you clearly do not understand how it works. analogWriteRange() does not adjust the LED's brightness, period. You use analogWrite() to do that, like I already provided an example earlier. analogWriteRange() just changes the range of what analogWrite() considers the maximum value, like e.g. with the default setting (ie. 1023) half brightness would be analogWrite(PIN, 511), but if you changed the maximum to only 255 with analogWriteRange(255) you'd get half the brightness with analogWrite(PIN, 127) instead.

You really need to read what is being said to you: analogWrite() is the command that sets the brightness.

@gorec2005
Copy link
Author

analogWrite(gpio,1);
analogWrite(gpio,0);
analogWrite(gpio,1);
analogWrite(gpio,0);
work stable!
but when do:
analogWrite(gpio,100);
analogWriteRange(10000); LED bright reduced
but when i try after that
analogWrite(gpio,100); esp reboot...

@gorec2005
Copy link
Author

WereCatf - thank you - i really understand how it's work! but i have'nt enought english knowledge :-) for explain it's.... ( chukcha not writer - chucha just reader (only joke)) i understand analogWriteRange change resolution - that what i needed... but bright i change with analog write of course.... thank's and sorry for my english....

@WereCatf
Copy link
Contributor

analogWrite(gpio,1);
analogWrite(gpio,0);
analogWrite(gpio,1);
analogWrite(gpio,0);
work stable!
but when do:
analogWrite(gpio,100);
analogWriteRange(10000); LED bright reduced
but when i try after that
analogWrite(gpio,100); esp reboot...

No. That is not how it works, period.

@gorec2005
Copy link
Author

analogWriteRange(100000);
analogWrite(gpio,100);
gpio will blink with ~3..5 Hz!

@WereCatf
Copy link
Contributor

@gorec2005 Okay, I am only going to say this once: stop using analogWriteRange()! You do not understand how it works, and you do not need it! Just simply change the value of analogWrite()-call and POOF -- the LED's brightness will change!

@gorec2005
Copy link
Author

gorec2005 commented Oct 10, 2016

@WereCatf thank you again! - for change brightness i use analogWrite(). but range of 1000 (~10bit) is not enought for me - i need 10000 (~12bit) or may be 16bit for linearry change brightness of LED from switched off state to full brightness, but LED bright physic's and human bright sens eye is not equal :-(... now i use equation for linearry change bright :

range=1000;
analogWriteRange(range);
for (i=0;i++;i<1000)
{
 analogWrite(PIN_OF_LED, (( i*i) / range));
 delay(10);
}

for soft ON
and similarry for soft OFF with from 1000 to 0 i--
...

@gorec2005
Copy link
Author

it's my mistake - i did not clearly describe.... - sorry....

@gorec2005
Copy link
Author

@me-no-dev you said "You are going outside of the range that the hardware can do."
explain please - where i can see this (hardware) range for software PWM?
and how much (biggest) analogRange can be for inside hardware range?

@me-no-dev
Copy link
Collaborator

simple math ;) but I do not want to go deeper than that. If you want 12-16 bit PWM, go get a PWM chip that can do it. You do not ever need 10000 steps to change the brightness of a LED!!! Ever!!!!
Further on, 1023 is 10 bit and not 8 bit.
Before wanting something that you do not need, try something that you already have and just work with analogWrite(pin, [0-1023])

@me-no-dev
Copy link
Collaborator

10000 steps * 1000 Hz = 10MHz or 100ns between 0 and 1 <<<< not doable by software!!!

@gorec2005
Copy link
Author

"Further on, 1023 is 10 bit and not 8 bit." - i mistake...
i try'ed it, but
from ~200 to 1000 brightness changed in 5%-10%
from 10 to 200 %20 and
from 1 to 10 %40
but most dislike'd from 0 to 1 so big-big brightness jump...

it's not a soft on and soft off - it's a brightness jump+soft brightness change and so on...
@me-no-dev : "10000 steps * 1000 Hz = 10MHz or 100ns between 0 and 1 <<<< not doable by software!!!" - but if i try'ed change freq to 200Hz?

@gorec2005
Copy link
Author

hm... i try'ed....
with change freq to 100 and range to 10000 and analog Write 1 more liked brightness!!!!!
but i think in equation for timer (for SoftPWM) have some bug...
change freq nad range for stable analogwrite(pin,1); very different result!!! in some case incredible....

@me-no-dev
Copy link
Collaborator

how you have connected your led? You do realize there are many users of this thing and if it was working as much as you say, we would have known about it :)
Best case time between two steps is a bit over 2us and going 0-1 is even more.
setting pwm value to 1 is pushing the boundaries of the software/interrupt capabilities. Understand it as you wish.

@gorec2005
Copy link
Author

i connect LED via mosfet when gpio is 0 mosfet is closed and led is off... i will try to use oscilloscope later and show what i get...

@gorec2005
Copy link
Author

RANGE 10000
FREQ 100
analogWrite(100)
https://s21.postimg.org/nk8uof9f7/IMAGE000.jpg
work stable

analogWrite(10)
https://s21.postimg.org/qflxvadf7/IMAGE001.jpg
work stable

analogwrite(1)
https://s21.postimg.org/6m9u2l01f/IMAGE002.jpg
but on the last one esp work only 4-6 second and than harware watchdog :-(

@me-no-dev
Copy link
Collaborator

you are more than welcome to improve the PWM code in the core and make it work better

@gorec2005
Copy link
Author

continue... :-)
analogWriteRange(1023); default from core
analogWrite(gpio,512); duty 50%
somthing interesting....
if set analogWriteFreq(78202 and more) real freq 3Hz! - LED just blinkin
analogWriteFreq(from 39101 to 78201) real freq will stay at 64kHz!
analogWriteFreq(from 26100 to 39100) real freq will stay at 35kHz!
analogWriteFreq(from 19099 to 26099) real freq will stay at 24kHz!
analogWriteFreq(from 15640 to 19098) real freq will stay at 18,5kHz!
analogWriteFreq(from 13034 to 15640) real freq will stay at 15,0kHz!
analogWriteFreq(from 11172 to 13033) real freq will stay at 12,5kHz!
analogWriteFreq(from 9776 to 11171) real freq will stay at 10,8kHz!
analogWriteFreq(from 8690 to 9775) real freq will stay at 9,5kHz!
analogWriteFreq( 8689) real freq will stay at 7,5kHz!
and so on...

@me-no-dev
Copy link
Collaborator

increasing the frequency or increasing the steps is the same exact thing.
1 increment in seconds = 1 / ( freq * range )
1 increment in seconds must not be less than 1 microsecond

@gorec2005
Copy link
Author

@gorec2005
Copy link
Author

gorec2005 commented Nov 1, 2016

Hi!
One more strange thing with analogWrite...
ESP-12F
core latest from git
160mHz

`#include ESP8266WiFi.h
#include WiFiClient.h
#include ESP8266WebServer.h
#include ESP8266httpUpdate.h
#include ESP8266mDNS.h

const char ssid = "_";
const char *password = "
_
";
int led = 13;

void setup() {
pinMode ( led, OUTPUT );
digitalWrite ( led, 0 );
Serial.begin ( 115200 );
WiFi.begin ( ssid, password );
WiFi.printDiag(Serial);
}

void loop() {
analogWrite ( led, 1 );
delay(1000);
analogWrite ( led, 1000 );
delay(1000);
}`

did not work! - says in serial:

`Mode: STA
PHY mode: N
Channel: 7
AP id: 0
Status: 1
Auto connect: 1
SSID (4): *****
Passphrase (8): ******
BSSID set: 0

ets Jan 8 2013,rst cause:4, boot mode:(1,6)

wdt reset
`

If i change analogWrite ( led, 1 ); to analogWrite ( led, 2 ); - it's work but only five sec's than also wdt reset!
if change to analogWrite ( led, 3 ); - work ok - as expected and without wdt reset.
i did not change freq and period!
help please... what i do wrong?

@gorec2005
Copy link
Author

this sketch have wdt reset! - try it please...

`int led = 15;

void setup() {
pinMode ( led, OUTPUT );
digitalWrite ( led, 0 );
}

void loop() {
analogWrite ( led, 1 );
delay(1000);
analogWrite ( led, 1000 );
delay(1000);
}`

@gorec2005
Copy link
Author

I try'ed newpwm from https://github.com/StefanBruens/ESP8266_new_pwm
and here result:
picture from oscil

It's really cool! - timebase 200ns and period 0-5000(default)!

@hmottestad
Copy link

Hi @gorec2005

Thanks for providing a link to a library that does more than 10bit.

@WereCatf and @me-no-dev, I currently use an arduino between my esp8266 and my leds, and run the arduino in 16bit pwm mode. I used to use 8bit pwm, but the difference between 0 and 1 is so huge with my 10 watt leds that I couldn't exactly get it to comfortably dim up and down.

Here is a blog post I found on doing 16bit pwm on an arduino: https://www.arduinoslovakia.eu/blog/2017/7/16-bitove-rozlisenie-pwm-pre-arduino?lang=en

@nickion
Copy link

nickion commented Dec 3, 2020

Hi @gorec2005

Thanks for providing a link to a library that does more than 10bit.

@WereCatf and @me-no-dev, I currently use an arduino between my esp8266 and my leds, and run the arduino in 16bit pwm mode. I used to use 8bit pwm, but the difference between 0 and 1 is so huge with my 10 watt leds that I couldn't exactly get it to comfortably dim up and down.

Here is a blog post I found on doing 16bit pwm on an arduino: https://www.arduinoslovakia.eu/blog/2017/7/16-bitove-rozlisenie-pwm-pre-arduino?lang=en

Just stumbled on this thread and I feel for @gorec2005 as the contributors berating him were evidently the ones not understanding. A decent range definitely matters, and when coding PWM for PICs such as in a DMX controller, I've always used 16 bit levels with 32 bit math. Incoming 8 bit DMX levels would be scaled up to 16 bit, and the engine would fade quickly between level changes in the 16 bit space to smooth the transitions. This gives the smoothest dimming imaginable without requiring a high DMX frame rate or using two DMX channels to increase range, and with a suitable response curve rather than simply linear, the bottom end can be handled with refinement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants