Нет, пока есть пара проблем в железе и огромная проблема со временем - внук у меня родился. Много времени уходит на помощь дочери (в поликлиннику свозить, документы оформить, прописать в квартире и т.д.) А с железом вот какая проблема. Было все собрано на DIP ATMega 328, на макетке. В нее сразу залил загрузчик с Ардуины 3-х вольтовой и потом скетч. Сначала все работало нормально, потом изображение на индикаторе пропало. Ресет не помог. Выключил - оставил так. Через пару часов включил, все работает. Потом снова все отключается. Закономерности по времени никакой нет, может и трое суток проработать, может через час выключиться. И на включение похожая ситуация, может сразу включиться, а может только через сутки. Не пойму. Хотя есть догадка - кварц на меге поставил тот который был - на 12 МГц, а нужен на 8. Может по этому через время срывается генерация...?
Я для narodmon.ru буду делать на Wemos D1, жду датчики, едут два BMP-280, DS18B20 у меня россыпью штук 50 есть, еще едут DS3231 и еще какие-то, на HMC5883L хотел флюгер сделать, но думаю проще будет на энкодере 360 градусов, но он по цене кусается 1500= )))
Я поколдую с твоим скетчем, запущу под I2C, скину здесь
Вот болванка под I2C, датчики не ставил, дисплей работает )))
Компилировал под 1.6.12 но некоторые библиотеки из под старых версий ставят систему в позу, подправил пути для файлов библиотек
- скетч получается аж 10 644 байт (34%) - есть мысли как запустить на библиотеке "Grove_BME280-master", мне кажется размер будет гораздо меньше.
- не удалось вычислить давление в мм ртутн. столба - перепробовал несколько вариантов - есть что подсказать?
- без строки "Serial.println(mySensor.begin(), HEX);" не выводится параметр "Pressure" - Давление, а с этой строкой также в начале выводится цифра 58 - ну и как это победить?
- не удалось вычислить давление в мм ртутн. столба - перепробовал несколько вариантов - есть что подсказать?
- без строки "Serial.println(mySensor.begin(), HEX);" не выводится параметр "Pressure" - Давление, а с этой строкой также в начале выводится цифра 58 - ну и как это победить?
1. умножить на коэффициент (ртуть в 13 с гаком раз тяжелее воды к примеру) или напрямую к примеру 1000 гектопаскалей это 750 мм ртутного столба
Привет всем. Когдо сам занимался этой темой перепробывал много библиотек. И с уверенностью могу отметить, что самая оптимальная, для меня, оказалась библиотека - "cactus_io_BME280_I2C.h"
Привет всем. Когдо сам занимался этой темой перепробывал много библиотек. И с уверенностью могу отметить, что самая оптимальная, для меня, оказалась библиотека - "cactus_io_BME280_I2C.h"
Получил китайский BMP-280, но настроить пока не получается.
Распиновка:
SCL - 13
SDA - 11
CSB - 10
SDO - 12
Запустил Adafruit'овский тестовый скетч. Библиотека естественно от Adafruit, но в архиве не было файла Adafruit_Sensor.h. Докачал откуда то, тоже вроде с github.
Температура в комнате где тестировался датчик примерно 25 градусов
Давление у нас по данным гидрометеостанций примерно 767 мм рт. ст.
А высота примерно 495 м над уровнем моря.
Сначала не стал паять ножки к плате датчика, а просто воткнул и соединил кабелями. Результаты были разные когда датчик просто лежал (результат №1) и когда прижимал кабели плотнее к датчику для лучшего соединения (результат №2):
Temp = 25.43 *C
Pressure = 562.72 mm.rt.st
~Height = 2465.58 m
Temp = 42.82 *C
Pressure = 728.79 mm.rt.st
~Height = 336.41 m
Из этого можно увидеть что на первом результате температура правильная, а вот давление и высота над уровнем моря вообще не то.
А на втором результате температура очень завышена, давление более менее нормальная, высота тоже не ахти но уже тоже более менее близка к правде.
Потом запаял ножки к датчику и тогда получаю только результаты ближе к №2.
Temp = 41.76 *C
Pressure = 723.45 mm.rt.st
~Height = 415.29 m
Temp = 41.73 *C
Pressure = 723.46 mm.rt.st
~Height = 415.07 m
Как получить правильные данные? А именно:
1. Температуру
2. Давление и высоту. Вроде надо поменять значение 1013.25 на другое. Так вот на какое? Из какой формулы рассчитать для моей местности эту значению? Или же надо копать в другую сторону?
это я подогнал показания bme280 под показания домашней метеостанции орегон. а вы можете в своей местности посмотреть на народмон и также подкорректировать показания
Всем привет, вчера закончил программу для своей погодной станции. Пока гуглил по датчику BMP280 натыкался на эту ветку форума.
У меня возникло одно замечание, для всех ваших скетчей, вы слишком часто опрашиваете датчики, у меня, когда я опрашиваю чаще чем 5-10 секунд, медленно но заметно начинает повышатся температура DHT3231 и DS18D20. За BMP280 такой беды не замеченно, но на всякий случай я опрашиваю датчики 1 раз в минуту.
Я собрал станцию (пока на макетке) на часах DHT3231, внешнем датчике температуры DS18D20, барометр BMP280, экран 20*4 I2C, гигрометр DHT-11 (знаю, гадость, но у нас из-за боевых действий другие купить проблематично) и 7 сегментный дисплей на TM1637 чтобы было издалека видно время.
Погодная станция прогнозирует изменение погоды по алгоритму Zambretti, основываясь на динамике изменения давления за последние 3 часа. Может строить график изменения давления, температуры внутри и снаружи за последние 20 часов. Запоминает время достижения минимального и максимального значения 2 температур, влажности и давления за эти сутки. Выводит основные показатели на COM порт. Возможность выставлять время, дату и день недели кнопками. На остальное не хватило памяти. Скорее всего, как разбогатею, куплю еще 1 микроконтроллер, на него повешу опрос всех датчиков и экраны и буду передавать через COM порт на 2-й МК, в котором будут обрабатываться данные, и прочие плюшки =)
Комменты на английском, мне так легче, ненавижу язык переключать =)
Что красивового то? Красиво - это когда черным по белому и понятным родным языком написано! :-)
Как война закончится (надеюсь когда-нибудь это случится), куплю нормальный экран с поддержкой кирилицы, а не выдранный из неведомой хрени на барахолке и корейским шрифтом.
И как уже говорилось выше, если у вас экран это поддерживает, замените в исходнике текст, дело 5 минут. А тратить драгоценную память переменных под русские буквы, для меня непозволительно. И так думаю уже о объединении 2 МК в одном устройстве, для освобождения ресурсов. Один чисто как хранилище данных использовать. Кстати, в данном виде, если вы проведете русификацию, у вас не загрузится прошивка, не хватит бамяти. В этом коде если использовать еще 42 байта памяти переменных программа начинает работать нестабильно, из-за нехватки памяти. Тут каждая команда выверена и 3 раза оценена именно с точки зрения уменьшения объема кода. Я пробовал разные варианты одного и того же, и выбирал самый легковесный. В планах еще поковырять библиотеки, возможно там есть за счет чего освободить память.
Лично для меня основная фишка прибора - именно прогноз. Я на непосредственно программу потратил от силы 5-6 часов. С подключением устройств и долбежкой с библиотеками. И примерно 20 часов искал в интернете что то вменяемое, что можно запрограммировать.
И второй фишкой является то, что на приборе можно выставлять время без сторонних примочек.
Сейчас буду пытаться подключить к программатору эту плату, надеюсь мне очень очень повезет и эта штука окажется рабочей, несмотря на то, что в плату явно попало 220.
Нашел на барахолке, не знаю что это, но явно втыкалось в комп.
Если заработает, я спасен и я смогу сделать еще кучу хотелок.
В планах, если заработает:
*Внести все варианты ветвления прогноза калькулятора Zambretti без обобщений и сокращений, с плавной прокруткой длинных строк, что то типа бегущей строки но 1-й;
*График изменения влажности (не хватило памяти);
*Графики с заполнением, а не черточки как сейчас. И шаг графиков 6 минут, вместо 1 часа, получается очень красиво красиво, но сейчас не хватает памяти даже для 1 параметра;
*Автоматическая плавная яркость 2 экранов;
*Будильник;
*RGB Подсветка с плавным переходом оттенков в зависимости от внешней t. (холодно - синий, по мере потепления - желтый, зона комфорта - зеленый, жарко - красный;
*Внешние радио датчики температуры, влажности, освещенности и т.п. связуемые через 433мГц передатчик;
*Датчик солнечной радиации;
*Счетчик Гейгера (уже готов, собран на другом МК, но на погодной станции не хватает памяти, чтобы получать данные с него). Планировал подключение через 433мГц пердатчик, чтобы счетчик Гейгера был автономным самсодостаточным устройством, но если окажется включенным в зоне погодной станции, чтобы она автоматом тянула с него показания.
Все это можно сделать за пару часов, но... Где бы мне купить Мегу 256 по цене как на Али, а не за 4700 рублей как у нас. =)
ЗЫ мне отчасти английский даже понятнее, жене - всеравно, мелкому пока вообще всеравно какая погода, время суток и температура)
ЗЫЫ а кто сказал, что для меня русский - родной ;)
>>Genri5 Да какие обиды. Просто у каждого свои вкусы и фломастеры на вкус и цвет разные )
>>ua6em Меня на плате интересует Мега 128, там есть где разгуляться в плане ресурсов. Кстати, сейчас гуглил по вопросу нехватки памяти, возможно я нашел выход. Нашел код, который позволяет хранить строковые данные в области памяти программы. А у меня там около 8 кб свободно еще, такчто возможно живем еще.
Алгоритм брал отсюда. Лучше алгоритм можете не искать, т.к. похоже инфа по прогнозированию погоды является чуть ли не достоянием нации и не подлежит широкой огласке. Сведения о прогнозировании очень туманны и слабо поддаются систематизации.
На данный момент окончательный код, до сборки в железе больше изменений не планирую.
По сравнению с предыдущим вариантом добавлено:
* Автояркость на основании аналогового фоторезистора
* Меню для пользовательского выставления высоты, вызывается одновременным нажатием кнопок + и -, изменение ими же, сохранение - кнопка Set.
* Реализованны все ветвления калькулятора Zambretti в оригинальном виде без изменений.
* Уменьшенны пороги определения динамики изменения погоды. Теперь считается, что давление падает или растет если изменилось на 0.2 мм за 3 часа или 0.3 мм за 4 часа.
* Исправленна ошибка размерности, при приведении давления к уровню моря в прогнозе прибавлял mmHg к hPa.
* Все массивы использующиеся в прогнозировании объявленны константами и закинуты в память программы. Таким образом, несмотря на значительное добавление записей в эти массивы освободил около 180 байт памяти переменных.
* Косметические изменения функции вывода времени (на основном экране точки мигают, на остальных экранах всегда отображаются статично)
* Автопрокрутка длинных строк для прогноза.
* Приделан костыль для датчика 18d20, который 50/50 при первых 1-2 замерах показывает температуру 85.0, после работает стабильно неделями. Уже не первый раз сталкиваюсь.
Кстати, сейчас на eBay активно продаются аналоги (судя по маркировке) BMP280 и фейковые BME280 с прямоугольным а не квадратным чипом. В конце июня получил свой BMP280 датчик, так не смог заставить его работать ни по SPI ни по I2C. Продавец вернул деньги и только сегодня я заметил, что чип впаян вверх ногами. Сдул и перепаял - работает отлично. Обратите внимание, что отверстие чипа должно быть направлено к резисторам а не к конденсатору. На фото неправильно впаянный чип.
Всем доброго дня! Товарищи подскажите приобрел BME280 на али подключил по i2c первые показания выдает нормальные но секунд через 5 сваливаеться в крайние значения мин темпиратура -144 макс влажность 100 процентов и давление тож самое в чем может быть проблема?
В описании модуля в магазине написано "Поставка Напряжение: 1.8-5 В DC"
Подключено к питанию 3,3V Но пробовал и 5V давать ничего не меняется. Только я к модулю ESP12N подключаю без ардуины но думаю это не важно суть не в этом.
Ну, а такой вариант допустим: модуль с LDO (на что описание намекает), вы его в 3.3V суете, на датчике получаете 2.1, в лучшем случае. Любая просадка напряжения и сенсор клинит. На модуль посмотрите - есть там кроме самого сенсора трехногие и более детальки или нет.
Вроде есть. Если не сложно посмотрите детальку.... сылка
У BME, конечно, минимальное напряжение питание 1.2V заявлено, но черт его знает, что там за LDO. Я бы такой подключил к обычной 5V ардуине (и подключал вполне успешно) и посмотрел на поведение. Если будет работать устойчиво - значит, скорее всего, какие-то провалы по питанию при работе с ESP.
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:1:0:
002
003
D:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:43:30: warning: type qualifiers ignored on function returntype [-Wignored-qualifiers]
004
005
operatorconstuint8_t() const{ return**this; }
006
007
^
008
009
D:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:92:26: warning: type qualifiers ignored on function returntype [-Wignored-qualifiers]
010
011
operatorconstint() const{ returnindex; }
012
013
^
014
015
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino: In function 'void setup()':
Да, именно о Вашем скетче. Он мне очень понравился, но компилятор что то не компилирует. Очень желаю вашу схему повторить. Больше, конечно, компилятор ругается на bme280i2c библиотеку. Поиски ведут в тупик.
Подскажите еще по подключению периферии к ардуино:
Дисплей lcd2004 с bme280 садится на а4/а5 (sdl/sda),
кнопки на d4...6,
Да,
dht11 садится на d9,
Ds18d20 садится на d8,
фоторезистор на пин a1
на i2c переходнике для дисплея снимается перемычка отвечающая за подсветку и на ногу, на которой нет потенциала относительно земли цепляется вывод d3 для управления яркостью. Но честно, плавное изменение делать не захотел (памяти не хватает уже) а без нее выглядит очень убого, потому в последней версии я автояркость отключил. Да и жене ночник хороший получился. =)
У меня есть предложение, я как доберусь домой, настрою эти библиотеки, и выложу настроенную среду сразу.
Обращаю внимание у меня еще подключен сегментный экран на d12 и d13
Содержимое заархивированной папки libraries\ распаковать в папку libraries\ в среде разработки и перезапустить.
Вроде библиотеки те же, завтра заберу с работы станцию попробую прошить.
Проблема была в том, что я писал используя версию от февраля 2017, а со последними версиями не компилируется.
Из замеченных багов за полгода:
*В строке 459 нужно добавить еще 1 пробел, стало заметно при минусовой температуре.
*константы определяющие динамику изменения погоды в функции byteForecast(byteMon)
(0,2 и 0,3) однозначно нужно увеличивать минимум в 2 раза, везде где встречаются. А вообще их нужно подбирать экспереминтально для вашего региона. У нас срань, а не погода в межсезонье.
Давление в течении дня на 5-8 мм прыгает за 2-3 часа, утром солнце и +15, в обед 0 и снежная крупа и легкий ветер нежно обрывает плитку со зданий и ласково прикладывает птичек к стенам домов и вечером снова ясно и +15. А зимой 4 месяца сракопада. Ну а летом датчик на солнце показывает до +60, а воздух прогревается до 35 и ниодного дождя за 4 месяца. Если где и приукрасил, то слегка, а кое где даже приуменьшил =)
Спасибо большое за помощь. Константы изменил, пробел добавил. На 2 компах компилировалось с ошибкой, на третьем пошло... Залил в ардуинку.Теперь проверить не могу. I2C дисплей не могу завести. Ничего не показывает.Будем тужиться завести на дисплей без I2C.
Спасибо большое за помощь. Константы изменил, пробел добавил. На 2 компах компилировалось с ошибкой, на третьем пошло... Залил в ардуинку.Теперь проверить не могу. I2C дисплей не могу завести. Ничего не показывает.Будем тужиться завести на дисплей без I2C.
Виктор Николаевич, не пробовал.Это идея. Заливал тестовый скетч из библиотеки liquid cristal pf8574. Загружал - в мониторе порта была какая то кракозября и не более того.О том, что нету дисплея - порт не сообщал
Сканер показал 0x3f. Как всегда, или лодка дырявая или акула глухая
В оригинале: LiquidCrystal_PCF8574 lcd(0x27)
Придется просить компилировать с вашим 0x3f. Потому как PCF8574A не переключится на 0x3F, насколько я помню. А, судя по адресу, именно он у вас, а не обычный простой PCF8574 без индекса.
Всем спрасибо за помощь. Проект пошел, только почему то атмосферное давление и другие параметры не обновляются автоматически. В скетче заменил адрес. Все показывает. Подсветка не работает, хоть и закинул на в3.но это мелочи.Проект начал хоть что то показывать.
Всем спрасибо за помощь. Проект пошел, только почему то атмосферное давление и другие параметры не обновляются автоматически. В скетче заменил адрес. Все показывает. Подсветка не работает, хоть и закинул на в3.но это мелочи.Проект начал хоть что то показывать.
Все показания с датчиков обновляются раз в минуту. Каждые 20 секунд обновляется значение 1 из датчиков. Чаще просто не вижу смысла, температура, давление и влажность крайне инертные велечины.
Она устанавливает значение PWM от 70 до 255 на пине 3 в зависимости от напряжения на входе А1. Этот вход замеряет напряжение на делителе 10кОм+фоторезистор. Маркировка последнего неизвестна, но эксперементально он меняет сопротивление примерно от 4кОм до 12кОм.
Нет, пока есть пара проблем в железе и огромная проблема со временем - внук у меня родился. Много времени уходит на помощь дочери (в поликлиннику свозить, документы оформить, прописать в квартире и т.д.) А с железом вот какая проблема. Было все собрано на DIP ATMega 328, на макетке. В нее сразу залил загрузчик с Ардуины 3-х вольтовой и потом скетч. Сначала все работало нормально, потом изображение на индикаторе пропало. Ресет не помог. Выключил - оставил так. Через пару часов включил, все работает. Потом снова все отключается. Закономерности по времени никакой нет, может и трое суток проработать, может через час выключиться. И на включение похожая ситуация, может сразу включиться, а может только через сутки. Не пойму. Хотя есть догадка - кварц на меге поставил тот который был - на 12 МГц, а нужен на 8. Может по этому через время срывается генерация...?
Я для narodmon.ru буду делать на Wemos D1, жду датчики, едут два BMP-280, DS18B20 у меня россыпью штук 50 есть, еще едут DS3231 и еще какие-то, на HMC5883L хотел флюгер сделать, но думаю проще будет на энкодере 360 градусов, но он по цене кусается 1500= )))
Я поколдую с твоим скетчем, запущу под I2C, скину здесь
Вот болванка под I2C, датчики не ставил, дисплей работает )))
Компилировал под 1.6.12 но некоторые библиотеки из под старых версий ставят систему в позу, подправил пути для файлов библиотек
01
/* Метео станция от Евгения, RA6FNQ, г.Ставрополь в модификации
02
* UA6EM под различные конфигурации
03
* 1. 08.12.2016 Прикрутил дисплей LCD-1602 по I2C
04
* 2. Создал раздел выбора конфигурации
05
* 3. кое-какие заготовки под другие дисплеи
06
*/
07
08
// *** Раздел выбора конфигурации *** //
09
/* */
10
11
//#define HARDWARE_LCD1602 // обычный дисплей
12
#define HARDWARE_LCD1602_I2C // дисплей подключенный по I2C
13
#define HARDWARE_DHT22 // датчик 1
14
#define HARDWARE_BMP280
15
#define interval 330 // обновление дисплея мс
16
17
#ifdef HARDWARE_LCD1602_I2C
18
#include <LiquidCrystal_I2C.h>
19
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
20
#endif
21
22
#ifdef HARDWARE_LCD1602
23
#include <LiquidCrystal.h>
24
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
// подправьте под свою схему
25
#endif
26
27
long
previousMillis = 0;
28
29
#include <Wire.h>
30
#include <SPI.h>
31
#include <Adafruit_Sensor.h>
32
#include <Adafruit_BMP280.h>
33
34
#ifdef HARDWARE_DHT22
35
#include "DHT.h"
36
#define DHTPIN 9 // 9 pin для датчика DHT22
37
#define DHTTYPE DHT22
38
DHT dht(DHTPIN, DHTTYPE);
39
#endif
40
41
#ifdef HARDWARE_BMP280
42
#define BMP_CS 10 // hardware SPI
43
#define SEALEVELPRESSURE_HPA (1013.25) //
44
Adafruit_BMP280 bme(BMP_CS);
// работаем по шине hardware SPI
45
#endif
46
47
48
long
temp3 = 0, Pressure = 0, Altitude = 0;
49
50
void
setup
() {
51
52
#ifdef HARDWARE_LCD1602
53
lcd.begin(16, 2);
54
#endif
55
56
#ifdef HARDWARE_LCD1602_I2C
57
lcd.begin(16,2);
58
#endif
59
60
lcd.print(
" Meteo v01_1602H"
);
// приветствие
61
lcd.setCursor(0,1);
62
lcd.print(
" RA6FNQ 2016 11"
);
// версия 0.3
63
delay(3000);
64
lcd.clear();
65
66
Wire.begin();
67
68
dht.begin();
69
bme.begin();
//запуск BME280
70
delay(2000);
71
}
72
73
void
loop
()
74
{
75
Pressure = bme.readPressure();
76
Altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
77
temp3 = bme.readTemperature();
78
79
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
80
float
h = dht.readHumidity();
81
float
t = dht.readTemperature();
// Read temperature as Celsius
82
delay(1000);
83
84
lcd.clear();
// очистим лсд дисплей
85
lcd.setCursor(0, 0);
86
lcd.print(
"T"
);
//задаем температуру снаружи, DHT22
87
lcd.setCursor(2, 0);
88
lcd.print(t, 1);
89
lcd.setCursor(8, 0);
90
lcd.print(
"t"
);
//задаем температуру
91
lcd.setCursor(10, 0);
92
lcd.print(bme.readTemperature(), 1);
//Это температура с барометра);
93
lcd.setCursor(14, 0);
94
lcd.print(
"*C"
);
95
96
97
delay (1000);
// Задержка 1 с
98
99
}
Ты BMP-280 к чему и как подключаешь?
У меня он не заработал, видимо брак, ни по I2C - ни по SPI-SOFT
Это заработавший скетч на библиотеке "SparkFun_BME280" - сокращёный пример, но есть несколько "но".
У меня он не заработал, видимо брак, ни по I2C - ни по SPI-SOFT
не знаю как тут вставлять картинки.
1. умножить на коэффициент (ртуть в 13 с гаком раз тяжелее воды к примеру) или напрямую к примеру 1000 гектопаскалей это 750 мм ртутного столба
2. А через String?
Привет всем. Когдо сам занимался этой темой перепробывал много библиотек. И с уверенностью могу отметить, что самая оптимальная, для меня, оказалась библиотека - "cactus_io_BME280_I2C.h"
Привет всем. Когдо сам занимался этой темой перепробывал много библиотек. И с уверенностью могу отметить, что самая оптимальная, для меня, оказалась библиотека - "cactus_io_BME280_I2C.h"
Отсюда?
Да.
У меня он не заработал, видимо брак, ни по I2C - ни по SPI-SOFT
не знаю как тут вставлять картинки.
Картинки вставлять просто, нажимаешь кнопку изображение, далее кнопку выбор на сервере, потом загрузить, потом вставить и всё
Получил китайский BMP-280, но настроить пока не получается.
Распиновка:
SCL - 13
SDA - 11
CSB - 10
SDO - 12
Запустил Adafruit'овский тестовый скетч. Библиотека естественно от Adafruit, но в архиве не было файла Adafruit_Sensor.h. Докачал откуда то, тоже вроде с github.
Из этого можно увидеть что на первом результате температура правильная, а вот давление и высота над уровнем моря вообще не то.
А на втором результате температура очень завышена, давление более менее нормальная, высота тоже не ахти но уже тоже более менее близка к правде.
Потом запаял ножки к датчику и тогда получаю только результаты ближе к №2.
Temp = 41.76 *C
Pressure = 723.45 mm.rt.st
~Height = 415.29 m
если датчик меняет значения адекватно, то просто в скетче сделайте вот так
1
lcd.print((uint32_t)mySensor.readFloatPressure() / 100 + 15); lcd.print(
"Pa "
);
//+15 korrekcija
это я подогнал показания bme280 под показания домашней метеостанции орегон. а вы можете в своей местности посмотреть на народмон и также подкорректировать показания
Всем привет, вчера закончил программу для своей погодной станции. Пока гуглил по датчику BMP280 натыкался на эту ветку форума.
У меня возникло одно замечание, для всех ваших скетчей, вы слишком часто опрашиваете датчики, у меня, когда я опрашиваю чаще чем 5-10 секунд, медленно но заметно начинает повышатся температура DHT3231 и DS18D20. За BMP280 такой беды не замеченно, но на всякий случай я опрашиваю датчики 1 раз в минуту.
Я собрал станцию (пока на макетке) на часах DHT3231, внешнем датчике температуры DS18D20, барометр BMP280, экран 20*4 I2C, гигрометр DHT-11 (знаю, гадость, но у нас из-за боевых действий другие купить проблематично) и 7 сегментный дисплей на TM1637 чтобы было издалека видно время.
Погодная станция прогнозирует изменение погоды по алгоритму Zambretti, основываясь на динамике изменения давления за последние 3 часа. Может строить график изменения давления, температуры внутри и снаружи за последние 20 часов. Запоминает время достижения минимального и максимального значения 2 температур, влажности и давления за эти сутки. Выводит основные показатели на COM порт. Возможность выставлять время, дату и день недели кнопками. На остальное не хватило памяти. Скорее всего, как разбогатею, куплю еще 1 микроконтроллер, на него повешу опрос всех датчиков и экраны и буду передавать через COM порт на 2-й МК, в котором будут обрабатываться данные, и прочие плюшки =)
Комменты на английском, мне так легче, ненавижу язык переключать =)
001
//lcd
002
#include <LiquidCrystal_PCF8574.h>
003
LiquidCrystal_PCF8574 lcd(0x27);
004
005
//Clock
006
#include <Wire.h>
007
#include "Sodaq_DS3231.h"
008
#include <DallasTemperature.h>
009
char
weekDay[][4] = {
"Mon"
,
"Tue"
,
"Wed"
,
"Thu"
,
"Fri"
,
"Sat"
,
"Sun"
};
010
011
012
013
//barometr
014
#include <BME280I2C.h>
015
BME280I2C bme;
016
float
hPa = 0;
017
float
Altitude = 0;
018
float
MaxPressure = 0, MinPressure = 65000;
019
float
MaxTempO = -200, MinTempO = 200, MaxTempIn = -200, MinTempIn = 200;
020
DateTime MaxPressureT, MinPressureT;
021
DateTime MaxTempOT, MinTempOT, MaxTempInT, MinTempInT, TempTime;
022
float
Pres = 0;
023
float
InT, OutT;
024
025
026
027
028
//LedDisplay
029
#include "TM1637.h" // Подключаем библиотеку
030
#define CLK 13 // К этому пину подключаем CLK
031
#define DIO 12 // К этому пину подключаем DIO
032
TM1637 tm1637(CLK, DIO);
033
034
//humidity
035
#include <SimpleDHT.h>
036
int
pinDHT11 = 9;
037
SimpleDHT11 dht11;
038
byte
Hum = 0;
039
byte
DHT11temperature = 0;
040
byte
MaxHum = 0, MinHum = 101;
041
DateTime MaxHumT, MinHumT;
042
043
044
045
//buttons
046
#define BTN 6
047
#define BTNUP 5
048
#define BTNDOWN 4
049
050
051
052
//int LCDled = 3; // the PWM pin the LED is attached to
053
054
//Main Display mode 1- show main screen,2 shov max and min time... etc..
055
int
DisplayMode = 0;
056
057
int
_m, _s, _mon, _day, _week;
058
int
_h, _year;
059
060
061
062
063
064
//unsigned long RefreshLCD;
065
unsigned
long
TimeReturn;
066
DateTime now;
067
DateTime PowerOn;
068
byte
LastRead, ResetVals;
069
unsigned
long
old_ts = 0;
070
071
072
073
074
float
PressureHistory [20] = {
075
700, 700, 700, 700, 700,
076
700, 700, 700, 700, 700,
077
700, 700, 700, 700, 700,
078
700, 700, 700, 700, 700
079
};
080
081
float
TempHistoryIn [20] = {
082
-127, -127, -127, -127, -127,
083
-127, -127, -127, -127, -127,
084
-127, -127, -127, -127, -127,
085
-127, -127, -127, -127, -127
086
};
087
float
TempHistoryOut [20] = {
088
30, 40, 42, 39, 38,
089
10, 40, 42, 39, 38,
090
-1, 40, 42, 39, 38,
091
30, 40, 42, 39, 38
092
};
093
094
095
//OutTemp
096
#define ONE_WIRE_BUS 8
097
OneWire oneWire(ONE_WIRE_BUS);
098
DallasTemperature sensors(&oneWire);
099
100
101
//Chars for graph
102
byte
ArrCharIndex[9] = {
103
254, 2, 95, 3, 4, 176, 5, 6, 7
104
};
105
106
//Zambretty array
107
byte
Zarr[32] =
108
{ 0,
//a
109
0,
//b
110
0,
//d
111
1,
//h
112
5,
//o
113
5,
//r
114
5,
//u
115
5,
//v
116
5,
//x
117
0,
//a
118
0,
//b
119
1,
//e
120
2,
//k
121
4,
//n
122
5,
//p
123
5,
//s
124
5,
//w
125
5,
//x
126
8,
//z
127
0,
//a
128
0,
//b
129
0,
//c
130
0,
//f
131
1,
//g
132
2,
//i
133
3,
//j
134
3,
//l
135
3,
//m
136
6,
//q
137
6,
//t
138
7,
//y
139
8
//z
140
};
141
142
String ForecastText[] =
143
{
144
"Will fine"
,
//0
145
"Fine>shower"
,
//1
146
"Shower>imp."
,
//2
147
"Changeable>imp."
,
//3
148
"Showery/bright"
,
//4
149
"Rain"
,
//5
150
"Unsettled"
,
//6
151
"Storm"
,
//7
152
"Storm>rain"
//8
153
};
154
155
//hum icon
156
byte
HumCHR[8] = {
157
B00100,
158
B00100,
159
B01010,
160
B01010,
161
B10001,
162
B10001,
163
B10001,
164
B01110
165
};
166
//temp icon
167
byte
Temp[8] = {
168
B00100,
169
B01010,
170
B01010,
171
B01110,
172
B01110,
173
B11111,
174
B11111,
175
B01110
176
};
177
178
//graph char 1/8
179
byte
ch1[8] = {
180
B00000,
181
B00000,
182
B00000,
183
B00000,
184
B00000,
185
B00000,
186
B00000,
187
B11111
188
};
189
//graph char 2/8 is _ char
190
191
//graph char 3/8
192
byte
ch3[8] = {
193
B00000,
194
B00000,
195
B00000,
196
B00000,
197
B00000,
198
B11111,
199
B00000,
200
B00000
201
};
202
//graph chars 4/8
203
byte
ch4[8] = {
204
B00000,
205
B00000,
206
B00000,
207
B00000,
208
B11111,
209
B00000,
210
B00000,
211
B00000
212
};
213
214
//graph char 5/8 is - char
215
216
//graph chars 6/8
217
byte
ch6[8] = {
218
B00000,
219
B00000,
220
B11111,
221
B00000,
222
B00000,
223
B00000,
224
B00000,
225
B00000
226
};
227
228
//graph char 7/8
229
byte
ch7[8] = {
230
B00000,
231
B11111,
232
B00000,
233
B00000,
234
B00000,
235
B00000,
236
B00000
237
};
238
239
//graph char 8/8
240
byte
ch8[8] = {
241
B11111,
242
B00000,
243
B00000,
244
B00000,
245
B00000,
246
B00000,
247
B00000
248
};
249
void
setup
()
250
{
251
252
pinMode(BTN, INPUT_PULLUP);
253
pinMode(BTNUP, INPUT_PULLUP);
254
pinMode(BTNDOWN, INPUT_PULLUP);
255
256
257
258
259
260
261
Wire.begin();
262
Wire.beginTransmission(0x27);
263
264
lcd.begin(20, 4);
// initialize the lcd
265
//load custom chars
266
lcd.createChar (0, Temp);
267
lcd.createChar (1, HumCHR);
268
lcd.createChar (2, ch1);
269
lcd.createChar (3, ch3);
270
lcd.createChar (4, ch4);
271
lcd.createChar (5, ch6);
272
lcd.createChar (6, ch7);
273
lcd.createChar (7, ch8);
274
275
//must be called after loading chars
276
lcd.home();
277
lcd.clear();
278
lcd.print(
"Wait"
);
279
280
while
(!bme.begin()) {
281
lcd.clear();
282
lcd.print(
"PrSensorError"
);
283
}
284
while
(!rtc.begin()) {
285
lcd.clear();
286
lcd.print(
"ClockError"
);
287
}
288
lcd.setBacklight(255);
289
290
// SetBrightness(brightness);
291
tm1637.init();
292
tm1637.
set
(7);
293
294
//just read data from sensors ds18d20 sometimes in first read return 85.0C
295
readSensors(rtc.now(),
true
,
false
);
296
297
PowerOn = rtc.now();
298
LastRead = rtc.now().hour();
299
ResetVals = rtc.now().date();
300
//store first values from sensors to limit values
301
readSensors(rtc.now(),
true
,
true
);
302
//save current values from the sensors to history
303
//for normal graph view in first 20 hours of work
304
for
(
int
tt = 0; tt < 20; tt++)
305
{
306
PressureHistory[tt] = Pres;
307
TempHistoryIn[tt] = InT;
308
TempHistoryOut[tt] = OutT;
309
310
}
311
//show main screen by default
312
DisplayMode = 1;
313
//try to forecast =)
314
Forecast(now.month());
315
Serial
.begin(9600);
316
}
317
318
319
320
void
loop
()
321
{
322
//return to main screen from any other mode in 10 sec inactivity
323
if
( millis() - TimeReturn > 10000) {
324
if
(DisplayMode != 1) {
325
lcd.clear();
326
lcd.home();
327
DisplayMode = 1;
328
}
329
TimeReturn = millis();
330
}
331
//main screen
332
if
(DisplayMode == 1 ) {
333
now = rtc.now();
//get the current date-time
334
uint32_t ts = now.getEpoch();
335
//check second changed or not
336
if
(old_ts != ts) {
337
old_ts = ts;
338
//Write time on tm1367
339
tm1637.display(0, now.hour() / 10);
340
tm1637.display(1, now.hour() % 10);
341
tm1637.display(2, now.minute() / 10);
342
tm1637.display(3, now.minute() % 10);
343
//blink dot
344
tm1637.point(ts % 2 == 0 ? POINT_OFF : POINT_ON);
345
//write current time and date on 20*4
346
WriteTimeDT(now, 0, 0);
347
WriteDateDT(now, 6, 0);
348
//if hour changes store current sensor values to history
349
if
(LastRead != now.hour())
350
{
351
LastRead = now.hour();
352
readSensors(rtc.now(),
true
,
true
);
353
for
(
byte
i = 0; i < 19; i++) {
354
PressureHistory[i] = PressureHistory[i + 1];
355
TempHistoryIn[i] = TempHistoryIn[i + 1];
356
TempHistoryOut[i] = TempHistoryOut[i + 1];
357
358
}
359
TempHistoryIn[19] = InT;
360
TempHistoryOut[19] = OutT;
361
PressureHistory[19] = Pres;
362
//if date changes reset limit values
363
if
( ResetVals != now.date()) {
364
ResetVals = now.date();
365
MaxTempO = -200;
366
MinTempO = 200;
367
MaxTempIn = -200;
368
MinTempIn = 200;
369
MaxPressure = 0;
370
MinPressure = 65000;
371
MaxHum = 0;
372
MinHum = 101;
373
readSensors(rtc.now(),
true
,
true
);
374
}
375
}
376
//read sensors values
377
//each sensor interrogated 1 time per 60 seconds
378
//and 20 seconds delay between different sensors
379
if
(now.second() % 10 == 0 && now.second() > 0)
380
{
381
readSensors(now,
false
,
true
);
382
lcd.setCursor(0, 3);
383
lcd.print(
" "
);
384
lcd.setCursor(0, 3);
385
//try to forecast
386
//this function wrute on 4 line forecast
387
lcd.print(Forecast(now.month()));
388
//serial write some data
389
Serial
.print(
"<h"
);
390
Serial
.print(now.hour());
391
Serial
.print(
"m"
);
392
Serial
.print(now.minute());
393
Serial
.print(
"s"
);
394
Serial
.print(now.second());
395
Serial
.print(
"D"
);
396
Serial
.print(now.date());
397
Serial
.print(
"M"
);
398
Serial
.print(now.month());
399
Serial
.print(
"Y"
);
400
Serial
.print(now.year());
401
Serial
.print(
"d"
);
402
Serial
.print(weekDay[now.dayOfWeek() - 1]);
403
Serial
.print(
"InT"
);
404
Serial
.print(InT);
405
Serial
.print(
"Out"
);
406
Serial
.print(OutT);
407
Serial
.print(
"Hum"
);
408
Serial
.print(Hum);
409
Serial
.print(
"Pres"
);
410
Serial
.print(Pres);
411
Serial
.print(
"F-t"
);
412
Serial
.print(Forecast(now.month()));
413
Serial
.println(
">"
);
414
}
415
}
416
417
//2 line
418
lcd.setCursor(0, 1);
419
//write in temp
420
lcd.print(
"In"
);
421
//write custom temp char
422
lcd.print(
char
(0));
423
lcd.print(InT);
424
//write out temp
425
lcd.print(
" Out"
);
426
//write custom temp char
427
lcd.print(
char
(0));
428
lcd.print(OutT);
429
//3 line
430
lcd.setCursor(0, 2);
431
//write custom humidity char
432
lcd.print(
char
(1));
433
//write humidity
434
lcd.print(Hum);
435
lcd.print(
"% "
);
436
lcd.print(Pres);
437
lcd.print(
"mmHg "
);
438
}
439
440
//show limit waluea for out temp
441
if
(DisplayMode == 2)
442
{
443
lcd.setCursor(0, 0);
444
lcd.print(
"Max out t"
);
445
WriteTimeDT(MaxTempOT, 0, 13);
446
lcd.setCursor(0, 1);
447
lcd.print(MaxTempO);
448
lcd.setCursor(0, 2);
449
lcd.print(
"Min out t"
);
450
WriteTimeDT(MinTempOT, 2, 13);
451
lcd.setCursor(0, 3);
452
lcd.print(MinTempO);
453
}
454
//draw graph for out temp
455
if
(DisplayMode == 3)
456
{
457
lcd.setCursor(0, 0);
458
lcd.print(
"Out t hist"
);
459
drawGraphFullScreen(TempHistoryOut);
460
}
461
//show limit walues for in temp
462
if
(DisplayMode == 4)
463
{
464
lcd.setCursor(0, 0);
465
lcd.print(
"Max in t"
);
466
WriteTimeDT(MaxTempInT, 0, 13);
467
lcd.setCursor(0, 1);
468
lcd.print(MaxTempIn);
469
lcd.setCursor(0, 2);
470
lcd.print(
"Min in t"
);
471
WriteTimeDT(MinTempInT, 2, 13);
472
lcd.setCursor(0, 3);
473
lcd.print(MinTempIn);
474
}
475
//draw graph for in temp
476
if
(DisplayMode == 5)
477
{
478
lcd.setCursor(0, 0);
479
lcd.print(
"In t hist"
);
480
drawGraphFullScreen(TempHistoryIn);
481
}
482
//show limit walues for pressure
483
if
(DisplayMode == 6)
484
{
485
lcd.setCursor(0, 0);
486
lcd.print(
"Max pressure"
);
487
WriteTimeDT(MaxPressureT, 0, 13);
488
lcd.setCursor(0, 1);
489
lcd.print(MaxPressure);
490
lcd.setCursor(0, 2);
491
lcd.print(
"Min pressure"
);
492
WriteTimeDT(MinPressureT, 2, 13);
493
lcd.setCursor(0, 3);
494
lcd.print(MinPressure);
495
}
496
//draw graph for pressure
497
if
(DisplayMode == 7)
498
{
499
lcd.setCursor(0, 0);
500
lcd.print(
"Pressure hist"
);
501
drawGraphFullScreen(PressureHistory);
502
}
503
//show limit walues for humidity
504
if
(DisplayMode == 8)
505
{
506
lcd.setCursor(0, 0);
507
lcd.print(
"Max humidity"
);
508
WriteTimeDT(MaxHumT, 0, 13);
509
lcd.setCursor(0, 1);
510
lcd.print(MaxHum);
511
lcd.setCursor(0, 2);
512
lcd.print(
"Min humidity"
);
513
WriteTimeDT(MinHumT, 2, 13);
514
lcd.setCursor(0, 3);
515
lcd.print(MinHum);
516
}
517
518
//show Altitude, uptime and (c)
519
if
(DisplayMode == 9)
520
{
521
lcd.setCursor(0, 0);
522
lcd.print(
"Altitude "
);
523
lcd.print(Altitude);
524
lcd.print(
"m "
);
525
526
lcd.setCursor(0, 1);
527
lcd.print(
"PowerOn"
);
528
WriteTimeDT(PowerOn, 2, 0);
529
WriteDateDT(PowerOn, 6, 2);
530
lcd.setCursor(0, 3);
531
lcd.print(
"(c)IvanchenkoAV 2017"
);
532
}
533
534
//if button up pressed
535
if
(!digitalRead(BTNUP) && DisplayMode < 100)
536
{
537
DisplayMode++;
538
lcd.clear();
539
540
}
541
//if button down pressed
542
if
(!digitalRead(BTNDOWN) && DisplayMode < 100)
543
{
544
DisplayMode--;
545
lcd.clear();
546
547
}
548
//display menu limits
549
if
(DisplayMode == 10)
550
{
551
DisplayMode = 1;
552
}
553
//display menu limits
554
if
(DisplayMode == 0)
555
{
556
DisplayMode = 9;
557
}
558
559
//set button pressed
560
if
(!digitalRead(BTN)) {
561
TimeReturn = millis();
562
//if set button pressed in main screen mode
563
if
(DisplayMode < 100)
564
{
565
DisplayMode = 100;
566
//save current time to temp values
567
TempTime = rtc.now();
568
_h = TempTime.hour();
569
_m = TempTime.minute();
570
_day = TempTime.date();
571
_mon = TempTime.month();
572
_year = TempTime.year();
573
_week = TempTime.dayOfWeek();
574
}
575
else
576
//if button pressed in set mode
577
DisplayMode++;
578
//menu limit
579
if
(DisplayMode == 107) {
580
lcd.setCursor(0, 1);
581
lcd.print(
"Cancel"
);
582
delay(3000);
583
DisplayMode = 1;
584
lcd.clear();
585
}
586
//delay(300);
587
588
}
589
delay(200);
590
//disp.set(brightness / 64 + 1);
591
592
//reset time return if any buton pressed
593
if
(!digitalRead(BTNUP) || !digitalRead(BTNDOWN)) {
594
TimeReturn = millis();
595
}
596
//temp hour set
597
if
(DisplayMode == 100)
598
{
599
if
(!digitalRead(BTNUP))
600
_h++;
601
if
(!digitalRead(BTNDOWN))
602
_h--;
603
604
if
(_h > 23)
605
_h = 0;
606
if
(_h < 0)
607
_h = 23;
608
lcd.clear();
609
lcd.home();
610
lcd.print(
"Hour "
);
611
lcd.print(_h);
612
}
613
//temp minute set
614
if
(DisplayMode == 101)
615
{
616
617
if
(!digitalRead(BTNUP))
618
_m++;
619
if
(!digitalRead(BTNDOWN))
620
_m--;
621
622
if
(_m >= 60)
623
_m = 0;
624
if
(_m < 0)
625
_m = 59;
626
lcd.clear();
627
lcd.home();
628
lcd.print(
"Minute "
);
629
lcd.print(_m);
630
}
631
//temp date set
632
if
(DisplayMode == 102)
633
{
634
635
if
(!digitalRead(BTNUP))
636
_day++;
637
if
(!digitalRead(BTNDOWN))
638
_day--;
639
640
if
(_day > 31)
641
_day = 1;
642
if
(_day < 1)
643
_day = 31;
644
lcd.clear();
645
lcd.home();
646
lcd.print(
"Day "
);
647
lcd.print(_day);
648
}
649
//temp month set
650
if
(DisplayMode == 103)
651
{
652
if
(!digitalRead(BTNUP))
653
_mon++;
654
if
(!digitalRead(BTNDOWN))
655
_mon--;
656
657
if
(_mon > 12)
658
_mon = 1;
659
if
(_mon < 1)
660
_mon = 12;
661
lcd.clear();
662
lcd.home();
663
lcd.print(
"Month "
);
664
lcd.print(_mon);
665
}
666
//temp year set
667
if
(DisplayMode == 104)
668
{
669
670
if
(!digitalRead(BTNUP))
671
_year++;
672
if
(!digitalRead(BTNDOWN))
673
_year--;
674
675
if
(_year > 3000)
676
_year = 1;
677
if
(_year < 1)
678
_year = 3000;
679
680
lcd.clear();
681
lcd.home();
682
lcd.print(
"Year "
);
683
lcd.print(_year);
684
}
685
//temp weekday set
686
if
(DisplayMode == 105)
687
{
688
if
(!digitalRead(BTNUP))
689
_week++;
690
if
(!digitalRead(BTNDOWN))
691
_week--;
692
693
if
(_week > 7)
694
_week = 1;
695
if
(_week < 1)
696
_week = 7;
697
698
699
lcd.clear();
700
lcd.home();
701
lcd.print(
"WeekDay "
);
702
lcd.print(weekDay[_week - 1]);
703
}
704
// set new time?
705
if
(DisplayMode == 106)
706
{
707
lcd.clear();
708
lcd.home();
709
lcd.print(
"Save Y/N?"
);
710
711
//if button up pressed save new time
712
if
(!digitalRead(BTNUP))
713
{
714
DateTime dt(_year, _mon, _day, _h, _m, 0, _week);
715
rtc.setDateTime(dt);
716
lcd.setCursor(0, 1);
717
lcd.print(
"Ok"
);
718
delay(3000);
719
DisplayMode = 1;
720
lcd.clear();
721
}
722
//if button down pressed - exit to main screen
723
if
(!digitalRead(BTNDOWN)) {
724
lcd.setCursor(0, 1);
725
lcd.print(
"Cancel"
);
726
delay(3000);
727
DisplayMode = 1;
728
lcd.clear();
729
}
730
}
731
}
732
//write time in x,y of lcd
733
void
WriteTimeDT(DateTime Time,
byte
y,
byte
x) {
734
lcd.setCursor(x, y);
735
if
(Time.hour() < 10)
736
lcd.print(
'0'
);
737
lcd.print(Time.hour());
738
lcd.print(Time.second() % 2 == 0 ?
':'
:
' '
);
739
if
(Time.minute() < 10)
740
lcd.print(
'0'
);
741
lcd.print(Time.minute());
742
}
743
//write date in x,y of lcd
744
void
WriteDateDT(DateTime Time,
int
x,
int
y) {
745
lcd.setCursor(x, y);
746
if
(Time.date() < 10)
747
lcd.print(
'0'
);
748
lcd.print(Time.date());
749
lcd.print(
'/'
);
750
if
(Time.month() < 10)
751
lcd.print(
'0'
);
752
lcd.print(Time.month());
753
lcd.print(
'/'
);
754
lcd.print(Time.year());
755
lcd.print(
' '
);
756
lcd.print(weekDay[Time.dayOfWeek() - 1]);
757
}
758
759
760
761
//draw graph
762
void
drawGraphFullScreen(
float
x[20]) {
763
//
764
float
maxp = -30000, minp = 30000;
765
float
divider;
766
byte
curVal;
767
//saerch max and min values in history
768
for
(
byte
i = 0; i < 20; i++)
769
{
770
if
( x[i] > maxp)
771
maxp = x[i];
772
if
( x[i] < minp)
773
minp = x[i];
774
}
775
//graph draw in 3 lines, so we have 24 pixels height graph
776
//Do not deny yourself anything =)
777
// divider - value of division of 1 pixel +0.01 to prevert division by 0
778
divider = (maxp - minp) / 24 + 0.01;
779
//write value of division
780
lcd.setCursor(14, 0);
781
lcd.print(divider);
782
783
for
(
byte
i = 0; i < 20; i++)
784
{
785
786
//draw 4 line, bottom of graph
787
curVal =
byte
((x[i] - minp) / divider);
788
lcd.setCursor(i, 3);
789
//if current value of graph catch in value 0 to 8*divider
790
//we draw chart
791
if
(curVal <= 8)
792
{
793
//seach appropriate char in array of custom chars
794
if
(curVal > 0)
795
lcd.print(
char
(ArrCharIndex[curVal]));
796
else
797
//if current val = min
798
lcd.print(
char
(2));
799
}
800
else
801
//if chart line upper than current line print blank char
802
lcd.print(
char
(ArrCharIndex[0]));
803
//draw 3 line - middle of graph
804
lcd.setCursor(i, 2);
805
if
(curVal <= 16 && curVal > 8)
806
//if current value of graph catch in value 8*divider to 16*divider
807
//we draw chart
808
//seach appropriate char in array of custom chars
809
lcd.print(
char
(ArrCharIndex[curVal - 8]));
810
else
811
//if chart line upper or lover than current line print blank char
812
lcd.print(
char
(ArrCharIndex[0]));
813
814
lcd.setCursor(i, 1);
815
//draw 4 line, bottom of graph
816
if
(curVal <= 24 && curVal > 16)
817
//if current value of graph catch in value 16*divider to 24*divider
818
lcd.print(
char
(ArrCharIndex[curVal - 16]));
819
else
820
//if chart line lover than current line print blank char
821
lcd.print(
char
(ArrCharIndex[0]));
822
}
823
}
824
825
//read data from sensors depending on currend second
826
//bool Now means read all data immideatly
827
//bool store mean save limiting values data or not
828
void
readSensors (DateTime Time, boolean Now, boolean store)
829
{
830
if
(!Now) {
831
switch
( Time.second()) {
832
833
case
20:
834
//out temp dht18d20
835
sensors.requestTemperatures();
836
OutT = sensors.getTempCByIndex(0);
837
//store limiting values and time when they arrived
838
if
(store) {
839
if
(OutT > MaxTempO) {
840
MaxTempO = OutT;
841
MaxTempOT = Time;
842
}
843
if
(OutT < MinTempO) {
844
MinTempO = OutT;
845
MinTempOT = Time;
846
}
847
}
848
849
break
;
850
case
30:
851
852
dht11.read(pinDHT11, &DHT11temperature, &Hum, NULL);
853
//store limiting values and time when they arrived
854
if
(store) {
855
if
(Hum > MaxHum) {
856
MaxHum = Hum;
857
MaxHumT = Time;
858
}
859
if
(Hum < MinHum) {
860
MinHum = Hum;
861
MinHumT = Time;
862
}
863
864
}
865
break
;
866
case
40:
867
868
float
hum(NAN);
869
uint8_t pressureUnit(0);
// unit: B000 = Pa, B001 = hPa, B010 = Hg, B011 = atm, B100 = bar, B101 = torr, B110 = N/m^2, B111 = psi
870
bme.read(Pres, InT, hum,
true
, pressureUnit);
871
hPa = Pres / 100 + Altitude / 9.4;
872
Pres = Pres * 0.00750063755419211;
873
Altitude = bme.alt(
true
);
874
//store limiting values and time when they arrived
875
if
(store) {
876
if
(Pres > MaxPressure) {
877
MaxPressure = Pres;
878
MaxPressureT = Time;
879
}
880
if
(Pres < MinPressure) {
881
MinPressure = Pres;
882
MinPressureT = Time;
883
}
884
885
if
(InT > MaxTempIn) {
886
MaxTempIn = InT;
887
MaxTempInT = Time;
888
}
889
if
(InT < MinTempIn) {
890
MinTempIn = InT;
891
MinTempInT = Time;
892
}
893
894
}
895
break
;
896
897
898
}
899
}
900
else
{
901
902
if
(store) {
903
904
}
905
//out temp dht18d20
906
sensors.requestTemperatures();
907
OutT = sensors.getTempCByIndex(0);
908
//read humidity
909
dht11.read(pinDHT11, &DHT11temperature, &Hum, NULL);
910
//reap pressure and temp
911
float
hum(NAN);
912
uint8_t pressureUnit(0);
// unit: B000 = Pa, B001 = hPa, B010 = Hg, B011 = atm, B100 = bar, B101 = torr, B110 = N/m^2, B111 = psi
913
bme.read(Pres, InT, hum,
true
, pressureUnit);
914
hPa = Pres / 100 + Altitude / 9.4;
915
//convert hPa to mmHh
916
Pres = Pres * 0.00750063755419211;
917
Altitude = bme.alt(
true
);
918
//store limiting values and time when they arrived
919
if
(store) {
920
if
(Pres > MaxPressure) {
921
MaxPressure = Pres;
922
MaxPressureT = Time;
923
}
924
if
(Pres < MinPressure) {
925
MinPressure = Pres;
926
MinPressureT = Time;
927
}
928
if
(InT > MaxTempIn) {
929
MaxTempIn = InT;
930
MaxTempInT = Time;
931
}
932
if
(InT < MinTempIn) {
933
MinTempIn = InT;
934
MinTempInT = Time;
935
}
936
if
(Hum > MaxHum) {
937
MaxHum = Hum;
938
MaxHumT = Time;
939
}
940
if
(Hum < MinHum) {
941
MinHum = Hum;
942
MinHumT = Time;
943
}
944
if
(OutT > MaxTempO) {
945
MaxTempO = OutT;
946
MaxTempOT = Time;
947
}
948
if
(OutT < MinTempO) {
949
MinTempO = OutT;
950
MinTempOT = Time;
951
}
952
953
}
954
955
956
}
957
958
}
959
960
961
// Select weather index Zambretti
962
String Forecast(
byte
Mon)
963
{
964
float
z = 0;
965
char
a;
966
//Pressure is up
967
if
(PressureHistory[19] - PressureHistory[18] > 0.8 && PressureHistory[18] - PressureHistory[17] > 0.8)
968
{
969
z = 179 - 2 * hPa / 12.9;
970
if
(Mon >= 5 && Mon <= 9)
971
z -= 2;
972
if
(Mon < 5 || Mon > 9)
973
z -= 1;
974
return
"_-"
+ ForecastText[Zarr[
int
(z)]];
975
}
976
else
977
// Pressure is down
978
if
(PressureHistory[19] - PressureHistory[18] < -0.8 && PressureHistory[18] - PressureHistory[17] < -0.8) {
979
z = 130 - hPa / 8.1;
980
return
"-_"
+ ForecastText[Zarr[
int
(z)]];
981
if
(Mon >= 5 && Mon <= 9)
982
z += 2;
983
if
(Mon < 5 || Mon > 9)
984
z += 1;
985
}
else
{
986
//stable pressure
987
z = 147 - 5 * hPa / 37.6;
988
return
"--"
+ ForecastText[Zarr[
int
(z)]];
989
}
990
//return forecast string
991
992
}
Фото основного экрана
еще фото
/sites/default/files/u29096/img_2017-05-26_123030_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123033_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123041_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123045_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123051_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123058_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123051_hdr_0.jpg
/sites/default/files/u29096/img_2017-05-26_123105_hdr.jpg
/sites/default/files/u29096/img_2017-05-26_123124_hdr.jpg
фоткать меню выставления времени не стал )
Красиво получилось
Красиво получилось
Что красивового то? Красиво - это когда черным по белому и понятным родным языком написано! :-)
Хотя бы вот так -
Красиво получилось
Что красивового то? Красиво - это когда черным по белому и понятным родным языком написано! :-)
так напишите, весь код выложен, вам надо вам и флаг в руки, мне лично безразлично, на каком из европейских языков написано
К коду замечания есть? есть - свой код в студию, посозерцаем на ваши шедевры
Лично я лучшей математики в реализации метеостанции не видел, носом ткните если знаете, что такое есть
Что красивового то? Красиво - это когда черным по белому и понятным родным языком написано! :-)
Как война закончится (надеюсь когда-нибудь это случится), куплю нормальный экран с поддержкой кирилицы, а не выдранный из неведомой хрени на барахолке и корейским шрифтом.
И как уже говорилось выше, если у вас экран это поддерживает, замените в исходнике текст, дело 5 минут. А тратить драгоценную память переменных под русские буквы, для меня непозволительно. И так думаю уже о объединении 2 МК в одном устройстве, для освобождения ресурсов. Один чисто как хранилище данных использовать. Кстати, в данном виде, если вы проведете русификацию, у вас не загрузится прошивка, не хватит бамяти. В этом коде если использовать еще 42 байта памяти переменных программа начинает работать нестабильно, из-за нехватки памяти. Тут каждая команда выверена и 3 раза оценена именно с точки зрения уменьшения объема кода. Я пробовал разные варианты одного и того же, и выбирал самый легковесный. В планах еще поковырять библиотеки, возможно там есть за счет чего освободить память.
Лично для меня основная фишка прибора - именно прогноз. Я на непосредственно программу потратил от силы 5-6 часов. С подключением устройств и долбежкой с библиотеками. И примерно 20 часов искал в интернете что то вменяемое, что можно запрограммировать.
И второй фишкой является то, что на приборе можно выставлять время без сторонних примочек.
Сейчас буду пытаться подключить к программатору эту плату, надеюсь мне очень очень повезет и эта штука окажется рабочей, несмотря на то, что в плату явно попало 220.
Нашел на барахолке, не знаю что это, но явно втыкалось в комп.
Если заработает, я спасен и я смогу сделать еще кучу хотелок.
В планах, если заработает:
*Внести все варианты ветвления прогноза калькулятора Zambretti без обобщений и сокращений, с плавной прокруткой длинных строк, что то типа бегущей строки но 1-й;
*График изменения влажности (не хватило памяти);
*Графики с заполнением, а не черточки как сейчас. И шаг графиков 6 минут, вместо 1 часа, получается очень красиво красиво, но сейчас не хватает памяти даже для 1 параметра;
*Автоматическая плавная яркость 2 экранов;
*Будильник;
*RGB Подсветка с плавным переходом оттенков в зависимости от внешней t. (холодно - синий, по мере потепления - желтый, зона комфорта - зеленый, жарко - красный;
*Внешние радио датчики температуры, влажности, освещенности и т.п. связуемые через 433мГц передатчик;
*Датчик солнечной радиации;
*Счетчик Гейгера (уже готов, собран на другом МК, но на погодной станции не хватает памяти, чтобы получать данные с него). Планировал подключение через 433мГц пердатчик, чтобы счетчик Гейгера был автономным самсодостаточным устройством, но если окажется включенным в зоне погодной станции, чтобы она автоматом тянула с него показания.
Все это можно сделать за пару часов, но... Где бы мне купить Мегу 256 по цене как на Али, а не за 4700 рублей как у нас. =)
ЗЫ мне отчасти английский даже понятнее, жене - всеравно, мелкому пока вообще всеравно какая погода, время суток и температура)
ЗЫЫ а кто сказал, что для меня русский - родной ;)
AD73360 однозначно вжаренная, шесть 16 битных ацп
_zerabot_, не принимайте все близко к сердцу. Извините, если обидел. Главное, Вы достигли цели, Вас это устраевает, а остальное .... .
>>Genri5 Да какие обиды. Просто у каждого свои вкусы и фломастеры на вкус и цвет разные )
>>ua6em Меня на плате интересует Мега 128, там есть где разгуляться в плане ресурсов. Кстати, сейчас гуглил по вопросу нехватки памяти, возможно я нашел выход. Нашел код, который позволяет хранить строковые данные в области памяти программы. А у меня там около 8 кб свободно еще, такчто возможно живем еще.
Если кто то хочет пострадать с прогнозом погоды http://monatkodenis.blogspot.com/2016/09/zambretti-3.html
Алгоритм брал отсюда. Лучше алгоритм можете не искать, т.к. похоже инфа по прогнозированию погоды является чуть ли не достоянием нации и не подлежит широкой огласке. Сведения о прогнозировании очень туманны и слабо поддаются систематизации.
На данный момент окончательный код, до сборки в железе больше изменений не планирую.
По сравнению с предыдущим вариантом добавлено:
* Автояркость на основании аналогового фоторезистора
* Меню для пользовательского выставления высоты, вызывается одновременным нажатием кнопок + и -, изменение ими же, сохранение - кнопка Set.
* Реализованны все ветвления калькулятора Zambretti в оригинальном виде без изменений.
* Уменьшенны пороги определения динамики изменения погоды. Теперь считается, что давление падает или растет если изменилось на 0.2 мм за 3 часа или 0.3 мм за 4 часа.
* Исправленна ошибка размерности, при приведении давления к уровню моря в прогнозе прибавлял mmHg к hPa.
* Все массивы использующиеся в прогнозировании объявленны константами и закинуты в память программы. Таким образом, несмотря на значительное добавление записей в эти массивы освободил около 180 байт памяти переменных.
* Косметические изменения функции вывода времени (на основном экране точки мигают, на остальных экранах всегда отображаются статично)
* Автопрокрутка длинных строк для прогноза.
* Приделан костыль для датчика 18d20, который 50/50 при первых 1-2 замерах показывает температуру 85.0, после работает стабильно неделями. Уже не первый раз сталкиваюсь.
* Почасовой график влажности.
0001
#include <EEPROM.h>
0002
//lcd
0003
#include <LiquidCrystal_PCF8574.h>
0004
LiquidCrystal_PCF8574 lcd(0x27);
0005
0006
//Clock
0007
#include <Wire.h>
0008
#include "Sodaq_DS3231.h"
0009
0010
char
weekDay[][4] = {
"Mon"
,
"Tue"
,
"Wed"
,
"Thu"
,
"Fri"
,
"Sat"
,
"Sun"
};
0011
0012
0013
0014
//barometr
0015
#include <BME280I2C.h>
0016
BME280I2C bme;
0017
float
hPa = 0;
0018
float
Altitude = 0;
0019
float
MaxPressure = 0, MinPressure = 65000;
0020
float
MaxTempO = -200, MinTempO = 200, MaxTempIn = -200, MinTempIn = 200;
0021
DateTime MaxPressureT, MinPressureT;
0022
DateTime MaxTempOT, MinTempOT, MaxTempInT, MinTempInT, TempTime;
0023
float
Pres = 0;
0024
float
InT, OutT;
0025
0026
0027
0028
0029
//LedDisplay
0030
#include "TM1637.h" // Подключаем библиотеку
0031
#define CLK 13 // К этому пину подключаем CLK
0032
#define DIO 12 // К этому пину подключаем DIO
0033
TM1637 tm1637(CLK, DIO);
0034
0035
//humidity
0036
#include <SimpleDHT.h>
0037
int
pinDHT11 = 9;
0038
SimpleDHT11 dht11;
0039
byte
Hum = 0;
0040
byte
DHT11temperature = 0;
0041
byte
MaxHum = 0, MinHum = 101;
0042
DateTime MaxHumT, MinHumT;
0043
0044
0045
0046
//buttons
0047
//set button
0048
#define BTN 6
0049
//+ button
0050
#define BTNUP 5
0051
//- button
0052
#define BTNDOWN 4
0053
//press + and - to set user altitude
0054
0055
//int LCDled = 3; // the PWM pin the LED is attached to
0056
0057
//Main Display mode 1- show main screen,2 shov max and min time... etc..
0058
int
DisplayMode = 0;
0059
0060
int
_m, _s, _mon, _day, _week;
0061
int
_h, _year;
0062
0063
0064
0065
0066
0067
//unsigned long RefreshLCD;
0068
unsigned
long
TimeReturn;
0069
DateTime now;
0070
DateTime PowerOn;
0071
byte
LastRead, ResetVals;
0072
unsigned
long
old_ts = 0;
0073
0074
0075
0076
0077
float
PressureHistory [20] = {
0078
700, 700, 700, 700, 700,
0079
700, 700, 700, 700, 700,
0080
700, 700, 700, 700, 700,
0081
700, 700, 700, 700, 700
0082
};
0083
0084
float
HumHistory [20] = {
0085
700, 700, 700, 700, 700,
0086
700, 700, 700, 700, 700,
0087
700, 700, 700, 700, 700,
0088
700, 700, 700, 700, 700
0089
};
0090
float
TempHistoryIn [20] = {
0091
-127, -127, -127, -127, -127,
0092
-127, -127, -127, -127, -127,
0093
-127, -127, -127, -127, -127,
0094
-127, -127, -127, -127, -127
0095
};
0096
float
TempHistoryOut [20] = {
0097
30, 40, 42, 39, 38,
0098
10, 40, 42, 39, 38,
0099
-1, 40, 42, 39, 38,
0100
30, 40, 42, 39, 38
0101
};
0102
0103
0104
//OutTemp
0105
#include <DallasTemperature.h>
0106
#define ONE_WIRE_BUS 8
0107
OneWire oneWire(ONE_WIRE_BUS);
0108
DallasTemperature sensors(&oneWire);
0109
0110
0111
//Chars for graph
0112
byte
ArrCharIndex[9] = {
0113
254, 2, 95, 3, 4, 176, 5, 6, 7
0114
};
0115
0116
//Zambretty array
0117
const
byte
Zarr[32] PROGMEM =
0118
{ 0,
//a
0119
1,
//b
0120
3,
//d
0121
7,
//h
0122
14,
//o
0123
17,
//r
0124
20,
//u
0125
21,
//v
0126
23,
//x
0127
0,
//a
0128
1,
//b
0129
4,
//e
0130
10,
//k
0131
13,
//n
0132
15,
//p
0133
18,
//s
0134
22,
//w
0135
23,
//x
0136
25,
//z
0137
0,
//a
0138
1,
//b
0139
2,
//c
0140
5,
//f
0141
6,
//g
0142
8,
//i
0143
9,
//j
0144
11,
//l
0145
12,
//m
0146
16,
//q
0147
19,
//t
0148
24,
//y
0149
25
//z
0150
};
0151
0152
0153
0154
0155
const
char
string_0[] PROGMEM =
"Settled fine"
;
//0
0156
const
char
string_1[] PROGMEM =
"Fine weather"
;
//0
0157
const
char
string_2[] PROGMEM =
"Becaming fine"
;
//0
0158
const
char
string_3[] PROGMEM =
"Fine, becoming less settled"
;
//0
0159
const
char
string_4[] PROGMEM =
"Fine, possible showers"
;
//0
0160
const
char
string_5[] PROGMEM =
"Fairly fine, improving"
;
//0
0161
const
char
string_6[] PROGMEM =
"Fairly fine, possible showers early"
;
//0
0162
const
char
string_7[] PROGMEM =
"Fairly fine, showery later"
;
//0
0163
const
char
string_8[] PROGMEM =
"Showery early, improving"
;
//0
0164
const
char
string_9[] PROGMEM =
"Changeable, mending"
;
//0
0165
const
char
string_10[] PROGMEM =
"Fairly fine, showers likely"
;
//0
0166
0167
const
char
string_11[] PROGMEM =
"Rather unsettled clearing later"
;
//0
0168
const
char
string_12[] PROGMEM =
"Unsettled, probably improving"
;
//0
0169
const
char
string_13[] PROGMEM =
"Showery, bright intervals"
;
//0
0170
const
char
string_14[] PROGMEM =
"Showery, becoming less settled"
;
//0
0171
const
char
string_15[] PROGMEM =
"Changeable, some rain"
;
//0
0172
const
char
string_16[] PROGMEM =
"Unsettled, short fine intervals"
;
//0
0173
const
char
string_17[] PROGMEM =
"Unsettled, rain later"
;
//0
0174
const
char
string_18[] PROGMEM =
"Unsettled, some rain"
;
//0
0175
const
char
string_19[] PROGMEM =
"Mostly very unsettled"
;
//0
0176
const
char
string_20[] PROGMEM =
"Occasional rain, worsening"
;
//0
0177
0178
const
char
string_21[] PROGMEM =
"Rain at times, very unsettled"
;
//0
0179
const
char
string_22[] PROGMEM =
"Rain at frequent intervals"
;
//0
0180
const
char
string_23[] PROGMEM =
"Rain, very unsettled"
;
//0
0181
const
char
string_24[] PROGMEM =
"Stormy, may improve"
;
//0
0182
const
char
string_25[] PROGMEM =
"Stormy, much rain"
;
//0
0183
0184
const
char
*
const
string_table[] PROGMEM = {
0185
string_0,
0186
string_1,
0187
string_2,
0188
string_3,
0189
string_4,
0190
string_5,
0191
string_6,
0192
string_7,
0193
string_8,
0194
string_9,
0195
string_10,
0196
string_11,
0197
string_12,
0198
string_13,
0199
string_14,
0200
string_15,
0201
string_16,
0202
string_17,
0203
string_18,
0204
string_19,
0205
string_20,
0206
string_21,
0207
string_22,
0208
string_23,
0209
string_24,
0210
string_25
0211
};
0212
0213
//hum icon
0214
const
byte
HumCHR[8] = {
0215
B00100,
0216
B00100,
0217
B01010,
0218
B01010,
0219
B10001,
0220
B10001,
0221
B10001,
0222
B01110
0223
};
0224
//temp icon
0225
const
byte
Temp[8] = {
0226
B00100,
0227
B01010,
0228
B01010,
0229
B01110,
0230
B01110,
0231
B11111,
0232
B11111,
0233
B01110
0234
};
0235
0236
//graph char 1/8
0237
const
byte
ch1[8] = {
0238
B00000,
0239
B00000,
0240
B00000,
0241
B00000,
0242
B00000,
0243
B00000,
0244
B00000,
0245
B11111
0246
};
0247
//graph char 2/8 is _ char
0248
0249
//graph char 3/8
0250
const
byte
ch3[8] = {
0251
B00000,
0252
B00000,
0253
B00000,
0254
B00000,
0255
B00000,
0256
B11111,
0257
B00000,
0258
B00000
0259
};
0260
//graph chars 4/8
0261
const
byte
ch4[8] = {
0262
B00000,
0263
B00000,
0264
B00000,
0265
B00000,
0266
B11111,
0267
B00000,
0268
B00000,
0269
B00000
0270
};
0271
0272
//graph char 5/8 is - char
0273
0274
//graph chars 6/8
0275
const
byte
ch6[8] = {
0276
B00000,
0277
B00000,
0278
B11111,
0279
B00000,
0280
B00000,
0281
B00000,
0282
B00000,
0283
B00000
0284
};
0285
0286
//graph char 7/8
0287
const
byte
ch7[8] = {
0288
B00000,
0289
B11111,
0290
B00000,
0291
B00000,
0292
B00000,
0293
B00000,
0294
B00000
0295
};
0296
0297
//graph char 8/8
0298
const
byte
ch8[8] = {
0299
B11111,
0300
B00000,
0301
B00000,
0302
B00000,
0303
B00000,
0304
B00000,
0305
B00000
0306
};
0307
int
scroll = 0;
0308
char
buffer [33];
0309
byte
UpDownStable = 0;
0310
int
UserAltitude;
0311
void
setup
()
0312
{
0313
0314
pinMode(3, OUTPUT);
0315
pinMode(BTN, INPUT_PULLUP);
0316
pinMode(BTNUP, INPUT_PULLUP);
0317
pinMode(BTNDOWN, INPUT_PULLUP);
0318
0319
0320
0321
0322
0323
0324
Wire.begin();
0325
Wire.beginTransmission(0x27);
0326
0327
lcd.begin(20, 4);
// initialize the lcd
0328
//load custom chars
0329
// lcd.setBacklight(255);
0330
lcd.createChar (0, Temp);
0331
lcd.createChar (1, HumCHR);
0332
lcd.createChar (2, ch1);
0333
lcd.createChar (3, ch3);
0334
lcd.createChar (4, ch4);
0335
lcd.createChar (5, ch6);
0336
lcd.createChar (6, ch7);
0337
lcd.createChar (7, ch8);
0338
0339
//must be called after loading chars
0340
lcd.home();
0341
lcd.clear();
0342
while
(!bme.begin()) {
0343
lcd.clear();
0344
lcd.print(
"PrSensorError"
);
0345
}
0346
while
(!rtc.begin()) {
0347
lcd.clear();
0348
lcd.print(
"ClockError"
);
0349
}
0350
0351
0352
// SetBrightness(brightness);
0353
tm1637.init();
0354
tm1637.
set
(7);
0355
0356
//Высота над уровнем моря
0357
UserAltitude = EEPROMReadInt(0);
0358
0359
//just read data from sensors. ds18d20 sometimes in first 1-2 read return 85.0C
0360
while
(OutT==85)
0361
readSensors(rtc.now(),
true
,
false
);
0362
0363
PowerOn = rtc.now();
0364
LastRead = rtc.now().hour();
0365
ResetVals = rtc.now().date();
0366
//store first values from sensors to limit values
0367
0368
0369
0370
readSensors(rtc.now(),
true
,
true
);
0371
//save current values from the sensors to history
0372
//for normal graph view in first 20 hours of work
0373
for
(
int
tt = 0; tt < 20; tt++)
0374
{
0375
PressureHistory[tt] = Pres;
0376
TempHistoryIn[tt] = InT;
0377
TempHistoryOut[tt] = OutT;
0378
HumHistory[tt]=Hum;
0379
0380
}
0381
//show main screen by default
0382
DisplayMode = 1;
0383
//try to forecast =)
0384
Forecast(now.month());
0385
Serial
.begin(9600);
0386
0387
}
0388
0389
0390
0391
void
loop
()
0392
{
0393
//return to main screen from any other mode in 10 sec inactivity
0394
if
( millis() - TimeReturn > 10000) {
0395
if
(DisplayMode != 1) {
0396
lcd.clear();
0397
lcd.home();
0398
DisplayMode = 1;
0399
}
0400
TimeReturn = millis();
0401
}
0402
//main screen
0403
if
(DisplayMode == 1 ) {
0404
now = rtc.now();
//get the current date-time
0405
uint32_t ts = now.getEpoch();
0406
//check second changed or not
0407
if
(old_ts != ts) {
0408
scroll++;
0409
old_ts = ts;
0410
//Write time on tm1367
0411
tm1637.display(0, now.hour() / 10);
0412
tm1637.display(1, now.hour() % 10);
0413
tm1637.display(2, now.minute() / 10);
0414
tm1637.display(3, now.minute() % 10);
0415
//blink dot
0416
tm1637.point(ts % 2 == 0 ? POINT_OFF : POINT_ON);
0417
//write current time and date on 20*4
0418
0419
WriteTimeDT(now, 0, 0,
false
);
0420
WriteDateDT(now, 6, 0);
0421
//if hour changes store current sensor values to history
0422
if
(LastRead != now.hour())
0423
{
0424
LastRead = now.hour();
0425
readSensors(rtc.now(),
true
,
true
);
0426
for
(
byte
i = 0; i < 19; i++) {
0427
PressureHistory[i] = PressureHistory[i + 1];
0428
TempHistoryIn[i] = TempHistoryIn[i + 1];
0429
TempHistoryOut[i] = TempHistoryOut[i + 1];
0430
HumHistory[i]=HumHistory[i+1];
0431
0432
}
0433
TempHistoryIn[19] = InT;
0434
TempHistoryOut[19] = OutT;
0435
PressureHistory[19] = Pres;
0436
HumHistory[19]=Hum;
0437
//if date changes reset limit values
0438
if
( ResetVals != now.date()) {
0439
ResetVals = now.date();
0440
MaxTempO = -200;
0441
MinTempO = 200;
0442
MaxTempIn = -200;
0443
MinTempIn = 200;
0444
MaxPressure = 0;
0445
MinPressure = 65000;
0446
MaxHum = 0;
0447
MinHum = 101;
0448
readSensors(rtc.now(),
true
,
true
);
0449
}
0450
}
0451
//read sensors values
0452
//each sensor interrogated 1 time per 60 seconds
0453
//and 20 seconds delay between different sensors
0454
if
(now.second() % 10 == 0 && now.second() > 0)
0455
{
0456
SetBrightness(analogRead(1));
0457
readSensors(now,
false
,
true
);
0458
lcd.setCursor(0, 3);
0459
lcd.print(
" "
);
0460
lcd.setCursor(0, 3);
0461
//try to forecast
0462
//this function wrute on 4 line forecast
0463
//lcd.print(Forecast(now.month()));
0464
Forecast(now.month());
0465
//serial write some data
0466
Serial
.print(
"<h"
);
0467
Serial
.print(now.hour());
0468
Serial
.print(
"m"
);
0469
Serial
.print(now.minute());
0470
Serial
.print(
"s"
);
0471
Serial
.print(now.second());
0472
Serial
.print(
"D"
);
0473
Serial
.print(now.date());
0474
Serial
.print(
"M"
);
0475
Serial
.print(now.month());
0476
Serial
.print(
"Y"
);
0477
Serial
.print(now.year());
0478
Serial
.print(
"d"
);
0479
Serial
.print(weekDay[now.dayOfWeek() - 1]);
0480
Serial
.print(
"InT"
);
0481
Serial
.print(InT);
0482
Serial
.print(
"Out"
);
0483
Serial
.print(OutT);
0484
Serial
.print(
"Hum"
);
0485
Serial
.print(Hum);
0486
Serial
.print(
"Pres"
);
0487
Serial
.print(Pres);
0488
Serial
.print(
"F-t"
);
0489
Serial
.print(buffer);
0490
Serial
.println(
">"
);
0491
}
0492
}
0493
0494
//2 line
0495
lcd.setCursor(0, 1);
0496
//write in temp
0497
lcd.print(
"In"
);
0498
//write custom temp char
0499
lcd.print(
char
(0));
0500
lcd.print(InT);
0501
//write out temp
0502
lcd.print(
" Out"
);
0503
//write custom temp char
0504
lcd.print(
char
(0));
0505
lcd.print(OutT);
0506
//3 line
0507
lcd.setCursor(0, 2);
0508
//write custom humidity char
0509
lcd.print(
char
(1));
0510
//write humidity
0511
lcd.print(Hum);
0512
lcd.print(
"% "
);
0513
lcd.print(Pres);
0514
lcd.print(
"mmHg "
);
0515
scrollInFromRight(3, buffer);
0516
}
0517
0518
//show limit waluea for out temp
0519
if
(DisplayMode == 2)
0520
{
0521
lcd.setCursor(0, 0);
0522
lcd.print(
"Max out t"
);
0523
WriteTimeDT(MaxTempOT, 0, 13,
true
);
0524
lcd.setCursor(0, 1);
0525
lcd.print(MaxTempO);
0526
lcd.setCursor(0, 2);
0527
lcd.print(
"Min out t"
);
0528
WriteTimeDT(MinTempOT, 2, 13,
true
);
0529
lcd.setCursor(0, 3);
0530
lcd.print(MinTempO);
0531
}
0532
//draw graph for out temp
0533
if
(DisplayMode == 3)
0534
{
0535
lcd.setCursor(0, 0);
0536
lcd.print(
"Out t hist"
);
0537
drawGraphFullScreen(TempHistoryOut);
0538
}
0539
//show limit walues for in temp
0540
if
(DisplayMode == 4)
0541
{
0542
lcd.setCursor(0, 0);
0543
lcd.print(
"Max in t"
);
0544
WriteTimeDT(MaxTempInT, 0, 13,
true
);
0545
lcd.setCursor(0, 1);
0546
lcd.print(MaxTempIn);
0547
lcd.setCursor(0, 2);
0548
lcd.print(
"Min in t"
);
0549
WriteTimeDT(MinTempInT, 2, 13,
true
);
0550
lcd.setCursor(0, 3);
0551
lcd.print(MinTempIn);
0552
}
0553
//draw graph for in temp
0554
if
(DisplayMode == 5)
0555
{
0556
lcd.setCursor(0, 0);
0557
lcd.print(
"In t hist"
);
0558
drawGraphFullScreen(TempHistoryIn);
0559
}
0560
//show limit walues for pressure
0561
if
(DisplayMode == 6)
0562
{
0563
lcd.setCursor(0, 0);
0564
lcd.print(
"Max pressure"
);
0565
WriteTimeDT(MaxPressureT, 0, 13,
true
);
0566
lcd.setCursor(0, 1);
0567
lcd.print(MaxPressure);
0568
lcd.setCursor(0, 2);
0569
lcd.print(
"Min pressure"
);
0570
WriteTimeDT(MinPressureT, 2, 13,
true
);
0571
lcd.setCursor(0, 3);
0572
lcd.print(MinPressure);
0573
}
0574
//draw graph for pressure
0575
if
(DisplayMode == 7)
0576
{
0577
lcd.setCursor(0, 0);
0578
lcd.print(
"Pressure hist"
);
0579
drawGraphFullScreen(PressureHistory);
0580
}
0581
//show limit walues for humidity
0582
if
(DisplayMode == 8)
0583
{
0584
lcd.setCursor(0, 0);
0585
lcd.print(
"Max humidity"
);
0586
WriteTimeDT(MaxHumT, 0, 13,
true
);
0587
lcd.setCursor(0, 1);
0588
lcd.print(MaxHum);
0589
lcd.setCursor(0, 2);
0590
lcd.print(
"Min humidity"
);
0591
WriteTimeDT(MinHumT, 2, 13,
true
);
0592
lcd.setCursor(0, 3);
0593
lcd.print(MinHum);
0594
}
0595
0596
if
(DisplayMode == 9)
0597
{
0598
lcd.setCursor(0, 0);
0599
lcd.print(
"Humidity hist"
);
0600
drawGraphFullScreen(HumHistory);
0601
}
0602
0603
//show Altitude, uptime and (c)
0604
if
(DisplayMode == 10)
0605
{
0606
lcd.setCursor(0, 0);
0607
lcd.print(
"Altitude "
);
0608
lcd.print(Altitude);
0609
lcd.print(
"m "
);
0610
0611
lcd.setCursor(0, 1);
0612
lcd.print(
"PowerOn"
);
0613
WriteTimeDT(PowerOn, 2, 0,
true
);
0614
WriteDateDT(PowerOn, 6, 2);
0615
lcd.setCursor(0, 3);
0616
lcd.print(
"(c)IvanchenkoAV 2017"
);
0617
}
0618
0619
//if button up pressed
0620
if
(!digitalRead(BTNUP) && DisplayMode < 100 && DisplayMode != 20)
0621
{
0622
DisplayMode++;
0623
lcd.clear();
0624
0625
}
0626
//if button down pressed
0627
if
(!digitalRead(BTNDOWN) && DisplayMode < 100 && DisplayMode != 20)
0628
{
0629
DisplayMode--;
0630
lcd.clear();
0631
0632
}
0633
0634
if
(!digitalRead(BTNUP) && !digitalRead(BTNDOWN) && DisplayMode < 100)
0635
{
0636
DisplayMode = 20;
0637
lcd.clear();
0638
0639
}
0640
0641
if
(DisplayMode == 20)
0642
{
0643
lcd.setCursor(0, 0);
0644
lcd.print(
"Altitude "
);
0645
0646
lcd.print(UserAltitude);
0647
lcd.print(
"m"
);
0648
lcd.setCursor(0, 1);
0649
lcd.print(
"press Set to save"
);
0650
0651
0652
if
(!digitalRead(BTNUP))
0653
UserAltitude++;
0654
if
(!digitalRead(BTNDOWN))
0655
UserAltitude--;
0656
0657
if
(!digitalRead(BTN))
0658
{
0659
EEPROMWriteInt(0, UserAltitude);
0660
lcd.clear();
0661
lcd.print(
"Saved"
);
0662
delay(1000);
0663
DisplayMode = 1;
0664
}
0665
0666
if
(UserAltitude > 800)
0667
UserAltitude = 0;
0668
if
(UserAltitude < 0)
0669
UserAltitude = 800;
0670
}
0671
0672
//display menu limits
0673
if
(DisplayMode == 11)
0674
{
0675
DisplayMode = 1;
0676
}
0677
//display menu limits
0678
if
(DisplayMode == 0)
0679
{
0680
DisplayMode = 10;
0681
}
0682
0683
//set button pressed
0684
if
(!digitalRead(BTN)) {
0685
TimeReturn = millis();
0686
//if set button pressed in main screen mode
0687
if
(DisplayMode < 100)
0688
{
0689
DisplayMode = 100;
0690
//save current time to temp values
0691
TempTime = rtc.now();
0692
_h = TempTime.hour();
0693
_m = TempTime.minute();
0694
_day = TempTime.date();
0695
_mon = TempTime.month();
0696
_year = TempTime.year();
0697
_week = TempTime.dayOfWeek();
0698
}
0699
else
0700
//if button pressed in set mode
0701
DisplayMode++;
0702
//menu limit
0703
if
(DisplayMode == 107) {
0704
lcd.setCursor(0, 1);
0705
lcd.print(
"Cancel"
);
0706
delay(3000);
0707
DisplayMode = 1;
0708
lcd.clear();
0709
}
0710
//delay(300);
0711
0712
}
0713
delay(200);
0714
//disp.set(brightness / 64 + 1);
0715
0716
//reset time return if any buton pressed
0717
if
(!digitalRead(BTNUP) || !digitalRead(BTNDOWN)) {
0718
TimeReturn = millis();
0719
}
0720
//temp hour set
0721
if
(DisplayMode == 100)
0722
{
0723
if
(!digitalRead(BTNUP))
0724
_h++;
0725
if
(!digitalRead(BTNDOWN))
0726
_h--;
0727
0728
if
(_h > 23)
0729
_h = 0;
0730
if
(_h < 0)
0731
_h = 23;
0732
lcd.clear();
0733
lcd.home();
0734
lcd.print(
"Hour "
);
0735
lcd.print(_h);
0736
}
0737
//temp minute set
0738
if
(DisplayMode == 101)
0739
{
0740
0741
if
(!digitalRead(BTNUP))
0742
_m++;
0743
if
(!digitalRead(BTNDOWN))
0744
_m--;
0745
0746
if
(_m >= 60)
0747
_m = 0;
0748
if
(_m < 0)
0749
_m = 59;
0750
lcd.clear();
0751
lcd.home();
0752
lcd.print(
"Minute "
);
0753
lcd.print(_m);
0754
}
0755
//temp date set
0756
if
(DisplayMode == 102)
0757
{
0758
0759
if
(!digitalRead(BTNUP))
0760
_day++;
0761
if
(!digitalRead(BTNDOWN))
0762
_day--;
0763
0764
if
(_day > 31)
0765
_day = 1;
0766
if
(_day < 1)
0767
_day = 31;
0768
lcd.clear();
0769
lcd.home();
0770
lcd.print(
"Day "
);
0771
lcd.print(_day);
0772
}
0773
//temp month set
0774
if
(DisplayMode == 103)
0775
{
0776
if
(!digitalRead(BTNUP))
0777
_mon++;
0778
if
(!digitalRead(BTNDOWN))
0779
_mon--;
0780
0781
if
(_mon > 12)
0782
_mon = 1;
0783
if
(_mon < 1)
0784
_mon = 12;
0785
lcd.clear();
0786
lcd.home();
0787
lcd.print(
"Month "
);
0788
lcd.print(_mon);
0789
}
0790
//temp year set
0791
if
(DisplayMode == 104)
0792
{
0793
0794
if
(!digitalRead(BTNUP))
0795
_year++;
0796
if
(!digitalRead(BTNDOWN))
0797
_year--;
0798
0799
if
(_year > 3000)
0800
_year = 1;
0801
if
(_year < 1)
0802
_year = 3000;
0803
0804
lcd.clear();
0805
lcd.home();
0806
lcd.print(
"Year "
);
0807
lcd.print(_year);
0808
}
0809
//temp weekday set
0810
if
(DisplayMode == 105)
0811
{
0812
if
(!digitalRead(BTNUP))
0813
_week++;
0814
if
(!digitalRead(BTNDOWN))
0815
_week--;
0816
0817
if
(_week > 7)
0818
_week = 1;
0819
if
(_week < 1)
0820
_week = 7;
0821
0822
0823
lcd.clear();
0824
lcd.home();
0825
lcd.print(
"WeekDay "
);
0826
lcd.print(weekDay[_week - 1]);
0827
}
0828
// set new time?
0829
if
(DisplayMode == 106)
0830
{
0831
lcd.clear();
0832
lcd.home();
0833
lcd.print(
"Save Y/N?"
);
0834
0835
//if button up pressed save new time
0836
if
(!digitalRead(BTNUP))
0837
{
0838
DateTime dt(_year, _mon, _day, _h, _m, 0, _week);
0839
rtc.setDateTime(dt);
0840
lcd.setCursor(0, 1);
0841
lcd.print(
"Ok"
);
0842
delay(3000);
0843
DisplayMode = 1;
0844
lcd.clear();
0845
}
0846
//if button down pressed - exit to main screen
0847
if
(!digitalRead(BTNDOWN)) {
0848
lcd.setCursor(0, 1);
0849
lcd.print(
"Cancel"
);
0850
delay(3000);
0851
DisplayMode = 1;
0852
lcd.clear();
0853
}
0854
}
0855
}
0856
//write time in x,y of lcd
0857
void
WriteTimeDT(DateTime Time,
byte
y,
byte
x,boolean dot) {
0858
lcd.setCursor(x, y);
0859
if
(Time.hour() < 10)
0860
lcd.print(
'0'
);
0861
lcd.print(Time.hour());
0862
lcd.print(Time.second() % 2 == 0||dot ?
':'
:
' '
);
0863
if
(Time.minute() < 10)
0864
lcd.print(
'0'
);
0865
lcd.print(Time.minute());
0866
}
0867
//write date in x,y of lcd
0868
void
WriteDateDT(DateTime Time,
int
x,
int
y) {
0869
lcd.setCursor(x, y);
0870
if
(Time.date() < 10)
0871
lcd.print(
'0'
);
0872
lcd.print(Time.date());
0873
lcd.print(
'/'
);
0874
if
(Time.month() < 10)
0875
lcd.print(
'0'
);
0876
lcd.print(Time.month());
0877
lcd.print(
'/'
);
0878
lcd.print(Time.year());
0879
lcd.print(
' '
);
0880
lcd.print(weekDay[Time.dayOfWeek() - 1]);
0881
}
0882
0883
0884
0885
//draw graph
0886
void
drawGraphFullScreen(
float
x[20]) {
0887
//
0888
float
maxp = -30000, minp = 30000;
0889
float
divider;
0890
byte
curVal;
0891
//saerch max and min values in history
0892
for
(
byte
i = 0; i < 20; i++)
0893
{
0894
if
( x[i] > maxp)
0895
maxp = x[i];
0896
if
( x[i] < minp)
0897
minp = x[i];
0898
}
0899
//graph draw in 3 lines, so we have 24 pixels height graph
0900
//Do not deny yourself anything =)
0901
// divider - value of division of 1 pixel +0.01 to prevert division by 0
0902
divider = (maxp - minp) / 24 + 0.01;
0903
//write value of division
0904
lcd.setCursor(14, 0);
0905
lcd.print(divider);
0906
0907
for
(
byte
i = 0; i < 20; i++)
0908
{
0909
0910
//draw 4 line, bottom of graph
0911
curVal =
byte
((x[i] - minp) / divider);
0912
lcd.setCursor(i, 3);
0913
//if current value of graph catch in value 0 to 8*divider
0914
//we draw chart
0915
if
(curVal <= 8)
0916
{
0917
//seach appropriate char in array of custom chars
0918
if
(curVal > 0)
0919
lcd.print(
char
(ArrCharIndex[curVal]));
0920
else
0921
//if current val = min
0922
lcd.print(
char
(2));
0923
}
0924
else
0925
//if chart line upper than current line print blank char
0926
lcd.print(
char
(ArrCharIndex[0]));
0927
//draw 3 line - middle of graph
0928
lcd.setCursor(i, 2);
0929
if
(curVal <= 16 && curVal > 8)
0930
//if current value of graph catch in value 8*divider to 16*divider
0931
//we draw chart
0932
//seach appropriate char in array of custom chars
0933
lcd.print(
char
(ArrCharIndex[curVal - 8]));
0934
else
0935
//if chart line upper or lover than current line print blank char
0936
lcd.print(
char
(ArrCharIndex[0]));
0937
0938
lcd.setCursor(i, 1);
0939
//draw 4 line, bottom of graph
0940
if
(curVal <= 24 && curVal > 16)
0941
//if current value of graph catch in value 16*divider to 24*divider
0942
lcd.print(
char
(ArrCharIndex[curVal - 16]));
0943
else
0944
//if chart line lover than current line print blank char
0945
lcd.print(
char
(ArrCharIndex[0]));
0946
}
0947
}
0948
0949
//read data from sensors depending on currend second
0950
//bool Now means read all data immideatly
0951
//bool store mean save limiting values data or not
0952
void
readSensors (DateTime Time, boolean Now, boolean store)
0953
{
0954
if
(!Now) {
0955
switch
( Time.second()) {
0956
0957
case
20:
0958
//out temp dht18d20
0959
sensors.requestTemperatures();
0960
OutT = sensors.getTempCByIndex(0);
0961
//store limiting values and time when they arrived
0962
if
(store) {
0963
if
(OutT > MaxTempO) {
0964
MaxTempO = OutT;
0965
MaxTempOT = Time;
0966
}
0967
if
(OutT < MinTempO) {
0968
MinTempO = OutT;
0969
MinTempOT = Time;
0970
}
0971
}
0972
0973
break
;
0974
case
30:
0975
0976
dht11.read(pinDHT11, &DHT11temperature, &Hum, NULL);
0977
//store limiting values and time when they arrived
0978
if
(store) {
0979
if
(Hum > MaxHum) {
0980
MaxHum = Hum;
0981
MaxHumT = Time;
0982
}
0983
if
(Hum < MinHum) {
0984
MinHum = Hum;
0985
MinHumT = Time;
0986
}
0987
0988
}
0989
break
;
0990
case
40:
0991
0992
float
hum(NAN);
0993
uint8_t pressureUnit(0);
// unit: B000 = Pa, B001 = hPa, B010 = Hg, B011 = atm, B100 = bar, B101 = torr, B110 = N/m^2, B111 = psi
0994
bme.read(Pres, InT, hum,
true
, pressureUnit);
0995
hPa = Pres / 100+
float
(UserAltitude* 12.502 / 100);
0996
Pres = Pres * 0.00750063755419211;
0997
Altitude = bme.alt(
true
);
0998
//store limiting values and time when they arrived
0999
if
(store) {
1000
if
(Pres > MaxPressure) {
1001
MaxPressure = Pres;
1002
MaxPressureT = Time;
1003
}
1004
if
(Pres < MinPressure) {
1005
MinPressure = Pres;
1006
MinPressureT = Time;
1007
}
1008
1009
if
(InT > MaxTempIn) {
1010
MaxTempIn = InT;
1011
MaxTempInT = Time;
1012
}
1013
if
(InT < MinTempIn) {
1014
MinTempIn = InT;
1015
MinTempInT = Time;
1016
}
1017
1018
}
1019
break
;
1020
1021
1022
}
1023
}
1024
else
{
1025
1026
if
(store) {
1027
1028
}
1029
//out temp dht18d20
1030
sensors.requestTemperatures();
1031
OutT = sensors.getTempCByIndex(0);
1032
//read humidity
1033
dht11.read(pinDHT11, &DHT11temperature, &Hum, NULL);
1034
//reap pressure and temp
1035
float
hum(NAN);
1036
uint8_t pressureUnit(0);
// unit: B000 = Pa, B001 = hPa, B010 = Hg, B011 = atm, B100 = bar, B101 = torr, B110 = N/m^2, B111 = psi
1037
bme.read(Pres, InT, hum,
true
, pressureUnit);
1038
hPa = Pres / 100+
float
(UserAltitude* 12.502 / 100) ;
1039
//convert hPa to mmHh
1040
Pres = Pres * 0.00750063755419211;
1041
Altitude = bme.alt(
true
);
1042
//store limiting values and time when they arrived
1043
if
(store) {
1044
if
(Pres > MaxPressure) {
1045
MaxPressure = Pres;
1046
MaxPressureT = Time;
1047
}
1048
if
(Pres < MinPressure) {
1049
MinPressure = Pres;
1050
MinPressureT = Time;
1051
}
1052
if
(InT > MaxTempIn) {
1053
MaxTempIn = InT;
1054
MaxTempInT = Time;
1055
}
1056
if
(InT < MinTempIn) {
1057
MinTempIn = InT;
1058
MinTempInT = Time;
1059
}
1060
if
(Hum > MaxHum) {
1061
MaxHum = Hum;
1062
MaxHumT = Time;
1063
}
1064
if
(Hum < MinHum) {
1065
MinHum = Hum;
1066
MinHumT = Time;
1067
}
1068
if
(OutT > MaxTempO) {
1069
MaxTempO = OutT;
1070
MaxTempOT = Time;
1071
}
1072
if
(OutT < MinTempO) {
1073
MinTempO = OutT;
1074
MinTempOT = Time;
1075
}
1076
1077
}
1078
1079
1080
}
1081
1082
}
1083
1084
1085
// Select weather index Zambretti
1086
byte
Forecast(
byte
Mon)
1087
{
1088
float
z = 0;
1089
char
a;
1090
//Pressure is up
1091
if
((PressureHistory[19] >= PressureHistory[18] || PressureHistory[18] >= PressureHistory[17] ) && (PressureHistory[19] - PressureHistory[17] > 0.3 || PressureHistory[19] - PressureHistory[16] > 0.2))
1092
{
1093
z = 179 - 2 * hPa / 12.9;
1094
if
(Mon >= 5 && Mon <= 9)
1095
z -= 2;
1096
if
(Mon < 5 || Mon > 9)
1097
z -= 1;
1098
strcpy_P(buffer, (
char
*)pgm_read_word(&(string_table[pgm_read_byte(&Zarr[
int
(z)])])));
1099
UpDownStable = 1;
1100
}
1101
else
1102
// Pressure is down
1103
if
((PressureHistory[19] - PressureHistory[17] <= -0.3 || PressureHistory[19] - PressureHistory[16] <= -0.2) && ( PressureHistory[19] <= PressureHistory[18] || PressureHistory[18] <= PressureHistory[17]))
1104
{
1105
z = 130 - hPa / 8.1;
1106
strcpy_P(buffer, (
char
*)pgm_read_word(&(string_table[pgm_read_byte(&Zarr[
int
(z)])])));
1107
1108
//return "-_" + ForecastText[Zarr[int(z)]];
1109
if
(Mon >= 5 && Mon <= 9)
1110
z += 2;
1111
if
(Mon < 5 || Mon > 9)
1112
z += 1;
1113
UpDownStable = 2;
1114
}
else
{
1115
//stable pressure
1116
z = 147 - 5 * hPa / 37.6;
1117
strcpy_P(buffer, (
char
*)pgm_read_word(&(string_table[pgm_read_byte(&Zarr[
int
(z)])])));
1118
UpDownStable = 3;
1119
}
1120
}
1121
1122
//write scroll text
1123
void
scrollInFromRight (
byte
line,
char
str1[]) {
1124
String s = buffer;
1125
byte
len = strlen(str1);
1126
lcd.setCursor(0, line);
1127
//15 instead 20 to see, that line ends
1128
if
(len - scroll < 15)
1129
scroll = 0;
1130
lcd.print(s.substring(scroll, scroll + 20 > len ? len : scroll + 20));
1131
if
(len - scroll < 20)
1132
lcd.print(
" "
);
1133
1134
}
1135
void
SetBrightness(
int
brightness)
1136
{
1137
1138
analogWrite(3, constrain( map(brightness / 4, 0, 255, 70, 255), 70, 255));
1139
}
1140
1141
void
EEPROMWriteInt(
int
p_address,
int
p_value)
1142
{
1143
byte
lowByte = ((p_value >> 0) & 0xFF);
1144
byte
highByte = ((p_value >> 8) & 0xFF);
1145
1146
EEPROM.write(p_address, lowByte);
1147
EEPROM.write(p_address + 1, highByte);
1148
}
1149
1150
//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
1151
unsigned
int
EEPROMReadInt(
int
p_address)
1152
{
1153
byte
lowByte = EEPROM.read(p_address);
1154
byte
highByte = EEPROM.read(p_address + 1);
1155
1156
return
((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
1157
}
Кстати, сейчас на eBay активно продаются аналоги (судя по маркировке) BMP280 и фейковые BME280 с прямоугольным а не квадратным чипом. В конце июня получил свой BMP280 датчик, так не смог заставить его работать ни по SPI ни по I2C. Продавец вернул деньги и только сегодня я заметил, что чип впаян вверх ногами. Сдул и перепаял - работает отлично. Обратите внимание, что отверстие чипа должно быть направлено к резисторам а не к конденсатору. На фото неправильно впаянный чип.
у меня получилось вот это...
001
#include <Wire.h>
002
#include <DS1307RTC.h>
003
#include <Time.h>
004
#include <LiquidCrystal_I2C.h>
005
#include <Adafruit_Sensor.h>
006
#include <Adafruit_BMP280.h>
007
#define BMP_CS 10
008
009
LiquidCrystal_I2C lcd(0x3f,20,4);
010
static
byte
addon_letters[16];
011
void
init_rus(
const
char
* letters_use )
012
{
013
static
byte
letters[][8] = {
014
{ B11110, B10000, B10000, B11110, B10001, B10001, B11110, B00000 },
//Б
015
{ B11111, B10000, B10000, B10000, B10000, B10000, B10000, B00000 },
//Г
016
{ B00110, B01010, B01010, B01010, B01010, B11111, B10001, B00000 },
//Д
017
{ B10001, B10101, B10101, B01110, B10101, B10101, B10001, B00000 },
//Ж
018
{ B01110, B10001, B00001, B00110, B00001, B10001, B01110, B00000 },
//З
019
{ B10001, B10001, B10001, B10011, B10101, B11001, B10001, B00000 },
//И
020
{ B10101, B10001, B10001, B10011, B10101, B11001, B10001, B00000 },
//Й
021
{ B00110, B01001, B01001, B01001, B01001, B01001, B11001, B00000 },
//Л
022
{ B11111, B10001, B10001, B10001, B10001, B10001, B10001, B00000 },
//П
023
{ B10001, B10001, B10001, B01111, B00001, B10001, B01110, B00000 },
//У
024
{ B01110, B10101, B10101, B10101, B01110, B00100, B00100, B00000 },
//Ф
025
{ B10010, B10010, B10010, B10010, B10010, B10010, B11111, B00001 },
//Ц
026
{ B10001, B10001, B10001, B01111, B00001, B00001, B00001, B00000 },
//Ч
027
{ B10101, B10101, B10101, B10101, B10101, B10101, B11111, B00000 },
//Ш
028
{ B10101, B10101, B10101, B10101, B10101, B10101, B11111, B00001 },
//Щ
029
{ B10000, B10000, B10000, B11110, B10001, B10001, B11110, B00000 },
//Ь
030
{ B11000, B01000, B01000, B01110, B01001, B01001, B01110, B00000 },
//Ъ
031
{ B10001, B10001, B10001, B11001, B10101, B10101, B11001, B00000 },
//Ы
032
{ B01110, B10001, B00001, B00111, B00001, B10001, B01110, B00000 },
//Э
033
{ B10010, B10101, B10101, B11101, B10101, B10101, B10010, B00000 },
//Ю
034
{ B01111, B10001, B10001, B01111, B00101, B01001, B10001, B00000 },
//Я
035
{ B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000 },
//г
036
};
037
static
char
chars[] = {
'Б'
,
'Г'
,
'Д'
,
'Ж'
,
'З'
,
'И'
,
'Й'
,
'Л'
,
'П'
,
'У'
,
'Ф'
,
'Ц'
,
'Ч'
,
'Ш'
,
'Щ'
,
'Ь'
,
'Ъ'
,
'Ы'
,
'Э'
,
'Ю'
,
'Я'
,
'г'
};
038
static
byte
empty[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
039
int
index = 0, cl =
sizeof
(chars)/
sizeof
(
char
),i,j,symb;
040
memset(addon_letters,0,
sizeof
(addon_letters));
041
for
( j = 0; j < strlen(letters_use) && j < 16; j++ )
042
lcd.createChar(j, empty);
043
044
for
( j = 0; j < strlen(letters_use) && j < 16; j++ )
045
{
046
symb = -1;
047
for
( i=0; i < cl; i++ )
if
( chars[i] == letters_use[j] ) { symb = i; addon_letters[index] = letters_use[j];
break
; }
048
if
( symb != -1 ) { lcd.createChar(index, letters[symb]); index++; }
049
}
050
}
051
void
print_rus(
char
*str) {
052
static
char
rus_letters[] = {
'А'
,
'В'
,
'Е'
,
'Ё'
,
'К'
,
'М'
,
'Н'
,
'О'
,
'Р'
,
'С'
,
'Т'
,
'Х'
};
053
static
char
trans_letters[] = {
'A'
,
'B'
,
'E'
,
'E'
,
'K'
,
'M'
,
'H'
,
'O'
,
'P'
,
'C'
,
'T'
,
'X'
};
054
int
lcount =
sizeof
(rus_letters)/
sizeof
(
char
), i, j;
055
for
( i=0; i<strlen(str); i++ )
056
{
057
if
(
byte
(str[i]) == 208 )
continue
;
// 208 ignore
058
int
found = 0;
059
for
(j=0; j < 16; j++)
if
( addon_letters[j] != 0 &&
byte
(str[i]) ==
byte
(addon_letters[j]) ) { lcd.write(j); found = 1;
break
; }
060
if
(!found)
for
(j=0; j < lcount; j++)
if
(
byte
(str[i]) ==
byte
(rus_letters[j]) ) { lcd.write(trans_letters[j]); found = 1;
break
; }
061
if
(!found) lcd.write(
byte
(str[i]));
062
}
063
}
064
void
print_rus(
int
x,
int
y,
char
*str) {
065
lcd.setCursor(x, y);
066
print_rus(str);
067
}
068
Adafruit_BMP280 bmp(BMP_CS);
069
void
setup
()
070
{
071
bmp.begin(9600);
072
lcd.init();
073
lcd.begin(20, 4);
074
lcd.backlight();
075
init_rus(
"ПУДЛИГЯг"
);
076
}
077
void
loop
()
078
{
079
tmElements_t tm;
080
RTC.read(tm);
081
lcd.setCursor(2, 1);
082
print_rus(
"ВРЕМЯ - "
);
083
print2digits(tm.Hour);
084
lcd.print(
":"
);
085
print2digits(tm.Minute);
086
lcd.print(
":"
);
087
print2digits(tm.Second);
088
lcd.print(
" "
);
089
lcd.setCursor(0, 0);
090
print_rus(
"СЕГОДНЯ-"
);
091
print2digits(tm.Day);
092
lcd.print(
"."
);
093
print2digits(tm.Month);
094
lcd.print(
"."
);
095
lcd.print(tmYearToCalendar(tm.Year));
096
print_rus(
" Г"
);
097
lcd.setCursor(0, 2);
098
print_rus(
"ТЕМПЕРАТУРА-"
);
099
lcd.print(bmp.readTemperature());
100
print_rus(
"г С"
);
101
lcd.setCursor(1, 3);
102
print_rus(
"ДАВЛЕНИЕ-"
);
103
lcd.print(bmp.readPressure()/133.322);
104
print_rus(
" ММ"
);
105
delay(1000);
106
}
107
void
print2digits(
int
number) {
108
if
(number >= 0 && number < 10) {
109
lcd.print(
'0'
);
110
}
111
lcd.print(number);
112
}
Всем доброго дня! Товарищи подскажите приобрел BME280 на али подключил по i2c первые показания выдает нормальные но секунд через 5 сваливаеться в крайние значения мин темпиратура -144 макс влажность 100 процентов и давление тож самое в чем может быть проблема?
попрубуй посадить cs на 3,3v
На али есть BMP280 с level converter + ldo для работы с 5V МК, а есть чисто 3.3v. Вы там не втыкаете в 5V ардуину "облегченный" модуль?
В описании модуля в магазине написано "Поставка Напряжение: 1.8-5 В DC"
Подключено к питанию 3,3V Но пробовал и 5V давать ничего не меняется. Только я к модулю ESP12N подключаю без ардуины но думаю это не важно суть не в этом.
Ну, а такой вариант допустим: модуль с LDO (на что описание намекает), вы его в 3.3V суете, на датчике получаете 2.1, в лучшем случае. Любая просадка напряжения и сенсор клинит. На модуль посмотрите - есть там кроме самого сенсора трехногие и более детальки или нет.
Вроде есть. Если не сложно посмотрите детальку.... сылка
Вроде есть. Если не сложно посмотрите детальку.... сылка
У BME, конечно, минимальное напряжение питание 1.2V заявлено, но черт его знает, что там за LDO. Я бы такой подключил к обычной 5V ардуине (и подключал вполне успешно) и посмотрел на поведение. Если будет работать устойчиво - значит, скорее всего, какие-то провалы по питанию при работе с ESP.
Спасибо! Попробую так сделать.
Пытаюсь скомпилировать скетч - выдает море ошибок.
Посему вопрос: какие у Вас библиотеки стоят?
Не компилируется скетч. Выдает кучу ошибок. Библиотеки качал с Гита. В чем может быть проблема?
001
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:1:0:
002
003
D:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:43:30: warning: type qualifiers ignored on function
return
type [-Wignored-qualifiers]
004
005
operator
const
uint8_t()
const
{
return
**
this
; }
006
007
^
008
009
D:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:92:26: warning: type qualifiers ignored on function
return
type [-Wignored-qualifiers]
010
011
operator
const
int
()
const
{
return
index; }
012
013
^
014
015
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino: In function
'void setup()'
:
016
017
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:330:26: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
018
019
lcd.createChar (0, Temp);
020
021
^
022
023
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
024
025
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
026
027
void
createChar(uint8_t, uint8_t[]);
028
029
^
030
031
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:331:28: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
032
033
lcd.createChar (1, HumCHR);
034
035
^
036
037
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
038
039
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
040
041
void
createChar(uint8_t, uint8_t[]);
042
043
^
044
045
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:332:25: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
046
047
lcd.createChar (2, ch1);
048
049
^
050
051
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
052
053
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
054
055
void
createChar(uint8_t, uint8_t[]);
056
057
^
058
059
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:333:25: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
060
061
lcd.createChar (3, ch3);
062
063
^
064
065
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
066
067
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
068
069
void
createChar(uint8_t, uint8_t[]);
070
071
^
072
073
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:334:25: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
074
075
lcd.createChar (4, ch4);
076
077
^
078
079
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
080
081
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
082
083
void
createChar(uint8_t, uint8_t[]);
084
085
^
086
087
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:335:25: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
088
089
lcd.createChar (5, ch6);
090
091
^
092
093
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
094
095
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
096
097
void
createChar(uint8_t, uint8_t[]);
098
099
^
100
101
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:336:25: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
102
103
lcd.createChar (6, ch7);
104
105
^
106
107
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
108
109
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
110
111
void
createChar(uint8_t, uint8_t[]);
112
113
^
114
115
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:337:25: warning: invalid conversion from
'const byte* {aka const unsigned char*}'
to
'uint8_t* {aka unsigned char*}'
[-fpermissive]
116
117
lcd.createChar (7, ch8);
118
119
^
120
121
In file included from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:3:0:
122
123
D:\Program Files (x86)\Arduino\libraries\LiquidCrystal_PCF8574-master\src/LiquidCrystal_PCF8574.h:89:8: note: initializing argument 2 of
'void LiquidCrystal_PCF8574::createChar(uint8_t, uint8_t*)'
124
125
void
createChar(uint8_t, uint8_t[]);
126
127
^
128
129
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino: In function
'void readSensors(DateTime, boolean, boolean)'
:
130
131
weatherstation:994: error: no matching function
for
call to
'BME280I2C::read(float&, float&, float&, bool, uint8_t&)'
132
133
bme.read(Pres, InT, hum,
true
, pressureUnit);
134
135
^
136
137
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:994:52: note: candidate
is
:
138
139
In file included from D:\Program Files (x86)\Arduino\libraries\BME280-master\src/BME280I2C.h:33:0,
140
141
from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:15:
142
143
D:\Program Files (x86)\Arduino\libraries\BME280-master\src/BME280.h:166:11: note:
void
BME280::read(
float
&,
float
&,
float
&, BME280::TempUnit, BME280::PresUnit)
144
145
void
read(
146
147
^
148
149
D:\Program Files (x86)\Arduino\libraries\BME280-master\src/BME280.h:166:11: note: no known conversion
for
argument 4 from
'bool'
to
'BME280::TempUnit'
150
151
weatherstation:997: error:
'class BME280I2C'
has no member named
'alt'
152
153
Altitude = bme.alt(
true
);
154
155
^
156
157
weatherstation:1037: error: no matching function
for
call to
'BME280I2C::read(float&, float&, float&, bool, uint8_t&)'
158
159
bme.read(Pres, InT, hum,
true
, pressureUnit);
160
161
^
162
163
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:1037:48: note: candidate
is
:
164
165
In file included from D:\Program Files (x86)\Arduino\libraries\BME280-master\src/BME280I2C.h:33:0,
166
167
from C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:15:
168
169
D:\Program Files (x86)\Arduino\libraries\BME280-master\src/BME280.h:166:11: note:
void
BME280::read(
float
&,
float
&,
float
&, BME280::TempUnit, BME280::PresUnit)
170
171
void
read(
172
173
^
174
175
D:\Program Files (x86)\Arduino\libraries\BME280-master\src/BME280.h:166:11: note: no known conversion
for
argument 4 from
'bool'
to
'BME280::TempUnit'
176
177
weatherstation:1041: error:
'class BME280I2C'
has no member named
'alt'
178
179
Altitude = bme.alt(
true
);
180
181
^
182
183
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino: In function
'byte Forecast(byte)'
:
184
185
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:1089:8: warning: unused variable
'a'
[-Wunused-variable]
186
187
char
a;
188
189
^
190
191
C:\Users\Nikolay\Documents\Arduino\weatherstation\weatherstation.ino:1120:1: warning: no
return
statement
in
function returning non-
void
[-Wreturn-type]
192
193
}
194
195
^
196
197
Несколько библиотек найдено для
"OneWire.h"
198
Используется: C:\Users\Nikolay\Documents\Arduino\libraries\OneWire
199
Не используется: D:\Program Files (x86)\Arduino\libraries\OneWire-master
200
Не используется: D:\Program Files (x86)\Arduino\libraries\OneWire
201
exit status 1
202
no matching function
for
call to
'BME280I2C::read(float&, float&, float&, bool, uint8_t&)'
если речь о моем скетче то у меня используется http://www.mathertel.de/Arduino/LiquidCrystal_PCF8574.aspx
Она отилчно ищется в подключении библиотек по фразе LiquidCrystal_PCF8574.
Обращаю внимание, что у меня экран подключен через i2c адаптер.
Да, именно о Вашем скетче. Он мне очень понравился, но компилятор что то не компилирует. Очень желаю вашу схему повторить. Больше, конечно, компилятор ругается на bme280i2c библиотеку. Поиски ведут в тупик.
Библиотека отсюда. https://github.com/finitespace/BME280 Инсталится ручками.
Это кстати единственная библиотека, которая на моем китайском клоне выдает результаты похожие на правду.
PS у меня версия arduino 1.8.2
Библиотека отсюда. https://github.com/finitespace/BME280 Инсталится ручками.
Это кстати единственная библиотека, которая на моем китайском клоне выдает результаты похожие на правду.
PS у меня версия arduino 1.8.2
А чем хуже : "cactus_io_BME280_I2C.h" ?
Кто может скомпилировать скетч _zerabot_ из поста #120 под nano v3 и выложит здесь?
Кто может скомпилировать скетч _zerabot_ из поста #120 под nano v3 и выложит здесь?
После работы сделаю.
Обращаю внимание у меня еще подключен сегментный экран на d12 и d13
0029
//LedDisplay
0030
#include "TM1637.h" // Подключаем библиотеку
0031
#define CLK 13 // К этому пину подключаем CLK
0032
#define DIO 12 // К этому пину подключаем DIO
0033
TM1637 tm1637(CLK, DIO);
Конечно, буду ждать.Премного буду благодарен.
Только пока у меня TM1637 нет. Буду покупать.
Вот ссылка на архив с библиотеками. https://cloud.mail.ru/public/L4vX/UFrvfkHat
Содержимое заархивированной папки libraries\ распаковать в папку libraries\ в среде разработки и перезапустить.
Вроде библиотеки те же, завтра заберу с работы станцию попробую прошить.
Проблема была в том, что я писал используя версию от февраля 2017, а со последними версиями не компилируется.
Из замеченных багов за полгода:
*В строке 459 нужно добавить еще 1 пробел, стало заметно при минусовой температуре.
*константы определяющие динамику изменения погоды в функции
byte
Forecast(
byte
Mon)
(0,2 и 0,3) однозначно нужно увеличивать минимум в 2 раза, везде где встречаются. А вообще их нужно подбирать экспереминтально для вашего региона. У нас срань, а не погода в межсезонье.
Давление в течении дня на 5-8 мм прыгает за 2-3 часа, утром солнце и +15, в обед 0 и снежная крупа и легкий ветер нежно обрывает плитку со зданий и ласково прикладывает птичек к стенам домов и вечером снова ясно и +15. А зимой 4 месяца сракопада. Ну а летом датчик на солнце показывает до +60, а воздух прогревается до 35 и ниодного дождя за 4 месяца. Если где и приукрасил, то слегка, а кое где даже приуменьшил =)
Спасибо большое за помощь. Константы изменил, пробел добавил. На 2 компах компилировалось с ошибкой, на третьем пошло... Залил в ардуинку.Теперь проверить не могу. I2C дисплей не могу завести. Ничего не показывает.Будем тужиться завести на дисплей без I2C.
Спасибо большое за помощь. Константы изменил, пробел добавил. На 2 компах компилировалось с ошибкой, на третьем пошло... Залил в ардуинку.Теперь проверить не могу. I2C дисплей не могу завести. Ничего не показывает.Будем тужиться завести на дисплей без I2C.
а сканер I2C дисплей находит?
Виктор Николаевич, не пробовал.Это идея. Заливал тестовый скетч из библиотеки liquid cristal pf8574. Загружал - в мониторе порта была какая то кракозября и не более того.О том, что нету дисплея - порт не сообщал
Сканер показал 0x3f. Как всегда, или лодка дырявая или акула глухая
Сканер показал 0x3f. Как всегда, или лодка дырявая или акула глухая
В оригинале: LiquidCrystal_PCF8574 lcd(0x27)
Придется просить компилировать с вашим 0x3f. Потому как PCF8574A не переключится на 0x3F, насколько я помню. А, судя по адресу, именно он у вас, а не обычный простой PCF8574 без индекса.
Всем спрасибо за помощь. Проект пошел, только почему то атмосферное давление и другие параметры не обновляются автоматически. В скетче заменил адрес. Все показывает. Подсветка не работает, хоть и закинул на в3.но это мелочи.Проект начал хоть что то показывать.
Всем спрасибо за помощь. Проект пошел, только почему то атмосферное давление и другие параметры не обновляются автоматически. В скетче заменил адрес. Все показывает. Подсветка не работает, хоть и закинул на в3.но это мелочи.Проект начал хоть что то показывать.
Все показания с датчиков обновляются раз в минуту. Каждые 20 секунд обновляется значение 1 из датчиков. Чаще просто не вижу смысла, температура, давление и влажность крайне инертные велечины.
За установку яркости отвечает процедура
void
SetBrightness(
int
brightness)
1136
{
1137
1138
analogWrite(3, constrain( map(brightness / 4, 0, 255, 70, 255), 70, 255));
1139
}
Она устанавливает значение PWM от 70 до 255 на пине 3 в зависимости от напряжения на входе А1. Этот вход замеряет напряжение на делителе 10кОм+фоторезистор. Маркировка последнего неизвестна, но эксперементально он меняет сопротивление примерно от 4кОм до 12кОм.