Функция выполняется только 1 раз

itehno
Offline
Зарегистрирован: 18.04.2015

Доброго дня. Помогите, пожалуйста, не могу понять почему функция "walk" выполняется только 1 раз.

#include <IRremote.h>                       // Подключаем библиотеку инфракрасного приемника
IRrecv irrecv(3);                           // Указываем вывод, к которому подключен приемник
decode_results results;
bool b_walk = false;
#define RIGHT_FORWARD 14                    // Пин 1 мотора (пин А0) для L298N
#define LEFT_FORWARD 16                     // Пин 2 мотора (пин А2) для L298N

void setup() {
  Serial.begin(9600);                       // Инициализация последовательного порта
  irrecv.enableIRIn();                      // Инизиализаця IR приемника
  for(int8_t i = 14; i <= 19; i++){         // С помощью цикла указываем аналоговые порты, как выход
    pinMode(i, OUTPUT);                     // С помощью цикла указываем аналоговые порты, как выход
  }
}

void loop() {
  ir();
}

void ir() {
  if ( irrecv.decode( &results )) { // Если данные пришли
    if (results.value == 0xE9F1A5C0){b_walk = !b_walk; walk(b_walk, LEFT_FORWARD, RIGHT_FORWARD, 300);}
    irrecv.resume();  // Принимаем следующую команду
  }
}

void walk(bool b_walk, int8_t act_a, int8_t act_b, uint16_t stopping){
  if (b_walk == true){
  digitalWrite(act_a, HIGH);
  delay(stopping);
  digitalWrite(act_a, LOW);
  delay(stopping);
  digitalWrite(act_b, HIGH);
  delay(stopping);
  digitalWrite(act_b, LOW);
  delay(stopping);
  }
}

 

b707
Offline
Зарегистрирован: 26.05.2017

насколько я вижу. функция должна выполнятся не один раз, а "через раз". Один раз послали команду - функция выполнилась, второй раз послали - ничего не произошло. Третий раз - выполнилась, четвертый - опять ничего. Так написан код.

itehno
Offline
Зарегистрирован: 18.04.2015

Да. По задумке при однократном нажатии кнопки пульта функция должна начать выполняться, пока булевая переменная истинна.

Но так не происходит. Она не работает в цикле. Код выполняется только однократно. Для повторного запуска нужно вновь нажать кнопку.

При этом до повторного нажатия кнопки булевая переменная сохраняет свое состояние, как истина.

itehno
Offline
Зарегистрирован: 18.04.2015

В целом мне необходимо, такая логика:

а) 1 мотор включился

б) 1 мотор работает в течении 300 мс

в) 1 мотор останавливается

г) 2 мотор включился

д) 2 мотор работает в течении 300 мс

е) 2 мотор останавливается

ж) Повторение цикла

itehno
Offline
Зарегистрирован: 18.04.2015

Если избавиться от булевой переменной, то все-равно функция "walk" выполняется только 1 раз.

#include <IRremote.h>                       // Подключаем библиотеку инфракрасного приемника
IRrecv irrecv(3);                           // Указываем вывод, к которому подключен приемник
decode_results results;
#define RIGHT_FORWARD 14                    // Пин 1 мотора (пин А0) для L298N
#define LEFT_FORWARD 16                     // Пин 2 мотора (пин А2) для L298N

void setup() {
  Serial.begin(9600);                       // Инициализация последовательного порта
  irrecv.enableIRIn();                      // Инизиализаця IR приемника
  for(int8_t i = 14; i <= 19; i++){         // С помощью цикла указываем аналоговые порты, как выход
    pinMode(i, OUTPUT);                     // С помощью цикла указываем аналоговые порты, как выход
  }
}

void loop() {
  ir();
}

void ir() {
  if ( irrecv.decode( &results )) { // Если данные пришли
    if (results.value == 0xE9F1A5C0){walk(LEFT_FORWARD, RIGHT_FORWARD, 300);}
    irrecv.resume();  // Принимаем следующую команду
  }
}

void walk(int8_t act_a, int8_t act_b, uint16_t stopping){
  digitalWrite(act_a, HIGH);
  delay(stopping);
  digitalWrite(act_a, LOW);
  delay(stopping);
  digitalWrite(act_b, HIGH);
  delay(stopping);
  digitalWrite(act_b, LOW);
  delay(stopping);
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Реализованное в коде не соответствует алгоритму, описанному словами. Поэтому и "не работает, как надо".

itehno
Offline
Зарегистрирован: 18.04.2015

Я нашел причину: irrecv.resume();  // Принимаем следующую команду

Если избавиться от этой строки, то все начинает работать, но и новые команды не принимаются. Прошу помощи, я в тупике.

itehno
Offline
Зарегистрирован: 18.04.2015

sadman41 пишет:

Реализованное в коде не соответствует алгоритму, описанному словами. Поэтому и "не работает, как надо".

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Вы как врач из поликлиники: "а давайте-ка попьем эти таблеточки от головы"  ... " нога, значит, не прошла за месяц - странно, таблеточки были хорошие".

sadman41
Offline
Зарегистрирован: 19.10.2016

itehno пишет:

sadman41 пишет:

Реализованное в коде не соответствует алгоритму, описанному словами. Поэтому и "не работает, как надо".

А не могли бы Вы указать, что именно не правильно?

Работа с драйвером двигателя производится в блокирующем стиле. Поэтому никакое воздействие извне прервать ее не способно. А переписывать придется процентов на 80...

strarbit
Offline
Зарегистрирован: 12.06.2016

irrecv.resume();  это хорошая таблетка. В код от Вас чтение новая команда, если walk()  имеет работа завершено. если 
 walk() имеет выполнение,  чтение новая команда от รพ блокировка.

itehno
Offline
Зарегистрирован: 18.04.2015

strarbit пишет:

irrecv.resume();  это хорошая таблетка. В код от Вас чтение новая команда, если walk()  имеет работа завершено. если 
 walk() имеет выполнение,  чтение новая команда от รพ блокировка.

Да, но мне не понятна такая вещь:

Я в функции "ir" только меняю состояние внешней булевой переменной. Почему она останавливает цикл после однократного выполнения если для функции "walk" булевая переменная остается истиной?

b707
Offline
Зарегистрирован: 26.05.2017

itehno пишет:

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

 


посмотрите в код - у вас выполнение команды walk() стоит внутри условия строки 21 "если пришли данные с пульта". Вот оно и выполняется только если на пульте кнопку нажать

itehno
Offline
Зарегистрирован: 18.04.2015

b707 пишет:
itehno пишет:

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

 

посмотрите в код - у вас выполнение команды walk() стоит внутри условия строки 21 "если пришли данные с пульта". Вот оно и выполняется только если на пульте кнопку нажать

Спасибо. Вроде начинают глаза открываться )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Деньги на счёте есть? Может там только одно выполнение оплачено?

itehno
Offline
Зарегистрирован: 18.04.2015

Да вроде норм. Баланс положительный.

 

SLKH
Offline
Зарегистрирован: 17.08.2015

itehno пишет:

b707 пишет:
itehno пишет:

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

 

посмотрите в код - у вас выполнение команды walk() стоит внутри условия строки 21 "если пришли данные с пульта". Вот оно и выполняется только если на пульте кнопку нажать

Спасибо. Вроде начинают глаза открываться )))

Цитата:
...Отладка есть мучительный и болезненный процесс осознания программистом того факта, что программа работает именно так, как он написал.

itehno
Offline
Зарегистрирован: 18.04.2015

Согласен. Вроде и начинаешь что-то понимать, потом поднимаешь те участки кода. к которым не возвращался несколько месяцев и не понимаешь, как это вообще работает.