Часы-Термометр на Arduino Uno, 4 разрядном 7 сегментном индикаторе, датчике температуры LM35 и RTC модуле DS1302.
- Войдите на сайт для отправки комментариев
Чт, 09/07/2015 - 12:21
Сразу оговорюсь лепил из того что было. Лежал у меня неисправный 16х32 индикатор, от рекламного щита. Решил я его распаять под семисегментный индикатор и собрать часы на ардуино. Позже добавил датчик температуры LM35. Перебрал массу скетчей и выжал из них то что мне нужно. Единственное так и не смог понизить яркость значка градусов. Температуру показывают десять секунд, каждую десятую минуту.


#define DIGIT1 A2
#define DIGIT2 A3
#define DIGIT3 A4
#define DIGIT4 A5
#define SEGMENTA 2
#define SEGMENTB 3
#define SEGMENTC 4
#define SEGMENTD 5
#define SEGMENTE 6
#define SEGMENTF 7
#define SEGMENTG 8
#define COLON A1
#define DELAYTIME 50
#define BUTTONMIN 12
#define BUTTONHOUR 13
#include <DS1302.h>
unsigned short hours, minutes, seconds, temp;
unsigned long lastTime;
DS1302 rtc(9, 10, 11);
Time t;
int lastButtonStatemin = LOW;
int lastButtonStatehour = LOW;
boolean tempFlag;
int tempPin = A0;
int tempc;
void setup() {
pinMode(DIGIT1, OUTPUT);
pinMode(DIGIT2, OUTPUT);
pinMode(DIGIT3, OUTPUT);
pinMode(DIGIT4, OUTPUT);
pinMode(SEGMENTA, OUTPUT);
pinMode(SEGMENTB, OUTPUT);
pinMode(SEGMENTC, OUTPUT);
pinMode(SEGMENTD, OUTPUT);
pinMode(SEGMENTE, OUTPUT);
pinMode(SEGMENTF, OUTPUT);
pinMode(SEGMENTG, OUTPUT);
pinMode(COLON, OUTPUT);
pinMode(BUTTONMIN, INPUT);
pinMode(BUTTONHOUR, INPUT);
rtc.halt(false);
rtc.writeProtect(false);
analogReference(INTERNAL);
}
void loop() {
t = rtc.getTime();
minutes = t.min % 10;
seconds = t.sec;
int temp = analogRead(tempPin)/ 10.5;
if (minutes == 0 && seconds >= 10 && seconds < 20){
clock_all_off();
clock_show_digit(0, 10);
delayMicroseconds(150);
unsigned short delaytime;
unsigned short num_leds[10] = {
6, 3, 5, 5, 4, 5, 6, 3, 7, 6 };
unsigned short digit[4];
if (tempFlag){
tempFlag = false;
tempc = temp;}
digit[1] = tempc / 10;
digit[2] = tempc % 10;
if (temp > 10) {
clock_all_off();
clock_show_digit(1, digit[1]);
delaytime = num_leds[digit[1]] * 50;
delayMicroseconds(delaytime);
}
clock_all_off();
clock_show_digit(2, digit[2]);
delaytime = num_leds[digit[2]] * 50;
delayMicroseconds(delaytime);
clock_all_off();
clock_show_digit(3, 11);
}
else{
tempFlag = true;
clock_show_time(t.hour, t.min);
if (t.sec % 2 == 0) {
clock_show_colon();
}
if (digitalRead(BUTTONMIN) != lastButtonStatemin) {
lastButtonStatemin = digitalRead(BUTTONMIN);
if (digitalRead(BUTTONMIN) == HIGH) {
minutes = t.min;
hours = t.hour;
if (minutes == 59) {
minutes = 0;
rtc.setTime(hours, minutes , 0);
}
else {
minutes++;
rtc.setTime(hours, minutes , 0);
}
}
}
if (digitalRead(BUTTONHOUR) != lastButtonStatehour) {
lastButtonStatehour = digitalRead(BUTTONHOUR);
if (digitalRead(BUTTONHOUR) == HIGH) {
minutes = t.min;
hours = t.hour;
if (hours == 23) {
hours = 0;
rtc.setTime(hours, minutes , 0);
}
else {
hours++;
rtc.setTime(hours, minutes , 0);
}
}
}
}
}
void clock_show_time(unsigned short hours, unsigned short minutes) {
unsigned short i;
unsigned short delaytime;
unsigned short num_leds[10] = {
6, 3, 5, 5, 4, 5, 6, 3, 7, 6 };
unsigned short digit[4];
unsigned short hide_leading_hours_digit;
if (hours > 99) hours = 99;
if (minutes > 59) minutes = 59;
if (hours < 10 && hours >= 0) {
hide_leading_hours_digit = 1;
}
else {
hide_leading_hours_digit = 0;
}
digit[0] = hours / 10;
digit[1] = hours % 10;
digit[2] = minutes / 10;
digit[3] = minutes % 10;
for (i = hide_leading_hours_digit; i < 4; i++) {
clock_all_off();
clock_show_digit(i, digit[i]);
delaytime = num_leds[digit[i]] * DELAYTIME;
delayMicroseconds(delaytime);
}
clock_all_off();
}
void clock_all_off(void) {
digitalWrite(DIGIT1, LOW);
digitalWrite(DIGIT2, LOW);
digitalWrite(DIGIT3, LOW);
digitalWrite(DIGIT4, LOW);
digitalWrite(SEGMENTA, LOW);
digitalWrite(SEGMENTB, LOW);
digitalWrite(SEGMENTC, LOW);
digitalWrite(SEGMENTD, LOW);
digitalWrite(SEGMENTE, LOW);
digitalWrite(SEGMENTF, LOW);
digitalWrite(SEGMENTG, LOW);
digitalWrite(COLON, LOW);
}
void clock_show_digit(unsigned short position, unsigned short value) {
byte a;
byte b;
byte c;
byte d;
byte e;
byte f;
byte g;
switch (position) {
case 0:
digitalWrite(DIGIT1, HIGH);
break;
case 1:
digitalWrite(DIGIT2, HIGH);
break;
case 2:
digitalWrite(DIGIT3, HIGH);
break;
case 3:
digitalWrite(DIGIT4, HIGH);
break;
}
a = !(value == 1 || value == 4 || value == 10);
b = !(value == 5 || value == 6 || value == 10);
c = !(value == 2 || value == 10 || value == 11);
d = !(value == 1 || value == 4 || value == 7 || value == 11);
e = (value == 0 || value == 2 || value == 6 || value == 8 || value == 10);
f = !(value == 1 || value == 2 || value == 3 || value == 7);
g = !(value == 0 || value == 1 || value == 7);
if (a) digitalWrite(SEGMENTA, HIGH);
if (b) digitalWrite(SEGMENTB, HIGH);
if (c) digitalWrite(SEGMENTC, HIGH);
if (d) digitalWrite(SEGMENTD, HIGH);
if (e) digitalWrite(SEGMENTE, HIGH);
if (f) digitalWrite(SEGMENTF, HIGH);
if (g) digitalWrite(SEGMENTG, HIGH);
}
void clock_show_colon(void) {
unsigned short delaytime;
digitalWrite(COLON, HIGH);
delaytime = DELAYTIME * 4;
delayMicroseconds(delaytime);
digitalWrite(COLON, LOW);
}
вот если б комментарии к прогаммке :) а то для неофитов трудно для понимания.
УПД.
я канешь продвинутый, однако от подсказки не откажусь: как добавить будильник в этот скетч? если автор или ктонить знает, подскажите плз. :)
мож кто знает: использую данный скетч(только поменял всё на индикатор с ОК) и схему использую без ключей - индикатор подключил прямо к МК через резисторы 270 Ом.
так вот, добавил в скетч две сточки (что б точки мигали)
void clock_show_colon(void) { unsigned short delaytime; digitalWrite(COLON, HIGH); digitalWrite(DIGIT2, LOW); // эту delaytime = DELAYTIME * 4; delayMicroseconds(delaytime); digitalWrite(COLON, HIGH); digitalWrite(DIGIT2, LOW);// и вот этувсё работатет, тольсо сами цифры святят еле-еле и мерцают, а точка нормально так себе мигает.
где б ещё пару строк добавить что б избавится от этой напасти? )))
так понимаю, что-то с частотой не то в динамической индикации.
разобрался - строка 136.
получается что и семисегментник можно зачудить самопальный и будет работать матрица необязательна ?
DarkGenius покажите где в скетче температуру конвертирует ?как под 18В20 переделать ?
karl2233 ткните носом где пентература в скетче считается ?
karl2233 ткните носом где пентература в скетче считается ?
Ну же ж в строке 49, и не зачем так орать)
спасибки !!! я не кричал!? :)
всем привет!
что за транзистор BD548?
всем привет!
что за транзистор BD548?
Простенько ведь, Митрофанушка, забиваем в хухель "bd548 datasheet" и наслаждаемся откровениями.
Схема таже но на 12 вольт, лента красная 14вт/м, контроллер ESP32 через степдаун 12v > 3.3v иначе сгорит, датчик DHT22, часы DS3231, кнопок нет, веб интерфейс, немного кривые, но в целом доволен.
#include "DHT.h" #include "SevSeg.h" #include <WiFi.h> #include <Wire.h> #include <ds3231.h> #define DHTPIN 5 #define DHTTYPE DHT22 byte colonPin = 2; byte numDigits = 4; byte digitPins[] = {19, 18, 23, 4}; byte oldSec; byte segmentPins[] = {13, 25, 12, 33, 14, 27, 26}; bool resistorsOnSegments = true; // 'false' means resistors are on digit pins byte hardwareConfig = N_TRANSISTORS; // See README.md for options bool updateWithDelays = false; // Default 'false' is Recommended bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected. Then, you only need to specify 7 segmentPins[] bool colon; bool colonSet; bool dhtRead; String header; String ConfigValue[8]; String climate = "On"; unsigned long dhtTimer; float temp_hum_val[2] = {0}; bool showClimate = true; WiFiServer server(80); ts t; SevSeg sevseg; DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(115200); Wire.begin(); dht.begin(); sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint); sevseg.setBrightness(100); WiFi.softAP("bigclock", "123456789",7,1,1); IPAddress IP = WiFi.softAPIP(); Serial.println(IP); server.begin(); Wire.begin(); //start i2c (required for connection) DS3231_init(DS3231_INTCN); //register the ds3231 pinMode(colonPin, OUTPUT); } void loop() { DS3231_get(&t); if ((t.min % 10 == 0) && (t.sec >= 10) && (t.sec < 30) && showClimate){ if (!dhtRead){ digitalWrite(colonPin, LOW); sevseg.setChars(" "); sevseg.refreshDisplay(); delay(20); if(!dht.readTempAndHumidity(temp_hum_val)){ dhtRead = true; } } String stringVar; if (t.sec < 20){ if (temp_hum_val[1] < 10) stringVar = " "; stringVar = stringVar + String(int(temp_hum_val[1]),DEC); stringVar = stringVar + "t*"; //Serial.println(stringVar); } else{ if (temp_hum_val[0] < 10) stringVar = " "; stringVar = stringVar + String(int(temp_hum_val[0]),DEC); stringVar = stringVar + "*-"; //Serial.println(stringVar); } char charBufVar[8]; stringVar.toCharArray(charBufVar, 8); sevseg.setChars(charBufVar); sevseg.refreshDisplay(); } else { if (oldSec != t.sec) { colonSet = true; oldSec = t.sec; } if (colonSet){ colon = !colon; if(colon) digitalWrite(colonPin, HIGH); else digitalWrite(colonPin, LOW); colonSet = false; } timeShow(); dhtRead = false; } WiFiClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { char c = client.read(); if (header.length() < 100) { header += c; } if (c == '\n') { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}</style></head>"); client.println("<body><h1>Big Clock Settings</h1>"); client.println("<form action=\"/action_page\">"); client.print("Hours: <input type=\"text\" name=\"Hours\" size=2 value=\"\">"); client.print("Minutes: <input type=\"text\" name=\"Minutes\" size=2 value=\"\">"); client.print("<br><br>"); client.print("<input type=\"submit\" value=\"Submit\">"); client.print("</form>"); //client.print(form_page); client.print("</p>"); client.print("<h1>Climat Show:" + climate); client.println("</h1></p>"); client.print("<input type=submit value=ON onClick=location.href='/?on8;'>"); client.print(" "); client.print("<input type=submit value=OFF onClick=location.href='/?off9;'>"); client.println("</body></html>"); delay(1); client.stop(); int posFirstCharToSearch = 1; int count = 0; while (header.indexOf('&', posFirstCharToSearch) > -1) { int posOfSeparatorChar = header.indexOf('&', posFirstCharToSearch); // position of & after start position int posOfValueChar = header.indexOf('=', posFirstCharToSearch); // position of = after start position ConfigValue[count] = header.substring(posOfValueChar + 1, posOfSeparatorChar); // extract everything between = and & and enter it in the ConfigValue posFirstCharToSearch = posOfSeparatorChar + 1; // shift the start position to search after the &-char count++; } int posOfValueChar = header.indexOf('=', posFirstCharToSearch); // search for = ConfigValue[count] = header.substring(posOfValueChar + 1, header.length()-10); // extract everything between = and end of string count++; if (count > 1){ if (int setHours = ConfigValue[0].toInt()){ if (setHours >= 0 && setHours < 23){ //Serial.print("Hours: "); //Serial.println(setHours, DEC); t.sec = 0; t.min = t.min; t.hour = setHours; t.wday = t.wday; t.mday = t.mday; t.mon = t.mon; t.year = t.year; DS3231_set(t); } } if (int setMinutes = ConfigValue[1].toInt()){ if (setMinutes >= 0 && setMinutes < 59){ //Serial.print("Minutes: "); //Serial.println(setMinutes, DEC); t.sec = 0; t.min = setMinutes; t.hour = t.hour; t.wday = t.wday; t.mday = t.mday; t.mon = t.mon; t.year = t.year; DS3231_set(t); } } } if(header.indexOf('8') >0)//checks for 8 { climate = "On"; showClimate = true; } if(header.indexOf('9') >0)//checks for 9 { climate = "Off"; showClimate = false; } header=""; } } } } } void timeShow() { String stringVar; if (t.hour < 10) stringVar = " "; stringVar = stringVar + String(t.hour, DEC); if (t.min < 10) { stringVar = stringVar + "0"; stringVar = stringVar + String(t.min, DEC); } else { stringVar = stringVar + String(t.min / 10, DEC); stringVar = stringVar + String(t.min % 10, DEC); } char charBufVar[8]; stringVar.toCharArray(charBufVar, 8); sevseg.setChars(charBufVar); sevseg.refreshDisplay(); // Must run repeatedly }