Плавный пуск 4 двигателей

Подскажите пожалуйста. У меня есть скетч (не мой). Мне нужно сделать плавный пуск и плавную остановку 4х двигателей через PWM от 100 до 150.

#define PWMA 12    //A Скорость двигателя
#define DIRA1 34 
#define DIRA2 35  //A Направление двигателя
#define PWMB 8    //B Скорость двигателя
#define DIRB1 37 
#define DIRB2 36  //B Направление двигателя
#define PWMC 9   //C Скорость двигателя
#define DIRC1 43 
#define DIRC2 42  //C Направление двигателя
#define PWMD 5    //D Скорость двигателя
#define DIRD1 A4  
#define DIRD2 A5  //D Направление двигателя

//Управление двигателем, вперед, назад, стоп
//левое переднее колесо
#define MOTORA_FORWARD(pwm)    do{digitalWrite(DIRA1,LOW); digitalWrite(DIRA2,HIGH);analogWrite(PWMA,pwm);}while(0)
#define MOTORA_STOP(x)         do{digitalWrite(DIRA1,LOW); digitalWrite(DIRA2,LOW); analogWrite(PWMA,0);}while(0)
#define MOTORA_BACKOFF(pwm)    do{digitalWrite(DIRA1,HIGH);digitalWrite(DIRA2,LOW); analogWrite(PWMA,pwm);}while(0)
//правое переднее колесо
#define MOTORB_FORWARD(pwm)    do{digitalWrite(DIRB1,HIGH); digitalWrite(DIRB2,LOW);analogWrite(PWMB,pwm);}while(0)
#define MOTORB_STOP(x)         do{digitalWrite(DIRB1,LOW); digitalWrite(DIRB2,LOW); analogWrite(PWMB,0);}while(0)
#define MOTORB_BACKOFF(pwm)    do{digitalWrite(DIRB1,LOW);digitalWrite(DIRB2,HIGH); analogWrite(PWMB,pwm);}while(0)
//левое заднее колесо
#define MOTORC_FORWARD(pwm)    do{digitalWrite(DIRC1,LOW); digitalWrite(DIRC2,HIGH);analogWrite(PWMC,pwm);}while(0)
#define MOTORC_STOP(x)         do{digitalWrite(DIRC1,LOW); digitalWrite(DIRC2,LOW); analogWrite(PWMC,0);}while(0)
#define MOTORC_BACKOFF(pwm)    do{digitalWrite(DIRC1,HIGH);digitalWrite(DIRC2,LOW); analogWrite(PWMC,pwm);}while(0)
//правое заднее колесо
#define MOTORD_FORWARD(pwm)    do{digitalWrite(DIRD1,HIGH); digitalWrite(DIRD2,LOW);analogWrite(PWMD,pwm);}while(0)
#define MOTORD_STOP(x)         do{digitalWrite(DIRD1,LOW); digitalWrite(DIRD2,LOW); analogWrite(PWMD,0);}while(0)
#define MOTORD_BACKOFF(pwm)    do{digitalWrite(DIRD1,LOW);digitalWrite(DIRD2,HIGH); analogWrite(PWMD,pwm);}while(0)


#define SERIAL  Serial

//PWM определение параметра
#define MAX_PWM   200
#define MIN_PWM   130

int Motor_PWM = 150;

//Управление движением двигателя Определение макроса

//    ↑A-----B↑   
//     |  ↑  |
//     |  |  |
//    ↑C-----D↑
void ADVANCE()
{
  MOTORA_FORWARD(Motor_PWM);MOTORB_FORWARD(Motor_PWM);    
  MOTORC_FORWARD(Motor_PWM);MOTORD_FORWARD(Motor_PWM);    
}

//    ↓A-----B↓ 
//     |  |  |
//     |  ↓  |
//    ↓C-----D↓
void BACK()
{
  MOTORA_BACKOFF(Motor_PWM);MOTORB_BACKOFF(Motor_PWM);
  MOTORC_BACKOFF(Motor_PWM);MOTORD_BACKOFF(Motor_PWM);
}
//    =A-----B↑   
//     |   ↖ |
//     | ↖   |
//    ↑C-----D=
void LEFT_1()
{
  MOTORA_FORWARD(Motor_PWM);MOTORB_STOP(Motor_PWM);
  MOTORC_STOP(Motor_PWM);MOTORD_FORWARD(Motor_PWM);
}

//    ↓A-----B↑   
//     |  ←  |
//     |  ←  |
//    ↑C-----D↓
void LEFT_2()
{
  MOTORA_BACKOFF(Motor_PWM);MOTORB_FORWARD(Motor_PWM);
  MOTORC_FORWARD(Motor_PWM);MOTORD_BACKOFF(Motor_PWM);
}
//    ↓A-----B=   
//     | ↙   |
//     |   ↙ |
//    =C-----D↓
void LEFT_3()
{
  MOTORA_BACKOFF(Motor_PWM);MOTORB_STOP(Motor_PWM);
  MOTORC_STOP(Motor_PWM);MOTORD_BACKOFF(Motor_PWM);
}
//    ↑A-----B=   
//     | ↗   |
//     |   ↗ |
//    =C-----D↑
void RIGHT_1()
{
  MOTORA_FORWARD(Motor_PWM);MOTORB_STOP(Motor_PWM);
  MOTORC_STOP(Motor_PWM);MOTORD_FORWARD(Motor_PWM);
}
//    ↑A-----B↓   
//     |  →  |
//     |  →  |
//    ↓C-----D↑
void RIGHT_2()
{
  MOTORA_FORWARD(Motor_PWM);MOTORB_BACKOFF(Motor_PWM);
  MOTORC_BACKOFF(Motor_PWM);MOTORD_FORWARD(Motor_PWM);
}
//    =A-----B↓   
//     |   ↘ |
//     | ↘   |
//    ↓C-----D=
void RIGHT_3()
{
  MOTORA_STOP(Motor_PWM);MOTORB_BACKOFF(Motor_PWM);
  MOTORC_BACKOFF(Motor_PWM);MOTORD_STOP(Motor_PWM);
}

//    ↑A-----B↓   
//     | ↗ ↘ |
//     | ↖ ↙ |
//    ↑C-----D↓
void rotate_1(uint8_t pwm_A,uint8_t pwm_B,uint8_t pwm_C,uint8_t pwm_D)
{
  MOTORA_BACKOFF(pwm_A);MOTORB_FORWARD(pwm_B);
  MOTORC_FORWARD(pwm_C);MOTORD_BACKOFF(pwm_D);
}

//    ↓A-----B↑   
//     | ↙ ↖ |
//     | ↘ ↗ |
//    ↓C-----D↑
void rotate_2(uint8_t pwm_A,uint8_t pwm_B,uint8_t pwm_C,uint8_t pwm_D)
{
  MOTORA_FORWARD(pwm_A);MOTORB_BACKOFF(pwm_B);
  MOTORC_BACKOFF(pwm_C);MOTORD_FORWARD(pwm_D);
}
//    =A-----B=  
//     |  =  |
//     |  =  |
//    =C-----D=
void STOP()
{
  MOTORA_STOP(Motor_PWM);MOTORB_STOP(Motor_PWM);
  MOTORC_STOP(Motor_PWM);MOTORD_STOP(Motor_PWM);
}

void IO_init()//Определение режима контакта
{
  pinMode(PWMA, OUTPUT);
  pinMode(DIRA1, OUTPUT);pinMode(DIRA2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(DIRB1, OUTPUT);pinMode(DIRB2, OUTPUT);
  pinMode(PWMC, OUTPUT);
  pinMode(DIRC1, OUTPUT);pinMode(DIRC2, OUTPUT);
  pinMode(PWMD, OUTPUT);
  pinMode(DIRD1, OUTPUT);pinMode(DIRD2, OUTPUT);
  pinMode(Trig,OUTPUT);
  pinMode(Echo,INPUT);
  STOP();
}

void setup()
{
  SERIAL.begin(9600);
}
void loop()
{
    
        ADVANCE();
     
}  ```

Хорошо.

вот так как-то

1 лайк

Понял. Спасибо большое.

задержку подобрать

1 лайк

Я написал подобный скетч для LED. И сталкнулся с проблемой, что он плавно загарается но после этого начинает цикл заного. Я не знаю как его остановить, чтобы он горел.

#define LED_START(pwm) do{analogWrite(LED_PIN, pwm);}while(0)
#define SERIAL Serial 

//int LED_PWM = 20; //начальное значение ШИМ
void LED_LIGHT(){
for (int i = 0; i <= 200; i++){
LED_START(i);
delay(30);
}
} 

void IO_init(){
pinMode(LED_PIN, OUTPUT);
} 

void setup(){ 
SERIAL.begin(9600)
} 

void loop() { 
LED_LIGHT()
}```

После 21 строки поставь
while(1);

1 лайк

Вроде разобрался. Но если будут советы как сделать проще, буду рад услышать.

#define LED_START(pwm) do{analogWrite(LED_PIN, pwm);}while(0)
#define SERIAL Serial 

int LED_PWM = 100; //начальное значение ШИМ
int i;

void LED_LIGHT(){
if(i<100){
for (i = 0; i <= 100; i++){
LED_START(i);
delay(30);
}
} 
else{
LED_START(LED_PWM);
}
}


void IO_init(){
pinMode(LED_PIN, OUTPUT);
} 

void setup(){ 
SERIAL.begin(9600)
} 

void loop() { 
LED_LIGHT()
}```

Большое спасибо.

  1. Зачем в первой строке do-while?
  2. Зачем нужна вторая строка?
  3. В тексте несколько раз встречаются константы 100. Это одна константа или разные?
  4. Переменная i встречается в единственном месте, зачем она глобальная?
  5. На строчках 14-16 можно сэкономить.
  6. Функция IO_init ниоткуда не вызывается.
  7. SERIAL инициализируется, но нигде не используется.
1 лайк

Этот скетч используется исключительно для проверки работоспособности. Основной скетч в первом сообщении темы.
Согласен, есть много лишнего, просто копипаст).
Пункты 3, 4, 5 очени помогут. Спасибо.

Самое смешное, что неупомянутые пункты 1, 2, 6 и 7 все до единого относятся и к “основному” скетчу. (хотя “вторая строка” в “основном” скетче имеет номер 33)

1 лайк

Не буду даже оправдываться) потому что сам не знаю ответы на эти пункты)))
Я совсем новичок, скетч не мой, я его взял за основу. звучит как оправдание
Планы намного грандиознее. Надеюсь со временем пойму зачем это там нужно и применю. Ну или нет)))
Как я уже сказал, я благодарен за любые советы и любую критику.

А не кажется Вам, что при управлении двигателем по ШИМ очень много будет разных помех? (особенно по питанию). Коммутация будет на индуктивную нагрузку с частотой несколько кГц. Может проще для каждого двигателя поставить по 4 оптрона и каждый оптрон, когда включен будет последовательно с мотором включать резистор. А при работе резистор будет отсутствовать. Поскольку разгон и торможение занимают мало по времени, то и резисторы будут маленькие. Такой Принцип сделан у электрических погрузчиков.
1 скорость напряжение на двигатель 40в с пусковым резистором.
2 скорость напряжение на двигателе 40в без резистора.
3 скорость напряжение батареи 2 шт по 40в включенные последовательно итого 80в на двигателе.

1 лайк

Очень надеюсь, что шилд драйвера моторов на базе двух tb6612 с отдельным питанием справится с четыремя двигателями 12v. Если нет, буду переделывать)

Сталкнулся с новой проблемой. Мне нужно добавить кнопку, и после однократного нажатия должен выполняться код. Кнопку собрал (кнопка возвратная). Но я не знаю как запомнить что я уже нажимал кнопку чтобы код выполнялся дальше по кругу игнорируя ожидание нажатия.

#define LED_PIN 44
#define BUTTOM 48
#define LED_START(pwm) do{analogWrite(LED_PIN, pwm);}while(0) 
#define LED_STOP(x) do{analogWrite(LED_PIN,0);}while(0)

int LED_PWM = 100; 
int i = 0;

void LED_LIGHT(){
if(i<100){
for (int i = 0; i <= 100; i++){
LED_START(i);
delay(30);
}
} 
else{
LED_START(LED_PWM);
}
}

void LED_BACK(){
i = 0;
LED_STOP(i);
}

void IO_init(){
pinMode(LED_PIN, OUTPUT);
} 

void setup(){ } 

void loop() { 
if(digitalRead(BUTTOM)==HIGH){
delay(10);
return;
}
LED_LIGHT();
delay(5000);
LED_BACK();
delay(3000);
} 

Заранее извеняюсь за ужас, но так надо пока что))) спасибо за понимание).

bool neNajimal = true;
...

if (neNajimal  && ....) {
  neNajimal  = false;
}
1 лайк

Только

static bool neNajimal = true;
1 лайк

Вроде получилось и даже работает. Спасибо вам. Но мне кажется я написал не так как вы имели ввиду. Я написал вот так…

....
bool neNajimal = true;
....
void loop(){
if(neNajimal && digitalRead(BUTTOM)==HIGH){
delay(10);
return;
}

neNajimal = false;

LED_LIGHT();
delay(5000);
LED_BACK();
delay(3000);
}

10 строку нужно переставить перед строкой 7, видимо