Объявление

США начнут предпринимать меры экономического и военного характера, если Россия не прекратит нарушать Договор о ракетах средней и меньшей дальности (ДРСМД)

Решение главы Национального Объединения "Новая Россия - Великая Россия" Rommstaina: http://russianew.ru/viewtopic.php?f=120&t=4039

OLED часы на arduino с датчиком температуры DS18B20

Правила форума
Внимание! Любой спам на нашем форуме запрещён!
Коммерческая реклама сайтов, ссылки, спам запрещены. Так же запрещены ссылки на сайты в профилях новичков.
Бан без предупреждений.

OLED часы на arduino с датчиком температуры DS18B20

Сообщение admin » 04 дек 2016, 21:24

На днях я решил создать часы на arduino с отображением времени, текущей даты, дня недели и температуры воздуха на OLED дисплее.

Список необходимых компонентов:

Часовой модуль DS1307 – 1 шт.
Датчик температуры DS18B20 – 1 шт.
OLED I2C дисплей 0.96″ – 1 шт.
Плата Arduino nano V 3.0 – 1 шт.

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

DS1307
OneWire
OLED I2C RUS

Далее подключаем все по схеме

Изображение

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

Код: выделить все
#include <OLED_I2C.h>         // Подключение библиотеки для дисплея
OLED  myOLED(SDA, SCL, 8);   
extern uint8_t MegaNumbers[]; // Подключение больших шрифтов
extern uint8_t SmallFont[];   // Подключение маленьких шрифтов
#include <DS1307.h>           // Подключение библиотеки для часового модуля
DS1307 rtc(A0, A1);
 
void setup() {
  myOLED.begin();
  rtc.halt(false);
  rtc.setDOW(SUNDAY);         // Настройка дня недели 
  rtc.setTime(12, 0, 0);      // Настройка времени
  rtc.setDate(10, 05, 2015);  // Настройка даты
}
 
void loop(){
  myOLED.setFont(SmallFont);
  myOLED.print(rtc.getDOWStr(), CENTER, 0);   // Отображение дня недели
  String stringOne = rtc.getTimeStr();
  myOLED.setFont(MegaNumbers);
  myOLED.print(stringOne.substring(0,2), 4, 12);   // Отображение часов
  myOLED.print("/", 51, 12);                       // Отображение двоеточия
  myOLED.print(stringOne.substring(3,5), 75, 12);  // Отображение минут
  myOLED.setFont(SmallFont);
  myOLED.print(rtc.getDateStr(), CENTER, 57);      // Отображение даты
  myOLED.update();
  delay(500);
  myOLED.setFont(MegaNumbers);                     // Скрытие двоеточия
  myOLED.print("-", 51, 12);
  myOLED.update();
  delay(500);
}


после загрузки скетча у нас на дисплее отобразятся часы как на фото

Изображение

Как видим все отображается нормально, но что бы добавить русские названия дней недели нам потребуется инициализировать русские шрифты добавив строку в скетч

Код: выделить все
extern uint8_t RusFont[];


и еще добавить строки которые помогут нам определить порядковый номер дня недели и отобразить название дня на русском языке.

Код: выделить все
switch (t.dow)
  {
    case 1:     myOLED.print("GJYTLTKMYBR", CENTER, 0);    break;
    case 2:     myOLED.print("DNJHYBR", CENTER, 0);        break;
    case 3:     myOLED.print("CHTLF", CENTER, 0);          break;
    case 4:     myOLED.print("XTNDTHU", CENTER, 0);        break;
    case 5:     myOLED.print("GZNYBWF", CENTER, 0);        break;
    case 6:     myOLED.print("CE<<JNF", CENTER, 0);        break;
    case 7:     myOLED.print("DJCRHTCTYMT", CENTER, 0);    break;
  }


и еще закомментируем строки

Код: выделить все
//  rtc.setDOW(MONDAY);       
//  rtc.setTime(13, 25, 0);     
//  rtc.setDate(27, 04, 2015);


что бы при повторной загрузке скетча не устанавливать заново время. После этого день недели на нашем дисплее отобразится на русском языке.

Изображение

теперь изменим отображения месяца, добавив в скетч строки

Код: выделить все
switch (t.mon)
  {
    case 1:
      myOLED.print(String(t.date), 30, 57);
      myOLED.print("ZYDFHZ", CENTER, 57);
      myOLED.print(String(t.year), 88, 57);
      break;
    case 2:
      myOLED.print(String(t.date), 26, 57);
      myOLED.print("ATDHFKZ", CENTER, 57);
      myOLED.print(String(t.year), 92, 57);
      break;
    case 3:
      myOLED.print(String(t.date), 30, 57);
      myOLED.print("VFHNF", CENTER, 57);
      myOLED.print(String(t.year), 88, 57);
      break;
    case 4:
      myOLED.print(String(t.date), 30, 57);
      myOLED.print("FGHTKZ", CENTER, 57);
      myOLED.print(String(t.year), 88, 57);
      break;
    case 5:
      myOLED.print(String(t.date), 36, 57);
      myOLED.print("VFZ", CENTER, 57);
      myOLED.print(String(t.year), 82, 57);
      break;
    case 6:
      myOLED.print(String(t.date), 35, 57);
      myOLED.print("B>YZ", CENTER, 57);
      myOLED.print(String(t.year), 81, 57);
      break;
    case 7:
      myOLED.print(String(t.date), 35, 57);
      myOLED.print("B>KZ", CENTER, 57);
      myOLED.print(String(t.year), 81, 57);
      break;
    case 8:
      myOLED.print(String(t.date), 28, 57);
      myOLED.print("FDUECNF", CENTER, 57);
      myOLED.print(String(t.year), 90, 57);
      break;
    case 9:
      myOLED.print(String(t.date), 24, 57);
      myOLED.print("CTYNZ<HZ", CENTER, 57);
      myOLED.print(String(t.year), 94, 57);
      break;
    case 10:
      myOLED.print(String(t.date), 26, 57);
      myOLED.print("JRNZ<HZ", CENTER, 57);
      myOLED.print(String(t.year), 92, 57);
      break;
    case 11:
      myOLED.print(String(t.date), 28, 57);
      myOLED.print("YJZ<HZ", CENTER, 57);
      myOLED.print(String(t.year), 90, 57);
      break;
    case 12:
      myOLED.print(String(t.date), 26, 57);
      myOLED.print("LTRF<HZ", CENTER, 57);
      myOLED.print(String(t.year), 92, 57);
      break;
  }


Теперь наши часики будут выглядеть как на фото.

Изображение

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

Код: выделить все
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL, 8);
extern uint8_t MegaNumbers[];
extern uint8_t RusFont[];
extern uint8_t SmallFont[];

#include <DS1307.h>
DS1307 rtc(A0, A1);
Time t;

void setup() {
  myOLED.begin();
  rtc.halt(false);
//  rtc.setDOW(WEDNESDAY);
//  rtc.setTime(10, 02, 0);
//  rtc.setDate(29, 4, 2015);
}

void loop() {
  myOLED.setFont(RusFont);
  t = rtc.getTime();
  switch (t.dow)
  {
    case 1:     myOLED.print("GJYTLTKMYBR", CENTER, 0);    break;
    case 2:     myOLED.print("DNJHYBR", CENTER, 0);        break;
    case 3:     myOLED.print("CHTLF", CENTER, 0);          break;
    case 4:     myOLED.print("XTNDTHU", CENTER, 0);        break;
    case 5:     myOLED.print("GZNYBWF", CENTER, 0);        break;
    case 6:     myOLED.print("CE<<JNF", CENTER, 0);        break;
    case 7:     myOLED.print("DJCRHTCTYMT", CENTER, 0);    break;
  }
  String stringOne = rtc.getTimeStr();
  myOLED.setFont(MegaNumbers);
  myOLED.print(stringOne.substring(0, 2), 4, 12);
  myOLED.print("/", 51, 12);
  myOLED.print(stringOne.substring(3, 5), 75, 12);
  myOLED.setFont(RusFont);
  switch (t.mon)
  {
    case 1:
      myOLED.print(String(t.date), 30, 57);
      myOLED.print("ZYDFHZ", CENTER, 57);
      myOLED.print(String(t.year), 88, 57);
      break;
    case 2:
      myOLED.print(String(t.date), 26, 57);
      myOLED.print("ATDHFKZ", CENTER, 57);
      myOLED.print(String(t.year), 92, 57);
      break;
    case 3:
      myOLED.print(String(t.date), 30, 57);
      myOLED.print("VFHNF", CENTER, 57);
      myOLED.print(String(t.year), 88, 57);
      break;
    case 4:
      myOLED.print(String(t.date), 30, 57);
      myOLED.print("FGHTKZ", CENTER, 57);
      myOLED.print(String(t.year), 88, 57);
      break;
    case 5:
      myOLED.print(String(t.date), 36, 57);
      myOLED.print("VFZ", CENTER, 57);
      myOLED.print(String(t.year), 82, 57);
      break;
    case 6:
      myOLED.print(String(t.date), 35, 57);
      myOLED.print("B>YZ", CENTER, 57);
      myOLED.print(String(t.year), 81, 57);
      break;
    case 7:
      myOLED.print(String(t.date), 35, 57);
      myOLED.print("B>KZ", CENTER, 57);
      myOLED.print(String(t.year), 81, 57);
      break;
    case 8:
      myOLED.print(String(t.date), 28, 57);
      myOLED.print("FDUECNF", CENTER, 57);
      myOLED.print(String(t.year), 90, 57);
      break;
    case 9:
      myOLED.print(String(t.date), 24, 57);
      myOLED.print("CTYNZ<HZ", CENTER, 57);
      myOLED.print(String(t.year), 94, 57);
      break;
    case 10:
      myOLED.print(String(t.date), 26, 57);
      myOLED.print("JRNZ<HZ", CENTER, 57);
      myOLED.print(String(t.year), 92, 57);
      break;
    case 11:
      myOLED.print(String(t.date), 28, 57);
      myOLED.print("YJZ<HZ", CENTER, 57);
      myOLED.print(String(t.year), 90, 57);
      break;
    case 12:
      myOLED.print(String(t.date), 26, 57);
      myOLED.print("LTRF<HZ", CENTER, 57);
      myOLED.print(String(t.year), 92, 57);
      break;
  }
  myOLED.update();
  delay(500);
  myOLED.setFont(MegaNumbers);
  myOLED.print("-", 51, 12);
  myOLED.update();
  delay(500);
}


Ну а теперь, еще более усовершенствуем наши OLED часы и добавим к ним отображение температуры, которую мы будем считывать с датчика температуры DS18B20.

Для отображения рисунка с градусником на OLED дисплее и значка градуса выберем картинку с рисунком градусника и с помощью графического редактора сохраним ее в формате GIF с именем term.gif, и тоже самое проделаем с картинкой с значком градуса — сохраним ее как grad.gif.

картинки должны быть двухцветными (белый и черный), доступные форматы картинок png, jpg, gif

У меня картинка term.bmp имеет размеры 19×40 пикселей, а картинка grad.bmp 13×12 пикселей. Потом нам потребуется конвертировать две картинки с помощью онлайн-сервиса

http://www.rinkydinkelectronics.com/t_imageconverter_mono.php

Изображение

выбираем наш файл изображения и жмем Make File

Изображение

Жмем на Click here to download your file и сохраняем файл grad.c в папку с нашим скетчем, тоже самое проделываем с другим изображением. Сохраняем и закрываем скетч. При повторном открытии он будет иметь еще две вкладки с файлами изображений.

Изображение

После этого добавим две строки в скетч, которые инициализируют наши файлы изображений


Код: выделить все
extern uint8_t term[];
extern uint8_t grad[];



а потом отобразим наши изображения на экране OLED дисплея, добавив строки

Код: выделить все
myOLED.drawBitmap(4, 12, term, 19, 40);
  myOLED.drawBitmap(92, 12, grad, 13, 12);



Добавим в наш скетч на два цикла. В первом цикле у нас будет отображаться время – назовем его void watch(); Второй цикл будет считывать и отображать температуру void temp();

А в основном цикле void loop(); пропишем для ротации циклов несколько строчек кода

Код: выделить все
if (x >= 10) {
    temp();
    x=0;
  }
  else
  {
    watch();
  }
  x++;


В цикле void temp(); пропишем кусочек кода для считывания и отображения температуры

Код: выделить все
for(int x = 0; x < 10; x++){
  byte data[2];
  ds.reset();
  ds.write(0xCC);
  ds.write(0x44);
  delay(150);
  ds.reset();
  ds.write(0xCC);
  ds.write(0xBE);
  data[0] = ds.read();
  data[1] = ds.read();
  int Temp = (data[1] << 8) + data[0];
  Temp = Temp >> 4;
 
  String stringOne = rtc.getTimeStr();
 
  myOLED.clrScr();
  myOLED.setFont(SmallFont);
  myOLED.print(stringOne.substring(0, 5), 98, 0);
  myOLED.print(rtc.getDateStr(), 0, 0);
  myOLED.setFont(RusFont);
  myOLED.print("NTVGTHFNEHF", CENTER, 57);
  myOLED.drawBitmap(4, 12, term, 19, 40);
  myOLED.setFont(MegaNumbers);
  myOLED.print(String(Temp), CENTER, 12);
  myOLED.drawBitmap(92, 12, grad, 13, 12);
  myOLED.update();
  myOLED.clrScr();
  }


В цикле void watch(); пропишем наш код, который отвечает за отображение времени

После заливки скетча, наши OLED часы сначала должны отображать время, а потом температуру.

Изображение

Полный скетч можно загрузить по ссылке: http://arduino-project.net/OLED_watch_temp.rar
admin
Администратор
 
Сообщений: 71
Зарегистрирован: 27 ноя 2016, 18:21
ТегиЧасовой модуль DS1307, OLED I2C дисплей, Arduino, DS18B20

Вернуться в Для новичков. Азы.

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

/