Ищу человека который напишет код настройки времени для часов
- Войдите на сайт для отправки комментариев
Втр, 08/06/2021 - 23:12
Есть часы-метеостанция к ним припаяно 3 кнопки нужно настраивать время через них.
За пример была взята метеостанция от Алекса Гивера https://alexgyver.ru/meteoclock/
Моя схема и уже имеющийся код приведены ниже.
Основной код:
001 | /* |
002 | Время и дата устанавливаются атвоматически при загрузке прошивки (такие как на компьютере) |
003 | График всех величин за час и за сутки (усреднённые за каждый час) |
004 | В модуле реального времени стоит батарейка, которая продолжает отсчёт времени после выключения/сброса питания |
005 | Как настроить время на часах. У нас есть возможность автоматически установить время на время загрузки прошивки, поэтому: |
006 | - Ставим настройку RESET_CLOCK на 1 |
007 | - Прошиваемся |
008 | - Сразу ставим RESET_CLOCK 0 |
009 | - И прошиваемся ещё раз |
010 | - Всё |
011 | */ |
012 |
013 |
014 |
015 | // ------------------------- НАСТРОЙКИ -------------------- |
016 | #define RESET_CLOCK 0 // сброс часов на время загрузки прошивки (для модуля с несъёмной батарейкой). Не забудь поставить 0 и прошить ещё раз! |
017 | #define SENS_TIME 30000 // время обновления показаний сенсоров на экране, миллисекунд |
018 | #define DISP_MODE 1 // в правом верхнем углу отображать: 0 - год, 1 - день недели, 2 - секундо |
019 | #define WEEK_LANG 0 // язык дня недели: 0 - английский, 1 - русский (транслит) |
020 | #define DEBUG 0 // вывод на дисплей лог инициализации датчиков при запуске. Для дисплея 1602 не работает! Но дублируется через порт! |
021 | #define DISPLAY_ADDR 0x27 // адрес платы дисплея: 0x27 или 0x3f. Если дисплей не работает - смени адрес! На самом дисплее адрес не указан |
022 |
023 | // адрес BME280 жёстко задан в файле библиотеки Adafruit_BME280.h |
024 | // стоковый адрес был 0x77, у китайского модуля адрес 0x76. |
025 | // Так что если юзаете не библиотеку из архива - не забудьте поменять |
026 |
027 | // если дисплей не заводится - поменяйте адрес (строка 54) |
028 |
029 | // библиотеки |
030 | #include <Wire.h> |
031 | #include <LiquidCrystal_I2C.h> |
032 |
033 |
034 | LiquidCrystal_I2C lcd(DISPLAY_ADDR, 20, 4); |
035 |
036 | #include "RTClib.h" |
037 | RTC_DS3231 rtc; |
038 | DateTime now; |
039 |
040 | #include <Adafruit_Sensor.h> |
041 | #include <Adafruit_BME280.h> |
042 | #define SEALEVELPRESSURE_HPA (1013.25) |
043 | Adafruit_BME280 bme; |
044 |
045 |
046 | #include <GyverTimer.h> |
047 | GTimer_ms sensorsTimer(SENS_TIME); |
048 | GTimer_ms drawSensorsTimer(SENS_TIME); |
049 | GTimer_ms clockTimer(1000); |
050 |
051 | int8_t hrs, mins, secs; |
052 | // переменные для вывода |
053 | float dispTemp; |
054 | byte dispHum; |
055 | int dispPres; |
056 |
057 |
058 |
059 | // символы |
060 | // цифры |
061 | uint8_t LT[8] = {0b00111, 0b01111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; |
062 | uint8_t UB[8] = {0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000}; |
063 | uint8_t RT[8] = {0b11100, 0b11110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; |
064 | uint8_t LL[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b01111, 0b00111}; |
065 | uint8_t LB[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; |
066 | uint8_t LR[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11110, 0b11100}; |
067 | uint8_t UMB[8] = {0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111}; |
068 | uint8_t LMB[8] = {0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; |
069 |
070 | void drawDig( byte dig, byte x, byte y) { |
071 | switch (dig) { |
072 | case 0: |
073 | lcd.setCursor(x, y); // set cursor to column 0, line 0 (first row) |
074 | lcd.write(0); // call each segment to create |
075 | lcd.write(1); // top half of the number |
076 | lcd.write(2); |
077 | lcd.setCursor(x, y + 1); // set cursor to colum 0, line 1 (second row) |
078 | lcd.write(3); // call each segment to create |
079 | lcd.write(4); // bottom half of the number |
080 | lcd.write(5); |
081 | break ; |
082 | case 1: |
083 | lcd.setCursor(x + 1, y); |
084 | lcd.write(2); |
085 | lcd.setCursor(x + 1, y + 1); |
086 | lcd.write(3); |
087 | break ; |
088 | case 2: |
089 | lcd.setCursor(x, y); |
090 | lcd.write(6); |
091 | lcd.write(6); |
092 | lcd.write(2); |
093 | lcd.setCursor(x, y + 1); |
094 | lcd.write(3); |
095 | lcd.write(7); |
096 | lcd.write(7); |
097 | break ; |
098 | case 3: |
099 | lcd.setCursor(x, y); |
100 | lcd.write(1); |
101 | lcd.write(6); |
102 | lcd.write(5); |
103 | lcd.setCursor(x, y + 1); |
104 | lcd.write(4); |
105 | lcd.write(7); |
106 | lcd.write(5); |
107 | break ; |
108 | case 4: |
109 | lcd.setCursor(x, y); |
110 | lcd.write(3); |
111 | lcd.write(4); |
112 | lcd.write(2); |
113 | lcd.setCursor(x + 2, y + 1); |
114 | lcd.write(3); |
115 | break ; |
116 | case 5: |
117 | lcd.setCursor(x, y); |
118 | lcd.write(0); |
119 | lcd.write(6); |
120 | lcd.write(6); |
121 | lcd.setCursor(x, y + 1); |
122 | lcd.write(7); |
123 | lcd.write(7); |
124 | lcd.write(5); |
125 | break ; |
126 | case 6: |
127 | lcd.setCursor(x, y); |
128 | lcd.write(0); |
129 | lcd.write(6); |
130 | lcd.write(6); |
131 | lcd.setCursor(x, y + 1); |
132 | lcd.write(3); |
133 | lcd.write(7); |
134 | lcd.write(5); |
135 | break ; |
136 | case 7: |
137 | lcd.setCursor(x, y); |
138 | lcd.write(1); |
139 | lcd.write(1); |
140 | lcd.write(5); |
141 | lcd.setCursor(x + 1, y + 1); |
142 | lcd.write(0); |
143 | break ; |
144 | case 8: |
145 | lcd.setCursor(x, y); |
146 | lcd.write(0); |
147 | lcd.write(6); |
148 | lcd.write(2); |
149 | lcd.setCursor(x, y + 1); |
150 | lcd.write(3); |
151 | lcd.write(7); |
152 | lcd.write(5); |
153 | break ; |
154 | case 9: |
155 | lcd.setCursor(x, y); |
156 | lcd.write(0); |
157 | lcd.write(1); |
158 | lcd.write(2); |
159 | lcd.setCursor(x + 1, y + 1); |
160 | lcd.write(7); |
161 | lcd.write(5); |
162 | break ; |
163 | case 10: |
164 | lcd.setCursor(x, y); |
165 | lcd.write(32); |
166 | lcd.write(32); |
167 | lcd.write(32); |
168 | lcd.setCursor(x, y + 1); |
169 | lcd.write(32); |
170 | lcd.write(32); |
171 | lcd.write(32); |
172 | break ; |
173 | } |
174 | } |
175 |
176 | void drawdots( byte x, byte y, boolean state) { |
177 | byte code; |
178 | if (state) code = 165; |
179 | else code = 32; |
180 | lcd.setCursor(x, y); |
181 | lcd.write(code); |
182 | lcd.setCursor(x, y + 1); |
183 | lcd.write(code); |
184 | } |
185 |
186 | void drawClock( byte hours, byte minutes, byte x, byte y, boolean dotState) { |
187 | // чисти чисти! |
188 | lcd.setCursor(x, y); |
189 | lcd.print( " " ); |
190 | lcd.setCursor(x, y + 1); |
191 | lcd.print( " " ); |
192 |
193 | //if (hours > 23 || minutes > 59) return; |
194 | if (hours / 10 == 0) drawDig(10, x, y); |
195 | else drawDig(hours / 10, x, y); |
196 | drawDig(hours % 10, x + 4, y); |
197 | // тут должны быть точки. Отдельной функцией |
198 | drawDig(minutes / 10, x + 8, y); |
199 | drawDig(minutes % 10, x + 12, y); |
200 | } |
201 |
202 | #if (WEEK_LANG == 0) |
203 | static const char *dayNames[] = { |
204 | "Sund" , |
205 | "Mond" , |
206 | "Tues" , |
207 | "Wedn" , |
208 | "Thur" , |
209 | "Frid" , |
210 | "Satu" , |
211 | }; |
212 | #else |
213 | static const char *dayNames[] = { |
214 | "BOCK" , |
215 | "POND" , |
216 | "BTOP" , |
217 | "CPED" , |
218 | "4ETB" , |
219 | "5YAT" , |
220 | "CYBB" , |
221 | }; |
222 | #endif |
223 |
224 | void drawData() { |
225 | lcd.setCursor(15, 0); |
226 | if (now.day() < 10) lcd.print(0); |
227 | lcd.print(now.day()); |
228 | lcd.print( "." ); |
229 | if (now.month() < 10) lcd.print(0); |
230 | lcd.print(now.month()); |
231 |
232 | if (DISP_MODE == 0) { |
233 | lcd.setCursor(16, 1); |
234 | lcd.print(now.year()); |
235 | } else if (DISP_MODE == 1) { |
236 | lcd.setCursor(16, 1); |
237 | int dayofweek = now.dayOfTheWeek(); |
238 | lcd.print(dayNames[dayofweek]); |
239 | } |
240 | } |
241 |
242 |
243 |
244 | void loadClock() { |
245 | lcd.createChar(0, LT); |
246 | lcd.createChar(1, UB); |
247 | lcd.createChar(2, RT); |
248 | lcd.createChar(3, LL); |
249 | lcd.createChar(4, LB); |
250 | lcd.createChar(5, LR); |
251 | lcd.createChar(6, UMB); |
252 | lcd.createChar(7, LMB); |
253 | } |
254 |
255 |
256 |
257 |
258 |
259 | void setup () { |
260 | Serial .begin(9600); |
261 | |
262 |
263 |
264 |
265 | lcd.init(); |
266 | lcd.backlight(); |
267 | lcd.clear(); |
268 |
269 | #if (DEBUG == 1) |
270 | boolean status = true ; |
271 |
272 | lcd.setCursor(0, 1); |
273 | lcd.print(F( "RTC... " )); |
274 | Serial .print(F( "RTC... " )); |
275 | delay(50); |
276 | if (rtc.begin()) { |
277 | lcd.print(F( "OK" )); |
278 | Serial .println(F( "OK" )); |
279 | } else { |
280 | lcd.print(F( "ERROR" )); |
281 | Serial .println(F( "ERROR" )); |
282 | status = false ; |
283 | } |
284 |
285 | lcd.setCursor(0, 2); |
286 | lcd.print(F( "BME280... " )); |
287 | Serial .print(F( "BME280... " )); |
288 | delay(50); |
289 | if (bme.begin(&Wire)) { |
290 | lcd.print(F( "OK" )); |
291 | Serial .println(F( "OK" )); |
292 | } else { |
293 | lcd.print(F( "ERROR" )); |
294 | Serial .println(F( "ERROR" )); |
295 | status = false ; |
296 | } |
297 |
298 | lcd.setCursor(0, 3); |
299 | if (status) { |
300 | lcd.print(F( "All good" )); |
301 | Serial .println(F( "All good" )); |
302 | delay(1000); |
303 | lcd.clear(); |
304 | } else { |
305 | lcd.print(F( "Check wires!" )); |
306 | Serial .println(F( "Check wires!" )); |
307 | delay(1000); |
308 | while (1); |
309 | } |
310 | #else |
311 |
312 |
313 | rtc.begin(); |
314 | bme.begin(&Wire); |
315 | #endif |
316 |
317 | bme.setSampling(Adafruit_BME280::MODE_FORCED, |
318 | Adafruit_BME280::SAMPLING_X1, // temperature |
319 | Adafruit_BME280::SAMPLING_X1, // pressure |
320 | Adafruit_BME280::SAMPLING_X1, // humidity |
321 | Adafruit_BME280::FILTER_OFF ); |
322 |
323 | if (RESET_CLOCK || rtc.lostPower()) |
324 | rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); |
325 |
326 | now = rtc.now(); |
327 | secs = now.second(); |
328 | mins = now.minute(); |
329 | hrs = now.hour(); |
330 |
331 | bme.takeForcedMeasurement(); |
332 | uint32_t Pressure = bme.readPressure(); |
333 | |
334 |
335 |
336 | loadClock(); |
337 | drawClock(hrs, mins, 0, 0, 1); |
338 | drawData(); |
339 | |
340 | readSensors(); |
341 | drawSensors(); |
342 | } |
343 |
344 | void loop () { |
345 | if (sensorsTimer.isReady()) readSensors(); // читаем показания датчиков с периодом SENS_TIME |
346 |
347 |
348 | if (clockTimer.isReady()) clockTick(); // два раза в секунду пересчитываем время и мигаем точками |
349 |
350 | if (drawSensorsTimer.isReady()) drawSensors(); // обновляем показания датчиков на дисплее с периодом SENS_TIME |
351 | |
352 |
353 | } |
Код с функциями:
01 | void readSensors() { |
02 | bme.takeForcedMeasurement(); |
03 | dispTemp = bme.readTemperature(); |
04 | dispHum = bme.readHumidity(); |
05 | dispPres = ( float )bme.readPressure() * 0.00750062; |
06 | } |
07 |
08 | void drawSensors() { |
09 |
10 | lcd.setCursor(0, 2); |
11 | lcd.print(String(dispTemp, 1)); |
12 | lcd.write(223); |
13 | lcd.setCursor(6, 2); |
14 | lcd.print( " " + String(dispHum) + "% " ); |
15 |
16 | lcd.setCursor(13, 2); |
17 | lcd.print(String(dispPres) + " mm" ); |
18 | lcd.setCursor(13, 3); |
19 |
20 | } |
21 |
22 |
23 |
24 | boolean dotFlag; |
25 | void clockTick() { |
26 | dotFlag = !dotFlag; |
27 | if (dotFlag) { // каждую секунду пересчёт времени |
28 | secs++; |
29 | if (secs > 59) { // каждую минуту |
30 | secs = 0; |
31 | mins++; |
32 | if (mins <= 59) drawClock(hrs, mins, 0, 0, 1); |
33 | } |
34 | if (mins > 59) { // каждый час |
35 | now = rtc.now(); |
36 | secs = now.second(); |
37 | mins = now.minute(); |
38 | hrs = now.hour(); |
39 | drawClock(hrs, mins, 0, 0, 1); |
40 | if (hrs > 23) { |
41 | hrs = 0; |
42 | } |
43 | drawData(); |
44 | } |
45 | if (DISP_MODE == 2) { |
46 | lcd.setCursor(16, 1); |
47 | if (secs < 10) lcd.print( " " ); |
48 | lcd.print(secs); |
49 | } |
50 | } |
51 | drawdots(7, 0, dotFlag); |
52 | |
53 | } |
Если есть 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