Input PWM signal messed up when outputting at the same time

Hi,
I am trying to read a pwm signal from a flight controller that comes through hardware interrupts on pin 2 of an arduino uno and the signal comes through clean and all working until I try to drive a IBT_2 BTS7960 with a remapped value of the input signal, the input signal becomes messed up and starts spiking up and down rapidly and reading very large incorrect readings. at first I though it was interference from the motors but I shielded the wires and then even tested just driving the motors at full speed with one Arduino while reading the signal with another and it was fine any help would be appreciated

Here is the code:

#define RCPin 2
volatile long StartTime = 0;
volatile long CurrentTime = 0;
volatile long Pulses = 0;
int PulseWidth = 0;
volatile int MOL = 0;
int MOR = 0;

int L_PWM = 6;
int R_PWM = 5;  



void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(RCPin, INPUT_PULLUP);
  pinMode(5, OUTPUT);
  pinMode(9, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(RCPin), PulseTimer, CHANGE);


}

void loop() {
  // put your main code here, to run repeatedly:
  if(Pulses < 2000){
    PulseWidth = Pulses;
    delay(50);
  }
  
  MOL = map(PulseWidth, 1100, 1900, 0, 255);


  if(PulseWidth >= 1100 && PulseWidth <= 1900){
    MOL = map(PulseWidth, 1100, 1900, 0, 255);
  }


  Serial.println(MOL);

  if(MOL > 10){
    analogWrite(R_PWM, 0);
    analogWrite(9, MOL);
  }

}
void PulseTimer(){
  CurrentTime = micros();
  if(CurrentTime > StartTime){
    Pulses = CurrentTime - StartTime;
    StartTime = CurrentTime;
  }
}

Any help would be highly appreciated
thanks, Matt

Sounds like a power supply problem. Please post a schematic diagram of the system, along with a link to the motor data sheet and the motor power supply.

Keep in mind that motors briefly draw the stall current (5-10x the rated current) every time they start moving, and shielding won't help if the voltage sags.

2 Likes

@jremington Sorry for late response I do not have a direct schematic, but the motor controllers that power and controll the motors are connected to an 18v ryobi battery, the arduino and the flight controller I am reading the pwm signal from are connected to power through my computer currently and also can take power through 9v batteries. Here is the motor datasheet:
https://nfpshop.com/wp-content/uploads/2022/02/24V-Dc-Worm-Gear-Motor-5840-31Zy-Spec.pdf

I also had incorporated a low pass filter into the code:

template <int order> // order is 1 or 2
class LowPass
{
  private:
    float a[order];
    float b[order+1];
    float omega0;
    float dt;
    bool adapt;
    float tn1 = 0;
    float x[order+1]; // Raw values
    float y[order+1]; // Filtered values

  public:  
    LowPass(float f0, float fs, bool adaptive){
      // f0: cutoff frequency (Hz)
      // fs: sample frequency (Hz)
      // adaptive: boolean flag, if set to 1, the code will automatically set
      // the sample frequency based on the time history.
      
      omega0 = 6.28318530718*f0;
      dt = 1.0/fs;
      adapt = adaptive;
      tn1 = -dt;
      for(int k = 0; k < order+1; k++){
        x[k] = 0;
        y[k] = 0;        
      }
      setCoef();
    }

    void setCoef(){
      if(adapt){
        float t = micros()/1.0e6;
        dt = t - tn1;
        tn1 = t;
      }
      
      float alpha = omega0*dt;
      if(order==1){
        a[0] = -(alpha - 2.0)/(alpha+2.0);
        b[0] = alpha/(alpha+2.0);
        b[1] = alpha/(alpha+2.0);        
      }
      if(order==2){
        float alphaSq = alpha*alpha;
        float beta[] = {1, sqrt(2), 1};
        float D = alphaSq*beta[0] + 2*alpha*beta[1] + 4*beta[2];
        b[0] = alphaSq/D;
        b[1] = 2*b[0];
        b[2] = b[0];
        a[0] = -(2*alphaSq*beta[0] - 8*beta[2])/D;
        a[1] = -(beta[0]*alphaSq - 2*beta[1]*alpha + 4*beta[2])/D;      
      }
    }

    float filt(float xn){
      // Provide me with the current raw value: x
      // I will give you the current filtered value: y
      if(adapt){
        setCoef(); // Update coefficients if necessary      
      }
      y[0] = 0;
      x[0] = xn;
      // Compute the filtered values
      for(int k = 0; k < order; k++){
        y[0] += a[k]*y[k+1] + b[k]*x[k];
      }
      y[0] += b[order]*x[order];

      // Save the historical values
      for(int k = order; k > 0; k--){
        y[k] = y[k-1];
        x[k] = x[k-1];
      }
  
      // Return the filtered value    
      return y[0];
    }
};

// Filter instance
LowPass<2> lp(3,1e3,true);

double channel;
int L_PWR;
int R_PWR;
int L_PWM = 5;
int R_PWM = 6;
int R_OUT;

void setup() {
  Serial.begin(9600);
  pinMode (2, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  channel = pulseIn (2, HIGH);
  //Serial.print (channel);
  
  Serial.println (R_PWR);
  // Read pin A0 and compute current in mA
  // -- replace these two lines with your own sensor --
  
  float xn = (channel*5.0/1023.0 - 2.503)/0.185*1000;

  // Compute the filtered signal
  float yn = lp.filt(xn);

  // Output
  //Serial.print(xn);
  //Serial.print(" ");
  //Serial.print(yn);
  R_PWR = map (yn, 15600, 36600, 0, 255);

  analogWrite(R_PWM, 0);
  analogWrite(L_PWM, R_PWR);

  //Serial.println();
  
  delayMicroseconds(200);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.