Может ли кто-нибудь помочь мне решить вопрос цикла и пару других для моей программы?
В настоящее время я работаю над комплектом смарт-машины 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
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
- rfid_default_keys проверить с помощью RC522
- Команда strtok() с Serial связью
вам нужно очистить свой код, прежде чем делать что-либо еще... нет причин повторять команды в setup().... вы определяете функции для left(), right(), forward() и т. д., но вы не используйте функции в Square(), @jsotola
Ваша проблема в том, что вы используете код блокировки для
square()
иobstacleavoidance()
. Ничто другое не может произойти во время вызоваdelay()
, даже проверка кнопки (если только вы не используете прерывания). Вы должны переписать свой код без каких-либо вызововdelay()
, чтобы Arduino могла делать это, например, изменять выходы, когда придет время, и проверять кнопки между ними. Для этого посмотрите на пример BlinkWithoutDelay, который поставляется с Arduino IDE. Он объясняет, как использоватьmillis()
в качестве источника времени., @chrislТакже вы должны изучить конечные автоматы (FSM). Это довольно простая техника программирования, которая поможет вам упорядочить код и придать ему хорошую структуру для работы. Для обоих упомянутых стилей кодирования в Интернете есть учебные пособия., @chrisl
@sempaiscuba Не могли бы вы помочь мне переписать код так, как вы объясняете? Я совершенно новичок в программировании Arduino., @Hannah
Начните с изучения того, как использовать
millis()
. В сети есть куча обучающих программ для этого. После того, как вы это поняли, вы можете искать реализацию FSM. Должно быть достаточно материала, который можно погуглить. Помнится, я уже писал ответы про автоматы на этом сайте., @chrisl