Хочу посмотреть во что превратят мой "код" профессионалы.
- Войдите на сайт для отправки комментариев
Доброго времени суток уважаемые форумчане!
Собрал тут для себя устройство - автоматическая подсветка в прихожей и коридоре. В меру своих знаний и умений написал для него код. Код рабочий и работает так, как я и планировал. Просто мне стало интересно, если бы этот код писал профи, то у него он занял бы больше 5 строк?
Объясню принцип работы устройства:
Если сработл датчик движения (далее - ДД), и уровень освещенности (далее - УО) ниже определенного значения, и питание светодиодной ленты отключено, то мы включаем ленту.
Если во время работы ленты сработал ДД и УО не привышает минимального значения, то мы продлеваем время жизненного цикла работающей подстветки.
Если питание на ленте включено и жизненный цикл включенной ленты подошел к концу и (освещенность выше минимального предела или ДД не находится в "сработке"), то мы выключаем ленту.
Значение уровня минимальной освещенности берется из еепром. можно, конечно, и без нее обойтись, но мне просто хотелось ее использовать - раньше не использовал никогда. Значение попадает в еепром при нажатии кнопки buttonValuePin, путем считывания значения с подстроечного резистора potentiometr.
все, что связано с LCD вводилось временно и использовалось для определения значения комфортного уровня освещенности на месте и для вывода полезной и не очень информации. После настройки уровня минимальной освещенности данные строки кода я удалил.
#include <LiquidCrystal.h> //дисплей использовался только для выяснения % освещенности на месте, чтоб не таскать с собой бук. Когда нужный процент освещенности найден, то можно удалить все упоминания об экране. #include <EEPROM.h> //этот байт еепром используется для хранения предельного значения освещенности, просле превышения которого, лента загораться не будет. можно обойтись без него, но мне хотелось поиграться. #define buttonPin 12 //пин датчика движения #define ledPin 11 //пин подключения светодиодной ленты #define lightMeterPin A0 //пин подключения датчика освещенности - фоторезистор, х/з что за марка, какой-то валялся #define persentLight EEPROM.read(1) //чтоб каждый раз не писать этот еепром. #define potentiometr A1 //подстроечник для настройки предела освещенности. используется для настройки уровня освещенности для включения ленты. #define buttonValuePin 3 //пин кнопки для записи мануального значения освещенности в память устройства. можно и без нее, но я классную кнопку выпаял из старого сидюка, и мне захотелось её израсходовать. byte manualValue; //значение подстроечника для записи в паять приведенное к % unsigned long timer = 0; //таймер "дребезга" для датчика, с ним все понятно. unsigned long timer1 = 0; //таймер для параметра timeToLive boolean ledStatus = false; //статус светодиодной ленты (тру-вкл; фолс-выкл). boolean powerOn = false; //параметр 1-лента включена, 2 - лента выключена byte zad = 8; //задержака времени, влияющая на скорость плавного включения и плавного выключения светодиодной ленты. unsigned long timeToLive = 5000; //время, которое должна прогореть лента, до проверки условий выхода из цыкла unsigned long timer2 = 0; //используется для экрана, чтоб изображение не мельтешило. если от экрана отказываться, то спокойно можно удалять. LiquidCrystal lcd(9, 8, 7, 6, 5, 4); void setup() { //EEPROM.write(1, byte(50)); //Записать значение процента освещенности в память устройсва. Необходим для первого прогона, для присвоения дефолтного значения lcd.begin(20, 4); pinMode (buttonPin, INPUT); //датчик движения - вход pinMode (ledPin, OUTPUT); //лента - выход digitalWrite(ledPin, LOW); // подстраховаться и отключить подсветку при загрузке устройства. pinMode (lightMeterPin, INPUT); //датчик освещенности - вход pinMode(A1, INPUT); //подстроечный резистор для настройки минимального уровня освещенности. pinMode(buttonValuePin, INPUT); //кнопка для записи в память значения минимальной освещенности. delay(1500); //время, которое необходимо, чтоб протупил датчик движения lcd.setCursor(0, 0); lcd.print("Fotoresist."); //значение АЦП с фоторезистора/значение минимальной освещенности lcd.setCursor(0, 1); lcd.print("DD relay"); //статус датчика движения lcd.setCursor(0, 2); lcd.print("Timer"); //отсчет секунд с момента старта платы. Просто была строчка на экране лишняя. lcd.setCursor(0, 3); lcd.print("Manual val."); //значение АЦП с подстроечника установки уровня минимальной освещенности. } void loop() { if (digitalRead(buttonPin) == LOW && lightMeter() <= persentLight && powerOn == false /*&& first == false*/) { //то же, что и выше, только с выдержкой времени. lcd.setCursor(12, 1); for (byte i = 0; i <= 200; i++) { //полностью не зажигаю, и так ярко. analogWrite(ledPin, i); delay(zad); } powerOn = true; timer1 = millis(); //по нему отсчитывать жизненный цикл включенной ленты } if (millis() >= timer1 + timeToLive - 2000 && millis < timer1 + timeToLive && lightMeter() <= persentLight && digitalRead(buttonPin) == LOW) { //продлеваем TTL ввиду того, что люди еще шевелятся, а освещенность недостаточная. timer1 = millis(); } if (powerOn == true && timer1 + timeToLive <= millis() && (lightMeter() > persentLight || digitalRead(buttonPin) == HIGH)) { //если питане ленты ВКЛ и ТТЛ вышел и (освещенность высокая или датчик движения молчит) lcd.setCursor(12, 1); for (byte i = 200; i > 0; i--) { analogWrite(ledPin, i); delay(zad); } digitalWrite(ledPin, LOW); //опять перестраховываюсь. powerOn = false; // first = false; } lcd.setCursor(12, 2); //вот с этого места выводим всякую инфу на экран. после настройки можно все это отключить. lcd.print ((millis() / 1000)); if (timer2 + 500 <= millis()) { lcd.setCursor(12, 0); //АЦП фоторезистор lcd.print(" "); lcd.setCursor(12, 0); lcd.print(lightMeter()); lcd.print("/"); lcd.print(persentLight); manualValue = analogRead(potentiometr) / (1024 / 100); if (manualValue > 99) { manualValue = 99; } if (manualValue == 0) { manualValue = 1; } timer2 = millis(); lcd.setCursor(12, 3); lcd.print(manualValue); lcd.print(" "); lcd.setCursor(12, 1); if (digitalRead(buttonPin) == HIGH) { lcd.print("ON "); } else { lcd.print("OFF"); } } if (digitalRead (buttonValuePin) == HIGH) { //записываем значение минимального уровня освещенности в еепром. EEPROM.write(1, manualValue); } } byte lightMeter () { //функция для определения уровня освещенности в % byte persents = byte(analogRead(lightMeterPin) / (1024 / 100)); //не уверен, что в байте это значение считается правильно, но в данной конструкции это не играет существенной роли. return persents; }
Уважаемые профи и не очень профи. Можете привести свое видение данного кода или его части? мне будет интересно на это посмотреть, может быть что-то перекачует в устройство, если я его буду повторять или существующее переделывать.
Забыл сказать, если эту тему вдруг увидит Клапауций, то пусть он ее не запрещает!!!
El У вас неправильное представление о профессионалах программирования и их коде. Прежде всего программист не должен запутаться в своем коде, но при этом в этот код не обязан был понят постороними или же новичками. Спросите как профессионал может запутаться в своем коде. Да легко . Если строк будет больше 1000 и при изменения внесены были не один раз и в течении не одного года.
Мой вывод: Код от профессионала вам не поможет. В нем может быть всего "5 строк", но подключеных экзотических библиотек будет как бы с десяток. Пишите программу для себя и под себя, при этом постарайтесь не запутаться с алгоритмом работы свой программы.
El У вас неправильное представление о профессионалах программирования и их коде. Прежде всего программист не должен запутаться в своем коде, но при этом в этот код не обязан был понят постороними или же новичками. Спросите как профессионал может запутаться в своем коде. Да легко . Если строк будет больше 1000 и при изменения внесены были не один раз и в течении не одного года.
Это у Вас неправильное представление о профессионалах программирования и их коде.
Код должен быть понятен для любого программиста, а не только для его автора.
Представьте, что из проекта уходит один программитст и приходит другой - он что, должен писать код с нуля?
Опять же, есть такое понятие, как разделение труда. Один программист (группа программистов) готовят продукт к выходу, а другой (группа) осуществляют его поддержку в то время, когда первая группа уже занята новой версией или другим проектом.
Это у Вас неправильное представление о профессионалах программирования и их коде.
Код должен быть понятен для любого программиста, а не только для его автора.
Представьте, что из проекта уходит один программитст и приходит другой - он что, должен писать код с нуля?
Опять же, есть такое понятие, как разделение труда. Один программист (группа программистов) готовят продукт к выходу, а другой (группа) осуществляют его поддержку в то время, когда первая группа уже занята новой версией или другим проектом.
Ну это доброе пожелание. Делали как лучше, а получилось как всегда. А если бы все так и было, как вы сказали, то не было понятия как "индийский код", "китайский код". И да там соблюдена буква подхода, но дух уже не тот. То есть вроде конструкции правильные, правильные и простые. А вот что делают не с первого раза разберешься. А на вопрос: Та этот код непонятен? Идет такой же ответ: Так вы профессионал или любитель, если в "работающем" коде не разбираетесь.
El У вас неправильное представление о профессионалах программирования и их коде. Прежде всего программист не должен запутаться в своем коде, но при этом в этот код не обязан был понят постороними или же новичками. Спросите как профессионал может запутаться в своем коде. Да легко . Если строк будет больше 1000 и при изменения внесены были не один раз и в течении не одного года.
Это у Вас неправильное представление о профессионалах программирования и их коде.
Код должен быть понятен для любого программиста, а не только для его автора.
А еще код должен быть без ошибок, должен быть мир во всем мире, должны смеятся дети и много чего должно быть.
Вам про реалии написали, а вы тут лозунги цитируете. В реале разраб, спустя год, не всегда с первого взгляда даже признает что это он писал, пока в репозитории не удостоверится. А к разговору про один писал, а другой понял, так много зависит от знаний, опыта и интелекта первого и второго. Вы пишучи сишный код уверены что какой джуниор с вебдизайна поймет его? Как писать будете, чтоб он понял или чтоб оно работало?
По теме, код плотный, мне такой нравится, глубже не вникал ;)
Просили комментарии?
1. ЕЕПРОМ не нужно читать в цикле, читайте его один раз. То есть не очень хорошо его в дефайн ставить. Пока прграмма работает - Вы пользуетесь переменной, при перезапуске - прочтете из ЕЕПРОМ, один раз, в сетапе.
2. 0-1023 от аналогового чтения не нужно пересчитывать в проценты, это портит код, да и пересчет, так как он написан - не работает.
3. "цикл в цикле", я про плавное зажигание внутри лупа - это плохой стиль. Гибкость решения теряется. Уже есть один цикл - сам луп, выставляя флаги режимов и сделав счетчики цикла - статическими переменными, Вы любой вложенный цикл поднимаете на уровень лупа, это, собственно, и есть один из приемов "автоматного программирования". В следующем сообщении покажу как.
4.Уж совсем для блеска, можно вочдог настроить. Но тут я сам - грешен, для своих вещей, которые можно руками перезагрузить, не всегда делаю.
вот
указаны еще два дефайна для работы.
эту функцию нужно вызывать при входе в луп.
а в основном коде, вместо циклов просто задать направления плавного вкл-выкл.
1. ЕЕПРОМ не нужно читать в цикле, читайте его один раз.
Да ладно, то еще мелочи по сравнению с многократной записю пока нажата кнопка - стр.90
Кстати, универсальный совет, перед записью в ЕЕПРОМ всегда считывать и побайтово сравнивать что есть и что пишется. Записывать только при различии. Экономим время и ресурс ЕЕПРОМ. Соответствующий код оформить в функцию через которую и делать все записи всегда.
А так, таки да. Согласен с написаным кроме вачдога. Там вопрос глубоко индивидуальный, надо больше знать о проекте.
Код ламерский. Ошибки и полное отсутствие стиля.
timer2 + 500 <= millis()
Ошибка, нельзя к таймеру прибавлять, проделки Qwone...
Теряюсь в догадках, сколько раз произойдет запись в EEPROM за время нажатия кнопки.
А это что? Особенно / (1024 / 100);
так не пробовал: map(analogRead(potentiometr),0,1023,1,99)?
Если ошибки можно поправить, то стиль прививается годами.
...не было понятия как "индийский код", "китайский код".
Ну то есть по Вашим понятиям именно такой код и соответствует "правильному представлению о профессионалах программирования и их коде".
1. ЕЕПРОМ не нужно читать в цикле, читайте его один раз. ... при перезапуске - прочтете из ЕЕПРОМ, один раз, в сетапе.
2. 0-1023 от аналогового чтения не нужно пересчитывать в проценты
3. "цикл в цикле",
4.Уж совсем для блеска, можно вочдог настроить.
5.
1. каюсь, даже не подумал, что читаю ЕЕПРОМ в цикле. А кнопку специально задумывал для настройки контроллера на лету,
2. я это уже позже понял, когда устройство собрал.
3. Об этом даже не подумал ввиду того, что я представлял себе работу устройства именно так, как в коде написано. Но на будущее обязательно помечу себе этот пункт красным фламастером.
4. Я, к сожалению, не знаю, как это работает...
5. Код уже себе записал.
...то еще мелочи по сравнению с многократной записю пока нажата кнопка - стр.90
Кстати, универсальный совет, перед записью в ЕЕПРОМ всегда считывать и побайтово сравнивать что есть и что пишется...
Про запись даже не подумал во время написания программы.
Сверять ЕЕПРОМ - очень хорошая идея! учту.
Ошибка, нельзя к таймеру прибавлять
Почему?
Теряюсь в догадках, сколько раз произойдет запись в EEPROM за время нажатия кнопки.
много... (
А это что? Особенно / (1024 / 100);
так не пробовал: map(analogRead(potentiometr),0,1023,1,99)?
А это мой код.
Не пробовал. Теперь попробую так, как показал.
Спасибо за конструктивную критику. Будем развиваться дальше.
Чем плохо читать EEPROM столько раз, сколько вздумается?
Чем плохо читать EEPROM столько раз, сколько вздумается?
плохо делать бесполезные вещи сейчас, когда мог бы делать что-то полезное сейчас
Чем плохо читать EEPROM столько раз, сколько вздумается?
Если ты ждал фразы о том, что ЕЕПРОМ "сотрется", то ее не будет. Не сотрется, за время жизни устройства - точно "не сотрется".
Просто это плохой стиль. Тебе нравиццо - пиши так, мне - не нравится.
Или в любую дискуссию нужно свой нос засунуть?
Без тебя тут срача нет - скучновато что-то.
Чем плохо читать EEPROM столько раз, сколько вздумается?
Вместо delay()?
Чем плохо читать EEPROM столько раз, сколько вздумается?
Вместо delay()?
Да не корми ж ты троля! не выгонишь потом его из темы. Пока модераторы не потрут.
Почитай страрые его срачи с ptr или с ОлегМ. Это ж по 10 страниц воды и газа.