DigitalWrite and AnalogWrite on the same pin hate each other?

Status
Not open for further replies.

MuShoo

Well-known member
So my current solution to this is to just always use analogWrite() on the pins I use PWM on (just analogWrite(PIN, 0) or (PIN, 1023) for LOW/HIGH) - took me a while to figure out that this was the problem, though.

Basically i've got a DC motor hooked to an H-bridge (L293DD), and to swap directions I'd been using:
Code:
//up
digitalWrite(FDR1_MOTOR_EN, HIGH);
digitalWrite(FDR1_MOTOR_A, LOW);
analogWrite(FDR1_MOTOR_B, speed);
//down
digitalWrite(FDR1_MOTOR_EN, HIGH);
digitalWrite(FDR1_MOTOR_B, LOW);
analogWrite(FDR1_MOTOR_A, speed);

But it was only working in one direction (whichever one went first) - and it only worked once. Once I switch directions, everything would stop and no more motor movement would occur.

If I instead use:
Code:
//up
digitalWrite(FDR1_MOTOR_EN, HIGH);
analogWrite(FDR1_MOTOR_A, 0);
analogWrite(FDR1_MOTOR_B, speed);
//down
digitalWrite(FDR1_MOTOR_EN, HIGH);
analogWrite(FDR1_MOTOR_B, 0);
analogWrite(FDR1_MOTOR_A, speed);

Everything works as expected. So, while I've solved the problem, I'm not entirely certain of the CAUSE of the problem (all pins are pinMode(pin, OUTPUT)). Why does doing a digitalWrite break analog/PWM output on the same pin? Or is it the opposite, and doing an analogWrite on a pin stops digitalWrite from having access to the same pin?
 
Is it simply this:
One pin.
At a moment in time, it can be digital 1 or 0. Or PWM. But of course, not both.
To reverse directions, I'd think you'd one's complement the number used for analogWrite(), or some such.
 
Yeah, my code above is sort of pseudo-code. Neither of those up/down chunks would run simultaneously. But toggling back and forth between up, then down, then up again, etc, it would only go 'up' once, then never go down, or up again.

My best guess is that once a pin has a PWM value assigned to it, it can't be un-PWMed and become a digital output again unless you restate pinMode() as output.

I decided to make up a quick test code for a stock 3.1 (my earlier testing/frustration was on a custom board with a LOT of other stuff on it):

Code:
void setup(){
   pinMode(23, OUTPUT);
   pinMode(21, OUTPUT);
   digitalWrite(21, LOW);
}

void loop(){
   for (int i = 1; i <= 5; i++){
      test1();
   }
   for (int i = 1; i <= 5; i++){
      test2();
   }
      for (int i = 1; i <= 5; i++){
      test1();
   }
   for (int i = 1; i <= 5; i++){
      test2();
   }
   for (int i = 1; i <= 5; i++){
      test3();
   }
   while (1);
}

void test1(){
   digitalWrite(23, HIGH);
   delay(250);
   digitalWrite(23, LOW);
   delay(250);
}

void test2(){
   for (int i = 0; i < 256; i++){
      analogWrite(23, i);
      delay(2);
   }
   for (int i = 255; i >0; i--){
      analogWrite(23, i);
      delay(2);
   }
}
void test3(){
   pinMode(23, OUTPUT);
   digitalWrite(23, HIGH);
   delay(250);
   digitalWrite(23, LOW);
   delay(250);
}

To run this - grab an LED, shove the long leg onto pin 23, and the short leg into pin 21. What will happen is the LED will flash 5 times using digitalWrite (test1), then pulse 5 times with analogWrite (test2). What should then happen is another round of digitalWrite flashing (test1 again), but all that happens physically is a very dim LED. Then it'll pulse another 5 times (test2 again), and then it will flash again with digitalWrite (test3) because the pinMode has been redefined. After test3, nothing will happen as it gets locked in a while(1) loop.

Anyway, I just figured since I had such trouble searching the forums for anything concrete about this, I'd make a thread - this seems to be different behavior from Teensy ++ 2.0 (which could swap back and forth between digital and analog output on a pin with no extra work).

Testing occurred on Teensyduino 1.20rc-4 (I think? might be 3. Just updated it earlier today), OSX 10.9.5.
 
When you use analogWrite(), it puts the pin into a special PWM mode. If you want to control it again using digitalWrite(), you first need to use pinMode() to get it back into normal OUTPUT mode.
 
Status
Not open for further replies.
Back
Top