Hello there. At the moment I have been testing a motor with relay attached to it. I use analogWrite() function together with PWM pins both for Arduino and I298N relay to control the speed of the motor. The problem is that when the argument (0-255) is less than 100, sometimes, I hear a continous buzzing sound (motor stops rotating) which disappears when I stop the motor or pass some higher values to analogWrite() function. Thus, I can't assign very slow speed for the motor. Would you, please, tell me what may be the reason of that?
You make it sound like you are using analogWrite() to control a relay. Is that really what you are doing ?
UKHeliBob, thank you for your reply. Sometimes, relay starts buzzing when I use analogWrite(PWMpin, 50), for example, which is less than 100. But when I use analogWrite(PWMpin, 200) everything is just fine. Maybe, it's not enough power (0 - 255 ~ 0V - 5V) for the motor to rotate when analogWrite() argument is too low. I just want to know the lowest boundary for the motor to rotate very slowly.
What's the relay?
Do you mean a
or something another?
I298N is not a relay, it is a motor driver.
Can you post a datasheet for the motor?
Well, first you should know why you hear sound physically. It is the vibrations of motor wires.
PWM is a pulsation of voltage and hence current to the motor. If the frequency of the PWM is within the range of a human ear response (possibly 20Hz to 20kHz), you will hear the vibration.
Unfortunly, the official arduino library for pwm seem to be around 500Hz to 1kHz, of course you will hear it.
When the duty cycle (pwm) is low or current is large, the pulsation effect is larger, you feel the vibrations more likely. When the duty is large it sound like a DC voltage, the vibration effect seem lower.
I have tried to make the switching frequency to 31.5kHz, I hear no noise (in fact, it is out of the frequency response of my ear
)
Of course, the frequency of the timer can be changed, but it is a little advanced design, and you should consider whether your modifications will affect other standard functions such as standard time delay function... etc.
Hi, @fixer_84
Can you please post your code?
What model Arduino are you using?
What is your motor?
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Thanks.. Tom...
![]()
Hi, @fixer_84
Is this your project you are talking about?
The L298N is not called a RELAY, it is called a Motor Driver.
Tom..
![]()
Thank you for your reply. Yes, actually I meant a motor driver with pwm jumpers for two motors. And yes, it's connected to another topic which I created yesterday (there is some info I already provided there). Please, let me know if you need more information on that. I will send an updated code with pwm speed control as soon as I end it up.
Thank you for you reply. You can find a datasheet with this link:
Here is a basic code which works for now, but with buzzing sound:
//Copyright (C) 15.11.2023, Kirill ZHivotkov
#include <IRremote.h>
#include <limits.h>
class Engine {
private:
unsigned long keyCode;
int engineSpeed;
int gearSpeed;
int pwm;
int in1; //Motor 1
int in2; //Motor 1
bool engineStart;
bool gearIsSwitched;
//int in3 = 9; int in4 = 10; //Motor 2
//int in5 = 2; int in6 = 3; //Motor 3
//int in7 = 6; int in8 = 5; //Motor 4
String speedStatus;
String engineDir;
public:
//Setters
void setKeyCode(unsigned long keyCode) {
this->keyCode = keyCode;
}
void setEngineSpeed(int engineSpeed) {
this->engineSpeed = engineSpeed;
}
void setGearSpeed(int gearSpeed) {
this->gearSpeed = gearSpeed;
}
void setSpeedStatus(String speedStatus) {
this->speedStatus = speedStatus;
}
void setEngineDir(String engineDir) {
this->engineDir = engineDir;
}
void setEngineStart(bool engineStart) {
this->engineStart = engineStart;
}
//Setters
//Getters
unsigned long getKeyCode() {
return this->keyCode;
}
int getEngineSpeed() {
return this->engineSpeed;
}
int getGearSpeed() {
return this->gearSpeed;
}
String getSpeedStatus() {
return this->speedStatus;
}
String getEngineDir() {
return this->engineDir;
}
bool getEngineStart() {
return this->engineStart;
}
//Getters
//Function prototypes
void startEngine();
void stopEngine();
void driverChangesDir();
void driverSpeedsUp();
void driverSlowsDown();
void setEngineGear();
//Function prototypes
//Default constructor
Engine() {
this->keyCode = ULONG_MAX;
this->engineSpeed = 255;
this->gearSpeed = 60;
this->pwm = 10;
this->in1 = 11;
this->in2 = 12;
this->speedStatus = "";
this->engineDir = "";
this->engineStart = false;
this->gearIsSwitched = false;
pinMode(this->in1, OUTPUT);
pinMode(this->in2, OUTPUT);
pinMode(this->pwm, OUTPUT);
pinMode(A0, INPUT);
IrReceiver.begin(A0, ENABLE_LED_FEEDBACK);
}
//Default constructor
};
//Stop engine
void Engine::startEngine() {
if ((digitalRead(this->in1) == 1 && digitalRead(this->in2) == 0) && this->engineStart == false) {
this->setEngineDir("FORWARD");
delay(100);
this->engineSpeed = this->gearSpeed;
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 1); digitalWrite(this->in2, 0);
this->engineStart = true;
} else if ((digitalRead(this->in1) == 0 && digitalRead(this->in2) == 1) && this->engineStart == false) {
this->setEngineDir("BACKWARD");
delay(100);
this->engineSpeed = this->gearSpeed;
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 0); digitalWrite(this->in2, 1);
this->engineStart = true;
}
}
//Stop engine
//Stop engine
void Engine::stopEngine() {
if (this->engineStart == true) {
if (this->getKeyCode() == 3108437760) {
this->setEngineDir("STOP");
analogWrite(this->pwm, 0);
digitalWrite(this->in1, 0); digitalWrite(this->in2, 0);
//Reset settings for the next engine start
this->setEngineSpeed(255);
this->engineStart = false;
this->gearIsSwitched = false;
this->speedStatus = "";
this->engineDir = "";
//Reset settings for the next engine start
}
}
}
//Stop engine
//Change gear
void Engine::setEngineGear() {
if (this->engineStart == false) { //If engine is idle
if (this->keyCode == 4077715200) { //1-st Gear (key 1)
this->gearSpeed = 60;
this->gearIsSwitched = true;
Serial.print("1 Gear: ");
Serial.println(this->gearSpeed);
} else if (this->keyCode == 3877175040) { //2-nd Gear (key 2)
this->gearSpeed = 120;
this->gearIsSwitched = true;
Serial.print("2 Gear: ");
Serial.println(this->gearSpeed);
} else if (this->keyCode == 2707357440) { //3-d Gear (key 3)
this->gearSpeed = 180;
this->gearIsSwitched = true;
Serial.print("3 Gear: ");
Serial.println(this->gearSpeed);
} else if (this->keyCode == 4144561920) { //4-th Gear (key 4)
this->gearSpeed = 255;
this->gearIsSwitched = true;
Serial.print("4 Gear: ");
Serial.println(this->gearSpeed);
}
} else if (this->engineStart == true) { //If engine has started
if (this->keyCode == 4077715200) { //1-st Gear (key 1)
this->engineSpeed = 60;
this->gearIsSwitched = true;
Serial.print("1 Gear: ");
Serial.println(this->engineSpeed);
} else if (this->keyCode == 3877175040) { //2-nd Gear (key 2)
this->engineSpeed = 120;
this->gearIsSwitched = true;
Serial.print("2 Gear: ");
Serial.println(this->engineSpeed);
} else if (this->keyCode == 2707357440) { //3-d Gear (key 3)
this->engineSpeed = 180;
this->gearIsSwitched = true;
Serial.print("3 Gear: ");
Serial.println(this->engineSpeed);
} else if (this->keyCode == 4144561920) { //4-th Gear (key 4)
this->engineSpeed = 255;
this->gearIsSwitched = true;
Serial.print("4 Gear: ");
Serial.println(this->engineSpeed);
}
}
if (this->getEngineDir() == "FORWARD") {
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 1); digitalWrite(this->in2, 0);
} else if (this->getEngineDir() == "BACKWARD") {
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 0); digitalWrite(this->in2, 1);
}
}
//Change gear
//Change engine rotate direction
void Engine::driverChangesDir() {
if (this->engineStart == false) {
if (this->keyCode && this->keyCode == 3141861120) {
this->engineDir = "BACKWARD";
} else if (this->keyCode && this->keyCode == 3208707840) {
this->engineDir = "FORWARD";
}
Serial.println(this->engineDir);
}
}
//Change engine rotate direction
//Increase engine speed
void Engine::driverSpeedsUp() {
if (this->engineStart == true) {
if (this->keyCode == 3927310080) {
this->speedStatus = "INC";
this->gearIsSwitched = false;
} else if (this->keyCode == 0 && this->speedStatus == "INC") {
if (this->engineSpeed >= 60 && this->engineSpeed <= 240) {
if (this->gearIsSwitched == false) {
this->engineSpeed += 15;
}
if (this->engineDir == "FORWARD") {
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 1); digitalWrite(this->in2, 0);
} else if (this->engineDir == "BACKWARD") {
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 0); digitalWrite(this->in2, 1);
}
}
Serial.print("Speed: ");
Serial.println(this->engineSpeed);
}
}
}
//Increase engine speed
//Decrease engine speed
void Engine::driverSlowsDown() {
if (this->engineStart == true) {
if (this->keyCode == 4161273600) {
this->speedStatus = "DEC";
this->gearIsSwitched = false;
} else if (this->keyCode == 0 && this->speedStatus == "DEC") {
if (this->engineSpeed >= 75 && this->engineSpeed <= 255) {
if (this->gearIsSwitched == false) {
this->engineSpeed -= 15;
}
if (this->engineDir == "FORWARD") {
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 1); digitalWrite(this->in2, 0);
} else if (this->engineDir == "BACKWARD") {
analogWrite(this->pwm, this->engineSpeed);
digitalWrite(this->in1, 0); digitalWrite(this->in2, 1);
}
}
Serial.print("Speed: ");
Serial.println(this->engineSpeed);
}
}
}
//Deccrease engine speed
Engine* engine;
void setup() {
engine = new Engine();
//pinMode(in3, OUTPUT); pinMode(in4, OUTPUT ); //Motor 2
//pinMode(in5, OUTPUT); pinMode(in6, OUTPUT ); //Motor 3
//pinMode(in7, OUTPUT); pinMode(in8, OUTPUT ); //Motor 4
Serial.begin(9600);
}
void loop() {
if (IrReceiver.decode()) {
unsigned long a = IrReceiver.decodedIRData.decodedRawData; //Receive a value from remote control
IrReceiver.resume();
//Serial.println(a);
engine->setKeyCode(a);
engine->driverChangesDir();
engine->driverSpeedsUp();
engine->driverSlowsDown();
engine->setEngineGear();
engine->stopEngine();
engine->startEngine();
}
}
Arduino Leonardo.
You can find it out with this link:
Here it is:

The screenshot above does not have a pwm going from motor driver which I called "relay" to the 10-th Arduino pwm pin (see program code above).
Please, tell me how I can do it. I do not want to hear that buzzing sound.
Ok, I need to remind you again, this modification is a bit advanced, you should capable to know down to the microcontroller hardware/ firmware and all your changes will only suit your board being used.
You may need to change the libraries/ header files/ register values and you should know you will AFFECT other timing functions of the stardard library ..... may be involving the IR module .... you need to check and try.
My previous test is a microcontroller based C compiled code (with no library used) for ATMEGA328 and is not an direct arduino program, so, I will not give you a solution code, but, related information below:
-
Your board is Leonardo, so the pwms will use pins 3,5,6,9,10,11 and 13 and it uses timer 0 for pwm.
-
You need to change the values of registers of timer0 with revalent formulas, I give you the link of information that guide you somehow:
https://docs.arduino.cc/tutorials/generic/secrets-of-arduino-pwm
Hi,
How have you got the UNO powered?
Have you tried powering your project from a power supply, or batteries more suited to the job.
2 x 9V PP3 batteries are not designed for this application.
What voltage do your 9V batteries measure at when you are driving the motors?
Thanks.. Tom..
![]()
Hello. Actually, I don't use UNO for this project, but Leonardo as I mentioned in post #12, if, of course, it makes any difference. As for the source of power, I use two 9V batteries for testing purposes, but my teacher also said I should use a power supply. BTW, Would you, please, explain why?
They both give a total of 9V because connected in a parallel way.
Anyway, thank you very much for this information. I will try to sort it out with my teacher. It really sounds a bit advanced for my current level of knowledge.