Help with adding the smoothing sketch into my ppm to pwm code.

HI all I am just starting to learn arduino so I don't know much but I want to find out why the code I have come up with is not working. I started with some simple code I found somewhere to take the ppm inputs from my rc receiver and output them to pwm for a h bridge motor driver that I am using on a 3d printed tracked vehicle that I made. It works great but since the motors I am using are so powerful I want to add some ramping to the motors so that there is not so much instant power and hopefully I want break stuff on it as often. Here is the sketch I started with.

This is what I have after adding in the values from the smoothing sketch. I added some of the values twice since I figured I need to smooth both outputs going to the h bride. From what I understand I should be able to adjuest the amount of smoothing by changing the numReadings value. I have uploaded this sketch but it does not seem to effect how the the motors react so I am guessing I have something wrong.

This is the first sketch before I added the smoothing.

//read PPM signals from 2 channels of an RC reciever and convert the values to PWM in either direction.
// digital pins 5 & 9 control motor1, digital pins 6 & 10 control motor2. DP 12 and 13 are neutral indicator lights. DP 2 and 3 are inputs from the R/C receiver. All analog pins are open. When motor pin is HIGH, bridge is open. All mosfets are pulled up/down to stay closed unless told to open. 


int motor1_a = 5;    
int motor1_b = 9;    

int motor2_a = 6;
int motor2_b = 10;    

//Neutral indicator LED's (FWD and REV LED's are on the motor driver board.
int ledPin1 = 12;      
int ledPin2 = 13;

int ppm1 = 2;  // connect the desired channel (PPM signal) from your RC receiver to digital pin 2 on Arduino. 
int ppm2 = 3;

unsigned long rcval1 = 1500;
unsigned long rcval2 = 1500;

int deadband_high = 265; // set the desired deadband ceiling (ie. if adj_val is above this, you go forward)
int deadband_low = 245;  // set deadband floor (ie. below this, go backward)

int pwm_ceiling = 256; // adjusts speed of PWM signal at turn-on
int pwm_floor = 254;

void setup() {

Serial.begin(9600);  

// set all the other pins you're using as outputs:
//motor1 pins
pinMode(motor1_a, OUTPUT); 
pinMode(motor1_b, OUTPUT); 

pinMode(motor2_a, OUTPUT); 
pinMode(motor2_b, OUTPUT); 

//led's
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);

//PPM inputs from RC receiver
pinMode(ppm1, INPUT); //Pin 2 as input
pinMode(ppm2, INPUT); //Pin 3 as input
  
}


void driveMotor(int thisMotor, int driveVal)
{
 //Convert RC signal from 1000 range to 512 range (256 for each direction).
 driveVal = map(constrain(driveVal, 1000, 2000), 1000, 2000, 0, 511); 
 // Default to motor 2
 int motor_a = motor2_a;
 int motor_b = motor2_b;
 int ledPin = ledPin2;
 
 // if motor is 1 change pins
 if(thisMotor == 1) {
   motor_a = motor1_a;
   motor_b = motor1_b;
   ledPin = ledPin1;
 }

  if (driveVal > deadband_high) {  
    //Forward
    digitalWrite(motor_b, LOW);
    analogWrite(motor_a, driveVal - pwm_ceiling);
    digitalWrite(ledPin, LOW);
  } 
  else if (driveVal < deadband_low) {
    //REVERSE
    digitalWrite(motor_a, LOW); 
    analogWrite(motor_b, pwm_floor - driveVal);
    digitalWrite(ledPin, LOW);
  }
  else {
  //STOP
  digitalWrite(motor_a, LOW);
  digitalWrite(motor_b, LOW);
  digitalWrite(ledPin, HIGH); // turn on neutral light, turn motor pins off 
 }
}


void loop() {
rcval1 = pulseIn(ppm1, HIGH); // Listen for pulse on PPM1
rcval2 = pulseIn(ppm2, HIGH); // Listen for pulse on PPM2
driveMotor(1,rcval1);
driveMotor(2,rcval2);


/*
//print values
Serial.print("channel 1:  ");
Serial.print(adj_val1);
Serial.print("        ");  
Serial.print("rc1_val raw:  ");
Serial.print(rc1_val);  
Serial.print("        ");
Serial.print("channel 2:  ");   
Serial.print(adj_val2);
Serial.print("        ");
Serial.print("rc2_val raw:  ");
Serial.print(rc2_val);  
Serial.println("        ");
*/

}
[code]

You can’t directly “read” [u]PWM[/u]. You can… but it’s tricky because it’s asynchronous and it’s not “normal” analog or digital-data. You can take a moving-average of all those 1s & 0s, and maybe that’s what you’re trying to do???

PWM is digital (high or low). You can filter it with an RC filter to create a variable DC voltage, which you can read with analogRead(). Then, you could process that data (for “ramping”) and re-write it as PWM again. Or, if you use a filter with a low-enough cutoff frequency (a large capacitor and/or a large resistor) you may get enough smoothing that you don’t need to process the data.

It sounds like what you want to do is to change the PWM value more slowly than the RC signal is changing.

I suggest you read the RC pulse width and convert it to the equivalent PWM value but do NOT directly apply it with analogWrite()

Separately every 50 millisecs (say), compare the RC value with the previous value used for analogWrite() and if the RC value is higher increase the analogWrite() value a little - but not beyond the RC value.

...R

look at this. I was going to post the full sketch earlier but it would not let me since I had just posted and then I forgot so here is the full sketch I am working on.

//read PPM signals from 2 channels of an RC reciever and convert the values to PWM in either direction.
// digital pins 5 & 9 control motor1, digital pins 6 & 10 control motor2. DP 12 and 13 are neutral indicator lights. DP 2 and 3 are inputs from the R/C receiver. All analog pins are open. When motor pin is HIGH, bridge is open. All mosfets are pulled up/down to stay closed unless told to open. 


int motor1_a = 5;    
int motor1_b = 9;    

int motor2_a = 6;
int motor2_b = 10;    

//Neutral indicator LED's (FWD and REV LED's are on the motor driver board.
int ledPin1 = 12;      
int ledPin2 = 13;

int ppm1 = 2;  // connect the desired channel (PPM signal) from your RC receiver to digital pin 2 on Arduino. 
int ppm2 = 3;

unsigned long rcval1 = 1500;
unsigned long rcval2 = 1500;

int deadband_high = 265; // set the desired deadband ceiling (ie. if adj_val is above this, you go forward)
int deadband_low = 245;  // set deadband floor (ie. below this, go backward)

int pwm_ceiling = 256; // adjusts speed of PWM signal at turn-on
int pwm_floor = 254;

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int readings2[numReadings];      // the readings from the analog input
int readIndex2 = 0;              // the index of the current reading
int total2 = 0;                  // the running total
int average2 = 0;                // the average


void setup() {

Serial.begin(9600);  

// set all the other pins you're using as outputs:
//motor1 pins
pinMode(motor1_a, OUTPUT); 
pinMode(motor1_b, OUTPUT); 

pinMode(motor2_a, OUTPUT); 
pinMode(motor2_b, OUTPUT); 

//led's
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);

//PPM inputs from RC receiver
pinMode(ppm1, INPUT); //Pin 2 as input
pinMode(ppm2, INPUT); //Pin 3 as input
  
// initialize all the readings to 0: 
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;          
}


void driveMotor(int thisMotor, int driveVal)
{
 //Convert RC signal from 1000 range to 512 range (256 for each direction).
 driveVal = map(constrain(driveVal, 1000, 2000), 1000, 2000, 0, 511); 
 // Default to motor 2
 int motor_a = motor2_a;
 int motor_b = motor2_b;
 int ledPin = ledPin2;
 
 // if motor is 1 change pins
 if(thisMotor == 1) {
   motor_a = motor1_a;
   motor_b = motor1_b;
   ledPin = ledPin1;
 }

  if (driveVal > deadband_high) {  
    //Forward
    digitalWrite(motor_b, LOW);
    analogWrite(motor_a, driveVal - pwm_ceiling);
    digitalWrite(ledPin, LOW);
  } 
  else if (driveVal < deadband_low) {
    //REVERSE
    digitalWrite(motor_a, LOW); 
    analogWrite(motor_b, pwm_floor - driveVal);
    digitalWrite(ledPin, LOW);
  }
  else {
  //STOP
  digitalWrite(motor_a, LOW);
  digitalWrite(motor_b, LOW);
  digitalWrite(ledPin, HIGH); // turn on neutral light, turn motor pins off 
 }
}


void loop() {
rcval1 = pulseIn(ppm1, HIGH); // Listen for pulse on PPM1
rcval2 = pulseIn(ppm2, HIGH); // Listen for pulse on PPM2

 // subtract the last reading:
 total= total - readings[readIndex];         
 // read from the sensor:  
 readings[readIndex] = rcval1; 
 // add the reading to the total:
 total= total + readings[readIndex];       
 // advance to the next position in the array:  
 readIndex = readIndex + 1;                    

 // if we're at the end of the array...
 if (readIndex >= numReadings)              
   // ...wrap around to the beginning: 
   readIndex = 0;                           

 // calculate the average:
 average = total / numReadings;         
 // send it to the computer as ASCII digits
 Serial.println(average);   
 delay(1);        // delay in between reads for stability  
 
   // subtract the last reading:
 total= total2 - readings2[readIndex2];         
 // read from the sensor:  
 readings[readIndex2] = rcval2; 
 // add the reading to the total:
 total= total2 + readings2[readIndex2];       
 // advance to the next position in the array:  
 readIndex2 = readIndex2 + 1;                    

 // if we're at the end of the array...
 if (readIndex2 >= numReadings)              
   // ...wrap around to the beginning: 
   readIndex2 = 0;                           

 // calculate the average:
 average2 = total / numReadings;         
 // send it to the computer as ASCII digits
 Serial.println(average);   
 delay(1);        // delay in between reads for stability  
 
driveMotor(1,rcval1);
driveMotor(2,rcval2);  




/*
//print values
Serial.print("channel 1:  ");
Serial.print(adj_val1);
Serial.print("        ");  
Serial.print("rc1_val raw:  ");
Serial.print(rc1_val);  
Serial.print("        ");
Serial.print("channel 2:  ");   
Serial.print(adj_val2);
Serial.print("        ");
Serial.print("rc2_val raw:  ");
Serial.print(rc2_val);  
Serial.println("        ");
*/

}
[code]

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum Your code is too long for me to study quickly without copying to a text editor.

And what are your comments on what I wrote in Reply #3

…R

How is this?

//read PPM signals from 2 channels of an RC reciever and convert the values to PWM in either direction.
// digital pins 5 & 9 control motor1, digital pins 6 & 10 control motor2. DP 12 and 13 are neutral indicator lights. DP 2 and 3 are inputs from the R/C receiver. All analog pins are open. When motor pin is HIGH, bridge is open. All mosfets are pulled up/down to stay closed unless told to open. 


int motor1_a = 5;    
int motor1_b = 9;    

int motor2_a = 6;
int motor2_b = 10;    

//Neutral indicator LED's (FWD and REV LED's are on the motor driver board.
int ledPin1 = 12;      
int ledPin2 = 13;

int ppm1 = 2;  // connect the desired channel (PPM signal) from your RC receiver to digital pin 2 on Arduino. 
int ppm2 = 3;

unsigned long rcval1 = 1500;
unsigned long rcval2 = 1500;

int deadband_high = 265; // set the desired deadband ceiling (ie. if adj_val is above this, you go forward)
int deadband_low = 245;  // set deadband floor (ie. below this, go backward)

int pwm_ceiling = 256; // adjusts speed of PWM signal at turn-on
int pwm_floor = 254;

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int readings2[numReadings];      // the readings from the analog input
int readIndex2 = 0;              // the index of the current reading
int total2 = 0;                  // the running total
int average2 = 0;                // the average


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

 // set all the other pins you're using as outputs:
 //motor1 pins
 pinMode(motor1_a, OUTPUT); 
 pinMode(motor1_b, OUTPUT); 

 pinMode(motor2_a, OUTPUT); 
 pinMode(motor2_b, OUTPUT); 
 
 //led's
 pinMode(ledPin1, OUTPUT);
 pinMode(ledPin2, OUTPUT);
 
 //PPM inputs from RC receiver
 pinMode(ppm1, INPUT); //Pin 2 as input
 pinMode(ppm2, INPUT); //Pin 3 as input
   
 // initialize all the readings to 0: 
 for (int thisReading = 0; thisReading < numReadings; thisReading++)
 readings[thisReading] = 0;          
}


void driveMotor(int thisMotor, int driveVal)
{
  //Convert RC signal from 1000 range to 512 range (256 for each direction).
  driveVal = map(constrain(driveVal, 1000, 2000), 1000, 2000, 0, 511); 
  // Default to motor 2
  int motor_a = motor2_a;
  int motor_b = motor2_b;
  int ledPin = ledPin2;
  
  // if motor is 1 change pins
  if(thisMotor == 1) {
    motor_a = motor1_a;
    motor_b = motor1_b;
    ledPin = ledPin1;
  }

   if (driveVal > deadband_high) {  
     //Forward
     digitalWrite(motor_b, LOW);
     analogWrite(motor_a, driveVal - pwm_ceiling);
     digitalWrite(ledPin, LOW);
   } 
   else if (driveVal < deadband_low) {
     //REVERSE
     digitalWrite(motor_a, LOW); 
     analogWrite(motor_b, pwm_floor - driveVal);
     digitalWrite(ledPin, LOW);
   }
   else {
   //STOP
   digitalWrite(motor_a, LOW);
   digitalWrite(motor_b, LOW);
   digitalWrite(ledPin, HIGH); // turn on neutral light, turn motor pins off 
  }
}


void loop() {
 rcval1 = pulseIn(ppm1, HIGH); // Listen for pulse on PPM1
 rcval2 = pulseIn(ppm2, HIGH); // Listen for pulse on PPM2

  // subtract the last reading:
  total= total - readings[readIndex];         
  // read from the sensor:  
  readings[readIndex] = rcval1; 
  // add the reading to the total:
  total= total + readings[readIndex];       
  // advance to the next position in the array:  
  readIndex = readIndex + 1;                    

  // if we're at the end of the array...
  if (readIndex >= numReadings)              
    // ...wrap around to the beginning: 
    readIndex = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer as ASCII digits
  Serial.println(average);   
  delay(1);        // delay in between reads for stability  
  
    // subtract the last reading:
  total= total2 - readings2[readIndex2];         
  // read from the sensor:  
  readings[readIndex2] = rcval2; 
  // add the reading to the total:
  total= total2 + readings2[readIndex2];       
  // advance to the next position in the array:  
  readIndex2 = readIndex2 + 1;                    

  // if we're at the end of the array...
  if (readIndex2 >= numReadings)              
    // ...wrap around to the beginning: 
    readIndex2 = 0;                           

  // calculate the average:
  average2 = total / numReadings;         
  // send it to the computer as ASCII digits
  Serial.println(average);   
  delay(1);        // delay in between reads for stability  
  
 driveMotor(1,rcval1);
 driveMotor(2,rcval2);  




/*
 //print values
 Serial.print("channel 1:  ");
 Serial.print(adj_val1);
 Serial.print("        ");  
 Serial.print("rc1_val raw:  ");
 Serial.print(rc1_val);  
 Serial.print("        ");
 Serial.print("channel 2:  ");   
 Serial.print(adj_val2);
 Serial.print("        ");
 Serial.print("rc2_val raw:  ");
 Serial.print(rc2_val);  
 Serial.println("        ");
*/

}

Thanks! I did not realize you could insert code. Sorry for messing up the workflow. haha