![ESP8266, OLED дисплей, RTC и DS18B20 ръчно направен подарък!](http://ardudevelop.eu/wp-content/uploads/2024/10/DSC0688.png)
Този проект използва микроконтролера ESP8266 D1 mini за създаване на устройство, което показва дата, час, температура и има анимации на OLED дисплей, докато се възпроизвежда мелодия чрез пиезо зумер (happy birthday to you). Основни компоненти включват RTC модул за точна дата и час, температурен сензор DS18B20 за измерване на температурата и LED за визуална сигнализация.
![](http://ardudevelop.eu/wp-content/uploads/2024/10/ESP8266-OLED-дисплей-RTC-и-DS18B20-ръчно-направен-подарък-2.png)
![](http://ardudevelop.eu/wp-content/uploads/2024/10/ESP8266-OLED-дисплей-RTC-и-DS18B20-ръчно-направен-подарък-3.png)
Това е идеален начин да съчетаете сръчност, креативност и технически умения за да създадете хубав подарък за рожден ден!
Необходими компоненти:
- ESP8266 D1 mini
- OLED дисплей (SSD1306) – за визуализация
- RTC модул (DS1307) – за текуща дата и час
- Температурен сензор (DS18B20) – за измерване на температура
- Пиезо зумер– за възпроизвеждане на мелодия
- LED (светодиод) – за визуални индикации
- Резистори и проводници за свързване
Кода който ще предоставим отдолу е написан на MicroPython на процесора ESP8266 D1 mini. Ако все още не сте инсталирали MicroPython или не знаете как, може да прочетете нашата страница с обяснение на: Как да инсталирате MicroPython на ESP8266
ESP8266, OLED дисплей, RTC и DS18B20 код: boot.py
import os, machine
import gc
gc.collect()
from machine import I2C, Pin, PWM
import ssd1306
import time
i2c = I2C(sda=Pin(4), scl=Pin(5))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
display.fill(0)
display.text('Happy Birthdaty!', 0, 5, 1)
display.text('may your innova-', 0 , 14 , 1)
display.text('tive ideas con-', 0 , 22 , 1)
display.text('tinue to shape', 0 , 30 , 1)
display.text('the future and ', 0 , 39 , 1)
display.text('make the imposs-', 0 , 48 , 1)
display.text('ible possible!!!', 0 , 57 , 1)
display.show()
# Дефиниране на тоновете
tones = {
'C': 261, # До
'D': 294, # Ре
'E': 330, # Ми
'F': 349, # Фа
'G': 392, # Сол
'A': 440, # Ла
'B': 494, # Си
'H': 523, # До
'P': 20000, # Пауза
}
# Дефиниране на пиезо бузера
beeper = PWM(Pin(12, Pin.OUT), freq=440, duty=512)
# Мелодия на песента"
melody = "C P C D C F E C P C D C G F C P C H A F E D A P A F G F "
rhythm =[0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0,01, 0,4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 2]
# Темпо на мелодияа за всяка нота
tempo = [0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0,01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 2]
# Изпълнение на мелодията
for tone, length, temp in zip(melody.split(), rhythm, tempo):
beeper.freq(tones[tone])
time.sleep(temp)
beeper.deinit() # Изключване на PWM
Обяснение на: boot.py
Файлът boot.py
се стартира автоматично при всяко включване на устройството. Неговата основна функция е да покаже поздравително съобщение на OLED дисплея и да свири мелодия чрез пиезо бипера.
![ESP8266, OLED дисплей, RTC и DS18B20 ръчно направен подарък! OLED](http://ardudevelop.eu/wp-content/uploads/2024/10/ESP8266-OLED-дисплей-RTC-и-DS18B20-ръчно-направен-подарък-OLED.png)
import os, machine
import gc
gc.collect()
from machine import I2C, Pin, PWM
import ssd1306
import time
i2c = I2C(sda=Pin(4), scl=Pin(5))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
display.fill(0)
display.text('Happy Birthdaty!', 0, 5, 1)
display.text('may your innova-', 0 , 14 , 1)
display.text('tive ideas con-', 0 , 22 , 1)
display.text('tinue to shape', 0 , 30 , 1)
display.text('the future and ', 0 , 39 , 1)
display.text('make the imposs-', 0 , 48 , 1)
display.text('ible possible!!!', 0 , 57 , 1)
display.show()
Обяснение:
Тази част от кода служи за инициализация и използване на OLED дисплей чрез I2C интерфейс за показване на поздравително съобщение.
В началото на кода се импортират няколко библиотеки:
os
иmachine
: предоставят достъп до основни функции на микроконтролера.gc
(Garbage Collector): използва се за събиране на ненужните данни от паметта чрез командатаgc.collect()
, което освобождава памет и оптимизира работата на устройството.time
: за контрол на времето и паузите в кода.ssd1306
: библиотека за управление на OLED дисплея (модел SSD1306). Ако я нямате може да я свалите от тук:ssd1306
.pyI2C
,Pin
,PWM
: тези библиотеки управляват комуникацията с периферията на микроконтролера.
След това се създава I2C комуникация с дисплея, като пиновете 4 и 5 са съответно свързани към SDA (данни) и SCL (часовник) на дисплея. Размерът на OLED дисплея е зададен като 128×64 пиксела.
След инициализацията на дисплея:
display.fill(0)
изчиства екрана, като го запълва с черен фон.display.text()
се използва за показване на текста на различни координати на дисплея, като всеки ред съдържа част от поздравително съобщение за рожден ден.- Накрая, командата
display.show()
обновява дисплея, като показва въведените текстове на екрана.
Мелодия:
# Дефиниране на тоновете
tones = {
'C': 261, # До
'D': 294, # Ре
'E': 330, # Ми
'F': 349, # Фа
'G': 392, # Сол
'A': 440, # Ла
'B': 494, # Си
'H': 523, # До
'P': 20000, # Пауза
}
# Дефиниране на пиезо бузера
beeper = PWM(Pin(12, Pin.OUT), freq=440, duty=512)
# Мелодия на песента"
melody = "C P C D C F E C P C D C G F C P C H A F E D A P A F G F "
rhythm =[0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0,01, 0,4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 2]
# Темпо на мелодияа за всяка нота
tempo = [0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0,01, 0.4, 0.7, 0.7, 0.7, 1.5, 0.4, 0.01, 0.4, 0.7, 0.7, 2]
# Изпълнение на мелодията
for tone, length, temp in zip(melody.split(), rhythm, tempo):
beeper.freq(tones[tone])
time.sleep(temp)
beeper.deinit() # Изключване на PWM
Обяснение:
Тази част от кода е предназначена за генериране на мелодия с помощта на пиезо-зумер (електронен компонент, който създава звук при подаване на електрически импулс). Кодираната мелодия се изпълнява чрез промяна на честотата на звука, което съответства на различни музикални ноти.
![ESP8266, OLED дисплей, RTC и DS18B20 ръчно направен подарък! пиезо зумер](http://ardudevelop.eu/wp-content/uploads/2024/10/ESP8266-OLED-дисплей-RTC-и-DS18B20-ръчно-направен-подарък-пиезо-зумер.png)
1. Дефиниране на тоновете:
В първата част на кода се създава речник tones
, който съдържа честотите за всяка музикална нота. Тези честоти са в херци (Hz) и съответстват на стандартните музикални ноти в октава:
- C (До) = 261 Hz
- D (Ре) = 294 Hz
- E (Ми) = 330 Hz
- F (Фа) = 349 Hz
- G (Сол) = 392 Hz
- A (Ла) = 440 Hz
- B (Си) = 494 Hz
- H (До) = 523 Hz
- Специалната нота
P
(пауза) има стойност 20000 Hz, която е извън слуховия диапазон и се използва, за да създаде пауза в мелодията.
2. Дефиниране на пиезо-бузера:
Чрез PWM
(широчинно-импулсна модулация) на пин 12 се създава контрол на пиезо-бузера. PWM
позволява регулиране на честотата на подаваните импулси, като в случая честотата е зададена на 440 Hz (стандартната честота за нота “Ла“), а дължината на импулсите е зададена чрез параметъра duty на 512 (от възможни 1023), което създава равномерно подаване на електрическите импулси.
3. Дефиниране на мелодията:
Мелодията се съхранява като текстова последователност от ноти, разделени с интервали, в променливата melody
. Всяка нота съответства на стойност от речника tones
. Например, “C” представлява нотата “До” с честота 261 Hz, а “P” е пауза.
4. Ритъм и темпо:
rhythm
: Списък от числови стойности, които задават продължителността на всяка нота в мелодията.tempo
: Темпото на всяка нота (скоростта, с която нотите ще се изпълняват). Тези стойности се използват в цикъла, за да контролират колко дълго всяка нота се свири.
5. Изпълнение на мелодията:
Цикълът for
взема последователно всяка нота от melody
, съответната ѝ продължителност от rhythm
, и времето на пауза между нотите от tempo
:
beeper.freq(tones[tone])
задава честотата на звука според текущата нота.time.sleep(temp)
добавя пауза след всяка нота в съответствие с темпото.
6. Изключване на PWM:
След като мелодията бъде изпълнена, beeper.deinit()
изключва PWM, прекъсвайки подаването на сигнала към пиезо-бузера и спирайки звука.
Тази част от кода съчетава хардуерна и софтуерна работа, за да възпроизведе мелодия чрез пиезо-зумера.
ESP8266, OLED дисплей, RTC и DS18B20 код: main.py
Файлът main.py
управлява основната функционалност на проекта. Използва RTC модул за текуща дата и час, температурен сензор DS18B20 за измерване на температурата и OLED дисплей, за да показва съответната информация.
import uasyncio as asyncio
from machine import I2C, Pin
import onewire, ds18x20
from time import sleep
import ssd1306
import ds1307
i2c = I2C(sda=Pin(4), scl=Pin(5))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
ds = ds1307.DS1307(i2c)
ds_pin = Pin(14)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()
led = Pin(2, Pin.OUT)
led.off()
temp = ""
#------ // RTC \\-------
async def date_time():
while True:
global date
global time
date = str(ds.datetime()[2]) + "-" + str(ds.datetime()[1]) + "-" + str(ds.datetime()[0])
date = str(date)
time = str(ds.datetime()[4]) + ":" + str(ds.datetime()[5]) + ":" + str(ds.datetime()[6])
time = str(time)
#print("date = " , date)
#print("time = " , time)
await asyncio.sleep_ms(500)
#------ // Temperature DS18B20 \\-------
async def temperature():
while True:
global temp
ds_sensor.convert_temp()
await asyncio.sleep_ms(1000)
for rom in roms:
temp = ds_sensor.read_temp(rom)
temp = round(temp,2)
temp = str(temp)
temp = ("temp = " + temp + "*C")
#print(temp)
await asyncio.sleep_ms(4000)
#------ // LED - ON/OFF \\-------
async def led_on_off():
while True:
led.on()
await asyncio.sleep_ms(1000)
led.off()
await asyncio.sleep_ms(1000)
#------ // OLED refresh \\-------
async def oled_refresh():
while True:
global temp
global date
global time
display.fill(0)
display.text('Happy Birthdaty!', 0, 5, 1)
display.text(date, 30, 20, 1)
display.text(time, 35, 31, 1)
display.text(temp, 15, 50, 1)
display.show()
await asyncio.sleep_ms(1000)
#-----// Създаване на асинхронните задачи \\-----
async def main():
task1 = asyncio.create_task(date_time()) # Изчитане на дата и час
task2 = asyncio.create_task(temperature()) # Изчитане на DS18B20
task3 = asyncio.create_task(led_on_off()) # LED_ON / LED_OFF
task4 = asyncio.create_task(oled_refresh()) # OLED refresh
await asyncio.gather(task1, task2, task3, task4)
# Стартиране на асинхронния цикъл
asyncio.run(main())
Обяснение на кода main.py
import uasyncio as asyncio
from machine import I2C, Pin
import onewire, ds18x20
from time import sleep
import ssd1306
import ds1307
# Инициализация на I2C, дисплей и RTC
i2c = I2C(sda=Pin(4), scl=Pin(5))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
ds = ds1307.DS1307(i2c)
# Температурен сензор DS18B20
ds_pin = Pin(14)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()
# Инициализация на LED
led = Pin(2, Pin.OUT)
led.off()
temp = ""
Обяснение:
Тази част от кода представлява инициализация на основните хардуерни компоненти, използвани в проекта:
1. Импортиране на библиотеки:
- uasyncio: Библиотека за асинхронно програмиране, която позволява едновременно изпълнение на различни функции без блокиране.
- machine: Включва класовете I2C и Pin, които са необходими за управление на I2C комуникацията и цифровите пинове на микроконтролера.
- onewire и ds18x20: Използват се за работа със сензора за температура DS18B20, който комуникира чрез 1-Wire протокол. Може да свалите библитеката от тук: DS18B20.py
- time: Внася функцията
sleep
за управление на забавянето в програмата. - ssd1306: Управлява OLED дисплей, свързан през I2C интерфейс. Библитека: ssd1306.py
- ds1307: Позволява работа с реално времевия часовник (RTC) DS1307, който също използва I2C протокол. Свалете библитеката за RTC модула от тук: DS1307.py
2. Инициализация на I2C, OLED дисплей и RTC:
- I2C: Настройва се I2C комуникацията на пиновете SDA (пин 4) и SCL (пин 5). Тази шина се използва за свързване на OLED дисплея и DS1307 часовника.
- OLED дисплей: Обектът display управлява OLED екран с резолюция 128×64, който ще показва текст и данни като време и температура.
- RTC (DS1307): Обектът ds представлява реално времевия часовник, който ще предоставя текущата дата и час.
3. Инициализация на температурен сензор DS18B20:
- DS18B20: Сензорът за температура се свързва към пин 14 чрез 1-Wire протокол. Създава се обект ds_sensor, който комуникира с DS18B20. Функцията scan() сканира за всички налични сензори на шината и съхранява техните уникални адреси в променливата roms.
4. Инициализация на LED:
- LED: Пин 2 се настройва като изход и управлява LED индикатор. В началото, LED-ът се изключва с командата led.off().
- temp: Променлива temp е инициализирана като празен низ, за да съхранява бъдещите стойности на температурата, измерени от DS18B20.
Асинхронни задачи:
Часовник и календар (RTC):
#------ // RTC \\-------
async def date_time():
while True:
global date
global time
date = str(ds.datetime()[2]) + "-" + str(ds.datetime()[1]) + "-" + str(ds.datetime()[0])
date = str(date)
time = str(ds.datetime()[4]) + ":" + str(ds.datetime()[5]) + ":" + str(ds.datetime()[6])
time = str(time)
#print("date = " , date)
#print("time = " , time)
await asyncio.sleep_ms(500)
Обяснение:
- Функцията извлича текущата дата и час от RTC модула и ги съхранява в глобални променливи
date
иtime
. Обновява се на всеки 500 милисекунди.
Температурен сензор:
#------ // Temperature DS18B20 \\-------
async def temperature():
while True:
global temp
ds_sensor.convert_temp()
await asyncio.sleep_ms(1000)
for rom in roms:
temp = ds_sensor.read_temp(rom)
temp = round(temp,2)
temp = str(temp)
temp = ("temp = " + temp + "*C")
#print(temp)
await asyncio.sleep_ms(4000)
Обяснение:
- Функцията чете стойността на температурата от DS18B20 на всеки 5 секунди, след което я закръгля и показва в подходящ формат.
Управление на LED:
#------ // LED - ON/OFF \\-------
async def led_on_off():
while True:
led.on()
await asyncio.sleep_ms(1000)
led.off()
await asyncio.sleep_ms(1000)
Обяснение:
- LED светодиодът се включва и изключва на всеки 1 секунда.
Обновяване на дисплея:
#------ // OLED refresh \\-------
async def oled_refresh():
while True:
global temp
global date
global time
display.fill(0)
display.text('Happy Birthdaty!', 0, 5, 1)
display.text(date, 30, 20, 1)
display.text(time, 35, 31, 1)
display.text(temp, 15, 50, 1)
display.show()
await asyncio.sleep_ms(1000)
Обяснение:
- Дисплеят се изчиства и обновява на всеки 1 секунда с новите данни за дата, час и температура.
Основна програма и създаване на задачи:
#-----// Създаване на асинхронните задачи \\-----
async def main():
task1 = asyncio.create_task(date_time()) # Изчитане на дата и час
task2 = asyncio.create_task(temperature()) # Изчитане на DS18B20
task3 = asyncio.create_task(led_on_off()) # LED_ON / LED_OFF
task4 = asyncio.create_task(oled_refresh()) # OLED refresh
await asyncio.gather(task1, task2, task3, task4)
Стартиране на асинхронния цикъл
# Стартиране на асинхронния цикъл
asyncio.run(main())
Тази част стартира всички асинхронни функции, за да се стартира програмата.
Обяснение:
- Основната функция
main()
създава всички асинхронни задачи за управление на часовника, температурата, LED-а и дисплея, като се изпълняват паралелно с помощта наasyncio.gather()
.
Заключение:
Този проект съчетава различни хардуерни компоненти, които се управляват асинхронно от ESP8266. Устройството показва поздравително съобщение, реално време и температура, докато възпроизвежда мелодия и свети LED, правейки го чудесен подарък за рожден ден или специален повод.