Calculating the speed of my Hall Sensored BLDC Motor using ZS-X11H controller and Arduino

Hello all, hope you're doing well.
I got a brushless motor with 3 Hall sensors inside it. It is 3-phase motor and I want to write a code to calculate the speed in RPM of the motor. I know that using the hall sensors, the speed can be calculated, but I'm new and I don't know how to read the hole sensors and do the calculations. I appreciate any advice or help!


I have connected the 3phase and power supply, and also the wires of the hall sensors.

Shall I take wires from the hall sensors and connect them to arduino pins to read them using analogRead?

One is enough.

Thank you @Railroader,
I have tried with one wire and I noticed with spinning the motor with my hand that before reaching a full revolution, the pin outputs 0 and 1 multiple times.
I can relate to this image:
image
Any advices?

The 3 sensors simplify the implementation, in discrete circuits or in software. An ESC has to operate in 3 states: acceleration, deceleration and controlled run. For acceleration the phases should be switched as soon as possible, for deceleration as late as possible, and else synchronized with the set speed. A PLL algorithm may be sufficient for all that.

1 Like

How many pulses per rev?

I don't know how many pulses.
Actually if I use the Hall B to read from it, will this code measure the correct RPM?

#include <SPI.h>
#include <Wire.h>
int tON=0;
int tOFF=0;
int Tperiod=0;
int freq=0;
int RPM=0;
void setup() 
{
      Serial.begin(9600);

}

void loop() 
{
  tON=pulseIn(2,HIGH);
  tOFF=pulseIn(2,LOW);
  Tperiod=tON + tOFF;
  freq= 1000000.0/ Tperiod;
  RPM=freq * 30;
 if(digitalRead(2)==HIGH)
  {
    Serial.println(RPM);
  }
  tON=0;
  tOFF=0;
  Tperiod=0;
  freq=0;
  RPM=0;
}

The period Tperiod is the sum of the time when the sensor on and off. Then the frequency is calculated and then the rpm. I know there are mistakes since the numbers I'm getting I think are high. What do you think? I have seen this code on the internet and adjusted it a little bit.

freq will be in revs per second. Multiply by 60 for revs per minute.
Somebody knowing the interior of that motor can tell if there is only one cycle per rev, or if there are more cycles per rev. In that case add a divide by the number of pulse cycles per rev.

1 Like

Crank up the baudrate! 115200 often works well. Don't print RPM that often. Use a millis() timer to print some times per second.

1 Like

You would need to know how many poles the motor has. I believe hall pulses is poles/2.

Once you know that, use a counter. This may help

Another approach would be to use a frequency to voltage converter and measure its output voltage.

1 Like

I tried to update my code to this:

#include <SPI.h>
#include <Wire.h>

const int NUM_CYCLES_PER_REV = 1;
const int BAUDRATE = 115200;
const int PRINT_DELAY = 1000;

int tON = 0;
int tOFF = 0;
int Tperiod = 0;
int freq = 0;
int RPM = 0;
unsigned long previousMillis = 0;  //inorder to keep track of previous time

void setup() 
{
    Serial.begin(BAUDRATE);
}

void loop() 
{
  tON = pulseIn(2, HIGH);
  tOFF = pulseIn(2, LOW);
  Tperiod = tON + tOFF;
  freq = 1000000.0 / Tperiod;
  RPM = freq * 60 / NUM_CYCLES_PER_REV;

  //only print if the signal is high
  if (digitalRead(2) == HIGH)
  {
    // Check the current time and print only after the specified delay
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= PRINT_DELAY)
    {
      Serial.println(RPM);
      previousMillis = currentMillis;
    }
  }

  tON = 0;
  tOFF = 0;
  Tperiod = 0;
  freq = 0;
  RPM = 0;
}

Should it be calculating correctly right now? :stuck_out_tongue:
N.B. nothing is being printed ..

It got 6 poles, I finally got hands to the datasheet: ourproducts_housed_brushless_bldc_motor_din34-32-cdya_drawing (1).pdf - Google Drive
This is it, but i can't find the pulse per rev @Railroader

That will not work. The int variable can't hold such large numbers. Write like this: #define BAUDRATE 115200.
As print delay use some 300 mS giving You an update 3 time per second. That rate is low but nice for the human mind! I've used that and it feels fast enough but not like that hysterical tombola.

Thanks! I'll take a look at the datasheet.

1 Like

Well done! 6 poles confirms Your feeling for "more pulses". 3 phases and 6 poles. I interpret that as there are 2 pulses per rew for each phase.
30 000 000L / rev-time ought to give RPM. Make a test running the motor as slow as possible. That way You eye has a chance to verify it's reasonable correct.

1 Like

It's my English not so good, am I understanding your last comment right?

  Tperiod = tON + tOFF;
  freq = 1000000.0 / Tperiod;
  RPM = (freq * 60) / 6;

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.