Официальный сайт компании Arduino по адресу arduino.cc
Помогите с if
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Чт, 17/08/2017 - 12:40
Здравствуйте! Задача скетча выдавать сообщение об открытии/закрытии двери (в последующем открывать/закрывать дверь) при достижении MIN/MAX температур.
#include <OneWire.h> OneWire ds(10); float temp [3]; // temperature from DS18B20 int m=0; // Number of sensors float averageTemp; //average temperature from sensors DS18B20 int minTemp=24; //MIN temperature in the room int maxTemp=28; //MAX temperature in the room boolean doorPosition = false; // 0 - close; 1 - open void setup() { Serial.begin(9600); } void loop() { int n=0; float sumTemp = 0; scanTemp (); for (n=0; n<m; n++) { sumTemp = sumTemp + temp[n]; } averageTemp = sumTemp/m; for (n=0; n<m; n++) { Serial.print("Temperature from Sensor"); Serial.print(n+1);Serial.print(" "); Serial.println(temp[n]); } Serial.print("Average Temperature "); Serial.println(averageTemp); Serial.print("Number of sensors = "); Serial.println(m); Serial.print("doorPosition = "); Serial.println(doorPosition); Serial.println(); if (averageTemp < minTemp) { if (doorPosition == true) { Serial.println("Door close!"); Serial.println(); doorPosition = false; } } else if (averageTemp > maxTemp){ if (doorPosition == false) { Serial.println("Door open!"); Serial.println(); doorPosition=true; } } delay (5000); }
По задумке сообщение "Door open!" должно выдаваться только один раз при достижении температуры maxTemp, для чего введена логическая переменная doorPosition. То есть проверяем больше ли температура чем maxTemp, потом проверяем закрыта ли дверь ( if (doorPosition == false)) и только потом "открываем" дверь.
Но сообщение "Door open!" выдается всегда когда температура больше maxTemp. Почему?
Где ошибка зарыта?
Что будет если поменять
на
?
Ничего. Изначально так и было.
Вообще изначально были функции
И все работало так же, такое ощущение что при последющей итерации в loop doorPosition сбрасыватся на ноль.
... такое ощущение что при последющей итерации в loop doorPosition сбрасыватся на ноль.
Ну это легко проверить выводом в монитор, в какой строке true, а где false.
такое ощущение что при последющей итерации в loop doorPosition сбрасыватся на ноль.
К чему ощущения, если ты выводишь doorPosition перед условиями? Так покажи вывод. Все станет ясно.
...гы! опоздал. и даже цитата та же самая!
А число сенсоров m у вас специально установлено в ноль? не вижу. чтобы вы после где-то меняли на реальное значение
Для начала надо посмотреть код scanTemp() и лично меня смущает m=0.
А число сенсоров m у вас специально установлено в ноль? не вижу. чтобы вы после где-то меняли на реальное значение
скетч не весь. Это в scanTemp() все зырыто (вероятно), и там же утечка памяти, если она есть.
такое ощущение что при последющей итерации в loop doorPosition сбрасыватся на ноль.
К чему ощущения, если ты выводишь doorPosition перед условиями? Так покажи вывод. Все станет ясно.
...гы! опоздал. и даже цитата та же самая!
Для начала надо посмотреть код scanTemp() и лично меня смущает m=0.
Вот код функции сканирующей датчики.
Ну! Все верно. Значит сканТемп и портит где-то память! Давай погладим "какой ты Сухов" - то есть код сканТемп.
никаких секретов! м - никогда не возвращается к 0. переделывайте.
Я думаю, что ты хотел в 15 строке основного кода (первой строке loop() ) написать не
, а
никаких секретов! м - никогда не возвращается к 0. переделывайте.
Ура! Спасибо! В этом был косяк.
В 15 строке все верно. Просто нужно было добавить в функцию scanTemp() строку
перед while
Но только я не понял при чем тут вообще моя булевая переменная doorPosition...
Но все работает!
Но только я не понял при чем тут вообще моя булевая переменная doorPosition...
Но все работает!
Компилятор С не проверяет правильность индекса массива. Ты писал в память, как температуру, а данные попадали неведомо куда. Например в место для doorPosition. ЕвгенийП, как-то раз приводил смешной код, где выводишь "i love you", а печатается "i hate you".
такие ошибки очень трудно искать.
Стало понятнее?
Стало понятнее?
С этим да. Но тогда почему m всегда выдавала значение 3...
Number of sensors = 3
Если она не сбрасывалась в 0, то при каждом опросе датчиков m должна была увеличиваться на число их
3, 6, 9 и т.д.
чорт его знает. Это меня тоже напрягло.
Но если код ошибочен, то предсказать все нюансы нельзя. Вот как-то так получалось. Важно, что теперь все должно быть нормально.
Да! И не забудь вставить в сканТемп органичение на три датчика!!!
Прямо в while(), в котором поиск проводишь.
Да! И не забудь вставить в сканТемп органичение на три датчика!!!
Прямо в while(), в котором поиск проводишь.
А почему? Потому что temp [3]?
А если допустим будет 4 или 5 датчиков.
Вообще я все это затеял, если вдруг один из 3 датчиков отваливается, то автоматика будет работать дальше на 2 датчиках. И даже на одном)
Да! И не забудь вставить в сканТемп органичение на три датчика!!!
Прямо в while(), в котором поиск проводишь.
А почему? Потому что temp [3]?
А если допустим будет 4 или 5 датчиков.
Вообще я все это затеял, если вдруг один из 3 датчиков отваливается, то автоматика будет работать дальше на 2 датчиках. И даже на одном)
вставь такое ограничение, какой массив для температуры заведешь, чтобы не повторилась ерунда.
Еще раз - С не предусматривает контроль за индексом массива, полагая, что это сделает прогрмист. ОК?
... Да, и я не понял, как ограничение на максимальное количество датчиков, помешает тебе работать на 1 или 2?
... Да, и я не понял, как ограничение на максимальное количество датчиков, помешает тебе работать на 1 или 2?
Никак. Понял, спасибо большое за ответ.
так можно же?
Не хотелось бы никого обидеть, но код страшноватый.
Глобальная переменная с именем m лично меня приводит в состояние ужаса перед возможными последствиями.
И еще одно - Вы на редкость везучий человек, все таки перед использованием функции ds.search() в цикле следует до цикла вызывать ds.reset_search().
А собственно по теме - попробуйте отпечатать m перед вызовом scanTemp и сразу после него, я думаю, что будет 3 и 3.
Если так, то сделайте печать в функции сканирования перед
temp [m] = celsius;
после этого оператора и после инкремента - вангую 3 2 3 и это означает, что Вам дико не повезло (ошибку трудно обнаружить) или дико повезло (ошибка не приводит к падению программы) - кому что больше нравится .
Не хотелось бы никого обидеть, но код страшноватый.
Глобальная переменная с именем m лично меня приводит в состояние ужаса перед возможными последствиями.
Код конечно же страшноватый. Я в этой теме не больше месяца)
А в остальном вроде бы разобрались благодаря wdrakula :)
так и нужно.
---------------
Ситуация с ошибкой была уникальна. Сохрани тот код, если не трудно, и опубликуй тут, вместе с версией ИДЕ.
Там такая комбинация случайностей, что ты вообще заметишь ошибку было маловероятно.... просто редкость в коллекцию.
перед использованием функции ds.search() в цикле следует до цикла вызывать ds.reset_search()
Для чего, простите? ) Ну чтобы знать.
Код в scanTemp скопировал из готового шаблона библиотеки OneWare, удалив (на мой взгляд) ненужное. И добавив чуток своего. В целом для меня в этом коде еще много непонятного))
Еще раз, не хочу никого обидеть, но
"чорт его знает. Это меня тоже напрягло".
не оставляет ощущения, что мы до конца разобрались. Мы исправили ошибку, но почему именно так вела себя программа с ошибкой, так и осталось неизвестно. И это очень грустно.
Для чего, простите? ) Ну чтобы знать.
потому, что поиск - инкрементная функция, то есть такая, у которой следующий вызов зависит от результатов предыдущего.
То есть она хранит в невидимой зоне промежуточные данные.
Вот ресет и нужен, чтобы "обнулить" эти самые - промежуточные данные.
У тебя первый вызов идет сразу после старта контроллера, поэтому повезло. В этой истории у тебя вообще ведро везения. В казино ходить не пробовал?
По поводу вызова функций search - она использует при очередном поиске результаты предыдущего поиска, которые хранятся во внутренних переменных, и для того, чтобы поиск гарантировано работал правильно, необходимо эти переменные привести в исходное состояние, что и делает reset_search. Если этого не сделать. то результаты первого поиска будут зависеть от удачи (с последующими уже лучше - есть результаты первого).
Да, вы взяли пример из библиотеки, и это не говорит в ее пользу - крайне жаль, что авторы программы настолько не понимают ее работу.
Ну здесь, наверное, не сколько везение автора, а обнуление блока глобальных переменных при запуске программы, но полагаться на это я бы не стал.
Еще раз, не хочу никого обидеть, но
"чорт его знает. Это меня тоже напрягло".
не оставляет ощущения, что мы до конца разобрались. Мы исправили ошибку, но почему именно так вела себя программа с ошибкой, так и осталось неизвестно. И это очень грустно.
Я разобрался, но для подтверждения нужен ассемблерный код. Идея такая, что 4 байта "в никуда" пишутся по-очереди. Сперва меняя м на 0, а потом остальные попадают куда нужно... иначе никак не объяснить. Ну это как ножик по пьяни кинуть в стенку и он воткнется.... ;)
Сохрани тот код, если не трудно, и опубликуй тут, вместе с версией ИДЕ.
По просьбе wdrakula
Версия IDE 1.8.2
Исходный код
Функция ScanTemp () (собственно в которой ошибка)
Функция closeDoor ()
Функция openDoor ()