Используя платформу Arduino на 4-х индикаторах BJ18101AH (1,8 дюйма) можно собрать часы с большими цифрами. Светодиодные семисегментные индикаторы BJ18101AH (общий катод) имеют габаритный размер 56х38х11 мм, при высоте символа 45 мм.
Схема подключения к Arduino очень простая, содержит несколько резисторов и четыре транзистора BC337. Питание анодов сегментов индикатора происходит напрямую от цифровых выходов Arduino, при указанных на схеме номиналах ток потребления одного сегмента не превышает 17 мА (макс. 40 мА на один цифровой выход при максимальном общем токе на все выходы не более 200 мА), при этом сегменты индикаторов имеют достаточно большую яркость свечения.
Для отсчета времени в схеме используются часы реального времени DS3231.
Часы используют динамическую систему индикации, все одноименные выводы сегментов всех четырех индикаторов соединяются вместе. Во втором разряде используется точка для индикации такта секунд. Сигнал такта секунд подается в Arduino с выхода SQW DS3231.
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip #include <Wire.h> #include <DS3231.h> // http://rcl-radio.ru/wp-content/uploads/2022/02/DS3231.zip DS3231 clock;RTCDateTime DateTime; int an, segm,times,i,pd,pd_p; byte a[4]; void setup(){ Wire.begin();clock.begin(); MsTimer2::set(2, to_Timer);MsTimer2::start(); // clock.setDateTime(__DATE__, __TIME__); // Устанавливаем время на часах, основываясь на времени компиляции скетча pinMode(9,OUTPUT); // D9 === A0 pinMode(10,OUTPUT); // D10 === A1 pinMode(11,OUTPUT); // D11 === A2 pinMode(12,OUTPUT); // D12 === A3 pinMode(13,OUTPUT); // D13 === PD pinMode(2,OUTPUT); // D2 === a pinMode(3,OUTPUT); // D3 === b pinMode(4,OUTPUT); // D4 === c pinMode(5,OUTPUT); // D5 === d pinMode(6,OUTPUT); // D6 === e pinMode(7,OUTPUT); // D7 === f pinMode(8,OUTPUT); // D8 === g clock.setOutput(DS3231_1HZ); pinMode(A0,INPUT); // SQW DS3231 } void loop(){ DateTime=clock.getDateTime();// опрос времени times = DateTime.hour*100+DateTime.minute; a[0]=times/1000; a[1]=times/100%10; a[2]=times/10%10; a[3]=times%10%10; if(analogRead(A0)>900){pd_p=1;}else{pd_p=0;} }// loop void to_Timer(){ switch(i){ case 0: cl(); segm=a[0]; pd=0; an=0; anod(); segment();break; case 1: cl(); segm=a[1]; pd=pd_p; an=1; anod(); segment();break; case 2: cl(); segm=a[2]; pd=0; an=2; anod(); segment();break; case 3: cl(); segm=a[3]; pd=0; an=3; anod(); segment();break;}i++; if(i>3){i=0;}} void segment(){ switch(segm){ // A B C D E F G PD case 0: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,1);ch(7,1);ch(8,0);ch(13,pd);break;// 0 case 1: ch(2,0);ch(3,1);ch(4,1);ch(5,0);ch(6,0);ch(7,0);ch(8,0);ch(13,pd);break;// 1 case 2: ch(2,1);ch(3,1);ch(4,0);ch(5,1);ch(6,1);ch(7,0);ch(8,1);ch(13,pd);break;// 2 case 3: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,0);ch(7,0);ch(8,1);ch(13,pd);break;// 3 case 4: ch(2,0);ch(3,1);ch(4,1);ch(5,0);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// 4 case 5: ch(2,1);ch(3,0);ch(4,1);ch(5,1);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// 5 case 6: ch(2,1);ch(3,0);ch(4,1);ch(5,1);ch(6,1);ch(7,1);ch(8,1);ch(13,pd);break;// 6 case 7: ch(2,1);ch(3,1);ch(4,1);ch(5,0);ch(6,0);ch(7,0);ch(8,0);ch(13,pd);break;// 7 case 8: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,1);ch(7,1);ch(8,1);ch(13,pd);break;// 8 case 9: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// 9 case 10: ch(2,0);ch(3,0);ch(4,0);ch(5,0);ch(6,0);ch(7,0);ch(8,0);ch(13,pd);break;// пусто }} void anod(){ switch(an){ case 0:ch(9,1);ch(10,0);ch(11,0);ch(12,0);break; case 1:ch(9,0);ch(10,1);ch(11,0);ch(12,0);break; case 2:ch(9,0);ch(10,0);ch(11,1);ch(12,0);break; case 3:ch(9,0);ch(10,0);ch(11,0);ch(12,1);break; }} void cl(){ segm=10; pd=0; an=0; segment(); anod(); an=1; segment(); anod(); an=2; segment(); anod(); an=3; segment();anod(); } void ch(int pin, int logic){digitalWrite(pin,logic);}
Часы + давление + температура + влажность
DS3231 + BMP280 + DHT11
Добавив два датчика на основе часов можно собрать простую погодную станцию. С датчика DHT11 будет выводится показания влажности, а с датчика BMP280 атмосферное давление (мм.рт.ст) и температура.
Показания датчиков выводятся два раза в минуту в течении 4 секунд на каждый параметр.
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip #include <Wire.h> #include <Adafruit_Sensor.h> // http://rcl-radio.ru/wp-content/uploads/2018/08/Adafruit_Sensor.zip #include <Adafruit_BMP280.h> // http://rcl-radio.ru/wp-content/uploads/2018/08/Adafruit_BMP280.zip #include <DS3231.h> // http://rcl-radio.ru/wp-content/uploads/2022/02/DS3231.zip #include <DHT.h> // http://rcl-radio.ru/wp-content/uploads/2018/08/DHT.zip DHT dht(A1, DHT11); // выход DAT подключен к A1 DS3231 clock;RTCDateTime DateTime; Adafruit_BMP280 bmp; // I2C int an, segm,times,i,pd,pd_p,sek; byte a[4]; void setup(){ Wire.begin();clock.begin();bmp.begin();dht.begin(); MsTimer2::set(2, to_Timer);MsTimer2::start(); // clock.setDateTime(__DATE__, __TIME__); // Устанавливаем время на часах, основываясь на времени компиляции скетча pinMode(9,OUTPUT); // D9 === A0 pinMode(10,OUTPUT); // D10 === A1 pinMode(11,OUTPUT); // D11 === A2 pinMode(12,OUTPUT); // D12 === A3 pinMode(13,OUTPUT); // D13 === PD pinMode(2,OUTPUT); // D2 === a pinMode(3,OUTPUT); // D3 === b pinMode(4,OUTPUT); // D4 === c pinMode(5,OUTPUT); // D5 === d pinMode(6,OUTPUT); // D6 === e pinMode(7,OUTPUT); // D7 === f pinMode(8,OUTPUT); // D8 === g clock.setOutput(DS3231_1HZ); pinMode(A0,INPUT); // SQW DS3231 } void loop(){ DateTime=clock.getDateTime();// опрос времени sek=DateTime.second; if((sek>=10&&sek<=15)||(sek>=30&&sek<=35)){ times = bmp.readTemperature(); a[0]=times/10; a[1]=times%10; a[2]=11; a[3]=12; pd_p=0;} else if((sek>=15&&sek<=20)||(sek>=35&&sek<=40)){ times = bmp.readPressure()/133.3224; a[0]=13; a[1]=times/100; a[2]=times/10%10; a[3]=times%10; pd_p=0;} else if((sek>=20&&sek<=25)||(sek>=40&&sek<=45)){ times = dht.readHumidity(); a[0]=14; a[1]=10; a[2]=times/10; a[3]=times%10; pd_p=0;} else{ times = DateTime.hour*100+DateTime.minute; a[0]=times/1000; a[1]=times/100%10; a[2]=times/10%10; a[3]=times%10%10; if(analogRead(A0)>900){pd_p=1;}else{pd_p=0;} } }// loop void to_Timer(){ switch(i){ case 0: cl(); segm=a[0]; pd=0; an=0; anod(); segment();break; case 1: cl(); segm=a[1]; pd=pd_p; an=1; anod(); segment();break; case 2: cl(); segm=a[2]; pd=0; an=2; anod(); segment();break; case 3: cl(); segm=a[3]; pd=0; an=3; anod(); segment();break;}i++; if(i>3){i=0;}} void segment(){ switch(segm){ // A B C D E F G PD case 0: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,1);ch(7,1);ch(8,0);ch(13,pd);break;// 0 case 1: ch(2,0);ch(3,1);ch(4,1);ch(5,0);ch(6,0);ch(7,0);ch(8,0);ch(13,pd);break;// 1 case 2: ch(2,1);ch(3,1);ch(4,0);ch(5,1);ch(6,1);ch(7,0);ch(8,1);ch(13,pd);break;// 2 case 3: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,0);ch(7,0);ch(8,1);ch(13,pd);break;// 3 case 4: ch(2,0);ch(3,1);ch(4,1);ch(5,0);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// 4 case 5: ch(2,1);ch(3,0);ch(4,1);ch(5,1);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// 5 case 6: ch(2,1);ch(3,0);ch(4,1);ch(5,1);ch(6,1);ch(7,1);ch(8,1);ch(13,pd);break;// 6 case 7: ch(2,1);ch(3,1);ch(4,1);ch(5,0);ch(6,0);ch(7,0);ch(8,0);ch(13,pd);break;// 7 case 8: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,1);ch(7,1);ch(8,1);ch(13,pd);break;// 8 case 9: ch(2,1);ch(3,1);ch(4,1);ch(5,1);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// 9 case 10: ch(2,0);ch(3,0);ch(4,0);ch(5,0);ch(6,0);ch(7,0);ch(8,0);ch(13,pd);break;// пусто case 11: ch(2,1);ch(3,1);ch(4,0);ch(5,0);ch(6,0);ch(7,1);ch(8,1);ch(13,pd);break;// градус case 12: ch(2,1);ch(3,0);ch(4,0);ch(5,1);ch(6,1);ch(7,1);ch(8,0);ch(13,pd);break;// C case 13: ch(2,1);ch(3,1);ch(4,0);ch(5,0);ch(6,1);ch(7,1);ch(8,1);ch(13,pd);break;// P case 14: ch(2,0);ch(3,1);ch(4,1);ch(5,0);ch(6,1);ch(7,1);ch(8,1);ch(13,pd);break;// H }} void anod(){ switch(an){ case 0:ch(9,1);ch(10,0);ch(11,0);ch(12,0);break; case 1:ch(9,0);ch(10,1);ch(11,0);ch(12,0);break; case 2:ch(9,0);ch(10,0);ch(11,1);ch(12,0);break; case 3:ch(9,0);ch(10,0);ch(11,0);ch(12,1);break; }} void cl(){ segm=10; pd=0; an=0; segment(); anod(); an=1; segment(); anod(); an=2; segment(); anod(); an=3; segment();anod(); } void ch(int pin, int logic){digitalWrite(pin,logic);}
Форум — http://forum.rcl-radio.ru/viewtopic.php?id=148
Индикаторы — https://gotbest.by/redirect/cpa/o/q7r44lmph5thmzyesto83e4orgmgghso/
Дополнительные материалы
Печатную плату разработал и автор фотографий —
anatolij-postolenko@yandex.ru
Часы на светодиодных семисегментных индикаторах 1,8 дюйма_.lay6.zip
Опытный образец платы
При компиляции скетча выдает ошибку RTCDateTime» does not a type. Что это такое?
Нормально скомпилировалось под версию 1.8.7
Установил версию 1.8.7 и вот результат — RTCDateTime does not a type
http://forum.rcl-radio.ru/viewtopic.php?pid=2694#p2694
компиляция проходит без ошибок
Голова уже пухнет! Понимаю, что делаю что-то не так, но не пойму ЧТО. Результат компиляции по ссылке выше
Переустановите библиотеку DS3231
Вот ссылка на ту что я использую — http://rcl-radio.ru/wp-content/uploads/2020/12/DS3231.zip
Огромное спасибо! С этой библиотекой все великолепно скомпилировалось. Теперь сейчас поменяю 1 на 0, а 0 на 1 под общий анод и можно собирать. Еще раз, liman28, огромное спасибо за помощь.
Все-таки остался один вопрос — как быть с точками? Менять ли pd=0 на pd=1
да, менять
Да! И еще. У меня скетч использует 11982 байта и глобальные переменные 553 байта, а у Вас 8914 и 317 соответственно?
Значит скетчи разные или библиотеки
Спасибо!
Добрый день! Подскажите в каком формате вводить дату и время, через / ; _ , например (_20/12/2020_)(_12/45_) или (_20;12;2020_)(_12;45_)
??? не совсем понял вопрос. Как Вы будете выводить дату? Только в формате 20:12 (дата :месяц)
Теперь понятно — через двоеточие.