davenull
Posts: 1159
Joined: Thu Oct 22, 2015 7:22 am
Location: a small planet close to Betelgeuze

issues about pwm motor control using wiringPi softPwm

Wed Apr 27, 2016 4:13 pm

hello,
I encounter issues about pwm motor control using wiringPi softPwm.
both motors are partially running smooth from 0-255, and partially are jerking when the direction is changed from forward to backwards.

this is my pin setup:

Code: Select all

// Raspi motor pins, wiringPi numbering (in parenthesis: BCM numbering)
     motor[0].pinQa = 5;   // (BCM 24)   encpin
     motor[0].pinQb = 4;   // (BCM 23)   encpin
     motor[0].pind1 =24;   // (BCM 19)   dirpin
     motor[0].pind2 =25;   // (BCM 26)   dirpin
     motor[0].pinpwm=26;   // (BCM 12)  pwmpin
     
     motor[1].pinQa = 0;   // (BCM 17)   encpin
     motor[1].pinQb = 2;   // (BCM 27)   encpin
     motor[1].pind1 =21;   // (BCM 5)    dirpin
     motor[1].pind2 =22;   // (BCM 6)    dirpin
     motor[1].pinpwm=23;   // (BCM 13)  pwmpin
this is how I initialize the pins:

Code: Select all

#define  MAXPWMRANGE       255 // maximum software-pwm range (0-255)

void setupDpins() {
  int i, err;   
 
   
  // motor pin settings
  // encoder pin settings
  // setup for L293D motor driver
 
  // motor pins, wiringPi numbering (in parenthesis: BCM numbering)
 
     motor[0].pinQa = 5;   // (BCM 24)   encpin
     motor[0].pinQb = 4;   // (BCM 23)   encpin
     motor[0].pind1 =24;   // (BCM 19)   dirpin
     motor[0].pind2 =25;   // (BCM 26)   dirpin
     motor[0].pinpwm=26;   // (BCM 12)  pwmpin
     
     motor[1].pinQa = 0;   // (BCM 17)   encpin
     motor[1].pinQb = 2;   // (BCM 27)   encpin
     motor[1].pind1 =21;   // (BCM  5)   dirpin
     motor[1].pind2 =22;   // (BCM  6)   dirpin
     motor[1].pinpwm=23;   // (BCM 13)  pwmpin
     
     
     for( i=0; i< MAXMOTORSLOCAL; ++i)  {       
        pinMode( motor[i].pinQa, INPUT);        // encA   
        pinMode( motor[i].pinQb, INPUT);        // encB   
        pinMode( motor[i].pind1, OUTPUT);       // dir-1   
        pinMode( motor[i].pind2, OUTPUT);       // dir-2   
        pinMode( motor[i].pinpwm, PWM_OUTPUT);  // pwm
       
        err= softPwmCreate( motor[i].pinpwm, 0, MAXPWMRANGE);
       
        printf("err %-4d  qa %-4d qb %-4d d1 %-4d d2 %-4d pwm %-4d \n",
          err, motor[i].pinQa, motor[i].pinQb, motor[i].pind1, motor[i].pind2, motor[i].pinpwm);
       
        motor[i].motenc = 0;
        motor[i].oldenc = 0;
        ISRab[i] = 0;
   }
   //printf("press ENTER");
   //getchar();
}
this is my motor API:

Code: Select all

// motor control structure

typedef struct  {   
               // electrical motor pins
      uint8_t  pind1, pind2, pinpwm;    // dir + pwm L293 H-Bridge type
      uint8_t  pinQa, pinQb;            // rotary enc pins Qa,Qb
     
               // pwm and encoder values
      int16_t  dirpwm;     
      int32_t  motenc, oldenc;          // rotary encoder values
} tEncMotor;


tEncMotor motor[MAXMOTORS];


#define motorLeft  motor[0]
#define motorRight motor[1]


#define motorCoast(nr) motorOn(nr, 0)      // alias for motor coast

//*************************************************************

void motorBrake(int nr, int dirpwm) {      // brake by pwm power
   int pwm;
   
   pwm = abs(dirpwm);
   
   digitalWrite(motor[nr].pind1, HIGH);
   digitalWrite(motor[nr].pind2, HIGH);     
   
   motor[nr].dirpwm = pwm;
   softPwmWrite(motor[nr].pinpwm, pwm);    // brake power always > 0   
   
}

//*************************************************************

void motorOn(int nr, int dirpwm) { // motor On (nr, dir_pwm)
   int dir, pwm;                             // signed pwm:
   
   if(dirpwm > 0) dir = +1;                   // pwm > 0: forward
   else if(dirpwm < 0) dir = -1;              // pwm < 0: reverse
   else dir = 0;                              // pwm = 0: coast
   
   if(! _REMOTE_OK_) dirpwm=0;
   pwm = abs(dirpwm);
   
     
   if(dir> 0) {
      digitalWrite( motor[nr].pind1, HIGH);
      digitalWrite( motor[nr].pind2, LOW);     
   }
   else
   if(dir==0) {
      digitalWrite( motor[nr].pind1, LOW);
      digitalWrite( motor[nr].pind2, LOW);
   }
   else {
      digitalWrite( motor[nr].pind1, LOW);
      digitalWrite( motor[nr].pind2, HIGH);
   }
   motor[nr].dirpwm = dirpwm;
   softPwmWrite( motor[nr].pinpwm, pwm);  
   
}
and this is my motor control task (remote control values from -255...0...255 are transmitted well and displayed identically on the remote controller (Arduino TFT) and on the Raspi (openVG window), always smooth, never jerking:

Code: Select all

void* thread2Go (void* ) {   // high priority: motor remote control
   static int pwm0, pwm1, i;
   int deadzone = 10;
   
   while(_TASKS_ACTIVE_) {
      
     if( ! _REMOTE_OK_ ) {
       for (i=0; i< MAXMOTORS; ++i ) {
          motorCoast(i);         
       }
     }
     else
     if( _REMOTE_OK_ )  {       
         pwm0 = recvanaval[0];
         pwm1 = recvanaval[1];

         if(abs(pwm0) < deadzone) pwm0=0;
         if(abs(pwm1) < deadzone) pwm1=0;
     
         motorOn(0, pwm0 );
         motorOn(1, pwm1 );
     
         // debug
         // printf("pwm0=%5d  pwm1=%5d \n", pwm0, pwm1);
       
       }     
       
       if (!_TASKS_ACTIVE_) return NULL;
       delay(10);

   }
   return NULL;
}
1st question:
is anything faulty with the pin setup?

2nd,
is anything wrong for wiringPi softPwm (range 0-255) ?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}

Return to “C/C++”