OLED часы на arduino

от автора

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


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

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

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

image

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

Скетч

#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); } 

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

image

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

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); 

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

image

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

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;   } 

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

image

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

Скетч

#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 пикселей. Потом нам потребуется конвертировать две картинки с помощью онлайн-сервиса www.rinkydinkelectronics.com

image

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

image

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

image

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

	 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 часы сначала должны отображать время, а потом температуру как на видео в начале статьи.

image

Полный скетч можно загрузить по ссылке OLED_watch_temp.rar

Обсуждение статьи доступно в нашей группе vk.com

ссылка на оригинал статьи http://habrahabr.ru/post/257659/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *