Hello.
Recenty I started making a selfbalancing thingy with a reaction wheel. It uses MPU6050, Arduino NANO, BLDC motor. The exact driving motor is a Nidec 24H055M020 BLDC motor. I ordered it from aliexpress, it came all fine but I cant make it to work properly. I have not discovered any datasheets beside the roughly translated description on the Aliexpress page. I used this code to control the selfbalancing thing. The problem is the speed of the motor was constant despite the PWM output changing, so I had a robot that only switches the direction of rotation at a constant high speed.
Later on I started some tests on the motor and I found out that the speed of this motor is changing when I change the output frequency. So I made a small code where i used the "tone" function on pin9 whic value was being changed with a potentiometer, at an range from 100 to 26000 HZ. (The tone funcion is used for audio outputs for speakers I think). And it worked. kinda. The motor was speeding up when i increased the freguency and slowing down as I decreased it, but in increments, it was not linear. Idk if thats because of the motor driver or because arduino is only able to output certain frequencies like, 460, 1600, 2800, 6000 Hz etc. Also the motor would start vibrating if I would decrese or increase the frequency fast. The driver board of my nidec 24H 055M020 has only one aditional IC chip labaled 1036AA HIFI, compared to this Nidec 24H that is being used in the previous link i provided from remRC, whose motor is being driven with PWM change.
So I guess for this model I need a VFD to regulate the speed?
Maybe im doing something wrong with the wiring or code?
If anybody has any more info to share, I would be very thankful.
For informed help, please read and follow the directions in the "How to get the best out of this forum" post, linked at the head of every forum category.
Without reasonably complete documentation, a brushless motor is likely to be useless for the balancing task. You don't really "save money" by buying cheap, poorly documented components.
This nonsense on the product page is useless, except to point out that the seller doesn't know how to make the motor work, either.
For the correct use of this motor, we do not understand, we connect the motor according to the above wiring method, the motor can operate normally. But as for the feedback signal wiring, we do not know, and our wiring method, there are still some problems, because this motor it is suitable for speed regulation pulse frequency is between 1000HZ-26000HZ, frequency every 1000 HZ, the motor speed will increase 150 revolutions, very accurate, but we test machine found when the frequency is lower than 16000 HZ, according to our However, we found that when the frequency is lower than 16000 HZ, the motor cannot be started according to our wiring method, we use the last conductor of the starter line as the starter method, but it can only be started effectively when the frequency is between 16000HZ-26000HZ. When the start will be able to adjust the frequency between 1000HZ-26000HZ, so that you can adjust the speed of.
This is only a very odd point is that the input pulse 1000HZ it can also start, the input frequency in 16000HZ-26000HZ it can also start normally, is the middle of the pulse frequency (1100-16000HZ) start will jitter, but can not start, as for the technical principles inside, we do not understand.
Thank you for your fast replay. I basically want to see if anybody else came across this motor, or if somebody has any additional info about it. I used nidec 24H motors before, and all of them (also generaly speaking about this type of BLDC motors), all of them are pretty straight forward, you have your positive and negative power pins, direction pin, brake pin, and PWM which regulates the speed, + encoder feedback. This one is different, and its a bit strange that there is no datasheet, since Nidec is a pretty serious company.
Looks to me like Nidec dumped a defective lot.
I did some more tests, and I made this code that I will share in the end of this reply. This time the code works fine, I was able to control the motor with not problems. It didnt stutter or vibrate.
const int potentiometerPin = A0; // Potentiometer connected to analog pin A0
void setup() {
Serial.begin(9600);
pinMode(8, OUTPUT); // Set pin 8 as output for tone generation
}
void loop() {
// Read the potentiometer value
int potValue = analogRead(potentiometerPin);
// Map the potentiometer value to the desired frequency range
int frequency = map(potValue, 0, 1023, 1000, 26000);
// Generate tone on pin 8
tone(8, frequency);
Serial.print(frequency);
Serial.println(" Hz");
}
Hi,
I bought the same motor for the same project and it came without documentation…
Would you share your full code and wiring diagram?
Thanks
Joel
Dont bother with it, it wont work. The code I provided earlier was the only instance of code that could run the motor using the tone function, I dont have the full code for the balancing wheel, but it didnt work anyways. I bought this nidec 24H and used code from RemRC , and it worked perfect, without changing anything, not even tuning the PID values.
@vviner I am also trying to build this . I can't seem to find the code from RemRc. Could you share where to find this. Thanks
How have you implemented the circuit diagram? have u used any pcb? if u did , please can you provide a picture?
Hi!
The problem is that the Aliexpress description is wrong. The motor does not use PWM, it uses PFM (Pulse Frequency Modulation) signal.
With PWM, you have a type of signal, where you change the duty and you have fix duration time.
With PFM, you have 0 and 1 for the same time (you have 50% duty), and you change the duration time.
When you use the tone function, you have a PFM signal. The Arduino side said that about the tune function: "Generates a square wave of the specified frequency (and 50% duty cycle) on a pin."
Postscript, there is a picture, where you can see the difference between the PWM and the PFM signal.
I also bought this same motor, for this same balancing bot project, and it's giving the same issue with the sudden jittering or vibrations, could you recommend a better motor alternative from Aliexpress, my second option right now is to use a normal BLDC motor with a simple FOC driver board and a hall effect sensor.
I know this is late but I was able to use this motor using regular PWM (used AVR_PWM library). Use the so called PWM pin( which is actually PFM) as the switch pin and use the switch pin as PWM. Idk if this can cause any problems but the motor works
@sp_sarvesh Nice! Thank you for your tip! Can you share your code and your diagram? Did you use the nidec for the balanging project?
Its more likely that the issue is either noisy data or something wrong with foc configuration in your scenario. Also, why do the windings on this motor look uneven? That could also be causing the jitter
@sp_sarvesh
I'm also having trouble with this motor, more specifically I'm confused on how to wire it. Which pin is the switch pin that you are referring to? Do you know more details on the rest of the wires like the feedback on four lines?
I recently bought the same motors and after reaching out to the supplier found this version of the motor had several differences. I was sent the attached diagram, (google translated over the original Chinese characters). This wiring is different from the provided diagram on GitHub - remrc/Self-Balancing-Cube.
Changes found included,
- Swapped pins for Break and PWM
- Reverse logic of the break pin
- Reverse PWM logic, I needed to modify the code such that value near 0 moved the motor slower and values near 255 increased motor speed
I wrote a modified motor tester script to be able to command specified PWM rates and read the encoder to verify everything was working correctly. I'm new to this forum so I can't upload the file but I've added it below here if you would like to try it out. Made my debug process much easier.
#define BRAKE 26
#define BUZZER 27
#define DIR1 4
#define ENC1_1 35
#define ENC1_2 33
#define PWM1 32
#define PWM1_CH 1
#define DIR2 15
#define ENC2_1 13
#define ENC2_2 14
#define PWM2 25
#define PWM2_CH 0
#define DIR3 5
#define ENC3_1 16
#define ENC3_2 17
#define PWM3 18
#define PWM3_CH 2
#define TIMER_BIT 8
#define BASE_FREQ 20000
volatile int enc_count1 = 0, enc_count2 = 0, enc_count3 = 0;
int16_t motor1_speed;
int16_t motor2_speed;
int16_t motor3_speed;
long currentT, previousT_1, previousT_2;
int f;
boolean lock = false;
void beep() {
digitalWrite(BUZZER, HIGH);
delay(70);
digitalWrite(BUZZER, LOW);
delay(80);
}
void pwmSet(uint8_t channel, uint32_t value) {
ledcWrite(channel, value);
}
void Motor1_control(int sp) {
if (sp > 0) digitalWrite(DIR1, HIGH);
else digitalWrite(DIR1, LOW);
//pwmSet(PWM1_CH, 255 - abs(sp));
pwmSet(PWM1_CH, abs(sp));
}
void Motor2_control(int sp) {
if (sp > 0) digitalWrite(DIR2, LOW);
else digitalWrite(DIR2, HIGH);
pwmSet(PWM2_CH, 255 - abs(sp));
}
void Motor3_control(int sp) {
if (sp > 0) digitalWrite(DIR3, LOW);
else digitalWrite(DIR3, HIGH);
pwmSet(PWM3_CH, 255 - abs(sp));
}
void ENC1_READ() {
static int state = 0;
state = (state << 2 | (digitalRead(ENC1_1) << 1) | digitalRead(ENC1_2)) & 0x0f;
if (state == 0x02 || state == 0x0d || state == 0x04 || state == 0x0b) {
enc_count1++;
} else if (state == 0x01 || state == 0x0e || state == 0x08 || state == 0x07) {
enc_count1--;
}
}
void ENC2_READ() {
static int state = 0;
state = (state << 2 | (digitalRead(ENC2_1) << 1) | digitalRead(ENC2_2)) & 0x0f;
if (state == 0x02 || state == 0x0d || state == 0x04 || state == 0x0b) {
enc_count2++;
} else if (state == 0x01 || state == 0x0e || state == 0x08 || state == 0x07) {
enc_count2--;
}
}
void ENC3_READ() {
static int state = 0;
state = (state << 2 | (digitalRead(ENC3_1) << 1) | digitalRead(ENC3_2)) & 0x0f;
if (state == 0x02 || state == 0x0d || state == 0x04 || state == 0x0b) {
enc_count3++;
} else if (state == 0x01 || state == 0x0e || state == 0x08 || state == 0x07) {
enc_count3--;
}
}
void setup() {
Serial.begin(115200);
pinMode(BUZZER, OUTPUT);
pinMode(BRAKE, OUTPUT);
digitalWrite(BRAKE, HIGH);
pinMode(DIR1, OUTPUT);
pinMode(ENC1_1, INPUT);
pinMode(ENC1_2, INPUT);
attachInterrupt(ENC1_1, ENC1_READ, CHANGE);
attachInterrupt(ENC1_2, ENC1_READ, CHANGE);
ledcSetup(PWM1_CH, BASE_FREQ, TIMER_BIT);
ledcAttachPin(PWM1, PWM1_CH);
Motor1_control(0);
pinMode(DIR2, OUTPUT);
pinMode(ENC2_1, INPUT);
pinMode(ENC2_2, INPUT);
attachInterrupt(ENC2_1, ENC2_READ, CHANGE);
attachInterrupt(ENC2_2, ENC2_READ, CHANGE);
ledcSetup(PWM2_CH, BASE_FREQ, TIMER_BIT);
ledcAttachPin(PWM2, PWM2_CH);
Motor2_control(0);
pinMode(DIR3, OUTPUT);
pinMode(ENC3_1, INPUT);
pinMode(ENC3_2, INPUT);
attachInterrupt(ENC3_1, ENC3_READ, CHANGE);
attachInterrupt(ENC3_2, ENC3_READ, CHANGE);
ledcSetup(PWM3_CH, BASE_FREQ, TIMER_BIT);
ledcAttachPin(PWM3, PWM3_CH);
Motor3_control(0);
delay(2000);
}
void loop() {
currentT = millis();
if (currentT - previousT_1 >= 100) {
motor1_speed = enc_count1;
enc_count1 = 0;
motor2_speed = enc_count2;
enc_count2 = 0;
motor3_speed = enc_count3;
enc_count3 = 0;
// Check for serial input
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
// Check for set speed command
if (input.startsWith("S")) {
int speedValue = input.substring(1).toInt();
if (speedValue >= -255 && speedValue <= 255) {
digitalWrite(BRAKE, LOW);
Motor1_control(speedValue);
Serial.println("Motor1 speed set to: " + String(speedValue));
} else {
Serial.println("Invalid speed value. Enter between S0 and S255.");
}
}
// Check for get speed command
else if (input.equals("M1")) {
Serial.println("Motor1 speed: " + String(motor1_speed));
}
// Handle invalid commands
else {
Serial.println("Unknown command.");
}
}
previousT_1 = currentT;
}
if (currentT - previousT_2 >= 3000) {
f++;
if (f == 19) {
f = 1;
beep();
Serial.println("Beep!");
}
lock = 1;
previousT_2 = currentT;
}
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.