PWM duty problem MicroPython v1.18

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
JDRBoston
Posts: 21
Joined: Mon Feb 19, 2018 9:43 pm

PWM duty problem MicroPython v1.18

Post by JDRBoston » Mon Jan 24, 2022 12:09 am

Dear MicroPython gurus,

I am having trouble configuring PWM and I'd appreciate your help. I've been building a device that sends three different sets of PWM to a passive piezoelectric buzzer to generate three audible tones. I got this to work consistently using esp32-20210902-v1.17. But since I updated to esp32-20220117-v1.18 the PWM outputs don't seem to be working. In particular, I don't seem to be able to control the duty cycle. I understand that PWM was updated in esp32-20220117-v1.18 so I am now trying to figure out how I can update my code.

Details: I am using a HUZZAH32 feather with WROOM-32; the ESP32 frequency is 160000000. My passive buzzer is on GPIO 21, where it worked well before with the previous version of MicroPython. The wiring has not changed.

Here's the code and my unexpected inability to regulate the duty:

############

from machine import Pin, PWM
import utime

bzr = PWM(Pin(21))

# Get default values
print('Output:')
print('\nDefault frequency: ', bzr.freq())
print('Default duty: ', bzr.duty())

# Try different frequencies with duty set at 512

print('\nReinitialize bzr to freq 500 (A2) with duty 512')
bzr.init(freq = 500, duty = 512)
utime.sleep(3)
print('Report of current PWM settings:')
print(bzr)
bzr.deinit()

print('\nReinitialize bzr to freq 600 (A2) with duty 512')
bzr.init(freq = 600, duty = 512)
utime.sleep(3)
print('Report of current PWM settings:')
print(bzr)
bzr.deinit()

print('\nReinitialize bzr to freq 700 (A2) with duty 512')
bzr.init(freq = 700, duty = 512)
utime.sleep(3)
print('Report of current PWM settings:')
print(bzr)
bzr.deinit()

print('\nReinitialize bzr to freq 800 (A5) with duty 512')
bzr.init(freq = 800, duty = 512)
utime.sleep(3)
print('Report of current PWM settings:')
print(bzr)
bzr.deinit()

'''
Output:

Default frequency: 5000
Default duty: 256

Reinitialize bzr to freq 500 (A2) with duty 512
Report of current PWM settings:
PWM(Pin(21), freq=500, duty=0, resolution=17, (duty=0.00%, resolution=0.001%), mode=0, channel=0, timer=0)

Reinitialize bzr to freq 600 (A2) with duty 512
Report of current PWM settings:
PWM(Pin(21), freq=600, duty=0, resolution=17, (duty=0.00%, resolution=0.001%), mode=0, channel=0, timer=0)

Reinitialize bzr to freq 700 (A2) with duty 512
Report of current PWM settings:
PWM(Pin(21), freq=700, duty=32, resolution=16, (duty=50.00%, resolution=0.002%), mode=0, channel=0, timer=0)

Reinitialize bzr to freq 800 (A5) with duty 512
Report of current PWM settings:
PWM(Pin(21), freq=801, duty=32, resolution=16, (duty=50.00%, resolution=0.002%), mode=0, channel=0, timer=0)

'''

If the duty ranges from 0 - 1023, why does my setting it to 512 cause it be 0? Why at at the slightly higher frequences, does it set itself to be 32? As one would expect, the passive buzzer isn't generating any sound when the duty = 0; I can hear a tone when it is 32.

Do you have any advice about how I can fix this? I'd like to have more control over the duty for my application.

I guess that I could go back to MicroPython v1.17, but I went to v1.18 because I am planning to use mpy-cross with the final code and that's the version that I found.

Thank you, very much, Jay

User avatar
mattyt
Posts: 410
Joined: Mon Jan 23, 2017 6:39 am

Re: PWM duty problem MicroPython v1.18

Post by mattyt » Mon Jan 24, 2022 12:16 am

See forum thread MicroPython version 1.18 released, including PR 8200 from Roberthh which ought to address your issue.
Last edited by mattyt on Mon Jan 24, 2022 9:52 am, edited 1 time in total.

JDRBoston
Posts: 21
Joined: Mon Feb 19, 2018 9:43 pm

Re: PWM duty problem MicroPython v1.18

Post by JDRBoston » Mon Jan 24, 2022 2:15 am

Thank you!!

Post Reply