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

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

We ordered à STLINK V2 but it is 54 weeks delay! Is it possible to use STLINK V3?

Of course yes. Any STlink is OK, except counterfeit version

Hello,
I performed an firmware upgrade with a STlinkv2 counterfeit because I found only that quickly:


I am waiting for a true SLlinkV3

My upgrade steps:

  • STLinkV2 firmware upgrade with v3-15-6 upgrade tool from www.st.com
  • Connect STLink to motor driver according to Seraphina picture
  • I couldn’t install STM32 ST-LINK Utility from www.st.com so I installed STM32 cube programmer
  • I performed connect/eraseChip/Program
    The motor driver should be updated.

I tried the recomanded instruction:
Motor.frequency(50)

With the Grove_I2C_Motor_Driver_v1_3
In this simplified program:

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

void setup() {
  Motor.begin(I2C_ADDRESS);
  Motor.frequency(50);
}

void loop() {
  Motor.speed(MOTOR1, 50);
  delay(2000);
}

But I have the error:
Compilation error: 'class I2CMotorDriver' has no member named 'frequency'
There is no Motor.frequency in the library but just a frequence in the library.

I suppose you use an upgrade library to use Motor.frequency

Can you provide the upgrade library?

I’m sorry, I made a serious mistake. It’s frequence not frequency! I’ll change the part above where i made a mistake

Motor.frequence(50) is not possible with Grove_I2C_Motor_Driver_v1_3
According to the library:

/**************Prescaler Frequence***********/
#define F_31372Hz                 0x01
#define F_3921Hz                  0x02
#define F_490Hz                   0x03
#define F_122Hz                   0x04
#define F_30Hz                    0x05

and


if (_frequence < F_31372Hz || _frequence > F_30Hz) {
		Serial.println("frequence error! Must be F_31372Hz, F_3921Hz, F_490Hz, F_122Hz, F_30Hz");
		return;

So 50 in Motor.frequence(50) is not a valid argument because only 0x01,0x02, 0x03, 0x04 and 0x05 are valid.

We changed the underlying stm32 firmware so that you can use Motor. frequence(50).
Try it just OK

According to the library:

if (_frequence < F_31372Hz || _frequence > F_30Hz) {
		Serial.println("frequence error! Must be F_31372Hz, F_3921Hz, F_490Hz, F_122Hz, F_30Hz");
		return;

F_30Hz=5 and 50>5 so Motor. frequence(50) return without any wire.write.

Have a look to Grove_I2C_Motor_Driver.cpp line 126 in the library.

1 Like

Hello Seraphina,

I performed some test with the following program:

#include "Grove_I2C_Motor_Driver.h"
#define I2C_ADDRESS 0x0f
void setup() {
  Motor.begin(I2C_ADDRESS);
  Motor.speed(MOTOR1, 50);
  Motor.speed(MOTOR2, 50);
  Serial.begin(9600);
}
void loop() {
  Serial.println("3");
  Motor.frequence(1);
  delay(2000);
  Serial.println("50");
  Motor.frequence(50);
  delay(2000);
}

With the original library, the result is:

Because 50 is not a valid argument (as stated in my last post)

I tried to comment in the library:

if (_frequence < F_31372Hz || _frequence > F_30Hz) {
		Serial.println("frequence error! Must be F_31372Hz, F_3921Hz, F_490Hz, F_122Hz, F_30Hz");
		return;

But this don’t allow the frequency to change: with the new firmware, frequency is now 9.36Hz so worse than the original 25Hz before upgrade.

Sorry. My colleague had previously defined this function on the firmware when changing the firmware, and also confirmed that the frequency could be changed normally through this function. I may need to get more details from him about the issue with this library.

Unfortunately he left recently, so it will take me some time to get in touch with him

Hello Seraphina,
I was able to change the frequency with the help of the library:

and the Firmware source code . Is it really the last one for Grove - I2C Motor Driver (L298P)?

Here is a working example with no motor library(only wire used):

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Serial.println("-");
  delay(1000);
  Serial.println("default frequency start:200hz");

  //direction (no motor start without this)
  Wire.beginTransmission(0x0f);  // begin transmission
  Wire.write(0xaa);              // Direction control header
  Wire.write(0x0a);              // send direction control information BothClockWise=0x0a, BothAntiClockWise=0x05, M1CWM2ACW=0x06, M1ACWM2CW=0x09
  Wire.write(0x01);              // need to send this byte as the third byte(no meaning)
  Wire.endTransmission();

  //motor speed
  Wire.beginTransmission(0x0f);  // begin transmission
  Wire.write(0x82);              // set pwm header
  Wire.write(128);               // send speed of motor1 (full speed=255)
  Wire.write(128);               // send speed of motor2
  Wire.endTransmission();

  delay(10000);
  Serial.println("frequency: 255hz");
  //frequence
  Wire.beginTransmission(0x0f);  // begin transmission
  Wire.write(0x84);              // set frequence header
  Wire.write(255);              // send frequence
  Wire.write(0x01);              // need to send this byte as the third byte(no meaning)
  Wire.endTransmission();
  //frequency not changed yet: must set motor speed

  //motor speed
  Wire.beginTransmission(0x0f);  // begin transmission
  Wire.write(0x82);              // set pwm header
  Wire.write(128);               // send speed of motor1
  Wire.write(128);               // send speed of motor2
  Wire.endTransmission();
  //frequency changed
}

void loop() {
}

It is also possible to modify the library: edit and save the file Grove_I2C_Motor_Driver.cpp and comment line 122 & 123:

	if (_frequence < F_31372Hz || _frequence > F_30Hz) {
		//Serial.println("Not frequence error! Must be F_31372Hz, F_3921Hz, F_490Hz, F_122Hz, F_30Hz");
		//return;
	}

Then use this demo:

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

void setup() {
  Serial.begin(9600);
  Motor.begin(I2C_ADDRESS);
  Serial.println("run motors at default frequency=10hz");
  Motor.speed(MOTOR1, 50);
  Motor.speed(MOTOR2, 50);

  delay(2000);
  Serial.println("frequency change to 255hz");
  Motor.frequence(255);//not frequency change yet
  Motor.speed(MOTOR1, 50);//frequency change from now why:I don't know
  Motor.speed(MOTOR2, 50);
}

void loop() {
}
2 Likes

Hello Seraphina,

255Hz is much better than 25Hz but is not enough (Arduino UNO PWM is 490Hz for example).
The PWM frequency should be able to go over 255Hz with only light change in the firmware.
With it it should be possible to use the max ultrasonic frequency of L298D: 25 000 Hz
I made a pull request as benppppp user on github:

I was not able to test the code because I was not able to install according to the README.md (Usage for Windows) so do not accept pull request without testing.

According to /grove_stm32f030/blob/master/1.0.0/cores/arduino/wiring_analog.c
setPWMfrequence can go over 255: it is what I use.

Can you do one of the following:

  • Compile the firmware to bin, post it and I can test it
  • Test the new firmware yourself
  • Explain me how to install your github package for windows (blocked on step 3 “Find the downloading URL of stm32_serial_upload_tool and arm-none-eabi-gcc”

Regards,

Thank you very much for your support! I will contact the relevant colleagues to check your PR.