Здравствуйте. Я начал создавать робота, который работает и автономно. Для создания использовалось: Arduino uno(1 шт.). Motor Shield от Амперки(2 шт.). Ультразвуковой дальномер HC-SR04(1 шт.). Роботизированная платформа(1 шт.). Troyka Shield(1 шт.). Микросервопривод FS90(1 шт.). Bluetooth модуль HC-06(1 шт.). Батарейный отсек(1 шт). Вот код: Код (C++): #include <Ultrasonic.h> #include <Servo.h> #define SPEED_1 5 #define DIR_1 4 #define CON_MOTOR1 0 #define CON_MOTOR2 0 #define TRIGGER_PIN 8 #define ECHO_PIN 9 Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN); #define SPEED_2 6 #define DIR_2 7 #define FORWARD 0 #define BACKWARD 1 #define LEFT 2 #define RIGHT 3 Servo neck; int val; void go(int newDirection, int speed) { boolean motorDirection_1, motorDirection_2; switch ( newDirection ) { case FORWARD: motorDirection_1 = true; motorDirection_2 = true; break; case BACKWARD: motorDirection_1 = false; motorDirection_2 = false; break; case LEFT: motorDirection_1 = true; motorDirection_2 = false; break; case RIGHT: motorDirection_1 = false; motorDirection_2 = true; break; } analogWrite(SPEED_1, speed); analogWrite(SPEED_2, speed); digitalWrite(DIR_1, motorDirection_1); digitalWrite(DIR_2, motorDirection_2); } void robot_avtonomno() { delay(50); float dist_cm = ultrasonic.Ranging(CM); delay(100); if (dist_cm < 35.0) { go(FORWARD, 0); neck.write(180); delay(500); float dist_cm_1 = ultrasonic.Ranging(CM); neck.write(0); delay(500); float dist_cm_2 = ultrasonic.Ranging(CM); if (dist_cm_1 > dist_cm_2) { neck.write(90); delay(200); go(LEFT, 100); delay(600); } else { neck.write(90); delay(200); go(RIGHT, 100); delay(600); } } else { go(FORWARD, 70); } } void robot_upravlenie() { if (Serial.available()) { val = Serial.read(); if (val == 'W') { go(FORWARD, 125); delay(200); } if (val == 'S') { go(BACKWARD, 125); delay(200); } if (val == 'A') { go(LEFT, 90); delay(200); } if (val == 'D') { go(RIGHT, 90); delay(200); } if (val == 'C') { go(FORWARD, 0); } if (val == 'H') { neck.write(90); } if (val == 'M') { neck.write(180); } if (val == 'V') { neck.write(0); } } } void setup() { for (int i = 4; i <= 7; i++) pinMode(i, OUTPUT); neck.attach(2); neck.write(90); Serial.begin(9600); } void loop() { if (Serial.available()) { val = Serial.read(); if (val == '1') { robot_avtonomno(); } else if (val == '2') { robot_upravlenie(); } } } Но робот лишь переключается из режима но полностью не работает. Помогите исправить ошибку, пожалуйста.
Сложно, конечно, гадать что означает "полностью не работает". По коду навскидку есть замечание. Если вы подаете команды вручную, не слитно байт-за-байтом, то получив 2 алгоритм заходит в управление и пока вы пошлете ему букву, уже выходит из управления. Вам следует доработать алгоритм так, что из ваших двух главных процедур управление и автономно алгоритм должен выходить только по принятой специальной команде, пускай Q. Тогда приняв вначале 2, алгоритм будет ждать все последующие ручные медленные команды до получения выхода из ручного режима по Q.
Судя по коду в автономном режиме Вам нужно 1 слать непрерывно. Что бы он ловил ее на каждом цикле. А это режим уже не совсем автономный.
Изменил код на этот: Код (C++): #include <Ultrasonic.h> #include <Servo.h> #define SPEED_1 5 #define DIR_1 4 #define CON_MOTOR1 0 #define CON_MOTOR2 0 #define TRIGGER_PIN 8 #define ECHO_PIN 9 Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN); #define SPEED_2 6 #define DIR_2 7 #define FORWARD 0 #define BACKWARD 1 #define LEFT 2 #define RIGHT 3 Servo neck; int val; void go(int newDirection, int speed) { boolean motorDirection_1, motorDirection_2; switch ( newDirection ) { case FORWARD: motorDirection_1 = true; motorDirection_2 = true; break; case BACKWARD: motorDirection_1 = false; motorDirection_2 = false; break; case LEFT: motorDirection_1 = true; motorDirection_2 = false; break; case RIGHT: motorDirection_1 = false; motorDirection_2 = true; break; } analogWrite(SPEED_1, speed); analogWrite(SPEED_2, speed); digitalWrite(DIR_1, motorDirection_1); digitalWrite(DIR_2, motorDirection_2); } void robot_avtonomno() { delay(50); float dist_cm = ultrasonic.Ranging(CM); delay(100); if (dist_cm < 35.0) { go(FORWARD, 0); neck.write(180); delay(500); float dist_cm_1 = ultrasonic.Ranging(CM); neck.write(0); delay(500); float dist_cm_2 = ultrasonic.Ranging(CM); if (dist_cm_1 > dist_cm_2) { neck.write(90); delay(200); go(LEFT, 100); delay(600); } else { neck.write(90); delay(200); go(RIGHT, 100); delay(600); } } else { go(FORWARD, 70); } } void robot_upravlenie() { if (Serial.available()) { val = Serial.read(); if (val == 'W') { go(FORWARD, 125); delay(200); } if (val == 'S') { go(BACKWARD, 125); delay(200); } if (val == 'A') { go(LEFT, 90); delay(200); } if (val == 'D') { go(RIGHT, 90); delay(200); } if (val == 'C') { go(FORWARD, 0); } if (val == 'Q') { val == '1'; } } } void setup() { for (int i = 4; i <= 7; i++) pinMode(i, OUTPUT); neck.attach(2); neck.write(90); Serial.begin(9600); } void loop() { if (Serial.available()) { val = Serial.read(); if (val == '1') { while (1) { robot_avtonomno(); } } else if (val == '2') { while (1) { robot_upravlenie(); } } } } Теперь работает только режим управления. Как исправить?
Даже завидно блин, у меня в 5-ом классе такая игрушка была только в фантастических романах. То же бы с такого наверно начал программирование изучать. Так вижу основная проблема в том, что Вы плохо представляете как работает Ваш алгоритм. Поэтому Вам надо нарисовать блок схему Все рисовать долго поэтому изобразил блок входа в режим ручного управления. По блок схеме видно, что для блока 2 (соответствует while (1)) ветка "НЕТ" ни когда не будет активна. И похожие проблемы (не идентичные), у Вас на каждом уровне вложенности. И мне кажется этот алгоритм для Вас немного сложноват (очень много недоработок). Рекомендую пару недель порешать задачки попроще. Например мигание гирляндой в несколько каналов с разной частотой, потом с разной фазой, потом добавить управление режимами по порту. ----------------------------------------------- Лучше день потерять, потом за пять минут долететь(из мульта).
Я делал так: - читается команда с порта. Например - "MA090\n" Код (Text): M - Управление двигателями A - (первый двигатель вперед, или "B" первый двигатель назад) 090 - скорость \n - перевод строки завершает команду Т.е. строка всегда должна завершится - Парсим команду и изменяем соответствующие переменные (speed, derection, режим). В зависимости от команды. - Дальше управляем роботом в соответствии с сохраненными значениями переменных. Т.е. на последнюю команду здесь смотреть уже не нужно. Но режим управления в этом случае будет немного другой - если пришла команда вперед - то он будет ехать пока не придет "стоп".
Спасибо, всё работает! Оказалось я контакты у дальномера неправильно подключил. Всем большое спасибо!