Jerky PWM output for DC motor

Hi, I am building a remote control tank using the nrf24l01 radio modules. However, the device itself and the library I used aren't of importance, since the error is in my own code. Pasted below is the code for my RECEIVER Arduino Uno. I receive and store a data struct from the radio module (the data is set by joysticks on my transmitting Arduino), then use it to set the direction and output for each of my two motors using an L923D H-Bridge Motor Driver. The problem is this:

In the positive direction, each motor works fine (one direction of the joystick, that is) The power output responds smoothly to my moving of the joystick. However, when I move the joystick in the negative direction, the motors start acting weird: they jerk back and forth as if the output weren't constant. I switched the wires and saw that the motors can run in both ways, so it's not a hardware problem. There must be something wrong in my code that messes up my PWM output when the input is negative. Please help!!

#include <SPI.h> 
#include "RF24.h"

#define  CE_PIN  7   
#define  CSN_PIN 8

RF24 radio(CE_PIN, CSN_PIN);

byte addresses[][6] = {"1Node", "2Node"}; 


/* DATA STRUCT TO BE RECEIVED FROM RADIO*/
struct dataStruct {
  unsigned long _micros;
  int power1;          //an integer between -255 and 255 will be received for each motor
  int power2;
  bool sw1;            //booleans for push-button states - ignore
  bool sw2;        
} myData;               

const int enable_1 = 3;       //Enable pin for L293D motor driver - motor 1
const int control_1a = 2;     //The two control pins control which direction the current is allowed to flow
const int control_1b = 4;     

const int enable_2 = 6;      
const int control_2a = 5;    
const int control_2b = 10;   


void setup()   
{
  Serial.begin(115200); 

  pinMode(enable_1,OUTPUT);
  pinMode(control_1a,OUTPUT);
  pinMode(control_1b,OUTPUT);
  pinMode(enable_2,OUTPUT);
  pinMode(control_2a,OUTPUT);
  pinMode(control_2b,OUTPUT);

  radio.begin();
  radio.setChannel(108);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1, addresses[0]);

  radio.startListening();

}


void loop()  
{

 /****  This entire loop "if radio.available" simply stores the received information into my declared data struct: myData ****/
  
  if ( radio.available())
  {
     while (radio.available())   
    {
     radio.read( &myData, sizeof(myData) );            
    }
     radio.stopListening();                              
     radio.write( &myData, sizeof(myData) );             
     radio.startListening();        
    
  } 

/******  Once we have the data, first we decide what direction to set each motor  ****/
  
if (myData.power1 < 0){           //backwards: 1
  setDirec(0,1);
}

else if (myData.power1 > 0){        //forwards: 1
  setDirec(1,1);
}

if (myData.power2 < 0){             //backwards: 2
  setDirec(0,2);
}

else if (myData.power2 > 0){        //forwards: 2
  setDirec(1,2);
}

/*****  Now that we know what direction we are going in, we can get rid of signs and focus on magnitudes  ******/

myData.power1 = abs(myData.power1);
myData.power2 = abs(myData.power2);

setThrottle(1,myData.power1);
setThrottle(2,myData.power2);
  
delay(50);
}


void setDirec (bool dir, int whichMot){
  if (dir){
    switch(whichMot){
      case 1:
         digitalWrite(control_1a,HIGH);
         digitalWrite(control_1b,LOW);
      case 2:
         digitalWrite(control_2a,HIGH);
         digitalWrite(control_2b,LOW);
                    }
          }         
  else if (!dir){
     switch(whichMot){
      case 1:
         digitalWrite(control_1a,LOW);
         digitalWrite(control_1b,HIGH);
      case 2:
         digitalWrite(control_2a,LOW);
         digitalWrite(control_2b,HIGH);
                    
                    }

                 }
                                      }
           
void setThrottle (int whichMot, int data){
  switch(whichMot){
    case 1:
      analogWrite(enable_1,data);
    case 2:
      analogWrite(enable_2,data);
  }
}

Hi,
Welcome to the Forum

When you wrote just the motor drive part of your sketch on its own, did the motors behave properly then?

If you didn't write your sketch in sections, then put them together a section at a time, can you write a simple motor drive sketch to test direction and speed?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

Your problem: after the determination of the direction you make the power1 and power2 absolute. If no new input is read at the next iteration of loop(), the original direction is lost!

Simple solution: Only change the outputs after receiving a data package.

If there is a possibility that the problem is caused by the wireless communication and you are using the ManiacBug version of the RF24 library I suggest you change to the TMRh20 version of the RF24 library which solves some problems from the earlier ManiacBug version one of which is that it does not like intervals between messages.

...R
Simple nRF24L01+ Tutorial