Hey everyone, iv been trying to find some information on how to control a BLDC motor I am running using this board. what I'm trying to do is control the exact RPM of the motor using a ZS-X11H motor controller board with an Arduino and I am unsure how to exactly do this. I have done hours of research and there seems to not be a lot of information about a solution so I'm deciding I might as well ask for any future people looking into this. the image below shows the layout of the board.
At the bottom of the picture, it says PWM throttle and that is what is needed to control the motor using the Arduino which should be a PWM signal that controls the speed, possibly from 50Hz to 20kHz. Also, note I know the external PWM pins need to be connected so that is all done. I'm just unsure about the code plus I don't want to damage the motors.
The good news is that the Arduino PWM is 500-1000Hz, well within the 50-2000Hz range.
To control 'exact' RPM you will need a closed-loop system. You will read the RPM from the pulse rate on the "SpeedPulseOut" line and then use software (like the PID_v1 library) to control the PWM output to get the RPM input you want.
// Pin definitions
const int SPEED_PULSE_IN = 2; // Speed pulse input from zs-x11h board
const int PWM_THROTTLE_OUT = 9; // PWM throttle output to control motor RPM
// Global variables
unsigned long pulse_time = 0; // Time of last pulse
unsigned long pulse_period = 0; // Period of pulse in microseconds
unsigned int pulse_frequency = 0; // Pulse frequency in Hz
unsigned int pulse_rpm = 0; // RPM of motor
// Set up pins and interrupt
void setup() {
// Set PWM pin to output mode
pinMode(PWM_THROTTLE_OUT, OUTPUT);
// Set speed pulse input to input mode with pull-up resistor
pinMode(SPEED_PULSE_IN, INPUT_PULLUP);
// Set up interrupt to capture speed pulse
attachInterrupt(digitalPinToInterrupt(SPEED_PULSE_IN), pulse_captured, RISING);
}
// Interrupt service routine to capture speed pulse
void pulse_captured() {
// Calculate pulse period in microseconds
pulse_period = micros() - pulse_time;
pulse_time = micros();
// Calculate pulse frequency in Hz
pulse_frequency = 1000000 / pulse_period;
// Calculate motor RPM
pulse_rpm = pulse_frequency / 2;
}
// Main loop
void loop() {
// Set PWM throttle output to control motor RPM
analogWrite(PWM_THROTTLE_OUT, pulse_rpm);
}
Good start. For variables that are shared between an interrupt and other code, they should be declared 'volatile'.
volatile int pulse_rpm;
In the non-interrupt code you should turn off interrupts when you fetch the volatile variable:
void loop()
{
int localRPM;
noInterrupts();
localRPM = pulse_rpm;
interrupts();
// Set PWM throttle output to control motor RPM
analogWrite(PWM_THROTTLE_OUT, localRPM);
}
Now comes the control-loop part. Start by installing a PID library like "ArduPID by PoweerBroker2".
The "Input" to your PID will be the current RPM reading.
The "Setpoint" to the PID will be the desired RPM.
The "Output" will be the PWM value to control the motor.
Shot in the dark here i dont believe this thread is checked anymore but I was wondering how the external PWM plug works and what type of plug is required for it
@nava101 Hi, can you please share the connections to calculate the RPM of the motor using the ZS-X11H and Arduino? I have connected the speed pulse out pin to the arduino and the gnd to the gnd of the arduino. Is that enough?