Ничего не найдено :(
    В гостях у Самоделкина! » Электроника » Arduino » Часы + термометр на Arduino

    Часы + термометр на Arduino

    Приветствую всех любителей самоделок! Сегодня хочу рассказать о своём проекте - часы в подарок. У однокурсника в сентябре день рождения, но подарок решил начать готовить пораньше, так как в учебное время этим некогда будет заниматься. Эти часы начинал собирать ещё года так 3-4 назад, но потом забросил их чего-то и недавно наводя порядок в своих закромах наткнулся на них. То есть для меня по сути эти часы нужно доработать, а именно сделать культурный корпус и добавить датчик комнатной температуры, в его роли будет выступать ds18b20. Начинаем!


    Для этого нам понадобится:

    1. Светодиодная матрица на MAX7219. 
    2. Плата Arduino Nano (можно и другую, например Pro Mini).
    3. Модуль часов реального времени DS1302. 
    4. Датчик температуры ds18b20 и к нему резистор на 4,7 Ком.
    5. Тонкий провод (в моём случае это МГТФ-0,25). 
    6.  Стойки, винты и гайки к ним.
    7.  Двухсторонний скотч.
    8. Термоклей и клеевой пистолет. 
    9. Ненужный USB провод. 
    10. Два разъёма типа "мама" (необязательно, можно припаять провод без них). 
    11. Три тактовые кнопочки, кусочек макетной платы и 3 SMD резистора по 10 кОм. 
    12. Паяльник, припой, канифоль и т.д. 


    1. Прошиваемся

    Я постарался максимально понятно написать код с комментариями. Да, он не идеален и его можно упростить, но и так сойдёт. Функция dat работает с датчиком температуры и выводит всю информацию о нём в монитор порта, можно посмотреть. Стоит сразу отметить, что ds18b20 нужно подключать именно к аналоговому входу МК, сначала прицепил на цифровой и долго думал почему ничего не работает.


    Сам код: 

    //недостающие библиотеки качаем из инета
    #include <iarduino_RTC.h> // эта библиотека версии 1.3.4 от 09.01.2020
    #include <Wire.h>
    #include <SPI.h>
    #include <OneWire.h>
    #include <Adafruit_GFX.h>
    #include <Max72xxPanel.h>
    #include <DallasTemperature.h>
    OneWire  ds(A0); //(пин куда подключён датчик)
    byte i; //всё для датчика
    byte present = 0;
    byte type_s;
    byte data[9];
    byte addr[8];
    float celsius, fahrenheit;
    uint8_t h,m,s; // переменные для хранения времени
    Max72xxPanel matrix = Max72xxPanel(10, 1, 4); // пин CS, кол-во матриц по вертикали, кол-во матриц по горезонтали
    iarduino_RTC watch(RTC_DS1302,2,3,4); //rst clk dat модуля часов
    int spacer = 1; // расстояние между цифрами температуры
    int width = 5 + spacer; // размер шрифта
    
    void setup(void) {
    Serial.begin(9600);
    matrix.setIntensity(1); // Яркость от 0 до 15
    matrix.setRotation(matrix.getRotation()+1); // положение матриц  +1 - 90  +2 - 180   +3 - 270 градусов 
    watch.begin(); // запуск часов
    watch.settime(0,0,12); // установка текущего времени (сек, мин, час), записывается один раз 
    pinMode(8, OUTPUT); // настройка пинов для кнопок
    digitalWrite(8,1);
    pinMode(7, INPUT);
    pinMode(6, INPUT);
    pinMode(5, INPUT);
    }
    void dat() { // подключение датчика и вся инфа о нём
     
      if ( !ds.search(addr)) {
        Serial.println("No more addresses.");
        Serial.println();
        ds.reset_search();
        delay(10);
        return;
      }
      
      Serial.print("ROM =");
      for( i = 0; i < 8; i++) {
        Serial.write(' ');
        Serial.print(addr[i], HEX);
      }
    
      if (OneWire::crc8(addr, 7) != addr[7]) {
          Serial.println("CRC is not valid!");
          return;
      }
      Serial.println();
     
      // the first ROM byte indicates which chip
      switch (addr[0]) {
        case 0x10:
          Serial.println("  Chip = DS18S20");  // or old DS1820
          type_s = 1;
          break;
        case 0x28:
          Serial.println("  Chip = DS18B20");
          type_s = 0;
          break;
        case 0x22:
          Serial.println("  Chip = DS1822");
          type_s = 0;
          break;
        default:
          Serial.println("Device is not a DS18x20 family device.");
          return;
      } 
    
      ds.reset();
      ds.select(addr);
      ds.write(0x44, 1);        // start conversion, with parasite power on at the end
      
      //delay(750);     // maybe 750ms is enough, maybe not
      // we might do a ds.depower() here, but the reset will take care of it.
      
      present = ds.reset();
      ds.select(addr);    
      ds.write(0xBE);         // Read Scratchpad
    
      Serial.print("  Data = ");
      Serial.print(present, HEX);
      Serial.print(" ");
      for ( i = 0; i < 9; i++) {           // we need 9 bytes
        data[i] = ds.read();
        Serial.print(data[i], HEX);
        Serial.print(" ");
      }
      Serial.print(" CRC=");
      Serial.print(OneWire::crc8(data, 8), HEX);
      Serial.println();
    
      int16_t raw = (data[1] << 8) | data[0];
      if (type_s) {
        raw = raw << 3; // 9 bit resolution default
        if (data[7] == 0x10) {
          // "count remain" gives full 12 bit resolution
          raw = (raw & 0xFFF0) + 12 - data[6];
        }
      } else {
        byte cfg = (data[4] & 0x60);
        // at lower res, the low bits are undefined, so let's zero them
        if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
        else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
        else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    
      }
      
      celsius = (float)raw / 16.0; //расчёт температуры в градусах
     // fahrenheit = celsius * 1.8 + 32.0;
      Serial.print("  Temperature = ");
      Serial.print(celsius);
      Serial.print(" Celsius, ");
     // Serial.print(fahrenheit);
     // Serial.println(" Fahrenheit");
      //delay(500);
    }
    
    void loop(void){
      dat(); 
      Display();
      watch.gettime();
      if(millis()%1000==0){ // если прошло 1 секунда
       h = watch.Hours;    // Получаем текущие часы 
       m = watch.minutes;  // Получаем текущие минуты    
       s = watch.seconds;   // Получаем текущие секунды
       delay(2);
      }
      bool button_setup = digitalRead(7); // считываем состояние кнопок
      bool button_plus = digitalRead(6); 
      bool button_minus = digitalRead(5); 
      
      //Проверка нажатий
     int regim=1;
     int flag=0; 
      if (regim==1 and button_minus==1){
     temp();
      }
       if(button_setup==1&&flag==0)  
         { 
           regim++;   
           flag=1;                        
            if(regim>3) regim=1;             
         }       
          if(button_setup==0&&flag==1) flag=0;    
        if(regim==1)//настройка часов
        { 
          if(button_plus==1){ //настройка часов
             h++;
             if(h>23) h=0;
              watch.settime(0,m,h);
             delay(250);
          }
        }     
        if(regim==2)//настройка минут
        { 
          if(button_plus==1){
             m++;
             if(m>59) m=0;
              watch.settime(0,m,h);
             delay(250);
          }
        }      
    }
    void temp() { //вывод температуры
      String tape = String(celsius, 1)+" ";
        for ( int i = 0 ; i < width * tape.length() + matrix.width() - 1 - spacer; i++ ) {
            matrix.fillScreen(LOW);
    
            int letter = i / width;
            int x = (matrix.width() - 1) - i % width;
            int y = (matrix.height() - 8) / 2;
    
            while ( x + width - spacer >= 0 && letter >= 0 ) {
                if ( letter < tape.length() ) {
                    matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1);
                }
                letter--;
                x -= width;
            }
    
            matrix.write();
            delay(50);
        }
    }
    void Display(){  //вывод времени
        matrix.fillScreen(0);
        int y = (matrix.height() - 8) / 2; // центрирование по вертикали
      
        if(watch.seconds & 1)  // мигающее двоеточие
        {
          matrix.drawChar(14, y, (String(":"))[0], HIGH, LOW, 1);
        } 
        else
        {
          matrix.drawChar(14, y, (String(" "))[0], HIGH, LOW, 1);
          }
        
        String hour1 = String (h/10); // преобразовываем числа для вывода
        String hour2 = String (h%10);
        String min1 = String (m/10);
        String min2 = String (m%10);
        String sec1 = String (s/10);
        String sec2 = String (s%10);
        int xh = 2;
        int xm = 19;
    
        matrix.drawChar(xh, y, hour1[0], HIGH, LOW, 1);
        matrix.drawChar(xh+6, y, hour2[0], HIGH, LOW, 1);
        matrix.drawChar(xm, y, min1[0], HIGH, LOW, 1);
        matrix.drawChar(xm+6, y, min2[0], HIGH, LOW, 1);
     
        matrix.write(); // Вывод на дисплей
    }

    2. Паяем, собираем

    После успешной прошивки переходим к сборке часов. Прикручиваем стойки к матрице по краям для крепления в корпус. Крепим Arduino, модуль часов и кнопки на двухсторонний скотч к обратной стороне платы матрицы, провода на термоклей. Схема: 

    Датчик: 

    Клавиатура (вид снизу): 


    Провод питания можно сделать так. Берём ненужный USB-провод от зарядки и откусываем разъём микро-USB (в моём случае). Теперь зачищаем провода и аккуратно припаиваем разъёмы "мама". Места спайки изолируем термоусадкой. Соблюдая полярность питания подключаем провод к разъёму ISP для программатора. 

    Готово!


    3. Корпус

    Так как это подарок то корпус должен быть хороший, поэтому открываю программу Компас-3D, моделирую и отправляю для печати чудесной шайтан-машине под названием 3D-принтер. Только под кнопки вручную отверстия надо будет сделать. Вот как это будет выглядеть:

    4. Настройка

    Настройку немного переработал - осуществляется двумя кнопками + датчик.

    При нажатии кнопки 2, увеличиваем час на 1. 

    При одновременном нажатии на кнопки 1 и 2, увеличиваем минуты на 1.

    При нажатии на кнопку 3 отображаем температуру с датчика в виде бегущей строки. Вот как-то так:


    На этом у меня всё, будет интересно узнать ваше мнение об этом проекте. Всем удачных самоделок! 

    Становитесь автором сайта, публикуйте собственные статьи, описания самоделок с оплатой за текст. Подробнее здесь.
    Подборки: Часы

    Часы на индикаторах ИН-12 и Arduino

    Часы на Attiny88, с термометром, и настройкой пультом

    6.5
    Идея
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    8.5
    Описание
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    5
    Исполнение
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    Итоговая оценка: 6.67 из 10 (голосов: 2 / История оценок)

    Добавить комментарий


    • 0
    11 комментариев
    Гость Михаил #94632
    Гость Владимир,


    Поделитесь скетчем.

    лука #93927

    один вопрос, сколько такие часы потребляют? смысл это делать на ардуино с кнопками, если часы все равно много жрут для батарейного питания из за матрицы MAX7219, и можно вставить какую-нибудь esp, для настроки часов по wi-fi?

    Гость Алексей #93239

    Здравствуйте, собрал часы эти из этих же компонентов, всё работает, но есть нюанс минуты почему то переключаются не всегда поочереди, бывает так что застревает к примеру 22:51 ... и минуты 2-3 не меняется, а потом перескакивает на 22:53 , но при этом часы не отстают, они просто почему то пропускают минуты. сможете подсказать в чем проблема? 

    Гость Валерий #90091
    Гость Владимир,


    Добрый день.Поделитесь пожалуйста скетчем и схемой на часы с двумя датчиками температуры

    Гость Владимир #85873

    Спасибо всем кто помог! Немного доработал скетч, теперь часы показывают время, а раз в минуту бегущей строкой пробегает температура в помещении, и следом за ней температура на улице. Код конечно не идеален, но если кому надо, то поделюсь

    Гость Владимир #85746

    Помогите доработать скетч, чтобы отображать и уличную температуру со второго ds18b20. Уже неделю бьюсь, но недопонимаю. 

    sergeyp #82026

    Вот вариант для таких часов на адресниках, 8 х 32 гибкий, наклеил - и готов дисплей rgb...

    Нашёл ЗДЕСЬ

    v258 #81991

    Трех кнопок достаточно для организации нормальной настройки. Кнопка Set и две кнопки "+" и "-". Длинный клик кнопкой Set включает режим настройки часов, величину устанавливаем кнопками "+" и "-". Следующий клик кнопкой Set переводит в режим настройки минут. Третий клик кнопкой Set выводит в режим показа времени. И никаких ложных срабатываний из-за случайно задетой кнопки. Температуру можно выводить кликом, например, кнопки "+". А тут какой-то треш, автор сам забудет алгоритм через пару месяцев  smile 

    Jerry #81945
    Цитата: Artem_Proger
    Если один раз показать


    А если не показывать, через какое время пользователь догадается, что надо нажимать одновременно несколько кнопок? 

    Artem_Proger #81943 Автор
    Цитата: Jerry
    Вот и автор "гениально" реализовал настройки:


    На мой взгляд довольно простая настройка, на кнопку нажал и увидел температуру, держишь одну кнопку прибавляешь часы, а чтобы прибавлять минуты нужно параллельно удерживать вторую кнопку  dontknow Если один раз показать то думаю это легко запоминается

    Jerry #81934

    Недавно ремонтировал интересные часы. Понравилось как организовано управление четырьмя кнопками: одна кнопка отвечает за будильник (включение, выключение, переход в настройки), вторая переключение режимов, долгое удержание переход в настройки и переключение пунктов настройки, еще две кнопки "+" и "-". Оказалось, что наличие "+" и "-" чертовски удобно, особенно когда глючит кнопка переключения режимов и вместо переключения режимов она часто срабатывает как "+". Меня всегда удивляло и бесило, когда при возможности установки дополнительных кнопок люди заморачиваются усложнением программы, да так, что без инструкции хрен разберешься. Недавно попросили изменить уставки температуры восьмиканального контроллера фирмы "ОВЕН". Минут 10 пробовал, не получилось, пошел читать инструкцию. А ведь это простейшее действие должно быть реализовано интуитивно понятно. Чем думают заказчики, разработчики, тестировщики?

    Вот и автор "гениально" реализовал настройки:

    4. Настройка

    Настройку немного переработал - осуществляется двумя кнопками + датчик.

    При нажатии кнопки 2, увеличиваем час на 1. 

    При одновременном нажатии на кнопки 1 и 2, увеличиваем минуты на 1.

    При нажатии на кнопку 3 отображаем температуру с датчика в виде бегущей строки. Вот как-то так...

    fool 



    Привет, Гость!


    Зарегистрируйтесь

    Или войдите на сайт, если уже зарегистрированы...

    Войти

    Добавьте самоделку

    Добавьте тему

    Онлайн чат

    Последние комментарии

    Все комментарии