Ищу человека который напишет код настройки времени для часов
- Войдите на сайт для отправки комментариев
Втр, 08/06/2021 - 23:12
Есть часы-метеостанция к ним припаяно 3 кнопки нужно настраивать время через них.
За пример была взята метеостанция от Алекса Гивера https://alexgyver.ru/meteoclock/
Моя схема и уже имеющийся код приведены ниже.
Основной код:
/* Время и дата устанавливаются атвоматически при загрузке прошивки (такие как на компьютере) График всех величин за час и за сутки (усреднённые за каждый час) В модуле реального времени стоит батарейка, которая продолжает отсчёт времени после выключения/сброса питания Как настроить время на часах. У нас есть возможность автоматически установить время на время загрузки прошивки, поэтому: - Ставим настройку RESET_CLOCK на 1 - Прошиваемся - Сразу ставим RESET_CLOCK 0 - И прошиваемся ещё раз - Всё */ // ------------------------- НАСТРОЙКИ -------------------- #define RESET_CLOCK 0 // сброс часов на время загрузки прошивки (для модуля с несъёмной батарейкой). Не забудь поставить 0 и прошить ещё раз! #define SENS_TIME 30000 // время обновления показаний сенсоров на экране, миллисекунд #define DISP_MODE 1 // в правом верхнем углу отображать: 0 - год, 1 - день недели, 2 - секундо #define WEEK_LANG 0 // язык дня недели: 0 - английский, 1 - русский (транслит) #define DEBUG 0 // вывод на дисплей лог инициализации датчиков при запуске. Для дисплея 1602 не работает! Но дублируется через порт! #define DISPLAY_ADDR 0x27 // адрес платы дисплея: 0x27 или 0x3f. Если дисплей не работает - смени адрес! На самом дисплее адрес не указан // адрес BME280 жёстко задан в файле библиотеки Adafruit_BME280.h // стоковый адрес был 0x77, у китайского модуля адрес 0x76. // Так что если юзаете не библиотеку из архива - не забудьте поменять // если дисплей не заводится - поменяйте адрес (строка 54) // библиотеки #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(DISPLAY_ADDR, 20, 4); #include "RTClib.h" RTC_DS3231 rtc; DateTime now; #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; #include <GyverTimer.h> GTimer_ms sensorsTimer(SENS_TIME); GTimer_ms drawSensorsTimer(SENS_TIME); GTimer_ms clockTimer(1000); int8_t hrs, mins, secs; // переменные для вывода float dispTemp; byte dispHum; int dispPres; // символы // цифры uint8_t LT[8] = {0b00111, 0b01111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; uint8_t UB[8] = {0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000}; uint8_t RT[8] = {0b11100, 0b11110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; uint8_t LL[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b01111, 0b00111}; uint8_t LB[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; uint8_t LR[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11110, 0b11100}; uint8_t UMB[8] = {0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111}; uint8_t LMB[8] = {0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; void drawDig(byte dig, byte x, byte y) { switch (dig) { case 0: lcd.setCursor(x, y); // set cursor to column 0, line 0 (first row) lcd.write(0); // call each segment to create lcd.write(1); // top half of the number lcd.write(2); lcd.setCursor(x, y + 1); // set cursor to colum 0, line 1 (second row) lcd.write(3); // call each segment to create lcd.write(4); // bottom half of the number lcd.write(5); break; case 1: lcd.setCursor(x + 1, y); lcd.write(2); lcd.setCursor(x + 1, y + 1); lcd.write(3); break; case 2: lcd.setCursor(x, y); lcd.write(6); lcd.write(6); lcd.write(2); lcd.setCursor(x, y + 1); lcd.write(3); lcd.write(7); lcd.write(7); break; case 3: lcd.setCursor(x, y); lcd.write(1); lcd.write(6); lcd.write(5); lcd.setCursor(x, y + 1); lcd.write(4); lcd.write(7); lcd.write(5); break; case 4: lcd.setCursor(x, y); lcd.write(3); lcd.write(4); lcd.write(2); lcd.setCursor(x + 2, y + 1); lcd.write(3); break; case 5: lcd.setCursor(x, y); lcd.write(0); lcd.write(6); lcd.write(6); lcd.setCursor(x, y + 1); lcd.write(7); lcd.write(7); lcd.write(5); break; case 6: lcd.setCursor(x, y); lcd.write(0); lcd.write(6); lcd.write(6); lcd.setCursor(x, y + 1); lcd.write(3); lcd.write(7); lcd.write(5); break; case 7: lcd.setCursor(x, y); lcd.write(1); lcd.write(1); lcd.write(5); lcd.setCursor(x + 1, y + 1); lcd.write(0); break; case 8: lcd.setCursor(x, y); lcd.write(0); lcd.write(6); lcd.write(2); lcd.setCursor(x, y + 1); lcd.write(3); lcd.write(7); lcd.write(5); break; case 9: lcd.setCursor(x, y); lcd.write(0); lcd.write(1); lcd.write(2); lcd.setCursor(x + 1, y + 1); lcd.write(7); lcd.write(5); break; case 10: lcd.setCursor(x, y); lcd.write(32); lcd.write(32); lcd.write(32); lcd.setCursor(x, y + 1); lcd.write(32); lcd.write(32); lcd.write(32); break; } } void drawdots(byte x, byte y, boolean state) { byte code; if (state) code = 165; else code = 32; lcd.setCursor(x, y); lcd.write(code); lcd.setCursor(x, y + 1); lcd.write(code); } void drawClock(byte hours, byte minutes, byte x, byte y, boolean dotState) { // чисти чисти! lcd.setCursor(x, y); lcd.print(" "); lcd.setCursor(x, y + 1); lcd.print(" "); //if (hours > 23 || minutes > 59) return; if (hours / 10 == 0) drawDig(10, x, y); else drawDig(hours / 10, x, y); drawDig(hours % 10, x + 4, y); // тут должны быть точки. Отдельной функцией drawDig(minutes / 10, x + 8, y); drawDig(minutes % 10, x + 12, y); } #if (WEEK_LANG == 0) static const char *dayNames[] = { "Sund", "Mond", "Tues", "Wedn", "Thur", "Frid", "Satu", }; #else static const char *dayNames[] = { "BOCK", "POND", "BTOP", "CPED", "4ETB", "5YAT", "CYBB", }; #endif void drawData() { lcd.setCursor(15, 0); if (now.day() < 10) lcd.print(0); lcd.print(now.day()); lcd.print("."); if (now.month() < 10) lcd.print(0); lcd.print(now.month()); if (DISP_MODE == 0) { lcd.setCursor(16, 1); lcd.print(now.year()); } else if (DISP_MODE == 1) { lcd.setCursor(16, 1); int dayofweek = now.dayOfTheWeek(); lcd.print(dayNames[dayofweek]); } } void loadClock() { lcd.createChar(0, LT); lcd.createChar(1, UB); lcd.createChar(2, RT); lcd.createChar(3, LL); lcd.createChar(4, LB); lcd.createChar(5, LR); lcd.createChar(6, UMB); lcd.createChar(7, LMB); } void setup() { Serial.begin(9600); lcd.init(); lcd.backlight(); lcd.clear(); #if (DEBUG == 1) boolean status = true; lcd.setCursor(0, 1); lcd.print(F("RTC... ")); Serial.print(F("RTC... ")); delay(50); if (rtc.begin()) { lcd.print(F("OK")); Serial.println(F("OK")); } else { lcd.print(F("ERROR")); Serial.println(F("ERROR")); status = false; } lcd.setCursor(0, 2); lcd.print(F("BME280... ")); Serial.print(F("BME280... ")); delay(50); if (bme.begin(&Wire)) { lcd.print(F("OK")); Serial.println(F("OK")); } else { lcd.print(F("ERROR")); Serial.println(F("ERROR")); status = false; } lcd.setCursor(0, 3); if (status) { lcd.print(F("All good")); Serial.println(F("All good")); delay(1000); lcd.clear(); } else { lcd.print(F("Check wires!")); Serial.println(F("Check wires!")); delay(1000); while (1); } #else rtc.begin(); bme.begin(&Wire); #endif bme.setSampling(Adafruit_BME280::MODE_FORCED, Adafruit_BME280::SAMPLING_X1, // temperature Adafruit_BME280::SAMPLING_X1, // pressure Adafruit_BME280::SAMPLING_X1, // humidity Adafruit_BME280::FILTER_OFF ); if (RESET_CLOCK || rtc.lostPower()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); now = rtc.now(); secs = now.second(); mins = now.minute(); hrs = now.hour(); bme.takeForcedMeasurement(); uint32_t Pressure = bme.readPressure(); loadClock(); drawClock(hrs, mins, 0, 0, 1); drawData(); readSensors(); drawSensors(); } void loop() { if (sensorsTimer.isReady()) readSensors(); // читаем показания датчиков с периодом SENS_TIME if (clockTimer.isReady()) clockTick(); // два раза в секунду пересчитываем время и мигаем точками if (drawSensorsTimer.isReady()) drawSensors(); // обновляем показания датчиков на дисплее с периодом SENS_TIME }
Код с функциями:
void readSensors() { bme.takeForcedMeasurement(); dispTemp = bme.readTemperature(); dispHum = bme.readHumidity(); dispPres = (float)bme.readPressure() * 0.00750062; } void drawSensors() { lcd.setCursor(0, 2); lcd.print(String(dispTemp, 1)); lcd.write(223); lcd.setCursor(6, 2); lcd.print(" " + String(dispHum) + "% "); lcd.setCursor(13, 2); lcd.print(String(dispPres) + " mm"); lcd.setCursor(13, 3); } boolean dotFlag; void clockTick() { dotFlag = !dotFlag; if (dotFlag) { // каждую секунду пересчёт времени secs++; if (secs > 59) { // каждую минуту secs = 0; mins++; if (mins <= 59) drawClock(hrs, mins, 0, 0, 1); } if (mins > 59) { // каждый час now = rtc.now(); secs = now.second(); mins = now.minute(); hrs = now.hour(); drawClock(hrs, mins, 0, 0, 1); if (hrs > 23) { hrs = 0; } drawData(); } if (DISP_MODE == 2) { lcd.setCursor(16, 1); if (secs < 10) lcd.print(" "); lcd.print(secs); } } drawdots(7, 0, dotFlag); }
Если есть wifi, замените ардуину на esp8266 и получайте наиточнейшее время с NTP. Не думаю, что заказ станет от этого сильно дороже, но станет сильно удобнее
...все равно кнопки неправильно пририсованы.
Но тогда придётся как-то вводить SSID, passphrase и адрес NTP.
Даже не знаю, что лучше.
Проблема как раз таки в том, что требования чтобы часы были как обычные настольные но на Arduino, с настройкой кнопками и без дополнительных деталей. :(
NTP не надо вводить, их достаточно штук 20 проверенных прописать в цикл перебора. Могу скинуть свои топ-20. Вэб-морду писать придется, это да! Еще и кэш логин-пароль.. Но, что-то мне подсказывает, что для вас это не сильно обременительно)) И это решение будет всяко удобнее кнопок
Проблема как раз таки в том, что требования чтобы часы были как обычные настольные но на Arduino, с настройкой кнопками и без дополнительных деталей. :(
А так они еще и с телефона будут управляться! Годнота, да и только!
Для меня - нет, для заказчика - скорее всего.
Ну он же не сам собирается делать, он хочет решение готовое оплатить.
Ну он же не сам собирается делать, он хочет решение готовое оплатить.
Это и есть его бремя ))
У меня просто требование сделать с кнопками.
В принципе, я би уже давно всё сделал бы, но есть проблема, я уже нашел неплохой код настройки на https://lesson.iarduino.ru/page/urok-17-podklyuchenie-rtc-chasy-realnogo...
Но проблема в том что там другая библиотека, и при простом переносе - функции не работают, а при замене библиотеки - не работает пол кода.
Это и есть его бремя ))
Это не бремя, Это рыночные отношения. Вот вам ведь тоже знания и опыт даром не достались? И он, возможно, в чем-то профессионал. Теория вмененных издержек советует заниматься за деньги профильным делом, а непрофильные задачи отдавать на аутсорсинг.
Ну, это ваши личные проблемы. Решайте их с исполнителем
Возможно я начал тему не в том разделе, просто меня немного напрягло то, что я брал за основу чужой проект, а на форуме написано что "Здесь помогают тем, кто пытается что-то сделать сам, имеет самописный скетч и задает вопросы по нему. Если вас не устраивают требования, есть чудесный раздел: "Ищу исполнителя"."
Вы все сделали правильно. С разделом не ошиблись. Гайвера тут не очень уважают, но я уверен - это не помешает вам найти потенциального исполнителя для вашего проекта. Если ваши конкретизированные формулировки задачи совпадут с суммой, которую вы готовы отдать за работу
UPD: 74 это регион, или другое?))
Bogdan74, огласите бюджет, пожалуйста
Бюджет неважен. Напишите мне на почту barmaley2m@yandex.ru