Skip to content

Calls to digitalWrite() don't work after a previous analogWrite() #58

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

Open
technoblogy opened this issue Jul 18, 2023 · 8 comments
Open
Labels
type: imperfection Perceived defect in any part of project

Comments

@technoblogy
Copy link

Once you've generated PWM on a pin with analogWrite(), a subsequent digitalWrite() doesn't work.

Here is a sequence of calls and the resulting voltage on the pin (on core 0.8.7), compared to the same sequence on an original Arduino Uno R3:

Command Arduino R4 Arduino R3
pinMode(3, OUTPUT) 0V 0V
digitalWrite(3, HIGH) 4.7V 5V
analogWrite(3, 200) 3.68V 3.9V
digitalWrite(3, LOW) 3.68V 0V
digitalWrite(3, HIGH) 3.68V 5V

The R3 behaviour is what I'd expect.

Here's a visual demonstration of the problem. This program first blinks the builtin LED, and then pulsates it smoothly on and off:

void blink () {
  for (int i=0; i<5; i++) {
    digitalWrite(13, HIGH); delay(1000);
    digitalWrite(13, LOW); delay(1000);
  }
}

void pulse () {
  for (int i=0; i<5; i++) {
    for (int x=0; x<=255; x++) { analogWrite(13, x); delay(5); }
    for (int x=255; x>=0; x--) { analogWrite(13, x); delay(5); }
  }
}

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  blink();
  delay(1000);
  pulse();
  delay(1000);
}

The call to blink() only works the first time around loop().

The same problem occurs on the Uno R4 WiFi.

Note: Originally posted on the Early Access Program forum, but still an issue.

@mjs513
Copy link
Contributor

mjs513 commented Jul 20, 2023

@technoblogy
try this for your pulse function:

void pulse () {
  for (int i=0; i<5; i++) {
    for (int x=0; x<=255; x++) { analogWrite(13, x); delay(5); }
    for (int x=255; x>=0; x--) { analogWrite(13, x); delay(5); }
  }
    pinMode(13, OUTPUT);
}

looks like analogWrite does something to mess with pinMode. Tested on a Minima.

@technoblogy
Copy link
Author

Thanks, but my point is that calling pinMode() again shouldn't be necessary.

@mjs513
Copy link
Contributor

mjs513 commented Jul 20, 2023

Thanks, but my point is that calling pinMode() again shouldn't be necessary.

I agree thats why I added it to make it painfully clear.

@aentinger
Copy link
Contributor

Once you've generated PWM on a pin with analogWrite(), a subsequent digitalWrite() doesn't work.

Others may see this differently but this is acceptable behaviour to me.

This use case of using the same pin both as digital output and as PWM output within the same sketch is one that's unlikely to occur outside of your experimental setup (in the real world ™️). If you insist on doing it than one call to pinMode is a minor price to pay.

@technoblogy
Copy link
Author

technoblogy commented Jul 24, 2023

Others may see this differently but this is acceptable behaviour to me.

The reason I see it as unacceptable is that I have code (a more complicated version of the example at #58 (comment)) that works on all other Arduino compatible boards, but fails in a non-obvious way on the Uno R4 Minima and Uno R4 WiFi.

@facchinm facchinm reopened this Aug 4, 2023
@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Aug 5, 2023
@WestfW
Copy link

WestfW commented Aug 7, 2023

I really hate the "cluttering" of digitalWrite() with checks for whether an analogWrite() is in effect, whether the pin is in INPUT mode (and therefore should have a pullup enabled) (which the R4 code also doesn't do) and so on. Some of this is painful preservation of AVR behavior, and some is just things that ought to be the programmer's responsibility.

OTOH, other boards have implemented this behavior, so it is a backward incompatibility.

@aentinger
Copy link
Contributor

I really hate the "cluttering" of digitalWrite() with checks for whether an analogWrite() is in effect ...

That's my position too. It needlessly adds extra state and I can already see people bike-shedding about performance. To top it off, switching back and forth between PWM and digital output is simply not a sensible use case scenario in the real world ™️ . A PWM of 0 is digitalWrite(pin, LOW) and a PWM of 1024 (?) is digitalWrite(pin, HIGH) and vice versa. 🤷

@KurtE
Copy link
Contributor

KurtE commented Aug 9, 2023

I don't have a strong opinion, on if pinMode call should be needed here or not. But this issue was linked to in a thread I started, so decided to take a look.

It reminded me of a recent thread up on the PJRC forum: https://forum.pjrc.com/threads/73248-Teensy-4-1-PWM-pulsing-output-with-values-0-and-256

Where the PWM code does not give you the same effects for 0 and 256 (8 bit mode) as setting the pin High or Low. Instead it might still give a very small pulse or gap. Which is why some then explicitly set the pin High or Low. But this could cause problems for some devices that rely on a consistent timing of the pulses, of when the next pulse should start.

But I have seen more than once where sketches do intermix using PWM and digital mode.

pennam pushed a commit to pennam/ArduinoCore-renesas that referenced this issue Aug 9, 2023
New methods and flags + API refactoring
cristidragomir97 pushed a commit to cristidragomir97/ArduinoCore-renesas that referenced this issue May 20, 2024
New methods and flags + API refactoring

Former-commit-id: 97c3091
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

7 participants