Мой проект на 5110
- Войдите на сайт для отправки комментариев
Добрый день, уважаемые!
Это мой первый пост в этом форуме, хотя читаю его уже с полгода. Вобщем пинайте!
Лирическое отступление. Некоторое время назад решил освежить свое серое вещество и занялся ардуинством. Это было... трудно! Вещество не понимало, что от него хотят и требовало пива. Но постепенно ритм наладился и стало даже получаться копировать чужие наработки и понеслась.. Рабочий стол начал обрастать проводками, платками и прочей непонятной посторонним людям фигней. Вобщем все как у всех! Очень скоро стало не хватать экранчика 1602 и выбор пал на 5110. Заказал и стал мучить его. Или он меня. То одно не устраивало, то другое. Главным критерием было наличие русского языка. Перерыл кучу инфы, в том числе и на этом форуме. В итоге родился проект, которым и хочу сейчас поделиться.
Теперь собственно к делу. По плану в проекте должны быть использованы часы DS3231, экран Nokia 5110 и цифровой датчик температуры DS18B20, а также кнопка для корректировки времени. На экран должна быть выведена информация о текущем времени, дата, день недели и температура с обоих датчиков (в DS3231 свой датчик). Вот собственно то, что получилось в итоге (пока что на столе):
Ну и сам скетч:
#include <Adafruit_GFX.h> #include <Adafruit_PCD8544.h> // Software SPI (slower updates, more flexible pin options): // pin 7 - Serial clock out (SCLK) // pin 6 - Serial data out (DIN) // pin 5 - Data/Command select (D/C) // pin 4 - LCD chip select (CS) // pin 3 - LCD reset (RST) Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3); #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress Thermometer1 = {0x28, 0xFF, 0x03, 0xAD, 0x00, 0x16, 0x01, 0x2A}; // адрес датчика DS18B20 280054B604000092 #include <DS3231.h> DS3231 rtc(SDA, SCL); Time q; uint32_t ms, ms1 = 0; void setup() { pinMode(8, INPUT);//Слушаем кнопку digitalWrite(2, HIGH); //подключаем подтягивающий резистор sensors.begin(); sensors.setResolution(Thermometer1, 10); display.begin(); display.clearDisplay(); rtc.begin(); display.cp437(true); display.display(); } void printTemperature(DeviceAddress deviceAddress) { sensors.requestTemperatures(); float tempC = sensors.getTempC(deviceAddress); display.setTextSize(1); display.setCursor(0, 32); display.print(utf8rus("Внутри :")); display.setCursor(47, 32); display.print(rtc.getTemp()); display.setCursor(77, 32); display.print(utf8rus("°")); display.setCursor(0, 40); display.print(utf8rus("Cнаружи:")); display.setCursor(47, 40); display.print(tempC); display.setCursor(77, 40); display.print(utf8rus("°")); } void printTimeDate() { q = rtc.getTime(); display.setTextSize(2); display.setCursor(10, 0); if (q.hour < 10) { display.print("0"); display.setCursor(22, 0); } display.print(q.hour); display.setCursor(38, -3); display.print("_"); display.setCursor(52, 0); if (q.min < 10) { display.print("0"); display.setCursor(64, 0); } display.print(q.min); display.setTextSize(1); display.setCursor(37, 0); if (q.sec < 10) { display.print("0"); display.setCursor(43, 0); } display.print(q.sec); display.setCursor(13, 16); display.println(rtc.getDateStr(FORMAT_LONG)); if (rtc.getDOWStr(FORMAT_SHORT) == "Mon") { display.print(utf8rus(" Понедельник")); } if (rtc.getDOWStr(FORMAT_SHORT) == "Tue") { display.print(utf8rus(" Bторник")); } if (rtc.getDOWStr(FORMAT_SHORT) == "Wed") { display.print(utf8rus(" Cpeдa")); } if (rtc.getDOWStr(FORMAT_SHORT) == "Thu") { display.print(utf8rus(" Четверг")); } if (rtc.getDOWStr(FORMAT_SHORT) == "Fri") { display.print(utf8rus(" Пятница")); } if (rtc.getDOWStr(FORMAT_SHORT) == "Sat") { display.print(utf8rus(" Cуббота")); } if (rtc.getDOWStr(FORMAT_SHORT) == "Sun") { display.print(utf8rus(" Bоcкресенье")); } } void loop() { ms = millis(); if (digitalRead(8) == LOW) { rtc.setTime(q.hour, q.min + 1, 0); //Сброс секунд в 0, минуты +1 (можно -1, если часы спешат) } if ( ( ms - ms1 ) > 1000 || ms < ms1 ) { ms1 = ms; printTemperature(Thermometer1); printTimeDate(); display.display(); display.clearDisplay(); } } /* Recode russian fonts from UTF-8 to Windows-1251 */ String utf8rus(String source) { int i, k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; }
Очень хотелось бы услышать мнение специалистов, как можно оптимизировать код, потому как навыков в программировании еще очень мало, а задумок по проекту много, но все как всегда упрется в память.
Спасибо за внимание!
Про строки 80-100. День недели можно запрашивать силом, а не строкой и соответсвенно всё значительно упростится и по времени и по месту. В частности, все эти строки заменятся на одну.
Про строки 80-100. День недели можно запрашивать силом, а не строкой и соответсвенно всё значительно упростится и по времени и по месту. В частности, все эти строки заменятся на одну.
Извините я не в теме, что значит запрашивать силом?
Извините я не в теме, что значит запрашивать силом?
Виноват, опечатка - "числом".
Я понял Вас. Поменял условие.
Было:
Я понял Вас. Поменял условие.
Было:
Коннечно, можно. Я не помню там неделя начинается с воскресенья или понедельника, ну, допустим с воскресенья. Тогда воскресенью соответсвует 0, понедельник - 1, вторник - 2 и т.п. Допустим, также, что Вы уже прочитали день недели (числом) и присвоили его переменной dow (типа int8_t). Тогда Вам достаточно где-то определеить массив названий дней (хоть в progmem загоняйте), а вместо строк 80-100 написать одну вот такую строку
Проверьте что там чему соответствует, но идею Вы поняли. dow оказывается просто индексом в массиве и никакие if'ы вообще не нужны.
В моем случае dow это не переменная, а часть строки, которую выдает функция времени в строке:
Поэтому q.min - минуты, q.sec - секунды, а q.dow - DayOfWeek - день недели.
В принципе ход Ваших мыслей мне понятен, постараюсь учесть. Спасибо!
Вы не поняли.
Ну вот вроде сваял нечто. Правда все сырое и вместо дня недели выводит лишь последний символ из названия букву "а" (сегодня пятница).
Во-первых непонятно, почему у Вас days char, а не utf8rus как раньше.
Во-вторых, даже если char, так описывайте его правильно
не
а
это же строки, а не отдельные символы.
Спасибо за замечание Евгений. Все заработало. И (ровно килобайт) 500 байт памяти высвобождено.
Спасибо за замечание Евгений. Все заработало. И (ровно килобайт) 500 байт памяти высвобождено.
:)
Сейчас много работы, может вечерком я ещё посмотрю. Это было то, что просто само сразу в глаза бросилось.
По поводу вывода нуля перед числом менее 10
По поводу вывода нуля перед числом менее 10
Спасибо большое, как говорится В самую дырочку! И поучительно конечно же. Минус еще 100 байт.
По поводу вывода нуля перед числом менее 10
Спасибо большое, как говорится В самую дырочку! И поучительно конечно же. Минус еще 100 байт.
Можно такуюже функцию написать и для вывода дней недели и т.п.
Друзья подскажите если вместо DS18B20 заюзать LM35 (я понимаю что они разные, первый цифровой , второй аналог) что в скетче поменять нужно?
Прикрутите датчик давления для полноты информации о погоде!
а теперь выкинь ардуину и часы, бери время с ntp, вместо ардуины esp8266. ну это как дальнейшее развитие проекта
Автор, а где финальная версия скетча?
Автор, а где финальная версия скетча?
Да не будет финальной, этот проект был как баловство и процесс самообучения. Позже еще прикрутил датчик газа MQ-135, убедился в его неэффективности. Хотя проект до сих пор рука не поднимается разобрать. Кароче забросил)))
удалил
У меня жена окна мыла, градусник смахнула, хотел побыстрому собрать термометр, не вникая в детали. Видимо из первого поста скетч и так будет работать хорошо, как я понимаю. Просто в ходе обсуждения какието оптимизации происходили.
Оптимизация в коде присутствует, но чисто косметическая. А так да - работает.
Попробовал скомпелировать исходный код, получил;
DS3231 rtc(SDA, SCL)
no matching function for call to 'DS3231::DS3231(const uint8_t&, const uint8_t&)'
Принято к сведению.
Если появятся вопросы, не стесняйтесь, спрашивайте.
Евгений П спасибо что оперативно откликнулись. Я думал тема уже не рабочая, попробовал и неожиданно быстро получил ответ. С тринадцати лет занимаюсь электроникой, сделал много конструкций в том числе три транзистортестера на разных контроллерах, а вот на ардуино еще не пробовал. Конструкция понравилась своей гибкостью, поменял скетч, периферию и уже другой аппарат. Здесь понравилась картинка с первого поста, ардуино есть Mega 2560, дисплей есть, датчики есть. Взял код тоже с первого поста и сразу же облом, а в программировании знаю только как прошить контролер. Может потихоньку как-нибудь со временем разберусь что к чему, хотя в 66 лет оперативка уже не та.
Узнайте у автора кода какую именно библиотеку он использовал, поставьте её и всё будет нормально. У Вас библиотека другая.
вот эта бибилиотека
https://vk.com/doc428336442_461456678
распаковать в папку с бибилиотеками, при необходимости старую заменить на эту.
Спасибо boscfr, что откликнулись, установил Вашу библиотеку все, ожило, но снова застопорилось теперь выглядит так:
display.cp437(true); 'class Adafruit_PCD8544' has no member named 'cp437'
По-моему, опять не достает какой-то библиотеки с серии PCD8544. Перерыл весь интернет понаскачивал и установил кучу библиотек для 5110, не помогает.
этих адафруитов развелось куча))
лови: https://vk.com/doc428336442_461460117
Совершенно верно. У меня такая уже стояла, установил Вашу с заменой файлов и все скампилировалось. Спасибо. Буду игратся дальше.