Problem Overview
Engineers integrating the Siemens SIMATIC IOT2000 family (IOT2040 / IOT2050) with the Input/Output Module 6ES7 647-0KA01-0AA2 frequently hit an ImportError: No module named 'mraa' when their application logic is written in Python 3. The shipped Example Image (for example example-v2.2.0.wic dated 27 March 2018) exposes the C library libmraa but does not bundle the corresponding python3-mraa binding. Because the maintenance cadence of these prebuilt images is governed by an OSS Clearing workflow, an updated WIC image with Python 3 mraa support may not be available for many release cycles. This article documents the root cause, a reproducible build path on the host PC and on-device, and the verification procedure that confirms the shield pins are reachable from Python 3.
Affected Hardware and Software
| Component | Identifier / Version | Notes |
|---|---|---|
| SIMATIC IOT2040 | 6ES7 647-0AA00-0BA2 / 6ES7 647-0BA00-0BA2 | Intel Quark x86 SoC, 1 GB RAM |
| SIMATIC IOT2050 | 6ES7 647-0BA10-0YA2 (basic) / 6ES7 647-0BA10-0XA2 (advanced) | ARM TI AM6528, 1–2 GB RAM, replaces IOT2040 |
| Input/Output Module (Shield) | 6ES7 647-0KA01-0AA2 | Arduino-form-factor shield, exposes DI / DO / AI via mraa pin numbers |
| Example Image |
example-v2.2.0.wic (2018-03-27) and later V2.x releases |
Based on Yocto / Angstrom, ships Python 2 only by default |
| mraa library | libmraa ≥ 1.x (C library present, Python 3 binding missing) | Available as libmraa2, libmraa-dev, mraa-tools
|
| Python interpreter | Python 2.7.14 (default), Python 3.5 / 3.7 (optional) | Python 3 must be added manually |
Root Cause Analysis
Three independent gaps converge to produce the error:
- Image release policy. Siemens publishes the WIC image as an example rather than a product-grade firmware. Every binary that lands in the image must clear the OSS license review pipeline. The result is an update cadence measured in quarters, not days, which means newly available upstream packages (such as Python 3 mraa wheels) lag behind what an integrator can compile locally.
-
Python 3 binding not packaged. The image provides the
libmraa.soC library and themraa-gpioCLI utility, but the SWIG-generated Python 3 module (_mraa.so+mraa.py) is not installed under/usr/lib/python3.x/site-packages/. A bareimport mraatherefore raisesModuleNotFoundError(Python 3) orImportError(Python 2.7) on the same image. -
Hardware pin-map assumption. The I/O shield 6ES7 647-0KA01-0AA2 uses a fixed mraa board definition file (
/etc/mraa/iot2000.bmor/usr/share/mraa/platform/iot2000.json) that maps shield connectors to logical pin numbers. Even after the Python binding is installed,mraa.getVersion()and the pin look-ups must succeed; a mismatched board file will produce "No pins" output frommraa-gpio listeven when the library is correctly loaded.
Prerequisites
- PC host (Linux recommended; Ubuntu 18.04 / 20.04 LTS validated) with
git,cmake> 3.5,build-essential,swig> 3.0,python3-dev,python3-setuptools. - SSH access to the IOT2000 with root privileges (default user
root, no password on the example image with a serial console). - Network connectivity from the IOT2000 to a local APT/OPKG feed or to the host PC via SCP.
- Optional: cross-compilation toolchain if you want to avoid native compilation on the device (recommended for IOT2040 Quark due to slow CPU).
swig and mraa from source. Use the Yocto SDK (iot2040-sdk-*.sh) provided by Siemens Support to cut build time to under two minutes.Building mraa with Python 3 Bindings
The reference upstream is the Eclipse mraa project (formerly Intel). Clone, configure, build, and install on the host first; the same recipe runs natively on the device.
Step 1 — Fetch source
git clone https://github.com/eclipse/mraa.git
cd mraa
git checkout v2.2.0 # pin to a known-good tag for IOT2000
Step 2 — Configure build with Python 3
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_PYTHON3=ON \
-DPYTHON3_EXECUTABLE=$(which python3) \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TESTING=OFF \
..
Verify the configure summary contains Python3 support: ON and the correct interpreter path. If swig is missing, install swig3.0 (Debian/Ubuntu) or rebuild the host toolchain.
Step 3 — Compile and install
make -j$(nproc)
sudo make install
sudo ldconfig
The SWIG output src/python/mraa.py and the compiled extension src/python/_mraa.cpython-3Xm-x86_64-linux-gnu.so are copied to /usr/lib/python3/dist-packages/.
Step 4 — Quick smoke test on host
python3 -c "import mraa; print(mraa.getVersion())"
Expected output (mraa 2.2.0):
v2.2.0
Deploying to the IOT2000
-
Identify the running image. Connect via SSH and run
cat /etc/os-release; confirm the version and whetherlibmraa2is already installed via the package manager (opkg info libmraa2). -
Install prerequisites on the device.
opkg update opkg install python3 python3-pip libmraa2 libmraa-dev mraa-tools swig -
Stage built artefacts. SCP the compiled modules from the host:
On the device runscp /usr/lib/python3/dist-packages/mraa.py \ root@<iot2000-ip>:/usr/lib/python3.7/site-packages/ scp /usr/lib/python3/dist-packages/_mraa*.so \ root@<iot2000-ip>:/usr/lib/python3.7/site-packages/ scp /usr/lib/libmraa.so.2* \ root@<iot2000-ip>:/usr/lib/ldconfig. -
Verify board file. The shield relies on
/etc/mraa/mraa-platform-iot2000.bm. Ifmraa-gpio listreports No pins, copy the file from/usr/local/share/mraa/platform/iot2000.jsonto/etc/mraa/and reboot.
Hardware Configuration for 6ES7 647-0KA01-0AA2
The Input/Output Module is an Arduino-shield form-factor board that piggy-backs onto the IOT2040/IOT2050. The following mapping is used by mraa-gpio and the Python binding:
| mraa pin | Shield marking | Direction | Voltage domain |
|---|---|---|---|
| 0 | DIG IN 1 | Input | 24 V DC (IEC 61131-2 type 1) |
| 1 | DIG IN 2 | Input | 24 V DC |
| 2 | DIG IN 3 | Input | 24 V DC |
| 3 | DIG IN 4 | Input | 24 V DC |
| 4 | DIG OUT 1 | Output (sink) | 24 V DC, 0.5 A per channel |
| 5 | DIG OUT 2 | Output (sink) | 24 V DC, 0.5 A per channel |
| 6 | AIN 1 | Analog input | 0–10 V, 12-bit |
| 7 | AIN 2 | Analog input | 0–10 V, 12-bit |
| 8 | AOUT 1 | Analog output | 0–10 V, 12-bit |
| 9 | AOUT 2 | Analog output | 0–10 V, 12-bit |
| 10 | Relay K1 | Output (dry contact) | 30 V DC / 1 A |
| 11 | Relay K2 | Output (dry contact) | 30 V DC / 1 A |
| 14 | STATUS LED | Output | 3.3 V |
Always confirm the silk-screen on your specific hardware revision against the schematic in the Siemens Equipment Manual for the Input/Output Module (download via Siemens Industry Online Support, article ID 109769760).
Python 3 Sample Application
The following minimal script toggles digital output 1 in response to digital input 1 and logs the analog value on AIN 1:
#!/usr/bin/env python3
import mraa
import time
print("mraa version:", mraa.getVersion())
print("platform :", mraa.getPlatformName())
DI1 = mraa.Gpio(0) # shield terminal X1 / DIG IN 1
DO1 = mraa.Gpio(4) # shield terminal X2 / DIG OUT 1
AIN1 = mraa.Aio(6) # shield terminal X3 / AIN 1
DI1.dir(mraa.DIR_IN)
DO1.dir(mraa.DIR_OUT)
while True:
state = DI1.read()
DO1.write(state)
raw = AIN1.read() # 0..1023 from mraa, 12-bit
volts = raw * 10.0 / 1023.0 # convert to 0..10 V
print(f"DI1={state} AIN1={volts:0.2f} V")
time.sleep(0.25)
Save as /opt/iot2000/io_demo.py, mark executable (chmod +x), and launch with python3 /opt/iot2000/io_demo.py.
Verification Procedures
-
Library import.
python3 -c "import mraa; print(mraa.getVersion())"— expect the previously installed version string. -
Board detection.
mraa-gpio list— should display the pin table for the IOT2000 platform, not "No pins". -
Loopback test. Wire a wire from shield terminal X1 (DIG IN 1) to X2 (DIG OUT 1). Run the sample script. Apply 24 V to X1 and confirm the script reports
DI1=1; remove the 24 V and confirmDI1=0. A multimeter on X2 pin 1 should mirror the input. - Analog test. Apply 0 V, 5 V, and 10 V from a calibrated source to AIN 1. Readback should be within ±0.05 V of the input.
-
Reboot persistence. Reboot the device and confirm
systemctl restart io_demo(or the equivalent SysV init script) starts the Python 3 process cleanly with mraa available.
Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
ImportError: No module named 'mraa' in Python 3 |
python3-mraa not installed |
Build from source (this article) or add to Yocto recipe IMAGE_INSTALL_append = " python3-mraa"
|
mraa-gpio list shows No pins
|
Board definition file missing or wrong path | Copy correct iot2000.bm to /etc/mraa/ and reboot |
ImportError: libmraa.so.2: cannot open shared object file |
LD_LIBRARY_PATH not set or ldconfig not run |
Run ldconfig, verify /usr/lib/libmraa.so.2 exists |
| Pin reads random values on shield input | Shield not seated; no 24 V common reference | Re-seat shield; verify terminal X4 (24 V supply) is powered |
| SWIG errors during build | swig < 3.0 installed | Install swig3.0 or newer |
ModuleNotFoundError for _mraa only (not mraa) |
Architecture mismatch between .so and Python interpreter |
Rebuild on device or with the matching Yocto SDK |
Process killed with SIGSEGV on first DI1.read()
|
Pin number out of range for the platform | Confirm mraa.getPinCount() and use only valid indices |
Updates break after opkg upgrade
|
libmraa replaced without re-installing binding | Re-install python3-mraa after every libmraa upgrade |
Integrating into a Yocto Build (Recommended for Production)
For fleet deployments, build a custom image rather than patching a running WIC:
- Clone the Siemens-provided BSP layer
meta-iot2000matching your hardware (git clone https://github.com/siemens/meta-iot2000). - Add
meta-openembedded/meta-pythonandmeta-openembedded/meta-oetobblayers.conf. - Append the install list in your recipe:
IMAGE_INSTALL_append = " python3 python3-pip libmraa python3-mraa mraa-tools" - Build with
bitbake iot2000-example-imageand flash the resulting*.wicwithddorbmaptool.
This approach bypasses the OSS-clearing delay entirely because the artefacts are produced inside your own build pipeline.
Safety and Wiring Considerations
Route analog signals in twisted pair with the shield grounded at the panel entry only. Keep the IOT2000 at least 100 mm away from VFD power conductors to avoid conducted EMI on the analog inputs.
Performance Notes
On the IOT2040 (Quark @ 400 MHz) a Python 3 mraa digital I/O loop achieves approximately 1.5 kHz read rate before GIL contention becomes visible. The IOT2050 (ARM Cortex-A53 @ 1.0 GHz) reaches 8–10 kHz. For control loops faster than 1 ms, consider writing the deterministic portion in C and exposing it through a thin Python wrapper.
Frequently Asked Questions
Why does the official Siemens Example Image still ship Python 2 only?
Each WIC image must pass through OSS Clearing before public release, which is why update cadence is measured in quarters. Python 2 remains the default interpreter on releases built before the Python 2 end-of-life project concluded; you can layer Python 3 manually as described above, or build your own image with the meta-iot2000 BSP.
Is the Input/Output Module 6ES7 647-0KA01-0AA2 compatible with both IOT2040 and IOT2050?
Yes. The shield uses the Arduino Uno R3 pin-out and the mraa board definition iot2000.bm. On the IOT2050 you must enable the Arduino-shield interface in the BIOS and update to the latest firmware so the I2C and GPIO multiplexers route correctly to the shield header.
Can I install python3-mraa via pip instead of compiling from source?
No reliable pip wheel exists for the IOT2000 platform because PyPI only publishes x86_64 / aarch64 manylinux wheels. Compiling from the Eclipse mraa sources against the on-device Python interpreter guarantees ABI compatibility.
What is the difference between mraa-gpio showing "No pins" and a missing Python binding?
mraa-gpio list interrogates only the C library and the board map; it will work even when the Python 3 binding is absent. If the tool returns "No pins" but the library is present, the board file is missing or pointed at the wrong path. If the tool returns pins but import mraa still fails, install the Python 3 binding.
Do I need a license to use mraa commercially on the IOT2000?
mraa is licensed under the MIT License (source files) with select components under BSD-3-Clause. Both are permissive and compatible with commercial use, but you must still satisfy the OSS attribution obligations that come with shipping a Linux-based Siemens image to end customers.