цифровой вход порта запоминает первую 1 и уже не изменяется

Dalex
Offline
Зарегистрирован: 28.07.2016

Здраствуйте. Решил потренироваться в программировании arduino. Купил arduino uno, установил последнюю версию программы, подключил  LCD WH1602.Создал скетч считывания  порта и подсчета количества изменений состояния входа из 1 в 0 с выводом на экран. Проблема в чем:

порт запоминает первую1 и не желает её менять при считывании следующего 0.

При проверке переменной temp= =1, на экране L=0,  т.е. в порту записалась единица и когда на вход подаю 0 он его не воспринимает и условие зацикливается.

Если нажимаю сброс и одновременно удерживаю 0 на входе то на экране L= ( идет увеличение значения). Подаю 1 увеличение останавливается и когда вторично подаю 0 он его не воспринимает и условие зацикливается.  

 

void setup() {

  // put your setup code here, to run once:

int temp;

int val=0; 

pinMode(12, INPUT);                // Настраиваем pin на вход

digitalWrite(12,HIGH);           // включаем подтягивающие резисторы

lcd.begin(16, 2);                  // Задаем размерность экрана

lcd.setCursor(0, 0);              // Устанавливаем курсор в начало 1 строки

lcd.print("L=");                  // Выводим текст

lcd.print(val);

}

void loop() {

// put your main code here, to run repeatedly:

int temp;

int val=0;

M0:temp = digitalRead(12);

M1:if(temp==1)

{

goto M1;

}

val=val+1;

lcd.setCursor(0, 0);              // Устанавливаем курсор в начало 1 строки

lcd.print("L=");

lcd.print(val);         // Выводим текст

goto M0;

}

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

1. Вставляйте код согласно ЭТОЙ инструкции

2. Не нужно циклически в loop() инициализировать переменные temp и val. Уберите их оттуда, достаточно единоразовой инициализаци в setup()

3. Порт ничего не запоминает, это Ваша программа (алгоритм) так работает. У Вас в условии if после проверки на единицу, если условие истинно, идёт переход по метке М1 - то есть снова на эту проверку (зацикливается). А должен быть переход на считывание пина - на метку М0. Но с таким алгоритмом значение val будет с огромной скоростью увеличиваться, пока на пине будет 0. И вообще, тут не обязательно применять goto, можно обойтись без него... 

Araris
Offline
Зарегистрирован: 09.11.2012

1. А ведь редкий случай, когда новичёк приходит на форум с собственноручно написанным скетчем. Респект и уважуха Вам.

2. Конструкция

M0:temp = digitalRead(12);
M1:if(temp==1)
{
goto M1;
}

это пичаль, почитайте про оператор while, Вы увидите, что можно элегантно заменить её на

while (digitalRead(12)) {;}// ждём появления нуля на пине 12.

3. Метки и goto - считаются дурным тоном а программировании Ардуино, почему - долго рассказывать, об этом немало написано в Интернетах.

 

Araris
Offline
Зарегистрирован: 09.11.2012

Jeka_M пишет:

2. Не нужно циклически в loop() инициализировать переменные temp и val. Уберите их оттуда, достаточно единоразовой инициализаци в setup()

Или объявить их как static, опять же повод новичку найти и почитать, что оно такое и зачем.

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

Araris пишет:

while (digitalRead(12)) {;}// ждём появления нуля на пине 12.

А зачем фигурные скобки?

Araris
Offline
Зарегистрирован: 09.11.2012

ЕвгенийП пишет:

Araris пишет:

while (digitalRead(12)) {;}// ждём появления нуля на пине 12.

А зачем фигурные скобки?

Для красоты ))) , а точка с запятой - для души, с ней на смайлик похоже )))

Да, Вы правы, они необязательны.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

ЕвгенийП пишет:

Araris пишет:

while (digitalRead(12)) {;}// ждём появления нуля на пине 12.

А зачем фигурные скобки?

А я, например, всегда ставлю фигурные скобки. Это позволяет избежать тупой ошибки, когда нужно дописать еще чего нибудь, а про скобки можно и забыть, такое бывает. Так что вопрос о фигурных скобках скорее философский ;)

В данном случае я скорее всего спросил бы, зачем точка с запятой? Но это риторический вопрос.

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

kisoft пишет:

А я, например, всегда ставлю фигурные скобки. Это позволяет избежать тупой ошибки, когда нужно дописать еще чего нибудь, а про скобки можно и забыть, такое бывает. Так что вопрос о фигурных скобках скорее философский ;)

В данном случае я скорее всего спросил бы, зачем точка с запятой? Но это риторический вопрос.

граждане, экономьте скобки на работе и в быту!

Dalex
Offline
Зарегистрирован: 28.07.2016

Спасибо всем, кто принял участие в обсуждении данной темы. Применил оператор while и тип переменной static и все заработало. Но остался вопрос, который я хотел  задать в самом начале. Почему объявляя переменные в setup(), прога их не видит. При компиляции выводит:
'val' was not declared in this scope (ошибка была выделена в области loop())

 

 

Araris
Offline
Зарегистрирован: 09.11.2012

Прочтите http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-pamyat-1-chto-i-kak-ne-nado-delat и http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-pamyat-2-staticheskie-peremennye, многое прояснится. Там есть и ответ на Ваш вопрос - переменная, объявленная внутри функции (а хоть бы и в setup()), из всех остальных функций недоступна.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Есть такая вещь ...{}   фигурные скобки. Переменные внутри скобок не видны снаружи.  Если хотите что бы везде видели ваши переменые объявляйте снаружи скобок и сверху программы. Потому что переменые внизу не видны сверху.

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

qwone пишет:

Если хотите что бы везде видели ваши переменые объявляйте снаружи скобок и сверху программы. Потому что переменые внизу не видны сверху.

шото я запутался, где здесь {} верх и низ?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Jeka_M пишет:

2. Не нужно циклически в loop() инициализировать переменные temp и val. Уберите их оттуда, достаточно единоразовой инициализаци в setup()

Стыд и позор мне... Конечно же переменные надо инициализировать не "внутри" setup(), а "снаружи" перед setup(). Тогда эти переменные будут глобальными. Вот так:

int temp;
int val=0; 

void setup() {
  // put your setup code here, to run once:
}

Ну а про static Вы уже в курсе.