Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
MicroPython · types

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.

Raspberry Pi Pico WRaspberry Pi PicoESP32ESP8266Updated 3 Nov 2026

Community draft — report a mistake

What you see

OutputOutput
>>> 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 maths

Quick fix — try in order

  1. 1

    Wrap the value in int()

    led.duty_u16(int(65535 * brightness)). Any multiplication or division with / gives a float, even 10 / 2.

  2. 2

    Use // for whole-number division

    steps = total // 4 stays an int. / always returns a float in Python 3.

  3. 3

    time.sleep_ms() wants an int

    time.sleep_ms(int(ms)), or use time.sleep(0.25) which does take a float (seconds).

  4. 4

    Map servo angles to integers

    duty = int(1638 + angle * (8192 - 1638) / 180) for a 50 Hz servo with duty_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.

↑↓ to move · Enter to open