ESP8266, OLED дисплей, RTC DS1307 и DS18B20 ръчно направен подарък!

ESP8266, OLED дисплей, RTC и DS18B20 ръчно направен подарък!

Този проект използва микроконтролера ESP8266 D1 mini за създаване на устройство, което показва дата, час, температура и има анимации на OLED дисплей, докато се възпроизвежда мелодия чрез пиезо зумер (happy birthday to you). Основни компоненти включват RTC модул за точна дата и час, температурен сензор DS18B20 за измерване на температурата и LED за визуална сигнализация.

Това е идеален начин да съчетаете сръчност, креативност и технически умения за да създадете хубав подарък за рожден ден!

Необходими компоненти:

  1. ESP8266 D1 mini
  2. OLED дисплей (SSD1306) – за визуализация
  3. RTC модул (DS1307) – за текуща дата и час
  4. Температурен сензор (DS18B20) – за измерване на температура
  5. Пиезо зумер– за възпроизвеждане на мелодия
  6. LED (светодиод) – за визуални индикации
  7. Резистори и проводници за свързване

Кода който ще предоставим отдолу е написан на 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
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.py
  • I2C, 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 ръчно направен подарък! пиезо зумер

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, правейки го чудесен подарък за рожден ден или специален повод.

Translate »