Grove I2C Motor Driver not delivering correct tension

Hi everyone,

I’m making a 4 wheeled mecanum robot as a school project but I’m having a lot of trouble using the drivers I was provided.

Using the functions provided by the manufacturer but I am having an abnormal tension output (i.e : When providing 12V in the power in pin and setting the PWM at 255 I am only getting 8.2V from the motor output pin)

Because of this, the function giving the voltage based on PWM isn’t linear anymore. A PWM of 127 will give me around 7V (which is close the half of the 12V input but not of the real 8V maximum output). As such I can’t reliably control the rotation speed of my motors.

Provided hardware:

  • 2x Grove I2C Motor Driver V1.3
  • 4x 12V DC Geared Motor w/Encoder GB37Y3530-12V-83R
  • 1x Arduino UNO
  • 1x Grove Base Shield V2
  • 1x 12V battery (made from 2 6V lead–acid batteries)
#include <Wire.h>

#define MotorSpeedSet             0x82
#define DirectionSet              0xaa
#define MotorSetA                 0xa1
#define MotorSetB                 0xa5
#define Nothing                   0x01
#define I2CMotorDriverAdFT        0x0e // front driver address
#define I2CMotorDriverAdBK        0x0f // back driver address

void setup()  {
  Serial.begin(9600);
  Wire.begin(); // join i2c bus (Adress optional for master)
  delayMicroseconds(10000);
}

void MotorDirection(unsigned char DirectionFT, unsigned char DirectionBK)  {
  Wire.beginTransmission(I2CMotorDriverAdFT);                                    // transmit to device I2CMotorDriverAd
  Wire.write(DirectionSet);                                                      // Direction control header
  Wire.write(DirectionFT);                                                       // send direction control information
  Wire.write(Nothing);                                                           // need to send this byte as the third byte(no meaning)  
  Wire.endTransmission();                                                        // stop transmitting 

  Wire.beginTransmission(I2CMotorDriverAdBK);                                    // transmit to device I2CMotorDriverAd
  Wire.write(DirectionSet);                                                      // Direction control header
  Wire.write(DirectionBK);                                                       // send direction control information
  Wire.write(Nothing);                                                           // need to send this byte as the third byte(no meaning)  
  Wire.endTransmission();                                                        // stop transmitting
}

void MotorSpeedSetGDC(int MotorSpeedA , int MotorSpeedB, int MotorSpeedD, int MotorSpeedC)  {
  int dirA = 0b10;
  int dirB = 0b1000;
  int dirD = 0b10;
  int dirC = 0b1000;
  
  if (MotorSpeedA<0)  dirA = 0b1;
  if (MotorSpeedB<0)  dirB = 0b100;
  if (MotorSpeedD<0)  dirD = 0b1;
  if (MotorSpeedC<0)  dirC = 0b100;
  
  MotorSpeedB = abs(MotorSpeedB);
  MotorSpeedA = abs(MotorSpeedA);
  MotorSpeedD = abs(MotorSpeedD);  
  MotorSpeedC = abs(MotorSpeedC);  

  MotorSpeedB = map(MotorSpeedB, 0, 83, 0, 255);
  MotorSpeedA = map(MotorSpeedA, 0, 83, 0, 255);
  MotorSpeedD = map(MotorSpeedD, 0, 83, 0, 255);
  MotorSpeedC = map(MotorSpeedC, 0, 83, 0, 255);
  
  Wire.beginTransmission(I2CMotorDriverAdFT);  // transmit to device I2CMotorDriverAd
  Wire.write(MotorSpeedSet);                   // set pwm header 
  Wire.write(MotorSpeedA);                     // send pwm A 
  Wire.write(MotorSpeedB);                     // send pwm B 
  Wire.endTransmission();                      // stop transmitting

  Wire.beginTransmission(I2CMotorDriverAdBK);   // DRIVER MOTEURS ARRIERES // transmit to device I2CMotorDriverAd
  Wire.write(MotorSpeedSet);                    // set pwm header 
  Wire.write(MotorSpeedD);                      // send pwm D
  Wire.write(MotorSpeedC);                      // send pwm C
  Wire.endTransmission();    // stop transmitting
  
  MotorDirection(dirA|dirB,dirD|dirC);
}

void loop()  {    
    int SpeedMotA = 83;
    int SpeedMotB = 83;
    int SpeedMotC = 83;
    int SpeedMotD = 83;

    MotorSpeedSetGDC(SpeedMotA, SpeedMotB, SpeedMotD, SpeedMotC);
}

If anyone has managed to make this kind of setup work correctly or if you know what cloud have gone wrong I would greatly appreciate your advices.

Thanks

That motor driver uses an L298 chip. That chip drops 2V at least, and (I speak from memory) almost 5V when there's any significant current draw.

So getting 8 out from 12 in seems about right.

manor_royal: That chip drops 2V at least, and (I speak from memory) almost 5V when there's any significant current draw.

So getting 8 out from 12 in seems about right.

Then what do I do to get 12V ? Supply 15V ? Find a way to power the chip independently ?

I should also mention that because of this drop the PWM can't work correctly, when I ask for a PWM of 127 I get a voltage of around 7V, not even close to half of the maximum (8V being the maximum I can get)

Best advice is to look for a more effective driver like in this list; I use this one. The 298 is better with higher voltage motors where the drop is less significant.

And yeah I guess you could put a higher voltage in.

Not sure what you mean by "Find a way to power the chip independently ?" since you should be doing that anyway. The drop is inherent in the way the chip works.

Sadly because this is a school project I can't change the drivers but if it is the only way I can make this work I might give it a go.

What I mean by "Find a way to power the chip independently" is that currently the chip is powering itself from the power in pin of the driver (12V converted to a lower voltage). If I could make it so that the chip is powered by another power source there would not be a drop in the output voltage ?

There will always be a drop across the chip: it's not the board's fault, it's the way the chip works.

But you could put say 15V into the motor supply line of the board yes.