Servo PWM pins problem

Hi,

I am using PWM pins, h-bridge driver and the analogueWrite() function to control the speed and direction of a DC motor using an accelerometer data I am transmitting wirelessly. The x-axis of the accelerometer will cause the DC motor to rotate when tilted forward or backwards.

I then wanted to use the y-axis of the accelerometer to control a servo motor when tilted right or left.

I am using PWM pins to send signals to the h-bridge for the dc motor but when I used another PWM for the servo, the servo rotates when I tilt the accelerometer forward. Even when I take out the code for the servo to rotate, it still moves and twitches as if the signals from the other PWM pins are being sent to the pin attached to the servo

Any ideas what could be the problem?

I have attached my code and circuit.

Thanks,

Rui

Arduino_Rx_dc.fzz (7.86 KB)

adxl.rtf (6.24 KB)

First: RTF format? no, please repost your code as code in code tags please. FZZ? is that a Fritzing file? An image would be a better way
to post that so we can all see it.

Your problem is probably the noise from the accelerometer - they are normally quite noisy if you read them at full
bandwidth, so low-pass filtering might help (in hardware or software).

Analog reads on one pin can also affect the read on another. The simple solution is to perform an analogRead, discard the value, then analogRead again.

Though that is only an issue if the source has a very high impedance - if its 10k or less you can ignore such issues.

Hi,

Sorry for the wrong file type attachements!

I havne't tried controlling the motors from a distance yet so that might rule out some of the interference. At the moment the transmitter and receiver are quite close to each other when I am carrying out the testing.

The project involves a wireless controller to control an RC car. On the controller I have an ADXL-335 accelerometer and an Xbee module. Outputs from the ADXL-335 are wired directly to ADC pins on the Xbee module. These digital values are then sent wirelessly in packets to the receiving module which will be on the RC car.

The receiving Xbee module passed the packets to the arduino where code parses the packets and pulls out the sent digital values ranging between 0-1023. Bases on the values received on the x-axis of the ADXL-335 the code drives outputs to PWM pins on the arduino through a H-bridge driver and onto the dc motor. For the y-axis values, the code drives signals from a PWM pin to the servo motor.

The servo should not move when the ADXL-335 is tilted forwards or backwards as the y-axis values will not be changing. But I am seeing the servo rotate.

Here is my code:

//Code to control dc motor and servo using ADXL-335

#include <XBee.h>
#include <SoftwareSerial.h>
#include <Servo.h>
 
Servo myservo;  // create servo object to control a servo
 
int pos = 0;    // variable to store the servo position 

const int motor1Pin = 3;    // H-bridge leg 1 (pin 2, 1A)
const int motor2Pin = 5;    // H-bridge leg 2 (pin 7, 2A)
const int enablePin = 6;    // H-bridge enable pin

int x_axis = 0;
int y_axis = 0;
int z_axis = 0;

int axis[3];
  

/*
This example is for Series 1 XBee Radios only
Receives I/O samples from a remote radio with 16-bit addressing.
The remote radio must have IR > 0, at least one digital or analog input enabled
and DL set to the 16-bit address of the receiving XBee (the one connected to the Arduino).
 
This example uses the SoftSerial library to view the XBee communication.  I am using a
Modern Device USB BUB board (http://moderndevice.com/connect) and viewing the output
with the Arduino Serial Monitor.    
*/

XBee xbee = XBee();

Rx16IoSampleResponse ioSample = Rx16IoSampleResponse();

void setup() {
  Serial.begin(9600);
  xbee.setSerial(Serial);
  
  // set all the other pins you're using as outputs:
  pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(enablePin, OUTPUT);

  // set enablePin high so that motor can turn on:
  digitalWrite(enablePin, HIGH);
  
  myservo.attach(10);  // attaches the servo on pin 5 to the servo object 
}

void loop() {
  //attempt to read a packet    
  xbee.readPacket();

  if (xbee.getResponse().isAvailable()) {
    // got something

    if (xbee.getResponse().getApiId() == RX_16_IO_RESPONSE) {
      xbee.getResponse().getRx16IoSampleResponse(ioSample);

      Serial.println("Received I/O Sample from Xbee address: ");
      Serial.print(ioSample.getRemoteAddress16(), HEX);  

      Serial.print("Sample size is ");
      Serial.println(ioSample.getSampleSize(), DEC);

      if (ioSample.containsAnalog()) {
        Serial.println("Sample contains analog data");
      }

      if (ioSample.containsDigital()) {
        Serial.println("Sample contains digtal data");
      }
     
      for (int k = 0; k < ioSample.getSampleSize(); k++) {
        Serial.print("Sample ");
        Serial.print(k + 1, DEC);  
        Serial.println(":");    
       
        for (int i = 0; i <= 3; i++) {
          if (ioSample.isAnalogEnabled(i)) {
            Serial.print("Analog (AI");
            Serial.print(i, DEC);
            Serial.print(") is ");
            Serial.println(ioSample.getAnalog(i, k)); 
            axis[i] = ioSample.getAnalog(i, k);
          }
        }
        
        x_axis = constrain(axis[2], 400, 595);    //Constrain the x-axis values we receive to a range
        y_axis = constrain(axis[1], 405, 595);    //Constrain the y-axis values we receive to a range
        
        if(x_axis > 490 && x_axis < 510) // If the accelerometer is flat on x-axis
        {
        analogWrite(enablePin, HIGH);    // This allows speed control of the motor.
      
        //Stop motor (brake)
        digitalWrite(motor1Pin, LOW);    // set leg 1 of the H-bridge low
        digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
        Serial.println("Motor stopped"); //output message to serial monitor
        }
   
        if(x_axis < 490)                //If tilted forward, rotate dc  motor clockwise
        {
        x_axis = map(x_axis, 400, 489, 255, 0);   //Map the x-axis values values to the PWM output range
        Serial.println("Rotate motor forwards");
      
        //Rotate clockwise
        digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
        digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
        
        analogWrite(enablePin, x_axis); // This allows speed control of the motor.
        }
        else if(x_axis > 510)  //if the accelerometer is being tilted backwards.
        {
        x_axis = map(x_axis, 511, 600, 0, 255); //map values to 0-255
      
        //Rotate anti-clockwise
        digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge high
        digitalWrite(motor2Pin, LOW);  // set leg 2 of the H-bridge low
        
        analogWrite(enablePin, x_axis); // This allows speed control of the motor.
        Serial.println("Rotate motor backwards"); 
        }
        //Contro steering using the y_axis values
        if(y_axis > 480 && y_axis < 510) // If the accelerometer is flat on y-axis
        {

         myservo.write(90);                  // sets the servo position according to the scaled value

         Serial.println("Steering centered"); //output message to serial monitor
        }
        
        if(y_axis < 480)  // if accelerometer is tilted left
        {        
         y_axis = map(y_axis, 400, 479, 0, 90);     // scale it to use it with the servo (value between 0 and 90)
         myservo.write(y_axis);                  // sets the servo position according to the scaled value
         delay(15);  
         Serial.println("Turn servo left");
        }
        else if(y_axis > 510)  //if the accelerometer is being tilted right.
        {
         y_axis = map(y_axis, 511, 600, 90, 180);     // scale it to use it with the servo (value between 90 and 180)
         myservo.write(y_axis);                  // sets the servo position according to the scaled value
         delay(15);  
         Serial.println("Turn servo right"); 
        }
      }
    }   
  }

}

I do a 90% same thing with you. Please be-careful about the range of G-sensor. The G-sensor reading is not accurate. The range will change every time ever though same position.