Raspberry Pi, GPIO, Python, C/C++ Extension and wiringPi Connected


I used gpiozero and RPi.GPIO to control my 3D printer. However, the speed is quite slow. After some nervewracking thinking, I found it the python that cause the slow motion of those motors. Even I delete the time.sleep() line, it still run slowly. This give me no choice that I have to rewrite my control module into c code. After the rewriting, the problem finally solved.

In the c code, I choose wiringPi library to control the GPIO.

The numbering system of the gpiozero and RPi.GPIO with wiringPi is quite different. You should use

gpio readall

to get the number map of your Pi.

Next you should wrap your c code in python.

Create a file test.c

and a file setup.py

Once the coding is finished, you should build and install you code. I suggest you install this in a virtual environment.

sudo apt install python-virtualenv
python setup.py build
python setup.py install

You might meet some problems in compiling as well as importing.

PyArg_ParseTuple()

Compiling

python.h: No such file or directory

Reinstall python3-dev solved this.

Importing

As we used library wiringPi , it should be specified in setup.py. Otherwise, we’ll get error

undefined symbol digitalWrite()

Extension(...,
          library_dirs=[''],
          libraries=['wiringPi'])

‘ImportError: dynamic module does not define init function’

I named the init function in a wrong name. PyInit_keywdarg should has the same suffix as defined in your keywdargmodule.

static struct PyModuleDef keywdargmodule = {
    PyModuleDef_HEAD_INIT,
    "keywdarg",
    NULL,
    -1,
    keywdarg_methods
};

PyMODINIT_FUNC
PyInit_keywdarg(void)
{
    return PyModule_Create(&keywdargmodule);
}

SystemError: Bad call flags in PyCFunction_Call. METH_OLDARGS is no longer supported! In the myMethods array, the field number of parameters should be defined as

METH_VARARGS | METH_KEYWORDS
static PyMethodDef keywdarg_methods[] = {
    /* The cast of the function is necessary since PyCFunction values
     * only take two PyObject* parameters, and keywdarg_parrot() takes
     * three.
     */
    {"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
     "Print a lovely skit to standard output."},
    {NULL, NULL, 0, NULL}   /* sentinel */
};

More detail in
https://docs.python.org/3/extending/extending.html#the-module-s-method-table-and-initialization-function

发表评论

电子邮件地址不会被公开。 必填项已用*标注