Как установить текущее положение двигателя постоянного тока равным нулю + сохранить текущие позиции в массиве и запустить его?
Я хотел бы знать, как установить текущее положение двигателей постоянного тока равным нулю и сохранить текущее положение в массиве. после этого я хотел бы, чтобы он зацикливался в массиве, чтобы выполнить все шаги, которые были сохранены в массиве?
Я использую плату 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");
}
@Miss Nature, 👍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
- Как вернуть значение массива символов в функции Arduino IDE?
- avrdude ser_open() can't set com-state
- Float печатается только 2 десятичных знака после запятой
- ошибка: espcomm_upload_mem failed при загрузке скетча
- Печать массива байтов на экране последовательного монитора Arduino IDE
- Разные и самые быстрые способы вычисления синусов и косинусов в Arduino
- Arduino IDE Отказано В Разрешении На Загрузку, Ubuntu
- Нет заголовочных файлов (.h) в Documents\Arduino\libraries\arduino_144469 с демонстрационным кодом
Двигатель постоянного тока не знает шагов, если только вы не вводите их с помощью чего-то вроде поворотного энкодера, @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