Porting Raspberry Pi code to wiringPi for motor driver hat

I recently purchased one of these Raspberry Pi motor controller hats (Dual TB9051FTG Motor Driver for Raspberry Pi):

The HAT works as expected with the Python library. I am trying to port the code over to wiringPi C for my project. It has taken me quite a while to get to where the motor is at least turing, but right now it is only on/off. When the PWM duty cycle exceeds 50%, the motor switches on. I am pulling up the diag pin, setting the enable and direction pins high, and then using PWM – all on GPIO pins.

Also, when I run the Python code and try to observe the PWM signal using an oscilloscope, it does not look like a normal PWM signal. It seems to be some kind of pulse train with 30ms spacing.

Below is example code that I think takes all the necessary steps to ramp the motor speed up and down using PWM. But like I said, the motor is off until duty cycle reaches 50% (512) and then it switches to full on.

Any help would be appreciated.

Thanks,
Ryan Krauss

/*
 Change the Intensity of LED using PWM on Raspberry Pi
 http://www.electronicwings.com
 */

//gcc -Wall -o pwm_wiringpi_attempt1.o pwm_wiringpi_attempt1.c -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>

const int PWM_ = 1;   /* GPIO 1 as per WiringPi, GPIO18 as per BCM */
// DIAG pins need to be pulled up, if they read as low, the board
// pulled them down and there is a fault
// _pin_M1DIAG = 5
// _pin_M2DIAG = 6
// _pin_M1PWM = 12
// _pin_M2PWM = 13
// _pin_M1EN = 22
// _pin_M2EN = 23
// _pin_M1DIR = 24
// _pin_M2DIR = 25

#define M1DIAG 5
#define M2DIAG 6
#define M1PWM 12//GPIO12, Phys32
#define M2PWM 13
#define M1EN 22//WPi3, GPIO22
#define M2EN 23
#define M1DIR 24
#define M2DIR 25

int maxspeed = 1024;

int main (void)
{
  int intensity ;            

  if (wiringPiSetupGpio() == -1){
      printf("exitting\n");
      exit (1) ;
  }
  else{
    printf("ok\n");
  }

  pinMode(M1EN, OUTPUT);
  pinMode(M1DIAG, INPUT);
  pullUpDnControl(M1DIAG,PUD_UP);
  pinMode(M1DIR, OUTPUT);
  pinMode(M1PWM, PWM_OUTPUT);
  digitalWrite(M1EN, HIGH);
  digitalWrite(M1DIR, HIGH);


  for (intensity = 0 ; intensity < maxspeed ; ++intensity)
    {
      printf("intensity = %d\n", intensity);
      pwmWrite(M1PWM, intensity) ;	/* provide PWM value for duty cycle */
      delay (10) ;
    }

  delay(1);

  for (intensity = maxspeed ; intensity >= 0 ; --intensity)
    {
      pwmWrite(M1PWM, intensity) ;	/* provide PWM value for duty cycle */
      delay (1) ;
    }
    
  delay(1);
  
  digitalWrite(M1EN, LOW);
  digitalWrite(M1DIR, LOW);
  pwmWrite(M1PWM, 0) ;	/* provide PWM value for duty cycle */

}

Hello.

I don’t see anything obviously wrong in your code. What Raspberry Pi board are you using? It seems odd that the driver works as expected with our Python library, but the PWM signal doesn’t look normal to you. Could you post scope captures of the signal you get with the Python code? Also, have you looked at the PWM signal when running your wiringPi C code to compare?

Brandon

So, I recant about the PWM signal looking strange. I don’t think I had a ground wire from my scope connected to the hat (I haven’t wanted to modify the hat yet, so I was just setting pins in holes). The PWM signal when the python code is running is a 20kHz PWM signal with duty cycle that goes up and down as expected.

With the wiringPi C code, the PWM duty cycle seems to vary with duty cycle - like using pwmWrite affects duty cycle and frequency. So, I am assuming that my problem is not correctly generating a 20kHz PWM signal from wiringPi. I will look into that, but any suggestions would be welcome.

Thanks,
Ryan

Oh, and the answer to your other question is that I am using a model 4 B.

I think I have this working. It turns out that the default wiringPi pwm mode is balanced, which does vary the frequency based on the duty cycle. “mark/space” is apparently the opposite of balance and basically means constant frequency of the PWM square wave. I based my code on this thread (which I think uses an RPi 3, which is slightly slower than a 4):

I also learned from here:

I landed on these settings for 20kHz PWM with constant duty cycle:

int maxspeed = 540;

pwmSetMode(PWM_MODE_MS);
pwmSetClock(2);
pwmSetRange(maxspeed);

I have one wheel spinning with varying speed for now.

Woot.

Thanks,
Ryan

1 Like

I am glad you figured it out and were able to get it working! Thank you for letting us know what the problem was.

Good luck on your project!

Brandon