digitalWrite doesn't work after analogWrite on the same pin

pixelk

Well-known member
Unlike on vanilla arduino digitalWrite doesn't work after analogWrite, you cant set a pin to HIGH or LOW after using analogWrite(pin,value) on it.
 
Yes, analogWrite is putting the pin into a different mode, which digitalWrite can't use. I'll work on digitalWrite next week.
 
Digging up an old thread.

I have a sketch that needs to turn a pin full on (digitalWrite) then in another mode, it needs to be a PWM (analogWrite). It worked on an Arduino, but analogWrite happens later in the code, after it has already been digitalWritten and any PWM value in analogWrite results in full on (3v3).

How do I mix these 2 modes? I do not understand the example snippet? Do I define the pin again every time I need to switch modes between analopgWrite and digitalWrite? Do I need to define the frequency or is there a default value similar to previous arduino?

Keith
 
I don't know if it wasn't fixed in a recent update, but the sketch I'm working on does exactly that (define the pin again every time I need to switch modes) to address this issue (which may or may not be corrected since). I never changed PWM frequency, but I know it can be done in the latest teensyduino releases.
 
Yup, this is still a problem.

Tested with Arduino IDE 1.0.5 and 1.6.1, on a Teensy 3.1, using Teensy Loader 1.21.

Ok, it's probably a low-priority problem given that there's a bearable work-around, but I'm hoping it's helpful to flag such unexpected behaviour.
 
This just got me. Is there any reason to redefine the pin to turn the output off? I was using digitalWrite(pin,LOW), which didn't work so I tried analogWrite(pin,0), which did. That seems fine but I just want to make sure there's no reason to do something different.
 
I am reviving this post because this is not simply a simplicity of code issue!

PWM pins do not behave when driven at full duty cycle. For example. Driving a pin with digitalWrite(High) produces a flat, even 3.3V. However if I am using a PWM pin at 4577.64 Hz, and I set the analogWrite amplitude to be the maximum value, which does not produce a flat even 3.3V. Typically for 4 bit we would say 0,15, for 0% (true off) to 93.75% duty cycle, but in fact analogWrite accepts values 16 and above, which produce a 99.99999999% flat 3.3V. However at exactly 4577.64 Hz there is a single onset spike from the pin. From my oscilloscope the pulse has a Vpp of 6V and duration of about 100ns.

Using the fix of
Code:
  if (pwm_level >= (max_pwm)){
    pinMode(PWM_PIN, OUTPUT); // this is a weakness of the PWM pin, this step is required. AnalogWrite misbehaves at full amplitude.
    digitalWrite(PWM_PIN, HIGH);
  } else{
    analogWrite(PWM_PIN, pwm_level);
  }

Is successful at eliminating this spike.

After a little testing, the spike is identical regardless of the PWM frequency, it is the same at 1 MHz and 4 kHz.

I think it is likely that analogWrite is failing to keep the pin HIGH for a single clock when the PWM duty cycle is 100%
 
After a little testing, the spike is identical regardless of the PWM frequency, it is the same at 1 MHz and 4 kHz.

I think it is likely that analogWrite is failing to keep the pin HIGH for a single clock when the PWM duty cycle is 100%
That is correct, because PWM by design has on and off cycles. The hardware doesn't allow either cycle to be 0 length.
This is documented on PJRC's website: https://www.pjrc.com/teensy/td_pulse.html
Vales 0 and 256 are meant to correspond to logic low and high. However, the PWM hardware may not be capable of truly 100% low or high. A very short pulse may occur between each PWM cycle where the pin is driven to begin a new cycle, and then very quickly changed because the setting attempts to keep the pin always low or always high. To avoid any small glitch pulses, the pin may taken out of PWM mode using pinMode() and then controlled by digitalWrite().
 
Back
Top