Skip to content

shariltumin/c-module-tutorial-micropython

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

CModule short tutorial

This short writeup servers as a response to discussion 17284

The basic question here is how to pass a MicroPython object to a C function in a custom C module. In this case a PWM object.

The end result use case will be is something like this:

>>> from machine import Pin, PWM
>>> pwm = PWM(Pin(18), freq=5000, duty_u16=32768)
>>> import mypwm
>>> mypwm.channel(pwm)

The C module mypwm has a function channel. It takes the PWM object pwm as parameter.

There are probably many ways to do this. Here is my way of doing it. It may not be the right way, and it may not follow best practices, but it works for me.

source files

Create a C file and possibly a header file. You may want to read the Micropython source files to see how things are done. The header and program files are in the "xmod" directory.

cmake file

You need to use a modified "esp32_common.cmake". Save the original file.

cp esp32_common.cmake esp32_common.cmake-ORIG
cp esp32_common.cmake esp32_common.cmake-TEST

The file we want to change is "esp32_common.cmake-TEST". In this file we add a line "xmod/my_pwm.c" this is at the last entry to "list(APPEND MICROPY_SOURCE_PORT" right after "modespnow.c".

build script

To make the build process easier, we create an executable bash script "mpb_esp32_generic.sh". Just run this script to build the firmware.

test

Lastly, flash the firmware and test our new module in a script.

MPY: soft reboot
MicroPython v1.26.0-preview.82.gae6062a45.kaki5 on 2025-05-12; Generic ESP32 module with ESP32
Type "help()" for more information.
>>> 
MPY: soft reboot
MicroPython v1.26.0-preview.82.gae6062a45.kaki5 on 2025-05-12; Generic ESP32 module with ESP32
Type "help()" for more information.
>>> from machine import Pin, PWM
>>> pwm = PWM(Pin(18), freq=5000, duty_u16=32768)
>>> pwm.
deinit          duty            duty_ns         duty_u16
freq            init
>>> import mypwm
>>> mypwm.channel(pwm)
0
>>> 

The pwm object does not have a channel method. We build a custom firmware that includes a user C module called "mypwm" and this module provides us with a "channel" method.

The module here does not give us any significant new functionality. The main purpose here is to show the process of including a custom C module that takes a MicroPython object as a parameter.

Hope this is useful to someone.

About

A short C Module tutorial for MicroPython

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published