Может ли кто-нибудь помочь мне решить вопрос цикла и пару других для моей программы?
В настоящее время я работаю над комплектом смарт-машины elegoo uno r3, в котором используется Arduino. Я написал некоторый код, и он работает по большей части, но мне не помешала бы помощь. Я пытаюсь понять, что мне нужно сделать, чтобы моя квадратная программа зациклилась и продолжалась до тех пор, пока не будет нажата кнопка остановки. Может ли кто-нибудь помочь мне, пожалуйста? Кроме того, у меня есть 2 программы в нем. Один из них предназначен для обхода препятствий, которым управляет кнопка 2, и квадратной программы, которая управляется кнопкой 3. Кнопка остановки будет использоваться для остановки любой программы. Я поставлю код ниже.
#include <Servo.h>
//#включить <ArduinoJson.h>
// Таблица истинности левого мотора
// Вот несколько удобных таблиц, показывающих различные режимы работы.
// ENB IN1 IN2 Описание
// НИЗКИЙ Неприменимо Неприменимо Двигатель выключен
// HIGH LOW LOW Двигатель остановлен (тормоза)
// ВЫСОКИЙ ВЫСОКИЙ НИЗКИЙ Двигатель включен и вращается вперед
// ВЫСОКИЙ НИЗКИЙ ВЫСОКИЙ Двигатель включен и вращается назад
// HIGH HIGH HIGH Двигатель остановлен (тормоза)
#include <IRremote.h>
//#включить <Servo.h>
Servo myservo; // создаем сервообъект для управления сервоприводом
// Сервопривод; // Создаем объект привода постоянного тока
//#включить <stdio.h>
//#включаем "HardwareSerial.h"
int Echo = A4;
int Trig = A5;
//значения кнопок дистанционного управления/ таблица данных===========================
#define f 16736925 // ВПЕРЕД
#define b 16754775 // НАЗАД
#define l 16720605 // СЛЕВА
#define r 16761405 // ПРАВО
#define s 16712445 // СТОП
#define KEY2 16750695 //режим обхода препятствий
#define KEY3 16756815 // квадратный режим
#define KEY_STAR 16728765
#define KEY_HASH 16732845
// определить контакт ввода-вывода
#define ENB 5
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define ENA 6
#define RECV_PIN 12
#define ECHO_PIN A4
#define TRIG_PIN A5
#define LED_Pin 13
#define carSpeed 250
int rightDistance = 0, leftDistance = 0, middleDistance = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
void forward(){
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println("Forward");
}
void stop_r() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
/* digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);*/
Serial.println("Stop!");
}
void back() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println("Back");
}
void left() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println("Left");
}
void right() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
Serial.println("Right");
}
void stop_() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
/* digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);*/
Serial.println("Stop!");
}
//Подфункция ультразвукового измерения расстояния
int getDistance() {
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);
return (int)pulseIn(Echo, HIGH) / 58;
}
//--------------------ЗИГ ЗАГ--------------------------- --------------------------
//запускаем машину
void setup() {
//pinMode(IN1, OUTPUT); //установить режим вывода IO OUTPUT
//pinMode(IN2, OUTPUT);
// pinMode(ENB, OUTPUT);
// digitalWrite(ENB, HIGH); // Включить левый мотор
myservo.attach(3); // прикрепляем сервопривод к контакту 3 к сервообъекту
Serial.begin(9600);
pinMode(Echo, INPUT);
pinMode(Trig, OUTPUT);
pinMode(IN1, OUTPUT); //установить режим вывода IO OUTPUT
pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT);
digitalWrite(ENB, HIGH); // Включить левый мотор
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
digitalWrite(ENA, HIGH);//вперед
digitalWrite(ENB, HIGH);
pinMode(IN3, OUTPUT); //установить режим вывода IO OUTPUT
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
digitalWrite(ENA, HIGH); // Включить правый мотор
//attachInterrupt(0,CHECK_IR,CHANGE);
irrecv.enableIRIn(); // Запускаем приемник
stop_r();
//pinMode(IN3, OUTPUT); //установить режим вывода IO OUTPUT
//pinMode(IN4, OUTPUT);
//pinMode(ENA, OUTPUT);
// цифровая запись (ENA, HIGH); // Включить правый мотор
}
//основной цикл============================================ ================================================== =============================
void loop() {
if(irrecv.decode(&results)){
Serial.println(results.value);
irrecv.resume();
}
delay(100);
//квадрат();
if (results.value == KEY2){
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
obstacleavoidance();
//irrecv.resume();
} else if (results.value == s){
stop_r();
results.value = 12;
//irrecv.resume();
}
if(results.value == KEY3){
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
square();
//irrecv.resume();
}else if (results.value == s){
stop_r();
results.value = 12;
//irrecv.resume();
}
/* if(results.value == KEY3){
square();
} else if (results.value == s){
stop_r();
}*/
/*if (key_pressed == KEY2){
obstacleavoidance();
}
while (key_pressed == s){
stop_r();
}*/
}
void get_keys(){
}
void CHECK_IR(){
if(irrecv.decode(&results)){
Serial.println(results.value);
//key_pressed = results.value;
irrecv.resume();
}
delay(100);
}
void square (){
Serial.println("square");
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH); //иди вперед
delay(1000);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW); //останавливаться
delay(1000);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
delay(660); //правое колесо поворачивается вперед
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW); //останавливаться
delay(1000);
}
void obstacleavoidance(){
myservo.write(90); //установить положение сервопривода в соответствии с масштабированным значением
delay(500);
middleDistance = getDistance();
// задержка (100);
if(middleDistance <= 20) {
stop_r();
delay(500);
myservo.write(10);
delay(1000);
rightDistance = getDistance();
delay(500);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
leftDistance = getDistance();
delay(500);
myservo.write(90);
delay(1000);
if(rightDistance > leftDistance) {
right();
delay(360);
}
else if(rightDistance < leftDistance) {
left();
delay(360);
}
else if((rightDistance <= 20) || (leftDistance <= 20)) {
back();
delay(180);
}
else {
forward();
}
}
else {
forward();
}
}
@Hannah, 👍1
Обсуждение1 ответ
Ханна, люди, которые пишут программное обеспечение, по своей природе ленивы, поэтому, поскольку ваш код делает одно и то же снова и снова, это совершенно чуждо большинству людей здесь :) Как правило, если вы копируете и вставляете его более одного раза, он должен быть функцией.
В верхней части кода у вас есть функции для перемещения машины, но вы, похоже, ими не пользуетесь. Их использование сделает код короче, но при этом более читабельным.
В вашей функции setup() вы постоянно устанавливаете pinMode для выводов. Сгруппируйте все вызовы pinMode(), а затем используйте контакты. Опять же, это упростит чтение кода и снизит вероятность поломки при его изменении.
Возвращаясь к вашему вопросу, как заставить бота бегать по квадратам, пока вы не нажмете кнопку? Ну, это будет примерно так:
void square ()
{
while (condition)
{
for (int side = 0; side < 4 && condition; ++side)
{
forward ();
delay (1000);
stop ();
right ();
delay (660);
stop();
}
}
}
Вам нужно найти способ связать условие с помощью кнопки остановки, я не хочу делать все за вас.
Надеюсь, это поможет, если не кричать.
Как указывает Крисл в своем ответе, если вы используете задержку, вы не сможете обнаруживать нажатия кнопок (или ** что-то еще **) во время задержки. Код OP действительно нуждается в рефакторинге с использованием millis()., @Duncan C
- Печать string and integer LCD
- Как добавить гистерезис к пороговым значениям?
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Ожидаемый инициализатор?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
вам нужно очистить свой код, прежде чем делать что-либо еще... нет причин повторять команды в setup().... вы определяете функции для left(), right(), forward() и т. д., но вы не используйте функции в Square(), @jsotola
Ваша проблема в том, что вы используете код блокировки для
square()иobstacleavoidance(). Ничто другое не может произойти во время вызоваdelay(), даже проверка кнопки (если только вы не используете прерывания). Вы должны переписать свой код без каких-либо вызововdelay(), чтобы Arduino могла делать это, например, изменять выходы, когда придет время, и проверять кнопки между ними. Для этого посмотрите на пример BlinkWithoutDelay, который поставляется с Arduino IDE. Он объясняет, как использоватьmillis()в качестве источника времени., @chrislТакже вы должны изучить конечные автоматы (FSM). Это довольно простая техника программирования, которая поможет вам упорядочить код и придать ему хорошую структуру для работы. Для обоих упомянутых стилей кодирования в Интернете есть учебные пособия., @chrisl
@sempaiscuba Не могли бы вы помочь мне переписать код так, как вы объясняете? Я совершенно новичок в программировании Arduino., @Hannah
Начните с изучения того, как использовать
millis(). В сети есть куча обучающих программ для этого. После того, как вы это поняли, вы можете искать реализацию FSM. Должно быть достаточно материала, который можно погуглить. Помнится, я уже писал ответы про автоматы на этом сайте., @chrisl