DC motor on I2C Motor Driver(L298): PWM is 25Hz and can’t be changed

Hello,
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() {
  Motor.begin(I2C_ADDRESS);
  //Motor.frequence(0x05);
}

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

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.,

HTH
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;
  moteur(commande);
}

//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() {
  Motor.begin(I2C_ADDRESS);
  Motor.stop(MOTOR1);
}

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.
HTH
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)

(https://electronics.stackexchange.com/questions/204996/stm32-st-link-cannot-connect-to-mcu-after-successful-programming)

as far as the firmware fire off some emails to support. Or look around it may be in the wild?
HTH
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.

Thank you Seraphina,


We are waiting for your solution. We have a lot of Grove - I2C Motor Driver (L298P) we can’t use. See above picture: Drivers in machines we can’t use and drivers on stock.
Regards,

We still have no news from seed studio.
We will shortly return for money back all our Grove - I2C Motor Driver (L298P) to our French distributor Farnell for “product does not match the specifications”.

Sorry, dear.
Grove - I2C Motor Driver (L298P) and Grove - I2C Motor Driver V1.3 has the same chip so that they use the same library
Today, I will personally conduct some actual tests in an effort to try and reproduce and resolve the problem. We truly regret any inconvenience this may have caused you. Thank you once again for your patience and understanding.

Thank you Seraphina,
I send a message to the email you privided me in your PM.

We found that there is indeed a situation where the PWM frequency cannot be changed based on our test results.

Currently, our R&D team is working diligently to update the new STM32 firmware. We will definitely provide you with feedback on this topic when the latest STM32 firmware library is available.

Hello Everyone
Thanks for waiting, here is the solution:

To change the frequency, you need to update the firmware of the STM32 on the Grove - I2C Motor Driver (L298P) to the latest version. The link is provided below:

To change the frequency, use function below(The value represents the frequency, with a maximum of 255Hz.):

Motor.frequence(50)

You can use either ST-link or Jlink to flash the firmware on the STM32. Here are the steps:

Jlink

Hardware:

SWC - SWCLK,
SWD - SWDIO
VCC - 3V3
GND - GND
Voltage input: 12V

Software:
image SEGGER J-Flash V7.80

  1. Select STM32F030F4

  2. Change Use target RAM to 2KB.

  3. Drag the firmware into the box. Then click OK

  4. Then connect and flash
    image

FAQ
If the operation fails, please check whether all the above configurations have been properly set. Verify that all Sectors below are checked. All sectors need to be selected.

If flashing fails despite all configurations being completed, try pressing ‘Production Programming’ button several times and the flash should succeed.

ST-link

Hardware:
SWC - SWCLK,
SWD - SWDIO
VCC - 3V3
GND - GND
Voltage input: 12V

Software:STM32 ST-LINK Utility
image

If your wiring is correct, clicking on Connect will directly recognize your current chip without additional checking.
Then Erase Chip and Program & Verify

Finally, you can successfully flash the firmware

1 Like

Hi Seraphina,

Thank you for the new firmware.
I will use STLinkV2
I have some questions for hardware connexion:

  • Is it necessary to connect 3V3? Is 12V generate 3.3V through regulator?
  • How do you perform SWD and SWC contact? Are you using a manual contact or you have a better solution with a special connector?

You must connect the 3.3V, just as indicated in the picture. You need to connect the VCC of the ST-link and the Grove - I2C Motor Driver (L298P) together.

I soldered male wires to the SWD and SWC pads for easy connection with female wires.


1 Like