Как установить текущее положение двигателя постоянного тока равным нулю + сохранить текущие позиции в массиве и запустить его?

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

Я использую плату Genuino UNO, у меня есть 4 двигателя постоянного тока, и каждые 2 колеса подключены к H-мосту.

У меня есть приложение, в котором есть кнопка "сохранить" и кнопка "Выполнить". Что касается кнопки сохранения, то я бы хотел, чтобы она сначала установила текущую позицию для каждого колеса равной нулю, а затем сохранила позиции каждого колеса в массиве. Для кнопки run я бы хотел, чтобы она зацикливалась на массиве, созданном кнопкой save, и показывала вывод на каждом колесе.

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

Надеюсь, теперь все ясно

вот мой код

#include <SoftwareSerial.h>


SoftwareSerial Bluetooth(0, 1); // Arduino (RX, TX) - HC-05 Bluetooth (TX, RX)

// Определите двигатели и контакты  
// Мотор А1

int enA1 = 2;
int in11 = 3;
int in21 = 4;


// Двигатель В1

int enB1 = 5;
int in31 = 6;
int in41 = 7;

//другой H-мост 

// Двигатель A2

int enA2 = 8;
int in12 = 9;
int in22 = 10;


// Двигатель B2

int enB2 = 11;
int in32 = 12;
int in42 = 13;

int wheelSpeed = 125;
int dataIn, m;
//lbw левое заднее колесо / lfw левое переднее колесо / rbw правое заднее колесо / rfw правое переднее колесо
int lbw[50], lfw[50], rbw[50], rfw[50]; // для хранения позиций/шагов
int index = 0;

void setup() {
  // поместите свой установочный код здесь, чтобы запустить один раз:

  Bluetooth.begin(9600); // Скорость передачи данных модуля Bluetooth по умолчанию
  Bluetooth.setTimeout(1);
  Serial.print("connected");
  Serial.print("-------------------");
  delay(20);

  pinMode(enA1, OUTPUT);
  pinMode(enB1, OUTPUT);
  pinMode(in11, OUTPUT);
  pinMode(in21, OUTPUT);
  pinMode(in31, OUTPUT);
  pinMode(in41, OUTPUT);
  pinMode(enA2, OUTPUT);
  pinMode(enB2, OUTPUT);
  pinMode(in12, OUTPUT);
  pinMode(in22, OUTPUT);
  pinMode(in32, OUTPUT);
  pinMode(in42, OUTPUT);
}

void loop() {
  // Проверка входящих данных

 if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.read();  // Считывание данных

    if (dataIn == 0) {
      m = 0;
    }
    if (dataIn == 1) {
      m = 1;
    }
    if (dataIn == 2) {
      m = 2;
    }
    if (dataIn == 3) {
      m = 3;
    }
    if (dataIn == 4) {
      m = 4;
    }
    if (dataIn == 5) {
      m = 5;
    }
    if (dataIn == 6) {
      m = 6;
    }
    if (dataIn == 7) {
      m = 7;
    }
    if (dataIn == 8) {
      m = 8;

    }
    if (dataIn == 9) {
      m = 9;
    }
    if (dataIn == 10) {
      m = 10;
    }
    if (dataIn == 11) {
      m = 11;
    }

    if (dataIn == 12) {
      m = 12;
    }
    if (dataIn == 14) {
      m = 14;
    }
    // Заданная скорость
    if (dataIn >= 16) {
      wheelSpeed = dataIn * 10;
      Serial.println(wheelSpeed);
    }
  }
  if (m == 4) {
    moveSidewaysLeft();
  }
  if (m == 5) {
    moveSidewaysRight();
  }
  if (m == 2) {
    moveForward();
  }
  if (m == 7) {
    moveBackward();
  }
  if (m == 3) {
    moveRightForward();
  }
  if (m == 1) {
    moveLeftForward();
  }
  if (m == 8) {
    moveRightBackward();
  }
  if (m == 6) {
    moveLeftBackward();
  }
  if (m == 9) {
    rotateLeft();
  }
  if (m == 10) {
    rotateRight();
  }

  if (m == 0) {
    stopMoving();
  }
  //Serial.println(dataIn);
  // Если кнопка "СОХРАНИТЬ" нажата
  if (m == 12) {
    if (index == 0) {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, LOW);  
        digitalWrite(in31, LOW);  
        digitalWrite(in41, LOW); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, LOW);  
        digitalWrite(in32, LOW);  
        digitalWrite(in42, LOW); 

    }


    // сохранить позицию в массиве 
  }
  //if (m == 14) {
   // runSteps();
    //if (dataIn != 14) {
      //stopMoving();
      // Очистить данные массива до 0
   // }
  //}

}

//метод чтения массива из того, что было сохранено кнопкой сохранить, и запуска его шаг за шагом
//void runSteps() {}

void moveForward() {
        digitalWrite(in11, HIGH); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, HIGH); 
        digitalWrite(in41, LOW); 
        digitalWrite(in12, HIGH); 
        digitalWrite(in22, LOW); 
        digitalWrite(in32, HIGH); 
        digitalWrite(in42, LOW);
        Serial.println("Motor: move Forward");
}

void moveBackward() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, HIGH); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, HIGH); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, HIGH); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, HIGH);
        Serial.println("Motor: move Backward");
}

void moveSidewaysLeft() {
        digitalWrite(in11, HIGH); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, HIGH); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, HIGH); 
        digitalWrite(in32, HIGH); 
        digitalWrite(in42, LOW);
        Serial.println("Motor: move Sideways Left");
}
void moveSidewaysRight() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, HIGH); 
        digitalWrite(in31, HIGH); 
        digitalWrite(in41, LOW); 
        digitalWrite(in12, HIGH); 
        digitalWrite(in22, LOW); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, HIGH);   
        Serial.println("Motor: move Sideways right");
}

void moveRightForward() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, HIGH); 
        digitalWrite(in41, LOW); 
        digitalWrite(in12, HIGH); 
        digitalWrite(in22, LOW); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, LOW);   
        Serial.println("Motor: move Right Forward");
}


void moveLeftBackward() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, HIGH); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, HIGH); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, LOW);   
        Serial.println("Motor: move left Back ward");
}

void moveLeftForward() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, HIGH); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, HIGH); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, LOW);   
        Serial.println("Motor: move Left Forward");
}

void moveRightBackward() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, HIGH); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, LOW); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, LOW); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, HIGH);   
        Serial.println("Motor: move Right Backward");
}

void rotateLeft() {
        digitalWrite(in11, HIGH); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, HIGH); 
        digitalWrite(in12, HIGH); 
        digitalWrite(in22, LOW); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, HIGH); 
        Serial.println("Motor: rotate Left");
  }

void rotateRight() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, HIGH); 
        digitalWrite(in31, HIGH); 
        digitalWrite(in41, LOW); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, HIGH); 
        digitalWrite(in32, HIGH); 
        digitalWrite(in42, LOW); 
        Serial.println("Motor: rotate Right");
  }

void stopMoving() {
        digitalWrite(in11, LOW); 
        digitalWrite(in21, LOW); 
        digitalWrite(in31, LOW); 
        digitalWrite(in41, LOW); 
        digitalWrite(in12, LOW); 
        digitalWrite(in22, LOW); 
        digitalWrite(in32, LOW); 
        digitalWrite(in42, LOW); 
        Serial.println("Motor: off");
  }

, 👍1

Обсуждение

Двигатель постоянного тока не знает шагов, если только вы не вводите их с помощью чего-то вроде поворотного энкодера, @chrisl

Может быть, вы имеете в виду текущее состояние (т. Е. Содержимое переменных inXX и enXX двигателей постоянного тока вместо "положения"? Я предполагаю, что это так, потому что вы сказали, что хотите сбросить позицию до нуля при событии сохранения, и что вы делаете затем, это устанавливаете inXX all на LOW. Этого было бы легко достичь. Но сохранить текущее положение колес не так-то просто. Затем вы определяете, что означает позиция. Ваши колеса вращаются постоянно, как автомобильные, или они больше похожи на сервоприводы и имеют четко определенное положение в пределах 360 °? (Я думаю, они похожи на автомобильные колеса, когда я вижу прогу.), @Peter Paul Kiefer

Это тип двигателя постоянного тока, который я использую: https://www.amazon.com/Electric-Magnetic-Gearbox-Plastic-Yeeco/dp/B07DQGX369/ref=sr_1_fkmr0_1?keywords=OLatus+DC+BO+Motor+Dual+shaft+Smart+Car+Robot+Gear+Motor+for+Arduino+%282+Pieces%29&qid=1573914307&sr=8-1-fkmr0 Что я подразумеваю под позициями, так это то, что если я нажимаю кнопки, чтобы заставить автомобиль двигаться вперед, влево, затем назад -> все это я хочу сохранить в массиве, чтобы, когда я нажимаю кнопку запуска, он повторил все эти позиции вручную, зацикливаясь в массиве. Надеюсь, вы меня поняли, @Miss Nature

это не объясняет , что означает "позиции" ... вы в основном повторили то, что уже сказали в своем посте, @jsotola


1 ответ


1

Как я понял из ваших комментариев, ваша цель на самом деле состоит не в том, чтобы сохранить фактические положения колес или вашего робота, а в том, чтобы сохранить и повторить действия, которые сделал робот. (Это означает, что здесь у вас нет "положения", а только измерение скорости колеса)

Если это так, то вы можете сохранить это в 2-мерном массиве с формой элемента {speed_wheel_1, speed_wheel2, duration}. Таким образом, каждое действие определяется скоростями обоих колес и продолжительностью действия, например:

Driving forward at full speed for 3s, turn on the spot to the left with half speed for 1.5s, drive a curve with motor left full speed and motor right half speed for 5s

Это приведет к следующим элементам:

{100, 100, 3000}
{-50, 50, 1500}
{100, 50, 5000}

Скорости здесь должны быть указаны в процентах, а длительности - в миллисекундах.


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

Вы получаете скорости из последовательных в переменнуюскорость колеса. Мы не можем видеть, как вы используете эту переменную позже, но вы можете использовать ее каким-то образом, чтобы установить поля скорости нового элемента массива.

Тогда вам нужна продолжительность. В фреймворке Arduino есть функция для этого: millis(). Он вернет количество миллисекунд с момента запуска, как часы. При запуске действия (при получении соответствующей последовательной команды) необходимо установить метку времени:

unsigned long timestamp;
...
timestamp = millis();

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

Таким образом, соответствующие части кода будут выглядеть следующим образом:

unsigned long timestamp = 0; // Define timestamp at global scope
unsigned int current_element = 0; // Переменная для отслеживания текущего элемента массива
int actions[10][3]; // Массив для хранения до 10 действий

void start_action(byte speed_left, byte speed_right){
    actions[current_element][0] = speed_left;
    actions[current_element][1] = speed_right;
    timestamp = millis();
    // Начните действие с указанных скоростей здесь
}

void end_action(unsigned int element_index){
    actions[current_element][2] = millis() - timestamp;
    current_element++;
    if(current_element >= 10){
        // Сделайте что-нибудь, чтобы предотвратить новые действия. Может быть, просто отключить запись.
}

Для повторения действий вам просто нужно пройтись по массиву и установить соответствующие скорости на соответствующее время.

Если вы хотите пойти навстречу фантазии, вы можете отказаться от 2-мерного массива и вместо этого определить структуру для действия:

struct Action{
    int speed_left;
    int speed_right;
    unsigned long duration;
};

Затем вы можете создать простой массив объектов действия и ссылаться на поля по имени:

Action actions[10];
...
actions[1].duration = millis() - timestamp;
,

большое вам спасибо Я обновил свой вопрос + код. но у меня есть еще одна проблема, если вы можете мне помочь: когда мой телефон отправляет данные (любое число 1-14) через Bluetooth, он не показывает выходные данные на колесах!! пример: когда я нажал кнопку перемещения вперед, которая отправляет номер 2 на модуль Bluetooth, колеса не двигаются., @Miss Nature

Я не знаю, что именно вы отправляете, но я предполагаю, что вы отправляете ASCII "2" по Bluetooth. В вашем коде вы проверяете только десятичные значения считываемых данных. Цифра "2" в кодировке ASCII равна десятичной дроби 50. Теперь вы можете либо изменить код отправки, чтобы отправлять необработанные десятичные значения вместо данных в кодировке ASCII, либо изменить код приема, чтобы он реагировал на данные в кодировке ASCII. Последнее можно сделать, изменив числа в операторах if на соответствующие номера символов ASCII. Или просто записать их как символы: if(dataIn == '2'), @chrisl