-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
analogWrite - PWM Problem in IDE-Version 1.8.10 #339
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
Comments
I discovered the same issue today as I teach Arduino to my students , and a few of them has the issue of when putting a second analogWrite() for a second PWM on the same pin or a different pin, it will case online one PWM signal to appear. This happened on Mega 2560. After testing multiple boards with multiple Oscilliscopes, I was finally to find the reason as I tested one board on a computer that had 1.8.8 and it worked fine. I tried 1.8.11 it had the same problem. |
Should be moved to ArduinoCore-AVR and fixed ASAP (although I think it's due to the compiler update more than any core update) |
Hi all, i made some tests, and i found that:
Sketch size:
the AVR-Core patch to test it is the following:
|
Can anyone post a short example sketch that shows the problem, along with a description of what (incorrect) output it shows? |
yes sure:
if you check the output of the pin 3 with an oscilloscope, the correct output should be two PWM wave were in the first you have the 50% of the duty cycle and in the seconds the 25%, (two different square wave in other words), in the incorrect case the pin 3 doesn't show any activities |
@Rocketct And can you also describe the output you get when you run this particular sketch? |
yes sorry added on the previous comment let me know if clear 😄 |
@Rocketct, Thanks, perfectly clear. I have tried your sketch and looked at the generated machine code, which actually looks to be correct. I don't have an Arduino at hand right now to check if the same problem occurs for me, though. What Arduino did you test this with? |
I can confirm the problem happens with Arduino Mega using Arduino IDE 1.8.12. However, Arduino Uno seems to be unaffected. I got PWM output in pin 3 with the code as shipped. |
Ah, confirmed here: Uno works, Mega is broken. Gotta run now, I hope to look at the assembly again in the next days. |
I had a look at the generated assembly. Most is similar, except that the analogWrite has a jump table rather than nested branches to select between the different timers (probably because the mega has more timer pins). I originally thought the jump table handling was messed up (wrong RAMPZ value), but while annotating the assembly below, I realized it did seem correct after all. In any case, below is the assembly (comments with
I guess this either needs some debug prints (to read back various register values) or a JTAG debugger to verify what parts are correct and where the problem starts (or looking at the asm more closely and really verifying that all the values are correct). I probably won't have more time for this soon, though. |
Also, it might be useful to run with |
okk @matthijskooijman @PaulStoffregen thank you, in meanwhile will discuss with @facchinm about next steps |
@matthijskooijman tested with |
I have tested in IDE version 1.8.7, 1.8.9 and 1.8.12 and happens to all versions, so I do not understand how @alaqadi and @Nnambles could make it run in previous versions. void setup() {
// put your setup code here, to run once:
analogWrite (7, 100);
analogWrite (8, 200);
}
void loop() {
// put your main code here, to run repeatedly:
} This is what I am testing and with the oscilloscope I only see signal at pin 7... |
@Potul72 Did you check the AVR core version used? If you upgraded that through the boards manager, a newer version is downloaded into your user folder, which then replaces the IDE-bundled version, even when you change the IDE version I think. However, if you do not have the AVR core in your user folder, it will use the IDE bundled version which will then change with IDE changes (usually). To check, you can enable verbose compilation in the preferences, it should then use the AVR core version logged near the top of the compilation output. Using the board manager, you can also easily test different AVR core versions without having to change the IDE version. You can revert to the bundled version, I think, by selecting the bundled version number in the board manager and "installing" it (I think this just throws away the version from the user folder, reverting to the IDE bundled version again). |
Thanks @matthijskooijman. I have tested IDE version 1.8.5 with AVR core 1.8.2 and it failed also, then I tested IDE 1.8.5. with AVR core 1.6.12 and It work wounderfull. Then I tested latest IDE version 1.8.12 with AVR core 1.6.23 and it did work! So bug is on AVR Boards core from version 1.8.1, as there are no downloable version beween 1.6.23 and 1.8.1. |
I did a bit of tracing in the simulator. It looks like the code is ending up in the case for TIMER3B, when pin3 OUGHT to be TIMER3C - some sort off-by-one error in doing the jump table stuff? New:
Old:
|
Hello, excuse me for the interruption - I stumbled upon this issue lately and found this thread... if it helps in any way to pinpoint the source of the problem, I noticed that when I pass the duty cycle parameter to analogWrite using a variable declared as volatile, the problem disappears. Probably related to the optimization settings @Rocketct mentioned above. |
Hello, I can confirm that the issue happened to me with the IDE versions 1.8.10, and 1.8.13. |
The issue is definitely confirmed for IDEs 1.8.10 and higher. Just try to run this simple sketch on Mega2560
and make sure - there is no PWM on those pins. ### The workaround is found! Open the file "platform.txt" and remove all the options concerned to lto. Just look for "lto" with context search and remove all of them. That's all. Have a nice day! |
Thanks @elilitko! just let me clarify for other users (beginers like me) to remove only the options -lto and -flto. ... I removed the complete line ... and only the one containing -lto ... |
Confirmed this issue with Windows 10, Arduino 1.8.12 (Windows Store 1.8.33.0) |
I think this is a problem that we should somehow tackle. How about:
|
|
I've created a minimalized source tree and build scripts for working on this in https://github.com/WestfW/Duino-hacks/tree/master/pwmbug
(no actual results yet.) |
I've further consolidated the minimalized source, end up with a "consolidate" version that has one .cpp file and one .c file, each already pre-processed. (main.cpp has the main.cpp and sketch code, wiring_all.c has the necessary parts of wiring.c, wiring_digital.c, wiring_analog.c) It's still pretty mysterious. For example, it will start working if the code for turnOffPWM() is commented out. |
It certainly looks like an off-by-one error in calculating the start of the jump table, as theorized in #339 (comment) What's weird is that it doesn't seem to happen for the non-lto case, doesn't happen when there is only a single analogWrite() call, and (NEW DATA!) doesn't happen if the -relax option is removed from the link command. -relax causes certain long jumps/calls to be shortened to rjmp/rcall. Perhaps the intermediate representations passed to the linker with -flto are missing information as to locations that need "fixed up" after "relaxing" ? This is pretty much as far as I can go. I have no knowledge or understanding of avr-gcc internal operations... |
Ah, that is awesome new info, since that gives a very strong indication of what is happening here (jump tables getting messed up by jump relaxation). I had hoped that this extra info might turn up an existing bug report about this, but no such luck it seems. The minimized example also looks good. Not sure if it is minimal enough yet for a gcc bugreport, I suspect that there are still some definitions and declarations that can be removed? Also, it would be good if the generated assembly is simple enough so the problem can be shown based on that, rather than having to run the code, but that might be tricky and/or cause the problem to disappear... One thing that could maybe help is to pass Can we test this on newer gcc versions (or did we already)? It seems Arduino now ships 7.3.0, not sure if there are any versions available in staging or elsewhere? Debian only has 5.4.0 it seems... |
Just discovered this issue after trying to figure out for hours what was wrong with PWM. It is a very annoying bug... especially that I knew that all this was working in the past! From what I could observe in my tests (on two Mega2560 R3 boards), as soon as there is a second call to analogWrite() that is compiled (unless it is identical to the first one), all calls are not working at all, any only a flat 0V signal is observed with the oscilloscope on the corresponding output pin. This code works fine: void setup() {
pinMode(2, OUTPUT);
analogWrite(2, 42);
} This works too: void setup() {
pinMode(2, OUTPUT);
analogWrite(2, 42);
analogWrite(2, 42);
} This does not work: void setup() {
pinMode(2, OUTPUT);
analogWrite(2, 42);
analogWrite(2, 84);
} This works, as the second call is optimized out: void setup() {
pinMode(2, OUTPUT);
analogWrite(2, 42);
if (1 == 0) {
analogWrite(2, 84);
}
} This does not work as the second call is not optimized out by the compiler: int x = 12;
void setup() {
pinMode(2, OUTPUT);
analogWrite(2, 42);
if (x == 0) {
analogWrite(2, 84);
}
} What is surprising is that the second call to In all cases my Inserting a declaration to force the optimization level of the void setup() __attribute__((optimize("-O1"))); I also tried with -O2, but in this case the bug is present. |
This removes the --relax option, potentially producing slightly bigger code for the atmega2560. On the longer term, the AVR core should just add this option for all boards, but this is not currently the case yet because removing --relax also works around a gcc miscompilation (see arduino/ArduinoCore-avr#339). Close: #639
This removes the --relax option, potentially producing slightly bigger code for the atmega2560. On the longer term, the AVR core should just add this option for all boards, but this is not currently the case yet because removing --relax also works around a gcc miscompilation (see arduino/ArduinoCore-avr#339). Close: #639
Should be fixed by avr core 1.8.3 + IDE 1.8.13 ; updating to the new IDE is important since it ships with this patch (on the tooling side). |
For completeness, this is not actually fixed (the bug still exists in gcc), we just removed the circumstances that trigger this bug. Small (but IMHO relevant) difference. Any third party cores that would add |
There is a Bug in Version 1.8.10 of the Arduino IDE using analogWrite() for PWM on Arduino Mega 2560. If i use analogWrite() with any value for the pwm-Pins once in the loop()-Method everything works fine. If I put a second call of analogWrite() with the same pin and any value that is not 0 or 255, nothing happens. The loop-Method keeps on working, but the PWM-Pin used in analogWrite() shows an continous output of 0V. In Version 1.8.9 the same programm works fine.
The text was updated successfully, but these errors were encountered: