Controlling a BLDC motor with an Arduino and simpleFOCmini, code?

What code can I use to get an adjustable constant rotation out of this simpleFOCmini setup? I will use a simple switch to start and stop the motor. Please just a simple answer will do, if you have the code for this I'd really appreciate it. Seems like it should be pretty short.

Thanks!

NOTE: I have tried several sketches from the Arduino site of course, but nothing worked.
I do NOT want to use an encoder, sketches in the simpleFOC pages use an encoder.
The motor I use works fine, I used it in a setup with an L298N.

I don't think you can use SimpleFOC without an encoder.

It seems you are just swapping one motor driver for another, so can you adapt the code you had for L298N?

ETA: Just checked on SimpleFOC site and it does have an open loop (no encoder) mode, there is an example at Velocity Open-Loop | Arduino-FOC

Hi and thank you very much for your response!

You are correct, I am just swapping one driver for another. I would love to use the simpleFOCmini though because it's much smaller than the L298. I tried to adapt the code I used with the L298 but it didn't work for some reason. Could be me, I'm definitely not an expert coder.

I tried the open loop sketch from the SimpleFOC site, that didn't work either :frowning: I couldn't find a diagram without encoder... do you know if the hookups/wiring would be the same as "with" encoder, minus the encoder wires?

Thank you again! O.

Bobcousins, I checked out the link you sent. Thank you, I hadn't seen that yet, gonna try that as soon as I have a moment.

Here's my L298 setup, speed is controlled by the code, I use a push button to actuate the motor. That's really ALL I need it to do for this project, nothing fancy...
(hopefully the anim. GIF works)

BLDC_L298

https://electronoobs.com/eng_arduino_tut176.php

Thanks a bunch, I will check that out!

If you'd like to include a variable for adjustable speed with a potentiometer (assuming you meant "save max" as a variable name), you can modify the code as follows:

cppCopy code

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);  // Specify the motor pin
float speed = 0.0;  // Adjustable speed variable

void setup() {
  Serial.begin(115200);
  
  motor.linkSwitch(2);  // Link the switch to pin 2
}

void loop() {
  if (digitalRead(2) == HIGH) {
    motor.init();
    speed = analogRead(A0) / 1023.0;  // Read the potentiometer for adjustable speed (assuming it's connected to A0)
    motor.rotate(speed);  // Set the rotation speed based on the potentiometer reading
  } else {
    motor.rotate(0);  // Stop the motor when the switch is turned off
  }
}

This modification includes a potentiometer connected to analog pin A0 to control the motor speed. Adjust the potentiometer to change the rotation speed when the switch is turned on. Feel free to adapt the code further based on your specific requirements. If you have any more questions or need assistance, let me know!

Thank you Savemax, for taking the time to respond.

Being able to adjust the motor speed with a pot would be very nice (although not required for my project). Unfortunately, code without schematics is not so helpful for me. I'm not advanced enough yet to be able to place what you sent in context to make it work. Is what you sent a complete sketch or is it meant to be added to an existing existing code? What would be the schematic for it?

That said, I have succeeded in making my motor spin and I can adjust the speed pretty efficiently by tweaking and simplifying the code in the Electronoobs sketch I'm using (see my response to ZX80 above).
SFOCmini_2_480

Thank you Z80, the link you sent solved my issue! I was able to make my BLDC spin and adjust its (constant) rotation speed by modifying the code in that sketch (see below). I watched the long video also somehow I was able to understand enough of the “open loop” section to make it work.

Much much appreciated!
SFOCmini_2_480

const int Enable_Pin = 8;         // Enable pin for the driver
const int Motor_phase_A = 9;      //Pin for driver input of phase A
const int Motor_phase_B = 10;     //Pin for driver input of phase B
const int Motor_phase_C = 11;     //Pin for driver input of phase C

//Variables used in the code
int16_t SINE_A = 0;               //Initial angle value of the phase A
int16_t SINE_B = 120;             //Initial angle value of the phase B
int16_t SINE_C = 240;             //Initial angle value of the phase C
int poles = 11;                   /*Amount of poles of the motor (change this value if the motor is not
                                  getting to a full rotation. For example, my motor has 28 poles but I had
                                  to add "11" in order to make a full rotation*/
uint32_t adc_read = 0;            //Variable to store the pot ADC value.

                                 

void setup() {
  Serial.begin(9600);
  //We need to set the PWM frequency to be the same for all 3 pins D9, D10 and D11
  TCCR0B = TCCR0B & 0b11111000 | 0x03 ; // Changing would affect millis() and delay() so better to leave it default (0x03).
  TCCR1B = TCCR1B & 0b11111000 | 0x01;  // Set PWM frequency at 31250Hz for D9 and 10, (0x03 is default value, gives 490 Hz).
  TCCR2B = TCCR2B & 0b11111000 | 0x01;  // Set PWM frequency at 31250Hz for D11 D3, (0x03 is default value, gives 490 Hz).
 
  pinMode(Motor_phase_A, OUTPUT);
  pinMode(Motor_phase_B, OUTPUT);
  pinMode(Motor_phase_C, OUTPUT);
  pinMode(Enable_Pin, OUTPUT);
  digitalWrite(Enable_Pin, HIGH);
}
 
void loop() {
  moving(); // The motor is moving. 
}



void moving()
{   
  SINE_A = SINE_A + 3;      //Add # so the rotation will continue # by # | ADJUSTS THE MOTOR SPEED 1 and up
  SINE_B = SINE_A + 120;    //We have a 120 phase difference betweeen phase A and B
  SINE_C = SINE_B + 120;    //We have a 120 phase difference betweeen phase B and C
   
  //Range calculation of Sine Signal
  SINE_A = SINE_A%360;    //Keep the values between 0 and 359
  SINE_B = SINE_B%360;    //Keep the values between 0 and 359
  SINE_C = SINE_C%360;    //Keep the values between 0 and 359
 
  //Calculate the PWM values for creating a sine signal (SPWM)
  int SINE_A_PWM = sin((double)SINE_A*PI/180)*127.5+127.5;  //Multiply by PI and divide by 180 in order to pass from degrees to radians
  int SINE_B_PWM = sin((double)SINE_B*PI/180)*127.5+127.5;  //Multiply by 127.5 and add 127.5 in order to keep the range between 0-255
  int SINE_C_PWM = sin((double)SINE_C*PI/180)*127.5+127.5;  //Sine values between -1 and 1 are placed between 0-255 for PWM. 

  analogWrite(Motor_phase_A, SINE_A_PWM*0.7);               //You might change the 0.7 value for more torque...
  analogWrite(Motor_phase_B, SINE_B_PWM*0.7);               //You might change the 0.7 value for more torque...
  analogWrite(Motor_phase_C, SINE_C_PWM*0.7);               //You might change the 0.7 value for more torque...

 
}

In the code I attached in my previous response, I adjust the speed in:

where "3" adjusts the speed. The original value is 1 which is very slow. 3 is faster and suited for my project. The original code also included a potentiometer, I took that out for memory sake.

Hey I have the same simple FOC board and I am making use of the same code, I only changed a pin value and for some reason, it's not moving the motor, there's even no resistance to rotating the motor rotor.

I'm currently not sure what could be wrong, I feel it could be the motor itself, the rating of the motor is not suitable for the driver board. That's what I think. Do you have any other suggestions?

I'm far from an expert but it seems to me like you should get some kind of resistance out of your motor, even if it's not spinning when you turn on your circuit. How many coils does your motor have? mine has 12, 3 groups of 4 I guess since it's a 3-wire. Might have to do with it not actuating.

yeah it was indeed the motor, the board couldn't overcome its resistance to the motor and an over-current protection was being triggered, so I switched to using a gimbal motor which works well with the driver, it doesn't go very fast but it spins smoothly

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