I was trying to make a jumping moment cube, but I can't get the Brushless motors

Hello everyone I've been trying to make this jump cube, but I can't get the brushless motors to spin around.
I've been sitting here since 12 o'clock searching the internet, trying different code etc. so for four hours straight.
Not much code on the internet for a 8 wire bldc motor.
I can't get the motors spinning. I'm not very good with programming so I hope I can get some help from the more experience people.

Picture of the project..

Basically I just for now need the motors to spin, but they don't. I can feel resistance in the motor axel and when I turn it it makes noise, so something is going on.

I wrote this:

/*
 * 
 * 
 * This program is for the Prototype of a gyromoment turning cube for testing 
 * 
 * 1: CHA -> Arduino D2
 * 2: CHB -> Arduino D3
 * 3: 5V -> Arduino 5v connector
 * 4: CW/CCW -> Arduino D4
 * 5: PWM -> -> Arduino D8
 * 6: Brake -> Arduino D5
 * 7: GND -> Direkte fra Batteri
 * 8: VM (11.1v) Direkte fra batteri. 

 * 
 * 
 * 
 * 
 */


int CHA = 2; // Read encoder 
int CHB = 3; // Read encoder
int CWCCW =  4; // Low = CW, High = CCW
int PWM = 8;  // PWM 1 - 255 for Motor Speed 
int Brake = 5; // Low = Brake, High = Releases Brake Function




void setup() {

  pinMode(CHA, INPUT); 
  pinMode(CHB, INPUT);
  pinMode(CWCCW, OUTPUT);
  pinMode(PWM, OUTPUT);
  pinMode(Brake, OUTPUT); 

}

void loop() {

  digitalWrite(CWCCW, LOW); 
  digitalWrite(Brake, HIGH);
  analogWrite(PWM,255); 
  

}

The best example I find for me thoughout google searches is this code intentionally written for 3D printers by Miguel Sánchez

/*
   This program uses an Arduino for a closed-loop control of TWO brushless DC-motors. 
   Motor motion is detected by a quadrature encoder.
   Two inputs per motor named STEP and DIR allow changing the target position.
   Serial port prints current position and target position every second.
   Serial input can be used to feed a new location for the servo (no CR LF).
   
   Pins used: please read defines and code below

   Please note PID gains kp, ki, kd need to be tuned to each different setup. 
   
  
   */
#define DEBUG

#include <PID_v1.h>
#define encoder0PinA  2
#define encoder0PinB  3  
#define encoder1PinA  7 
#define encoder1PinB  6 
#define PWM           8
#define PWM1          10
#define CWCCW         4  
#define CWCCW1        9
#define BRAKE         5 


double kp=1,ki=0,kd=0.0;
double input=0, output=0, setpoint=0;
double input1=0, output1=0, setpoint1=0;
PID myPID(&input, &output, &setpoint,kp,ki,kd, DIRECT);
PID myPID1(&input1, &output1, &setpoint1,kp,ki,kd, DIRECT);

volatile long encoder0Pos = 0;
volatile long encoder1Pos = 0;

long previousMillis = 0;        // will store last time LED was updated

long target0=0;  // destination location at any moment
long target1=0;  // destination location at any moment

//for motor control ramps 1.4
bool newStep = false;
bool oldStep = false;

// Install Pin change interrupt for a pin, can be called multiple times
void pciSetup(byte pin) 
{
    *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin
    PCIFR  |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
    PCICR  |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group 
}

void setup() { 
  pinMode(encoder0PinA, INPUT); digitalWrite(encoder0PinA, HIGH); 
  pinMode(encoder0PinB, INPUT); digitalWrite(encoder0PinB, HIGH);  
  pciSetup(encoder0PinA);
  pciSetup(encoder0PinB);
  
  pinMode(encoder1PinA, INPUT); digitalWrite(encoder1PinA, HIGH); 
  pinMode(encoder1PinB, INPUT); digitalWrite(encoder1PinB, HIGH);  
  pciSetup(encoder1PinA);
  pciSetup(encoder1PinB);

  pinMode(BRAKE, OUTPUT);
  
  TCCR1B = TCCR1B & 0b11111000 | 1; // set  Hz PWM
  Serial.begin (115200);
  //Setup the pid 
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(1);
  myPID.SetOutputLimits(-150,150);
  pinMode(13,OUTPUT); digitalWrite(13,HIGH); // disable motor brake
  pinMode(CWCCW,OUTPUT); analogWrite(PWM,255);
  
  myPID1.SetMode(AUTOMATIC);
  myPID1.SetSampleTime(1);
  myPID1.SetOutputLimits(-150,150);
  pinMode(13,OUTPUT); digitalWrite(13,HIGH); // disable motor brake
  pinMode(CWCCW1,OUTPUT); analogWrite(PWM1,255);
  // step pin interrupts on rising edge
  attachInterrupt(0, countStep      , RISING);  // step0  input on interrupt 1 - pin 2
  attachInterrupt(1, countStep1     , RISING);  // step1  input on interrupt 1 - pin 3
} 

void loop(){
    digitalWrite(BRAKE,HIGH);
    input = encoder0Pos; 
    setpoint=target0;
    input1 = encoder1Pos;
    setpoint1=target1;
    myPID.Compute();
    myPID1.Compute();
    // interpret received data as an integer (no CR LR): provision for manual testing over the serial port
    if(Serial.available()) target1=Serial.parseInt();
    pwmOut(output); 
    pwmOut1(output1);
#ifdef DEBUG
    if(millis() % 2000 == 0) target0=target1=random(1000); // that was for self test with no input from main controller

    if( millis() % 1000 ==0 ) 
    {
        Serial.print(target1);
        Serial.print(":");
        Serial.print(" P=");
        Serial.print(output);
        Serial.print(" P1=");
        Serial.print(output1);
        Serial.print(" 0: ");
        Serial.print(encoder0Pos); // print out current location every second
                Serial.print(" 1: ");
        Serial.println(encoder1Pos); // print out current location every second
    } 
#endif
}

void pwmOut(int out) {
  // if(abs(out)<10) digitalWrite(13,LOW); else digitalWrite(13,HIGH); // brake, compensate dead-band
   if(out<0) { digitalWrite(CWCCW,HIGH);} 
   else { digitalWrite(CWCCW, LOW); }
   analogWrite(PWM, 255-abs(out) );
  }


void pwmOut1(int out) {
  // if(abs(out)<10) digitalWrite(13,LOW); else digitalWrite(13,HIGH); // brake, compensate dead-band
   if(out<0) { digitalWrite(CWCCW1,HIGH);} 
   else { digitalWrite(CWCCW1, LOW); }
   analogWrite(PWM1, 255-abs(out) );
  }
  
  
const int QEM [16] = {0,-1,1,2,1,0,2,-1,-1,2,0,1,2,1,-1,0};               // Quadrature Encoder Matrix
static unsigned char New, Old;

  ISR (PCINT0_vect) // handle pin change interrupt for D8 to D13 here
 { 
  Old = New;
  New = (PINB & 1 )+ ((PINB & 16)/8); //
  encoder0Pos+= QEM [Old * 4 + New];
}

static unsigned char New2, Old2;
ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7 here
 { 
  Old2 = New2;
  New2 =  (PIND & 192)/64; //(PIND & 128 )/128 + ((PIND & 64)/32); //
  encoder1Pos+= QEM [Old2 * 4 + New2];
}

void countStep(){ if (PINC&B0000001) target0++;else target0--; } // pin A0 represents direction0

void countStep1(){ if (PINC&B0000010) target1++;else target1--; } // pin A1 represents direction1

Can someone guide me in a direction to where I can get the motors spinning. I would be so appreaciated, this is something I would love to make happen and see my project work.

Thanks best regards Kevin.

Can you share the data sheets for the motors and motor controllers?

This is the only information I've found available.
http://www.nidec.com/en-NA/product/motor/category/A010/B020/P0000025/

  • Also see attached images.

Here is the datasheet - Look at page 6 / 7:
http://www.hcmfa.com/admin/data/product/1512290006_1.pdf

  • My motors are a 12v version and not 24v
    Can it be that the PWM frequency is too low?

Which Arduino are you using?

Hi,
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
NOT a FRITZY picture.....

Is pin14 a PWM pin on a MEGA, its a comms pin on my MEGA.

Thanks.. Tom.. :slight_smile:
OPs Picture

You must match the coils and sensors, in order to make a BLDC motor spin. Try without a PID first, to verify your cabling. You'll need 3 half-bridges at least, to drive the coils of one motor. Which motor driver modules do you use?

The output signals look like PWM, but not only the duty cycle must be controlled, also the frequency has to be varied, to match the intended motor speed. In fact the frequency is governed by the sensors, not by a fixed frequency.

First of all. Thanks for your inputs everyone, it's very pleasant to see.
I'm using an Arduino Mega.
I was trying first with the pwm pin 8, but couldn't get it to work, so I changed it to an analog pin (Because I thought that might work then......) . But know I've changed it back to pin 8.

It is now spinning with the code Miguel Sánchez has written, when I release the brake function.
I've updated all code written in the original/first post to match my current code

Unfortunately for me this code is written for the intent of an input of either STEP or DIR to make the motor spin.

  • and it looks so complicated to me to rewrite for my purpose. Therefore expect me to ask more questions again.

like.. How do I make my code work now? What is the small chunks of written code that makes Miguels code work / What am I missing to write in my code*

Also if this is at maximum speed which I don't hope since it should be +4000 rpm. (listen to the video) I'll have to go with brushless RC motors, but I wanted it to be quiet and not heat up to a level off +100.000 in Magma DAMAGE without air cooling! :slight_smile:

Do you have a stepper motor (2 phase) or BLDC motor (3 phase)?

This is a 3 phase Brushless motor..

Here is pictures of the Hand Drawn circuit as requested.

Hi.
Thanks for circuit diagrams.


Tom... :slight_smile:

Please read the first post in any forum entitled how to use this forum.

http://forum.arduino.cc/index.php/topic,148850.0.html

You don't need an Arduino to test that motor.

According to the pin definitions in the data sheet, you need only to connect/set the pins as follows

8 Motor Power
7 Ground
6 Brake (5V or HIGH to turn brake off)
5 PWM (5V or HIGH to run at full speed)
4 DIR (CW=leave open or 5V, CCW=ground)

Logic/motor control ground must be connected to motor power ground.