DC motor on I2C Motor Driver 1.3: PWM is 25Hz and can't be changed

I connect a DC motor to the L298 motor driver and performed some test with this code:

#include "Grove_I2C_Motor_Driver.h"
#define I2C_ADDRESS 0x0f

void setup() {

void loop() {
  Motor.speed(MOTOR2, 10);

I was able to hear a low frequence noise so I connected an oscilloscope to the driver (without the motor for easier reading).
The period of the signal is 40ms so the frequency is 25Hz.
If I uncomment the line Motor.frequence, and change the value from 0x05 to 0x01 (supposed to be 31372Hz, 3921Hz,490Hz, 122Hz, 30Hz according to the library), the PWM frequency is still 25Hz but the PWM ratio change a lot.
I performed some test on several cards with same results.
Is there a way to correct this? I think the problem is on STM32 side.
In this state, this card is not suitable for fast response application: position adjustment with an encoder in my case.
I can provide the oscilloscope screenshot for better understanding.

Hello & Welcome, benp
Can you show more of the code and how it’s connected? and what it’s connected to?
what board are you using and most important is how you power the whole thing, can you show a schematic or picture. Others will comment also with more to go by.
have you looked at this link for pointers.,

GL :slight_smile: PJ

Thank you PJ_Glasso
Motor control with the encoder is not the problem. My problem is slow motor response to command because:

  • I2C library is too slow (solved with library modification)
  • PWM frequency is too slow: 40ms period (not solved)
    Here is the context:
    We try to find an improve solution for EMG30 motor+encoder+arduino+Arduino motor shield L298.
    Here is one of the box which we use with our 800 students:

    The improved solution (in test) is made with an I2C Motor Driver V1.3

Why migrate: I2C free a lot of port for more complex projets and we can use interrupt pin 2 & 3(pin 3 is used by arduino motor shield).
The old design motor control can be done with this Arduino program (proportional control):

#include <Encoder.h>
Encoder myEnc(2, 5);

long commande = 0;
long Position;
int erreur;
int consigne = 180;
float kp = 20;

void setup() {
  pinMode(12, OUTPUT);    //pin Direction
  pinMode(3, OUTPUT);    //pin PWM

void loop() {
  Position = myEnc.read();
  erreur = consigne - Position;
  commande = kp * erreur;

//Commande du moteur
void moteur(int vit) {
  if (vit > 255) vit = 255;
  if (vit < -255) vit = -255;
  analogWrite(3, abs(vit));
  digitalWrite(12, (vit > 0));

The new design can be control with this program with a library modification:

#include "Grove_I2C_Motor_Driver.h"
#include <Encoder.h>

#define I2C_ADDRESS 0x0f
long consigne = 100;
float kp = 0.8;
Encoder myEnc(2, 3);

void setup() {

void loop() {
  long position = -myEnc.read();
  long erreur = consigne - position;
  float commande = kp * (float)(consigne - position);
  float commande2 =constrain(commande,-100,100);
  Motor.speed(MOTOR1, commande2);

This motor control can only be performed with library modification: remove the delay(4) in the library (point one solved at the beginning of this message). Without this, motor control is impossible
Note that Kp=40 in the old design and Kp= 0.8 in the new design!
The Kp value are obtained with Ziegler–Nichols method
Why such a difference? Because PWM is too slow. The result is very poor performance compared to old design: high error and slow speed: this motor control is not usable in real projects.
Next pictures/text in next message: I cannot post more as new user!

Here is the new design prototype with grove(not clean because still under test):

Why is 40ms not good: because our oscillation period Tu=45ms (typical) with EMG30+L298 (see Tu meaning in the Ziegler–Nichols method link.
Here are the response curves for old design:

You can notice the 45ms period on the ultimate gain Ku=100 and the low gain error.

Here is the oscilloscope screenshot (sorry for the old oscilloscope which is not picture friedly):

This is for my first post program: Motor 2=10% and default Motor.frequence
The time scale is 10ms so the period of pwm is 4x10ms=40ms (25 Hz)

I will post the other motor.frequence oscilloscope screenshot when I will have the right to post several picture.
I think there is a bug in STM32 embedded in the grove DC motor but I didn’t understand the On-Chip Firmware for I2C motor driver to do it myself.

Hi there,
Yes looks slow,I seem to remember something like
" Wire1.setClock(400000UL); //set 400kHz"
see if there is something like that available.
GL :slight_smile: PJ

Default Arduino UNO I2C frequency (100Khz) is not the problem: the loop time is 0.8 ms with the improved library (without delay(4) see in previous post).
The problem is the PWM frequency on the motor output: it is 490 Hz(2ms) on Arduino UNO+Arduino motor shield and 25Hz (40ms) on Grove Motor driver V1.3
The STM32 microcontroler on the grove motor driver generate the 25Hz PWM frequency.
motor.frequence (in the library) should change the pwm frequency but it changes only slighly the pwm ratio. See the oscilloscope capture:

Sorry, I made a mistake in the title :woozy_face:
My card is Grove - I2C Motor Driver (L298P) with STM32f030f4P6
it is NOT Grove - I2C Motor Driver V1.3 as stated in the title (with atmega8)
I didn’t find how to change the title (maybe I aml not allowed to).
What I understand from the wiki: the library is the same for Grove - I2C Motor Driver (L298P) and Grove - I2C Motor Driver V1.3
There is not firmware available for the STM32 in the wiki.
Can somebody provide the firmware (or better an upgraded firmware)?

Is it possible to reprogram the STM32 with a ST-LINK V2 on the SWD interface? Do you have an easy connection method?
Does somebody know where is the firmware? If not, I need to write everything from scratch!

Yes, There are several good reads on the subject. Check this link (title is misleading LOL)


as far as the firmware fire off some emails to support. Or look around it may be in the wild?
GL :slight_smile: PJ

Hi @benp ,

I apologize for any inconvenience caused. We have received your feedback, and we are currently discussing it internally. Once we have a resolution, we will reply to you in this thread promptly.

Thank you for your patience.