Servos and PWM

Hi all,

I'm trying to control multiple servo's and multiple dc motors, for which I use PWM via a motor driver. However, the Servo's are also responding if I change the values for the PWM of the motors. I already read a lot of people who had the same problem, but is there a workaround? Or is PWM completely unusable when you want to use Servo's? I am already using pin 9 and 10 and 6 for the servo's and pin 3 and 5 and 11 for the dc motors.

Thank you very much for your help!!

This is my code:

 // This program is used to control the blimp made by Blimp Monkeys. 

 int ledPin = 13; //declare variable ledPin. 13 is the address of the port
//to which the LED is connected.


#include <Servo.h>  // standard servo library


const int lM0 = 0, lM1 = 1, lM2 = 2, lG0 = 3, lG1 = 4, lG2 = 5, lS1 = 6;

Servo G1; // declare servo objects
Servo G2;
Servo S1;

int G1P = 7;
int G2P = 10;
int S1P = 6;

int M0P1 = 2;
int M0P2 = 4;
int M0PP = 3;
int M1P1 = 9;
int M1P2 = 8;
int M1PP = 5;
int M2P1 = 12;
int M2P2 = 13;
int M2PP = 11;





void WaitAndBlink( unsigned long DeltaMilliSec){
// wait DeltaMilliSec milliseconds, LED blinks as a sign of life
// as time passes frequency increases
  unsigned long DeltaT = 0;
  unsigned long TZero = millis(); //read start time
  while(DeltaT<DeltaMilliSec){
    unsigned long TCurrent = millis();
    DeltaT = TCurrent-TZero;      //compute elapsed time
    delay(500-400*DeltaT/DeltaMilliSec);
    digitalWrite(ledPin,LOW);
    delay(500-400*DeltaT/DeltaMilliSec);
    digitalWrite(ledPin,HIGH);
  } 
}  





void setup() {
  SoftPWMBegin();
     pinMode(13,OUTPUT);  
   Serial1.begin(115200); // Read from wifi
   G1.attach(G1P);// Attach to servos
   G2.attach(G2P);
   S1.attach(S1P);

   G1.write(180); // Set servo to default position.
   G2.write(50);
   S1.write(30);


   // Set all motor outputs to 0
  pinMode(M0P1, OUTPUT);
  pinMode(M0P2, OUTPUT);
 // pinMode(M0PP, OUTPUT);
  pinMode(M1P1, OUTPUT);
  pinMode(M1P2, OUTPUT);
  //pinMode(M1PP, OUTPUT);
  pinMode(M2P1, OUTPUT);
  pinMode(M2P2, OUTPUT);
  //pinMode(M2PP, OUTPUT);


   //Wait for things to get ready
    WaitAndBlink(10000);

   
  // read the input buffer until it is empty
  // any character in the buffer is ignored
  while (Serial.available()){
     Serial1.read();
  }
}

void loop() {


  
  // put your main code here, to run repeatedly:
  if(Serial1.available()){
    
    char in = Serial1.read();
    delay(1);
    int val = Serial1.read();
   
    bool neg = 1; //val < 0;
 
    switch(in){
      case '0' : 
        /*if(neg){
          digitalWrite(M0P1, 1);
          digitalWrite(M0P2, 0);
        }else{
          digitalWrite(M0P1, 0);
          digitalWrite(M0P2, 1);
        }*/
         digitalWrite(M0P1, HIGH);
          digitalWrite(M0P2, LOW);
        analogWrite(M0PP, val);
        delay(10);
        break;
      case '1' : 
        if(neg){
          digitalWrite(M1P1, 1);
          digitalWrite(M1P2, 0);
        }else{
          digitalWrite(M1P1, 0);
          digitalWrite(M1P2, 1);
        }
        analogWrite(M1PP, val);
        break;
      case '2':
        if(neg){
          digitalWrite(M2P1, 1);
          digitalWrite(M2P2, 0);
        }else{
          digitalWrite(M2P1, 0);
          digitalWrite(M2P2, 1);
        }
        analogWrite(M2PP, val);
        break;
      case 'g': 
        G1.write(val);  

        break;
      case 'h' : 
        G2.write(val);
        break;
      case 's' : 
        S1.write(val);
        break;
    }

    if(val < 100){
    digitalWrite(ledPin, LOW);
  }else{
    digitalWrite(ledPin, HIGH);
  }
  }else{
    //S1.write(0);
  }
  
  delay(1);
}

As far as I know, you can drive a servo effectively pretty much ONLY through PWM. How do your servos respond? Are they skittering around, or do they follow a pattern in sync with the motors? If it's the former, it sounds like a noise issue.

They do follow a pattern in sync with the motors indeed. But I'm using the servo's using the servo library, and with PWM I meant analogWrite(), but indeed, the servo library also uses something like that. But it looks like it interferes..

I also tried to use the old Servo library: PWMServo | Arduiniana, but this still gives me a interference on the Servo...

Do you use a Uno/Pro Mini/Nano and do you use by any chance use pin 9 or 10 for the motor?

And some tips / other things

  • Once you start using postfixes (numbering) in variable names, arrays are the answer :wink:

  • Spaces are free and can make your code a lot more readable.

  • Fix the indentation. Press Ctrl+T in the IDE. How does that look? Better, doesn't it?

  • You variable names are absolutely terrible. A variable name should absolutely not be short, it should describe what it holds. This makes reading the code a lot easier. Future you will thank you :wink:

  • What on earth is a call to SoftPwmBegin() doing in the code?

if(Serial1.available()){
   
    char in = Serial1.read();
    delay(1);
    int val = Serial1.read();

Ahh, bad idea. Read more bytes then you are sure is in the buffer... Change to:

if(Serial1.available() >= 2){
    char in = Serial1.read();
    int val = Serial1.read();