Fix MicroPython “TypeError: can't convert float to int”
duty_u16(), sleep_ms(), Pin() and range() need whole numbers. Wrap the maths in int() or use // so a 0.5 never reaches them.
Community draft — report a mistake
What you see
>>> from machine import Pin, PWM
>>> led = PWM(Pin(15), freq=1000)
>>> brightness = 0.5
>>> led.duty_u16(65535 * brightness)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't convert float to int>>> from machine import Pin, PWM >>> led = PWM(Pin(15), freq=1000) >>> brightness = 0.5 >>> led.duty_u16(65535 * brightness) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't convert float to int
Hardware registers hold whole numbers, so MicroPython refuses to pass a float to them. The trap is that Python 3’s / always produces a float:
brightness = 75 # percent
duty = 65535 * brightness / 100 # 49151.25 -> float
led.duty_u16(int(duty)) # OK
led.duty_u16(65535 * brightness // 100) # OK, integer mathsQuick fix — try in order
- 1
Wrap the value in int()
led.duty_u16(int(65535 * brightness)). Any multiplication or division with/gives a float, even 10 / 2. - 2
Use // for whole-number division
steps = total // 4stays an int./always returns a float in Python 3. - 3
time.sleep_ms() wants an int
time.sleep_ms(int(ms)), or usetime.sleep(0.25)which does take a float (seconds). - 4
Map servo angles to integers
duty = int(1638 + angle * (8192 - 1638) / 180)for a 50 Hz servo withduty_u16.
Why it happens
Which functions are strict about ints?
PWM.duty_u16(), PWM.duty(), PWM.freq(), time.sleep_ms()/sleep_us(), Pin(), range(), list indexes, bytearray() sizes and I2C/UART lengths.
Why did it work with some values?
It never did — a value like 65535 * 1 is an int, but as soon as a float sneaks into the calculation (a sensor reading, a /), the result is a float.
Variant: “ValueError: duty must be 0-65535”
The value is an int now but out of range. Clamp it: max(0, min(65535, value)).
Board-specific notes
ESP8266: Older code uses pwm.duty(0–1023); it also needs an int.
Pico W: Servo example with correct integer duty values: SG90 with Pico W.
Did this fix it?
Thanks — that helps us keep this page right.