![Генериране на PWM сигнали с ESP8266 и MicroPython Практически примери](http://ardudevelop.eu/wp-content/uploads/2024/09/Генериране-на-PWM-сигнали-с-ESP8266-и-MicroPython-Практически-примери.png)
PWM (Pulse Width Modulation) или Широчинно-импулсна модулация е широко използвана техника за управление на мощността на електронни компоненти, като например LED диоди и мотори. В тази статия ще разгледаме два примера за генериране на PWM сигнали с ESP8266, използвайки MicroPython.
Генериране на PWM сигнал и отпечатване на резултатите
Примерен код за генериране на PWM сигнал и отпечатване на резултатите:
from machine import Pin, PWM
from time import sleep
frequency = 5000 # честота в Hz
led = PWM(Pin(0), frequency)
while True:
sleep(1)
for duty_cycle in range(0, 1023):
led.duty(duty_cycle)
print(duty_cycle)
sleep(0.01)
Обяснение:
Инициализация на PWM пин
led = PWM(Pin(0), frequency)
- PWM (Pulse Width Modulation): PWM е техника, при която се генерира цифров сигнал, който редува включване и изключване на определен пин (в случая GPIO0) с определена честота и duty cycle (съотношение между времето, през което сигналът е включен, и общото време на цикъла). Това съотношение управлява средната мощност, подавана на устройството, което е свързано към пина (например светодиод).
- Pin(0): В този ред
Pin(0)
посочва GPIO0 на ESP8266, който ще се използва за генериране на PWM сигнала. В този пример се приема, че на този пин е свързан светодиод или друго устройство, което ще бъде управлявано чрез PWM. - Честота (frequency):
frequency = 5000
задава честотата на PWM сигнала на 5000 Hz. Това означава, че PWM сигналът ще се включва и изключва 5000 пъти в секунда. По-високата честота води до по-плавно управление на устройството, например по-плавна промяна в яркостта на светодиода.
Основен цикъл
while True:
sleep(1)
for duty_cycle in range(0, 1023):
led.duty(duty_cycle)
print(duty_cycle)
sleep(0.01)
- Безкраен цикъл (while True): Този цикъл се изпълнява непрекъснато, докато програмата работи. Това е основният цикъл на програмата, в който се извършват всички операции по генериране и управление на PWM сигнала.
- Забавяне (sleep(1)): Първото забавяне от 1 секунда позволява на устройството да се стабилизира, преди да започне да променя PWM сигнала. Включването на този ред не е задължително!
- Промяна на duty_cycle (for duty_cycle in range(0, 1023)): В този вътрешен цикъл се преминава през всички стойности на duty_cycle от 0 до 1023. Тези стойности представляват 10-битова резолюция, където 0 означава, че PWM сигналът е изключен през целия цикъл, а 1023 означава, че е включен през целия цикъл.
- Задаване на duty cycle (
led.duty(duty_cycle)
): Тази команда задава стойността на duty_cycle за PWM сигнала. Например, акоduty_cycle = 512
, това означава, че сигналът ще бъде включен през половината от времето на цикъла и изключен през останалата част (или ще е на 50%). - Принтиране в конзолата (
print(duty_cycle)
): Всяка стойност на duty_cycle се отпечатва в конзолата, което позволява да следим как се променя PWM сигналът в реално време. - Забавяне между промени на duty cycle (
sleep(0.01)
): След всяка промяна на duty_cycle има кратко забавяне от 0.01 секунди. Това забавяне осигурява плавно и постепенно увеличаване на интензитета на светодиода. Ако не беше приложено това забавяне, светодиодът щеше да променя своя интензитет твърде бързо, което би направило ефекта по-малко забележим.
Управление на PWM чрез аналогов вход
В този пример ще покажем как да използваме потенциометър за управление на duty_cycle на PWM сигнал чрез изчитане на аналогова стойност от ADC (Analog to Digital Converter).
Преди да започнем трябва да разгледаме схемата и да свържем компонентите. За да разгледате пин диаграмта (pinout) на ESP8266 и в нашия случай D1 mini, разгледайте нашето ревю за този процесор на страницата ни: ESP8266 D1 Mini – Малък, но Мощен Wi-Fi Микроконтролер.
Схема на свързване:
![](http://ardudevelop.eu/wp-content/uploads/2024/09/Генериране-на-PWM-сигнали-с-ESP8266-и-MicroPython-чрез-потенциометър-и-LED-диод.png)
Примерен код за управление на PWM чрез аналогов вход:
from machine import ADC, PWM, Pin
from time import sleep
# map function
def _map(x, in_min, in_max, out_min, out_max):
return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
pot = ADC(0) # Инициализация на ADC (функционира само с ADC(0) за ESP8266)
frequency = 5000 # Задаване на честота на PWM
led = PWM(Pin(14), frequency) # Инициализация на PWM pin
while True:
try:
pot_value = pot.read() # Прочитане на стойността от потенциометъра (0-1023)
#print(pot_value)
if pot_value < 10:
pot_value = 0
map_led = _map(pot_value, 0, 1023, 0, 100) # Преобразуване на стойността за PWM
print("pot_value = ", pot_value, "||","duty = ", map_led)
led.duty(pot_value) # Задаване на PWM duty cycle
sleep(0.05)
except KeyboardInterrupt:
print("exit")
break
Обяснение:
Този код за ESP8266 демонстрира как да се използва аналоговият вход (ADC) за четене на стойността от потенциометър и как тази стойност може да бъде преобразувана и използвана за управление на PWM (Pulse Width Modulation) сигнал, който управлява интензитета на светодиод. В предишната ни статия разгледахме как се изчита аналогова стойност с ESP8266 и MicroPython. Ако сте я пропуснали може първо да я разгледате. Тя ще донесе допълнителна яснота върху този код.
.
Импортиране на библиотеки и инициализация
from machine import ADC, PWM, Pin
from time import sleep
from machine import ADC, PWM, Pin
: Импортира основните класове от библиотекатаmachine
на MicroPython, които ще бъдат използвани за работа с хардуерните компоненти.ADC
: Аналогово-цифров преобразувател (АЦП), който ще чете аналоговите стойности от потенциометъра.PWM
: Широчинно-импулсна модулация, която ще управлява интензитета на светодиода.Pin
: Позволява достъп до GPIO пиновете на ESP8266.from time import sleep
: Импортира функциятаsleep
, която ще бъде използвана за въвеждане на забавяне между операциите.
Функция _map
def _map(x, in_min, in_max, out_min, out_max):
return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
- Функцията
_map
е изключително важна, защото позволява преобразуване на една стойност от един диапазон към друг. Това е особено полезно, когато искате да адаптирате аналогова стойност (от АЦП) към подходящ диапазон за PWM. - Аргументи на функцията:
x
: Входна стойност, която ще бъде преобразувана.in_min
иin_max
: Минималната и максималната стойност на входния диапазон.out_min
иout_max
: Минималната и максималната стойност на изходния диапазон.- Примерно обяснение: Ако потенциометърът подава стойност
512
, функцията_map
ще я преобразува в нов диапазон, например от 0 до 100, който е подходящ за управление на duty cycle на PWM. Това позволява стойността от потенциометъра да бъде адаптирана към изходен сигнал, който може да управлява светодиод или друг компонент.
Инициализация на ADC и PWM
pot = ADC(0) # Инициализация на ADC (функционира само с ADC(0) за ESP8266)
frequency = 5000 # Задаване на честота на PWM
led = PWM(Pin(14), frequency) # Инициализация на PWM pin
ADC(0)
: Инициализира АЦП на пин 0, който ще чете аналоговите сигнали от потенциометъра. При ESP8266, единственоADC(0)
е валиден.frequency = 5000
: Задава честотата на PWM сигнала на 5000 Hz.PWM(Pin(14), frequency)
: Инициализира PWM на GPIO14 с честота 5000 Hz, който ще управлява интензитета на светодиод или друг компонент.
Основен цикъл
while True:
try:
pot_value = pot.read() # Прочитане на стойността от потенциометъра (0-1023)
if pot_value < 10:
pot_value = 0
map_led = _map(pot_value, 0, 1023, 0, 100) # Преобразуване на стойността за PWM
print("pot_value = ", pot_value, "||","duty = ", map_led)
led.duty(pot_value) # Задаване на PWM duty cycle
sleep(0.05)
except KeyboardInterrupt:
print("exit")
break
- Четене на стойността от потенциометъра:
pot_value = pot.read()
: Прочита аналоговата стойност от потенциометъра. Стойността е между 0 и 1023.- Ако стойността е по-малка от 10, тя се закръгля до 0 (
if pot_value < 10: pot_value = 0
), за да се избегнат шумове. - Превръщане на стойността за PWM:
map_led = _map(pot_value, 0, 1023, 0, 100)
: Преобразува стойността от потенциометъра (0-1023) към диапазон, подходящ за duty cycle на PWM (например 0-100).- Управление на PWM:
led.duty(pot_value)
: Задава duty cycle на PWM сигнала спрямо стойността от потенциометъра.- Забавяне и обработка на прекъсвания:
sleep(0.05)
: Въвежда малко забавяне между циклите за по-плавна работа.except KeyboardInterrupt
: Ако бъде натиснатCtrl+C
, програмата излиза от цикъла и приключва работата си.
Заключение
Тези два примера демонстрират как лесно може да се генерират и управляват PWM сигнали с ESP8266, използвайки MicroPython. В първия пример показахме как се генерира PWM сигнал с променящ се duty_cycle, а във втория пример демонстрирахме как аналогов вход от потенциометър може да се използва за динамично управление на PWM. Това е полезно в различни приложения като контрол на яркостта на LED или регулиране на скоростта на двигатели. Може да разгледате видео инструкции тук.