Объявление

Внимание!
Данный форум предназначен только для радиолюбителей!
Никакие прочие объявления, реклама товаров либо услуг невозможны!


Любой спам на нашем форуме запрещён!
Разрешаются только ссылки по темам! 3а нарушения БАН.


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
Администратор
 
Сообщений: 56
Зарегистрирован: 27 ноя 2016, 18:21
ТегиЧасовой модуль DS1307, OLED I2C дисплей, Arduino, DS18B20

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

Сообщение JaryginSog » 13 фев 2017, 23:47

Если взять жирную ардуину типа 2560 много ног и на первом этапе не заморачиваться с ярко/тускло - для начала сгодится. Потом добавить шим для тускло.
JaryginSog
 
Сообщений: 1
Зарегистрирован: 03 фев 2017, 22:34


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

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

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

cron
/