Часы-Термометр на Arduino Uno, 4 разрядном 7 сегментном индикаторе, датчике температуры LM35 и RTC модуле DS1302.

DarkGenius
Offline
Зарегистрирован: 09.07.2015
Сразу оговорюсь лепил из того что было. Лежал у меня неисправный 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);
}

 

karl2233
karl2233 аватар
Offline
Зарегистрирован: 05.07.2015

вот если б комментарии к прогаммке :)  а то для неофитов трудно для понимания.

УПД.

я канешь продвинутый, однако от подсказки не откажусь: как добавить будильник в этот скетч? если автор или ктонить знает, подскажите плз. :)

мож кто знает: использую данный скетч(только поменял всё на индикатор с ОК) и схему использую без ключей - индикатор подключил прямо к МК через резисторы 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.

dgeka
Offline
Зарегистрирован: 05.07.2016

получается что и семисегментник можно зачудить самопальный и будет работать матрица необязательна ?

dgeka
Offline
Зарегистрирован: 05.07.2016

DarkGenius   покажите где в скетче температуру конвертирует ?как под 18В20 переделать ?

dgeka
Offline
Зарегистрирован: 05.07.2016

karl2233 ткните носом где пентература в скетче считается ?

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

dgeka пишет:

karl2233 ткните носом где пентература в скетче считается ?


Ну же ж в строке 49, и не зачем так орать)

dgeka
Offline
Зарегистрирован: 05.07.2016

спасибки !!! я не кричал!? :)

dgeka
Offline
Зарегистрирован: 05.07.2016
при попытке компиляции пишет 
что он хочет ? 
sketch_jan06a:23: error: no matching function for call to 'Time::Time()'
 
C:\Users\Арсений\Desktop\sketch_jan06a\sketch_jan06a.ino:23:8: note: candidates are:
 
In file included from C:\Users\Арсений\Desktop\sketch_jan06a\sketch_jan06a.ino:1:0:
 
D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302/DS1302.h:35:3: note: Time::Time(uint16_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, Time::Day)
 
   Time(uint16_t yr, uint8_t mon, uint8_t date,
 
   ^
 
D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302/DS1302.h:35:3: note:   candidate expects 7 arguments, 0 provided
 
D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302/DS1302.h:13:7: note: constexpr Time::Time(const Time&)
 
 class Time {
 
       ^
 
D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302/DS1302.h:13:7: note:   candidate expects 1 argument, 0 provided
 
D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302/DS1302.h:13:7: note: constexpr Time::Time(Time&&)
 
D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302/DS1302.h:13:7: note:   candidate expects 1 argument, 0 provided
 
C:\Users\Арсений\Desktop\sketch_jan06a\sketch_jan06a.ino: In function 'void loop()':
 
sketch_jan06a:49: error: 'class DS1302' has no member named 'getTime'
 
sketch_jan06a:80: error: 'class Time' has no member named 'hour'
 
sketch_jan06a:88: error: 'class Time' has no member named 'hour'
 
sketch_jan06a:91: error: 'class DS1302' has no member named 'setTime'
 
sketch_jan06a:95: error: 'class DS1302' has no member named 'setTime'
 
sketch_jan06a:103: error: 'class Time' has no member named 'hour'
 
sketch_jan06a:106: error: 'class DS1302' has no member named 'setTime'
 
sketch_jan06a:110: error: 'class DS1302' has no member named 'setTime'
 
Используем библиотеку ds1302 в папке: D:\Женины файлы\arduino-1.6.9-windows\arduino-1.6.9\libraries\ds1302 (legacy)
exit status 1
no matching function for call to 'Time::Time()'
dimasik89
Offline
Зарегистрирован: 11.08.2017

всем привет!

что за транзистор BD548?

bwn
Offline
Зарегистрирован: 25.08.2014

dimasik89 пишет:

всем привет!

что за транзистор BD548?

Простенько ведь, Митрофанушка, забиваем в хухель "bd548 datasheet" и наслаждаемся откровениями.

DarkGenius
Offline
Зарегистрирован: 09.07.2015

Схема таже но на 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("&nbsp;&nbsp;");
          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
}