Плавное увеличение оборотов мотора

AlekseyS
Offline
Зарегистрирован: 25.01.2015

Всем здравствуйте, помогите пожалуйста по другому реализовать код программы не задействуя delay();

for (int i = 55; i > 255; i += 10)
 { 
analogWrite(motor1, i); 
analogWrite(motor2, i); 
delay(1000);
 }

нужно что бы мотор плавно набирал скорость в течение заданного времяни, в данном случае 1 секунды.

 

bwn
Offline
Зарегистрирован: 25.08.2014
bwn
Offline
Зарегистрирован: 25.08.2014

Хотя по вашему коду, он набирает обороты 20 секунд. Если за секунду, то delay(50);

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

В первой строке опечатка или как? Если нет, то мотор с места вообще не сдвинется.

AlekseyS
Offline
Зарегистрирован: 25.01.2015

стыдно признаться, но я никак не могу понять как мне применить  эту часть кода

{
unsigned long currentMillis = millis();
 if(currentMillis - previousMillis > interval)
{
 previousMillis = currentMillis; 
...}

помогите пожалуйсто, мотор должен набрать скорость и продолжать с этой скоростью работать

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А во время набора скорости иные действия выполнять требуется?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Если нет, то просто в первой строке меняете > на <, а delay(1000) меняете на delay(50) Мотор разгонется за секунду с "55 до 255"

AlekseyS
Offline
Зарегистрирован: 25.01.2015

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

bwn
Offline
Зарегистрирован: 25.08.2014

AlekseyS пишет:

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

Вам тогда лучше это if-ами организовывать. For в таком варианте не очень подходит.

AlekseyS
Offline
Зарегистрирован: 25.01.2015

как это должно выглядеть?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Что-то вроде этого в упрощенном варианте

Для отладки команды давал с терминала. Даём 1 мотор раскручивается. Даём 3 мотор останавливается. состояние 0 и 2 для внутренних нужд, чтобы смотреть что там с мотором.

Для ознакомления сойдет, а дальше уже под Ваши нужды затачивайте.

/////////////////////////////////////////
// MotorState
// 0 - остановлен
// 1 - запуск, набор оборотов
// 2 - запущен, обороты набраны
// 3 - остановка
/////////////////////////////////////////
byte Motor1State = 0;
byte Motor1CurrentSpeed = 55;
long previousMillis = 0;

long interval = 50;
 
void setup()
{
  Serial.begin(9600);
}
 
void loop()
{
  if(Serial.available())
  {
    char inByte = (char)Serial.read();
    switch (inByte)
    {
      case '1':
        Motor1State = 1;
      break;
      case '3':
        Motor1State = 3;
      break;
    }
  }
  if(Motor1State==1)
  {
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval)
    {
      previousMillis = currentMillis;
      analogWrite(motor1, Motor1CurrentSpeed);
      Serial.println(Motor1CurrentSpeed);
      Motor1CurrentSpeed+=10;
      if(Motor1CurrentSpeed<55)
      {
        Motor1State=2;
        Motor1CurrentSpeed=255;
      }
    }
  }
  if(Motor1State==3)
  {
    Motor1CurrentSpeed=0;
    analogWrite(motor1, Motor1CurrentSpeed);    
    Motor1CurrentSpeed=55;
    Motor1State=0;
    Serial.println("motor stop");
  }
}

 

AlekseyS
Offline
Зарегистрирован: 25.01.2015
const int IN1 =  11;      
long previousMillis = 0;        
long interval = 100; 
int i=55; 
void setup() {
  pinMode(IN1, OUTPUT);     
}
 
void loop()
{
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 
    i += 10;
      analogWrite(IN1, i);
    }
}

набирает максимальные обороты, затем стоп и заново, как сделать чтобы, набрав обороты продолжал работать на максимуме

AlekseyS
Offline
Зарегистрирован: 25.01.2015

большое спасибо, попробую использовать данный вами код

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Только у меня там в сетап пинМоде не устанавливается для motor1, но это Вы уже и сами знаете :)

AlekseyS
Offline
Зарегистрирован: 25.01.2015

снова я, мотор набирает обороты, останавливается и снова в цикле... 

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

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А код можно глянуть?

AlekseyS
Offline
Зарегистрирован: 25.01.2015
#include <SoftwareSerial.h> 
char vcmd; 
SoftwareSerial BTSerial(0, 1); // RX, TX
int IN1 = 11; 
long previousMillis = 0;        
long interval = 50; 
int i=55;
byte cmd=0;

void setup() {
  BTSerial.begin(9600); 
  pinMode (IN1, OUTPUT);
}

void loop() 
{
  if (BTSerial.available()) 
  { 
        vcmd = (char)BTSerial.read(); 
         Serial.println(vcmd);
         switch (vcmd)
          {
            case 'F':
              cmd = 1;
             break;
            case 'S':
              cmd = 3;
             break;
         }
  }
    if (cmd == 1) 
   {
     unsigned long currentMillis = millis();
     if(currentMillis - previousMillis > interval) 
      {
      previousMillis = currentMillis; 
      analogWrite(IN1, i);
       i += 10;
        if (i<55){ i=255; }
         }
    } 
   if(cmd == 3)
    {
    i=0; 
    analogWrite(IN1, i); 
    i=55; 
    cmd=0;
      } 
}
Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

cmd это не просто команда это состояние мотора а значит в 39 строчке надо изменить это состояние присвоим cmd 2

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

if (i<55){ i=255; cmd=2;}

и еще i должна быть byte если хотите оставить int (хотя смысла в этом нет) то условие надо поменять и написать так if (i>255){ i=255; cmd=2;}

AlekseyS
Offline
Зарегистрирован: 25.01.2015

присвоил состояние

#include <SoftwareSerial.h> // Подключаем библиотеку для работы с Serial через дискретные порты
char vcmd; // Создаем переменную для команд Bluetooth 

SoftwareSerial BTSerial(0, 1); // RX, TX

int IN1 = 11; 

long previousMillis = 0;        
long interval = 50; 
int i=55;
byte cmd=0;

void setup() {
  BTSerial.begin(9600); 
  pinMode (IN1, OUTPUT);
}

void loop() 
{

  if (BTSerial.available()) 
  { 
        vcmd = (char)BTSerial.read(); 
         Serial.println(vcmd);
         switch (vcmd)
          {
            case 'F':
              cmd = 1;
             break;
            case 'S':
              cmd = 3;
             break;
         }
  }
    if (cmd == 1) 
   {
     unsigned long currentMillis = millis();
     if(currentMillis - previousMillis > interval) 
      {
      previousMillis = currentMillis; 
      analogWrite(IN1, i);
       i += 10;
        if (i<55)
         { 
           cmd=2; 
           i=255; 
              }
         }
    } 
   if(cmd == 3)
    {
    i=0; 
    analogWrite(IN1, i); 
    i=55; 
    cmd=0;
      } 
}

 

AlekseyS
Offline
Зарегистрирован: 25.01.2015

изменений в поведения мотора нет, зацикленно набирает обороты, стоп и всё снова

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Я там в посте выше добавил про тип данных либо изменение условия, это важно

AlekseyS
Offline
Зарегистрирован: 25.01.2015

помогло int i=55; , работает, а if (i<55){ i=255; cmd=2;} char i=55; -то же самое что и было

if (i>255)
         { 
           i=255;
           cmd=2;
          }

 

AlekseyS
Offline
Зарегистрирован: 25.01.2015

я соврал, где то глупость у меня,  сейчас посмотрю

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

char тоже нельзя он максимум до 127 а у вас 255. Оставляйте int i =55; и условие if(i>255) 

if(i<55) будет работать только когда напишете byte i=55 сверху. Именно byte а не char

AlekseyS
Offline
Зарегистрирован: 25.01.2015

вообщем вроди бы всё как надо, но меня смущает скорость двигателя, как то медленно крутит, хотя показания с порта похожи на правду

#include <SoftwareSerial.h> // Подключаем библиотеку для работы с Serial через дискретные порты
char vcmd; // Создаем переменную для команд Bluetooth 

SoftwareSerial BTSerial(0, 1); // RX, TX

int IN1 = 11; 

long previousMillis = 0;        
long interval = 50; 
int i=55;
byte cmd=0;

void setup() {
  Serial.begin(9600);
  BTSerial.begin(9600); 
  pinMode (IN1, OUTPUT);
}

void loop() 
{

  if (BTSerial.available()) 
  { 
        vcmd = (char)BTSerial.read(); 
         Serial.println(vcmd);
         switch (vcmd)
          {
            case 'F':
              cmd = 1;
             break;
            case 'S':
              cmd = 3;
             break;
         }
  }
    if (cmd == 1) 
   {
     unsigned long currentMillis = millis();
     if(currentMillis - previousMillis > interval) 
      {
      previousMillis = currentMillis; 
      analogWrite(IN1, i);
      Serial.println(i);
       i += 10;
        if (i>255)
         { 
           i=255;
           cmd=2;
          Serial.println(i); 
           }
         }
    } 
   if(cmd == 3)
    {
    i=0; 
    analogWrite(IN1, i); 
    i=55; 
    cmd=0;
      } 
}

ОГРОМНОЕ СПАСИБО ЗА ПОМОЩЬ, только я так и не понял, как это читать, теряюсь в понимание что происходит тут)

unsigned long currentMillis = millis();
     if(currentMillis - previousMillis > interval) 
      {
      previousMillis = currentMillis; 
      analogWrite(IN1, i);
      Serial.println(i);
       i += 10;
        if (i>255)
         { 
           i=255;
           cmd=2;
          }

 

AlekseyS
Offline
Зарегистрирован: 25.01.2015

не внимательный я, сейчас попробую поменять на byte

AlekseyS
Offline
Зарегистрирован: 25.01.2015

вы правы попробывал и так и так работает как и нужно, ещё раз ОГРОМНОЕ СПАСИБО!!!

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Насчёт скорости даже не знаю, можно ШИМ осциллографом глянуть, если ШИМ нормальный, то смотреть питание двигателя, может просто питания не хватает.

А читается там всё просто: в переменную currentMillis записываем сколько миллисекунд прошло с момента запуска программы. Далее (в условии if) смотрим разницу между текущим показанием и предыдущим показанием и если оно больше нашего интервала (т.е. мы не выполняли этот код более 50 микросекунд в нашем случае) то выполняем то что надо первым делом запоминаем текущее значение миллисекунд чтобы на следующем цикле сравнить уже с ним. Как то так :) Не умею я объяснять :) Это как в окно смотреть через каждый час. Первый раз посмотрел и запомнил время во сколько посмотрел, второй раз смотришь на часы и от текущего времени отнимаешь то когда смотрел в предыдущий раз, если уже час прошел то смотрим в окно и снова запоминаем во сколько смотрели и так далее по кругу :)

Не быть мне учителем в общем :) Оно и к лучшему.

AlekseyS
Offline
Зарегистрирован: 25.01.2015

обороты упали, потому что в БП конденсатор изжил своё, перепояю и всё будет нормуль, я понял вас, спасибо:)

AlekseyS
Offline
Зарегистрирован: 25.01.2015

в школах и институтах не учится нам, когда училось...) ХОРОШО, ЧТО ЕСТЬ ТАКИЕ КАК ВЫ !!!

AlekseyS
Offline
Зарегистрирован: 25.01.2015

снова я, помогите пожалуйсто добавить ещё один двигатель...

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А работать они должны синхронно? Т.е. запускаться вместе набирать обороты одинаково и тормозиться вместе?

AlekseyS
Offline
Зарегистрирован: 25.01.2015

именно так

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну тогда будем смотреть на код в посте номер 25.

После 6й строки добавляем такуюже строку как 6 ну только соответственно порт второго мотора указываем.

Тоже самое и после 16 строки, настраиваем пин на выход для второго мотора.

Далее после 42 строки вставляем тоже самое что и в 42 тоьлко меняем IN1 на IN2 (ну или название для второго мотора)

И тоже самое после 56 строки.

AlekseyS
Offline
Зарегистрирован: 25.01.2015

я сначало так и сделал, но не работало, второй мотор включался только после того как, первый мотор набирал максимальную скорость вращения, утром всё понял, второй мотор был подключен не к PWM портам. СПАСИБО!

AlekseyS
Offline
Зарегистрирован: 25.01.2015

Снова здравствуйте, помогите, если есть время) очень запутался...

AlekseyS
Offline
Зарегистрирован: 25.01.2015

не получается заставить крутиться один серво при совершение поворота другого

ilnarv
Offline
Зарегистрирован: 09.02.2015

Здраствуйте. Подскажите пожалуйста, хотел что бы плавно набирались обороты моторов а и в итоге при получении команды работает только одна сторона.


#include <CyberLib.h>  // Подключаем библиотеку
#include <Servo.h> // Подключаем библиотеку сервоприводов

Servo myservo1;
Servo myservo2;

int i;
int IN1 = 4; 
int IN2 = 5;
int IN3 = 7;
int IN4 = 6;
int ENA = 3;
int ENB = 9;

uint8_t inByte;

void setup()  
{ 
  myservo1.attach(10); // Подключение сервоприводов к порту
  myservo2.attach(12); // Подключение сервоприводов к порту
   init;  // Инициализация портов
  pinMode (ENA, OUTPUT);
  pinMode (IN1, OUTPUT);
  pinMode (IN2, OUTPUT);
  pinMode (ENB, OUTPUT);
  pinMode (IN4, OUTPUT);
  pinMode (IN3, OUTPUT);
  UART_Init(57600);// Инициализация порта для связи с роутером
}  

void loop()  
{ 
  
  if (UART_ReadByte(inByte)) //Если что то пришло
  {
    switch (inByte)  // Смотрим какая команда пришла
    {  
        case 'x': // Остоновка робота
          analogWrite(ENA, 0);
          analogWrite(ENB, 0);
          
        break; 
        
        case 'S': // Движение вперед
  digitalWrite (IN2, HIGH);
  digitalWrite (IN1, LOW); 
  digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW); 
  for (i = 20; i <= 180; ++i)
  {
      analogWrite(ENA, i);
      analogWrite(ENB, i);
      delay(30);
  }
        break;  
        
        case 'D': // Поворот влево
  digitalWrite (IN1, HIGH);
  digitalWrite (IN2, LOW); 
  digitalWrite (IN3, LOW);
  digitalWrite (IN4, HIGH);
  for (i = 20; i <= 180; ++i)
  {
      analogWrite(ENA, i);
      analogWrite(ENB, i);
      delay(30);
  }
        break;

        case 'A': // Поворот вправо
  digitalWrite (IN1, LOW);
  digitalWrite (IN2, HIGH); 
  digitalWrite (IN3, HIGH);
  digitalWrite (IN4, LOW);
  for (i = 20; i <= 180; ++i)
  {
      analogWrite(ENA, i);
      analogWrite(ENB, i);
      delay(30);
  }
        break; 
        
        case 'W': // Движение назад
  digitalWrite (IN1, HIGH);
  digitalWrite (IN2, LOW); 
  digitalWrite (IN3, HIGH);
  digitalWrite (IN4, LOW);
  for (i = 20; i <= 180; ++i)
  {
      analogWrite(ENA, i);
      analogWrite(ENB, i);
      delay(30);
  }
        break; 
        
        case 'U': // Серво поднимается
          myservo1.write(i -= 10);  
        break; 
        
        case 'J': // Серво опускается
          myservo1.write(i += 10);
        break; 
        
        case 'H': // Серво поворачивается влево
         myservo2.write(i += 10); 
        break; 
        
        case 'K': // Серво поворачивается вправо    
         myservo2.write(i -= 10);
        break; 
       
    }          
  } 
}  

Спасибо.