Плавная регулировка набора скорости бесщёточного мотора

Возьми формулу приведенного графика, в параметр подставляй значение analogRead(), а результатом корми мотор.

Даже если я скопирую скетч от AlexGyver, она мне не поможет в моей ситуации.
А шимановские звёздочки и цепи дороговато выходят по ценам при их выходе из строя.

Будь другом, вставь код правильно, если хочешь, чтобы его кто-нибудь посмотрел. Неоформленный код разбирать никто не будет

1 лайк

Спасибо за поправку.
Сейчас постараюсь.

#include <Servo.h>
 
Servo motor;
//Пин подключения мотора
int mot_pin = 9;
 
//Максимальное значение ШИМ 2.3 мс
int max_pwm = 1940;
 
//Минимальное значени ШИМ 0.8 мс
int min_pwm = 980;
int Speed;
 
void setup(){
  // запуск последовательного порта
  Serial.begin(9600);
  // инициализация мотора
  motor.attach(mot_pin);
  // калибровка
  delay(1000);
  motor.writeMicroseconds(max_pwm);
  delay(2000);
  motor.writeMicroseconds(min_pwm);
  delay(4000);
}
void loop() {
  Speed = analogRead(A1);
  Speed = map(Speed,0,1023,0,180);
  motor.write(Speed);
}  
 

Молодец!

Первый раз вижу такие правила отправки…
Наконец-то понял!

Всем спасибо за посильную помощь!!!

А вот для этого:

У тебя есть более понятный график, с циферками?

Чтобы можно было на что-то “опираться”, не от “болды” же писать?

Сейчас все что описано в коде примерно такое:

Совершенно верно!
График я сам взял от болды - скопировал фото с Гугла.
А хотелось бы подставить одну четверть от окружности. Это был бы наилучший вариант

ну как сказать, характеристику его мотора никто не видел
я бы для начала замапил ручку газа в 50%

void loop() {
  Speed = analogRead(A1)/2;
  Speed = map(Speed,0,1023,0,180);
  motor.write(Speed);
}
1 лайк

Характеристики моего мотора есть!!!
Я отправлю ссылку - можно будет глянуть.
Извините! Сегодня я буду уже без связи.
До связи!

Хочешь квадратичный график - возведи в квадрат значение с потенциометра и отнормируй на диапазон сервы.
Это все. Две строки

Вот эту хотелку желательно сформулировать в более понятных физических терминах.
Например:

  • хочу, чтобы напряжение на моторе было в 3 раза меньше, чем сейчас.
  • хочу, чтобы мотор реагировал на ручку с запаздыванием,
  • хочу ограничить производную увеличения напряжения величиной 2.3456,
  • хочу ограничить производную изменения напряжения величиной 2.3456,
  • хочу, чтобы при первом старте (указать, что именно подразумевается под первым стартом) напряжение на мотор подавалось плавно (указать, как именно плавно), а в дальнейшем - строго по положению ручки.

напряжение питания какое, 48 вольт?

Напряжение 48.
И полная ручка газа должна быть тоже.
Только на полную велосипед достигает скорости 100 км/ч

парабола, а ты её нарисовал тут точно не пойдёт, тебе от линейной нужно вниз изгибать, самое правильное нарисовать нужный график, закинуть в эксел и посмотреть формулу, а далее по этой формуле делать рассчет, я бы сдел дискретно, к примеру вся ручка газа это 36 значений, далее мапим полученный сигнал в диапазон 0-35, и берём значения из таблицы, ну а в таблице строим 36 значений нужной характеристики, и считать тогда ничего не надо, таблицу можно будет подогнать

Ну, собственно говоря, я так же “от болды” накидал код:

#include <Servo.h>

Servo motor;

#define kof 0.3   // этим коэффициентом "сглаживаем график". Значения от 0.1 до 1.0 (максимум!)

//Пин подключения мотора
int mot_pin = 9;

//Максимальное значение ШИМ 2.3 мс
int max_pwm = 1940;

//Минимальное значени ШИМ 0.8 мс
int min_pwm = 980;
uint32_t Speed;

void setup() {
  // запуск последовательного порта
  Serial.begin(9600);
  // инициализация мотора
  motor.attach(mot_pin);
  // калибровка
  delay(1000);
  motor.writeMicroseconds(max_pwm);
  delay(2000);
  motor.writeMicroseconds(min_pwm);
  delay(4000);
}
void loop() {
  uint32_t tmp;
  uint32_t top;
  Speed = analogRead(A1);
  tmp = map(Speed, 0, 1023, 0, 180);
  Speed = (uint32_t)(kof * (double)square(tmp));
  top = (uint32_t)(kof * (double)(square(180)));
  Speed = map (Speed, 0, top, 0, 180);
  motor.write(Speed);
}

Изменяя значение kof можно делать график более пологим. Я взял значение 0.3 просто “от болды”.

Вот тестовый лог для kof = 0.3:

Спойлер
Read = 10, Speed = 0
Read = 20, Speed = 2
Read = 30, Speed = 5
Read = 40, Speed = 8
Read = 50, Speed = 13
Read = 60, Speed = 20
Read = 70, Speed = 27
Read = 80, Speed = 35
Read = 90, Speed = 45
Read = 100, Speed = 55
Read = 110, Speed = 67
Read = 120, Speed = 80
Read = 130, Speed = 93
Read = 140, Speed = 108
Read = 150, Speed = 125
Read = 160, Speed = 142
Read = 170, Speed = 160
Read = 180, Speed = 180

Вот лог для kof = 0.7:

Спойлер
Read = 10, Speed = 0
Read = 20, Speed = 2
Read = 30, Speed = 5
Read = 40, Speed = 8
Read = 50, Speed = 13
Read = 60, Speed = 20
Read = 70, Speed = 27
Read = 80, Speed = 35
Read = 90, Speed = 45
Read = 100, Speed = 55
Read = 110, Speed = 67
Read = 120, Speed = 80
Read = 130, Speed = 93
Read = 140, Speed = 108
Read = 150, Speed = 125
Read = 160, Speed = 142
Read = 170, Speed = 160
Read = 180, Speed = 180

Ну и kof = 1.0 (больше 1.0 НИЗЗЯЯ !):

Спойлер
Read = 10, Speed = 0
Read = 20, Speed = 2
Read = 30, Speed = 5
Read = 40, Speed = 8
Read = 50, Speed = 13
Read = 60, Speed = 20
Read = 70, Speed = 27
Read = 80, Speed = 35
Read = 90, Speed = 45
Read = 100, Speed = 55
Read = 110, Speed = 67
Read = 120, Speed = 80
Read = 130, Speed = 93
Read = 140, Speed = 108
Read = 150, Speed = 125
Read = 160, Speed = 142
Read = 170, Speed = 160
Read = 180, Speed = 180

Скетч для тестирования данных
#include <Servo.h>

Servo motor;

#define kof 0.3   // этим коэффициентом "сглаживаем график".

//Пин подключения мотора
int mot_pin = 9;

//Максимальное значение ШИМ 2.3 мс
int max_pwm = 1940;

//Минимальное значени ШИМ 0.8 мс
int min_pwm = 980;
uint32_t Speed;

void setup() {
  // запуск последовательного порта
  Serial.begin(9600);
  // инициализация мотора
  motor.attach(mot_pin);
  // калибровка
//  delay(1000);
  motor.writeMicroseconds(max_pwm);
//  delay(2000);
  motor.writeMicroseconds(min_pwm);
//  delay(4000);
}
void loop() {
  uint32_t top;
  static uint32_t tmp = 10;
//  Speed = analogRead(A1);
//  tmp = map(Speed, 0, 1023, 0, 180);
  Speed = (uint32_t)(kof * (double)square(tmp));
  top = (uint32_t) (kof * (double)(square(180)));
  Speed = map (Speed, 0, top, 0, 180);
  motor.write(Speed);
  Serial.print("Read = ");
  Serial.print(tmp);
  Serial.print(", Speed = ");
  Serial.println(Speed);
  tmp += 10;
  if (tmp == 190) {
    while (1);
  }
}

Надеюсь коллеги поправят, если я где-то накосячил сильно…