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

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.

I found how to install step 3 (only need arm-none-eabi-gcc) and was able to compile my new firmware.
I performed successful PWM test up to 65 535 Hz (L298D datasheet specify 40 000 Hz only).

I will cancel my pull request and propose a global solution: library and firmware. Old library and new firmware and new library and old firmware must work. Low byte first will maybe be the solution.