Arduino CDROM BLDC Motor Driver, Enhanced Performance

In the last BLDC project “Run-A-CDROM-Brushless-Motor-With-Arduino” I’ve used a L293 to drive a brushless DC motor. There were two important problems in that project as follow:
– Low speed and torque of the motor due to minimal signaling.
– IC overheating due to signal feedback.

arduino schematic

In this project I solve these problems via additional L293 and corresponding hi impedance state. According to grand Wikipedia, Hi-Z (or High-Z or high impedance) refers to an output signal state in which the signal is not being driven. The signal is left open, so that another output pin (e.g. elsewhere on a bus) can drive the signal or the signal level can be determined by a passive device.

As I mentioned before, each BLDC complete turn, needs 36 steps that each 6 steps are similar as next 6 steps. So you have a sequence of 6 which repeated 6 times.
Due to having just one IC, I’ve used the (110, 100, 101, 001, 011, 010) signals with two states 1=high, 0=low in last project. But the correct signaling for each step is to drive two of three phases and leave the third one open (hi-z).

With three phase A, B and C:
A: 1 1 – 0 0 –
B: – 0 0 – 1 1
C: 0 – 1 1 – 0

In this table the “-” state means hi-z. So there one low and one high signal in each step. Having multiple low or high in each step will lead to wrong signal feedback and IC overheat.
In this project I used the chip enable pin to make hi-z state. According to l293 schematic, there is two enable pins, each one for each side. So we can make four hi-z pins via two l293 (three of them are enough).

So this circuit is a little bit different from the last one. The pins 2, 3, 4 are enable signals and 5, 6, 7 are motor input signals. Whenever the enable pin be low, the signals will be hi-z.

As the code has written optimized, some hints maybe helpful.

– In signals array, first index is the number of hi-z pin. Remaining 3 values are signal values.
– Wait value is used to make a delay after each step.
– Serial monitor window is used to get “+” or “-” to increase or decrease wait value and it will changes the motor speed.

 * *

int wait = 7;
const int phases = 3;
const int pinmodes = 2;
const int sigstates = 4;
const int sigcycle = 6;

//pin numbers [0=enable, 1=signal]
const int pins[phases][pinmodes] = {{2,5} ,{3,6} ,{4,7}};

//values [0=enable][1,2,3=signals]
const int signals[sigcycle][sigstates] = {{1,1,1,0},{2,1,0,0},{0,1,0,1},{1,0,0,1},{2,0,1,1},{0,0,1,0}};

char inChar;
int i, j;
int v;

void setup() {                
  for (i=0; i<phases; i++){
    for (j=0; j<pinmodes; j++){
      pinMode(pins[i][j], OUTPUT);


// the loop routine runs over and over again forever:
void loop() {

  //set wait value
  if (Serial.available()){
    inChar = (char); 
    if (inChar == '-'){
      wait -=1;
      wait +=1;

  //drive motor
  for (i=0; i<sigcycle; i++){
    for (j=0; j<phases; j++){

      //set enable pin
      digitalWrite(pins[j][0], signals[i][0]==j?LOW:HIGH);

      //set output signal
      digitalWrite(pins[j][1], signals[i][j+1]);

    //one turn complete


About محمد شمس

برنامه‌نویس، طراح انیمیشن و علاقمند به هوش مصنوعی


  1. (Nice article. How fast does the motor spin ? (RPM

  2. مهندس دستت درد نکنه دمت گرم!

پاسخ دهید