BLDC motor rpm setting via PWM

Hello everyone!
Is is some time that I played with my Arduino Leonardo. Now I have a task for it. I need to set a lower rotation speed to a brushless DC motor via a PWM signal. Perfect task for an Arduino one would say. This is the motor:
https://m.de.aliexpress.com/item/32855660580.html?trace=wwwdetail2mobilesitedetail&productId=32855660580&productSubject=Bringsmart-R2430-Brushless-Motor-DC-Motor-12V-High-Speed-6000rpm-with-Brake-High-Quality-Mirco-Motor&spm=a2g0x.10010108.1000016.1.ca672c05whNTum&isOrigTitle=true

If you put the PWM input to ground the motor runs at full speed=6000rpm. Disconnecting it makes it stop. The only spec for the PWM signal is 0-5V.
Using analogwrite with 128 as the argument results still in 6000rpm but the motor is not running as smoothly as with its PWM input on ground.

Any suggestions on how to reverse engineer the necessary PWM signal for the little friend.

A constant voltage of e.g. 1,5V if a battery does not start the motor at all.

Thanks for some ideas.

Hi,

Can you post your code and can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Please show how you are powering your project.

Thanks.. Tom... :slight_smile:

From what I have seen and the limited amount of specifications available, seems the controller for this runs at a select-by-jumper of 2 khz or 20khz.

Perhaps chasing info via the recommended controller will reveal more detail.

O.k. sorry for the few Info. This is the Code:

int ledPin = 9; // LED connected to digital pin 9
int val = 0; // variable to store the read value

void setup()
{
pinMode(ledPin, OUTPUT); // sets the pin as output
}

void loop()
{
val=128 // or 100 pro 254 …
analogWrite(ledPin, val); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
}

The speed of the motor is somewhat affected:

Ground=6100 rpm (very smooth sound from motor)
1=6100 rpm (less smooth sound)
100=5800 rpm (less smooth sound)
150=5400 rpm (…)
180=4800 rpm (…)
254=0 rpm (only silent beep tone)

I checked with LED and fading works fine.

CircuitOfHappyness:
but the motor is not running as smoothly as with its PWM input on ground.

Please explain what you mean by 'pwm input on ground'.

Don’t know why photos directly from the iPhone are not working for me. Here now the drawing of the circuit.

Southpark:
Please explain what you mean by 'pwm input on ground'.

In the spec to the motor is said: If you do not have a PWM signal then connect the PWM input to the negative pole. This gives you maximum rpm => in my case 6100 rpm Otherwise the motor is not turning without PWM signal given to it.

Hi,
OPs circuit.


Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.. :slight_smile:

Sorry for not considering that. On my iPhone I only got the quick reply form without any of the formatting tools that are in the screen shots that describes “how to use this forum”. But perhaps I also overlooked the “how to iPhone part”.

In any case thanks for the hint to the recommended controllers. I thought the board that are listed under the motor at the Ali.express site to be advertisements. But to look at them as a source of info is a good chance.

I will try to use the code that is described under the link below to run higher frequencies. I will keepyou informed.

I’m just saying that there is very little info around, next to zero specs. What is there seems to be broken English.

It seems there is some internal controller that takes a specified frequency PWM via the blue wire to give speed control.

If the blue wire is connected to ground, the motor goes full howl.

Leave it open, and the internal circuit operates some form of brake.

There is also a feedback out from the motor which in this instance does not connect to anything which is fine.

Perhaps get hold of the controller that suits and do some tests on it to see what actual frequency gives a smooth output on the motor speed

bluejets:
It seems there is some internal controller that takes a specified frequency PWM via the blue wire to give speed control.

If the blue wire is connected to ground, the motor goes full howl.

Leave it open, and the internal circuit operates some form of brake.

There is also a feedback out from the motor which in this instance does not connect to anything which is fine.

I also understood the “spec” like this and I managed to control the speed using the following code:

/**********************************************************
                Fast PWM Test

Demostrates the generation of high speed PWM
using timers 1 and 4
There are two pieces of code:

One for pins 9, 10 and 11 using TIMER 1
with frequencies up to 62kHz

Other for pins 6 and 13 using TIMER 4
with frequencies up to 187kHz

History:
  12/12/2014 - Version 1.0
  22/12/2014 - Adding a missing OCR4C value
  

***********************************************************/

/**********************************************************
   Fast PWM on pins 6, 13 (High Speed TIMER 4)
   
   Do not use analogWrite to pins 6 or 13 if using 
   this functions as they use the same timer.
   
   Those functions will conflict with the 
   MSTIMER2 library.

   Uses 7 PWM frequencies between 2930Hz and 187.5kHz
   
   Timer 4 uses a PLL as input so that its clock frequency
   can be up to 96MHz on standard Arduino Leonardo.
   We limit imput frequency to 48MHz to generate 187.5kHz PWM
   If needed, we can double that up to 375kHz

**********************************************************/

// Frequency modes for TIMER4
#define PWM187k 1   // 187500 Hz
#define PWM94k  2   //  93750 Hz
#define PWM47k  3   //  46875 Hz
#define PWM23k  4   //  23437 Hz
#define PWM12k  5   //  11719 Hz
#define PWM6k   6   //   5859 Hz
#define PWM3k   7   //   2930 Hz

// Direct PWM change variables
#define PWM6        OCR4D

// Terminal count
#define PWM6_13_MAX OCR4C

// Configure the PWM clock
// The argument is one of the 7 previously defined modes
void pwm613configure(int mode)
{
// TCCR4A configuration
TCCR4A=0;

// TCCR4B configuration
TCCR4B=mode;

// TCCR4C configuration
TCCR4C=0;

// TCCR4D configuration
TCCR4D=0;

// TCCR4D configuration
TCCR4D=0;

// PLL Configuration
// Use 96MHz / 2 = 48MHz
PLLFRQ=(PLLFRQ&0xCF)|0x30;
// PLLFRQ=(PLLFRQ&0xCF)|0x10; // Will double all frequencies

// Terminal count for Timer 4 PWM
OCR4C=255;
}

// Set PWM to D6 (Timer4 D)
// Argument is PWM between 0 and 255
void pwmSet6(int value)
{
OCR4D=value;   // Set PWM value
DDRD|=1<<7;    // Set Output Mode D7
TCCR4C|=0x09;  // Activate channel D
}


// Start of demostration code
// Generates 4 PWM signals, two constant and two variable

void setup()
{


// Configure Timer 4 (Pins 6 and 13)
// It will operate at 187kHz
// Valid options are:
//     PWM187k, PWM94k, PWM47k, PWM23k, PWM12k, PWM6k and PWM3k
pwm613configure(PWM23k);



// Pins 9 and 6 will change values in the loop function
// We first configure them

// Prepare pin 6 to use PWM
// We need to call pwm613configure
// For now, we set it at 0%
pwmSet6(0);
}

int value=255;

void loop()
{
// Set PWM at pins 9, 6
// Those fast macros require a previous configuration
// of the channels using the pwmSet9 and pwmSet6
// functions
// The functions pwmSet9 and pwmSet6 can be used
// instead, but the PWM9 and PWM6 macros are faster
// to execute
PWM6=value;
  
// Increment PWM value and return to 0 after 255
value=(value-10)%256;

delay(100);
}

The motor now does a ramp-up, but see for yourself:
Youtube link to testrun

Now I have successfully reengineered the required input signal and want to do the following:

  1. Put a ramp at the beginning of the first start up and then fix the speed at 50% => value=128
  2. Use the NANO that was yesterday in the mail instead of my big Leonardo.

How to I exit the loop or just run it up to a certain value?

The thing that worries me most ist the error I get when switching to my Nano-V3-0-Atmega328P

PWM_for_Unhold_fast.ino: In function 'void pwm613configure(int)':
PWM_for_Unhold_fast:59: error: 'TCCR4A' was not declared in this scope
PWM_for_Unhold_fast:62: error: 'TCCR4B' was not declared in this scope
PWM_for_Unhold_fast:65: error: 'TCCR4C' was not declared in this scope
PWM_for_Unhold_fast:68: error: 'TCCR4D' was not declared in this scope
PWM_for_Unhold_fast:75: error: 'PLLFRQ' was not declared in this scope
PWM_for_Unhold_fast:79: error: 'OCR4C' was not declared in this scope
PWM_for_Unhold_fast.ino: In function 'void pwmSet6(int)':
PWM_for_Unhold_fast:86: error: 'OCR4D' was not declared in this scope
PWM_for_Unhold_fast:88: error: 'TCCR4C' was not declared in this scope
PWM_for_Unhold_fast.ino: In function 'void loop()':
PWM_for_Unhold_fast:134: error: 'OCR4D' was not declared in this scope

Your code is using Timer4. Nano/328P does not have a fast Timer4.

Steve

Thanks! I will alter the code using timer 1 and try it out.

Ramp at the beginning should be accomplished by a while loop I guess.

Hello!
O.K. I got my Nano working and also tried to migrate the code to timer 1. I also temporarily added a blinking test to see if the new Nano is working properly at all. It does!

Here the code:

/**********************************************************
                Fast PWM Test

Demostrates the generation of high speed PWM
using timers 1
There are two pieces of code:

One for pins 9 using TIMER 1
with frequencies up to 62kHz

History:
  12/12/2014 - Version 1.0
  22/12/2014 - Adding a missing OCR4C value
  

***********************************************************/

/**********************************************************
   Fast PWM on pins 9, (TIMER 1)
   
   Do not use analogWrite to pins 9, 10 or 11 if using 
   this functions as they use the same timer.
   
   Those functions will probably conflict with the 
   servo library.
   
   Uses 5 PWM frequencies between 61Hz and 62.5kHz
   
**********************************************************/

// Frequency modes for TIMER1
#define PWM62k   1   //62500 Hz
#define PWM8k    2   // 7812 Hz
#define PWM1k    3   //  976 Hz
#define PWM244   4   //  244 Hz
#define PWM61    5   //   61 Hz

// Direct PWM change variables
#define PWM9   OCR1A


// Configure the PWM clock
// The argument is one of the 5 previously defined modes
void pwm91011configure(int mode)
{
// TCCR1A configuration
//  00 : Channel A disabled D9
//  00 : Channel B disabled D10
//  00 : Channel C disabled D11
//  01 : Fast PWM 8 bit
TCCR1A=1;

// TCCR1B configuration
// Clock mode and Fast PWM 8 bit
TCCR1B=mode|0x08;  

// TCCR1C configuration
TCCR1C=0;
}

// Set PWM to D9
// Argument is PWM between 0 and 255
void pwmSet9(int value)
{
OCR1A=value;   // Set PWM value
DDRB|=1<<5;    // Set Output Mode B5
TCCR1A|=0x80;  // Activate channel
}


// Start of demostration code
// Generates 4 PWM signals, two constant and two variable

void setup()
{


// Configure Timer 1 (Pins 9)
// It will operate at 62kHz
// Valid options are: 
//      PWM62k, PWM8k, PWM1k, PWM244 and PWM61
pwm91011configure(PWM62k);



// Pins 9 will change value in the loop function
// We first configure them

// Prepare pin 9 to use PWM
// We need to call pwm91011configure
// For now, we set it at 0%
pwmSet9(0);
}

int value=255;

void loop()
{
// Set PWM at pins 9
// Those fast macros require a previous configuration
// of the channels using the pwmSet9
// functions
// The functions pwmSet9 acan be used
// instead, but the PWM9 and PWM6 macros are faster
// to execute
PWM9=value;
  
// Increment PWM value and return to 0 after 255
value=(value-10)%256;
//value=RPM2PWM(3000);
//value=70;
// Small 10ms delay
delay(100);

}

Unfortunately the motor is not responding as it does to my Leonardo. I switched also the hardware to pin9, not only the code but no motion. Did I overlook something in the code or concerning the Nano?

Thanks and Greetings

Florian

To close this thread here:
I got the code working using timer 1 at 67kHz and I eaven implemented a ramp at the beginning and a speed change every 2 minutes for 15 seconds. So far so good. Thanks to all contributors.

I am now struggling to migrate this code to the Nano V3 that fits into the housing of my sous-vide-stick. But as this is a different issue I have put it into this thread:

Here is the code I am now successfully running on my Leonardo:

/**********************************************************
                Fast PWM Test

Demostrates the generation of high speed PWM
using timers 1
There are two pieces of code:

One for pins 91 using TIMER 1
with frequencies up to 62kHz

History:
  12/12/2014 - Version 1.0
  22/12/2014 - Adding a missing OCR4C value
  
  Works with Leonardo
  

***********************************************************/

/**********************************************************
   Fast PWM on pins 9, (TIMER 1)
   
   Do not use analogWrite to pins 9, 10 or 11 if using 
   this functions as they use the same timer.
   
   Those functions will probably conflict with the 
   servo library.
   
   Uses 5 PWM frequencies between 61Hz and 62.5kHz
   
**********************************************************/

// Frequency modes for TIMER1
#define PWM62k   1   //62500 Hz
#define PWM8k    2   // 7812 Hz
#define PWM1k    3   //  976 Hz
#define PWM244   4   //  244 Hz
#define PWM61    5   //   61 Hz

// Direct PWM change variables
#define PWM9   OCR1A


// Configure the PWM clock
// The argument is one of the 5 previously defined modes
void pwm91011configure(int mode)
{
// TCCR1A configuration
//  00 : Channel A disabled D9
//  00 : Channel B disabled D10
//  00 : Channel C disabled D11
//  01 : Fast PWM 8 bit
TCCR1A=1;

// TCCR1B configuration
// Clock mode and Fast PWM 8 bit
TCCR1B=mode|0x08;  

// TCCR1C configuration
TCCR1C=0;
}

// Set PWM to D9
// Argument is PWM between 0 and 255
void pwmSet9(int value)
{
OCR1A=value;   // Set PWM value
DDRB|=1<<5;    // Set Output Mode B5
TCCR1A|=0x80;  // Activate channel
}

// Generates 4 PWM signals, two constant and two variable

void setup()
{



// Configure Timer 1 (Pins 9)
// It will operate at 62kHz
// Valid options are: 
//      PWM62k, PWM8k, PWM1k, PWM244 and PWM61
pwm91011configure(PWM62k);



// Pins 9 will change value in the loop function
// We first configure them
// Prepare pin 9 to use PWM
// We need to call pwm91011configure
// For now, we set it at 0%
pwmSet9(0);
}

int value=255;
int steadyrpm=21; // =4900rpm
int steadytime=1200;   // Divide by 10 to get seconds here 2 min
int lowtime=150;      // Divide by 10 to get seconds here 15 sec
int counter=0;
int phase=1;


void loop()
{
// Set PWM at pins 9
// Those fast macros require a previous configuration
// of the channels using the pwmSet9
// functions
// The functions pwmSet9 acan be used
// instead, but the PWM9 and PWM6 macros are faster
// to execute
PWM9=value;
switch(phase){
  case 1:
    // Increment PWM value and return from 255 to steadyrpm=21
    value=(value-10)%256;
    if (value<steadyrpm)
      {
        phase=5;
      }
    // Small 100ms delay
    delay(100);
  break;
    
  case 2:
     value=(steadyrpm-15); // 5300 rmp = 21-15
     counter=counter+1;
     if (counter>lowtime)
      {
        phase=5;
        counter=0;
      }
    delay(100);
  break;
    
  default:
    value=(steadyrpm);
    counter=counter+1;
     if (counter>steadytime)
      {
        phase=2;
        counter=0;
      }
    delay(100);
    break;
  }
}