RB Interface/Bus Programming using MRAA
libmraa - Low Level Skeleton Library for Communication on GNU/Linux platforms Libmraa is a C/C++ library with bindings to Python, Java script and Java to interface with the I/O on ruggedBoard, Galileo, Edison & other platforms, with a structured and sane API where port names/numbering matches the board that you are on. Use of libmraa does not tie you to specific hardware with board detection done at runtime you can create portable code that will work across the supported platforms.
The intent is to make it easier for developers and sensor manufacturers to map their sensors & actuators on top of supported hardware and to allow control of low-level communication protocol by high level languages & constructs.

Fig: LIBMRAA ARCHITECTURE
- GPIO
- UART
- I2C
- SPI
LibMraa code flow: Code flow starts from arm.c file. In arm.c file, it calls different boards. In arm.c file we have to register our board information, like hardware name and board name. Example: rugged
These interfaces allow you to interact with all libmraa functionality. The C++ classes directly wrap the C API and provide a near 1:1 mapping of functionality

Fig: CODE FLOW
MRAA is a library from Intel that simplifies the logic for connecting to different sensor pins.
Libmraa is a C/C++ library with bindings to Python, Javascript and Java to interface with the I/O on X86, ARM & other platforms.
The intent is to make it easier for developers and sensor manufacturers to map their sensors & actuators on top of supported hardware and to allow control of low level communication protocol by high level languages & constructs
- Here is the simplest OnBoard-Gpio's program in mraa,to toggle three GPIO pins – 61,62,63
- a5d2x-rugged board
- USB cable
- Connect the Rugged board to your system
- Boot the board with SD card/NOR.
go to data folder after booting the board and copy the below python code.
[email protected]:/data# vi gpio_blink.py
import mraa
import time
gpio_1 = mraa.Gpio(61)
gpio_2 = mraa.Gpio(62) # initialise gpio 61 (D4 – Ref: Schematic)
gpio_3 = mraa.Gpio(63) # initialise gpio 63 (D17)
gpio_1.dir(mraa.DIR_OUT)
gpio_2.dir(mraa.DIR_OUT) # set gpio 61 to output
gpio_3.dir(mraa.DIR_OUT)
while True:
gpio_1.write(1)
gpio_2.write(0)
gpio_3.write(1)
time.sleep(1)
gpio_1.write(0)
gpio_2.write(1)
gpio_3.write(0)
time.sleep(1)
gpio_1.write(0)
gpio_2.write(0)
gpio_3.write(1)
time.sleep(1)
Execution :
- Run the above code with below command in rugged board.
[email protected]:/data# python3 gpio_blink.py
Watch the user LED's toggling on the RuggedBoard
- To test pwm with using of mraa c programming on a5d2x-Rugged board.
- a5d2x-rugged board
- USB cable
- External LED
- Boot the board from NOR/MMC.
- Please connect the positive pin of LED to the (16 th pin) of the M1 connector. And connect the other pin of led to ground (pin 8) .
- Open the below pwm.c source file in your host Terminal.
import mraa
import time
# initialise PWM
x = mraa.Pwm(72)
# set PWM period
x.period_us(700)
# enable PWM
x.enable(True)
value= 0.0
while True:
# write PWM value
x.write(value)
time.sleep(0.05)
value = value + 0.01
if value >= 1:
value = 0.0
Run the above code with below command in rugged board.
[email protected]:/data# python3 pwm.py
[email protected]:/data# python3 pwm.py
random: python3: uninitialized urandom read (24 bytes read)
libmraa[125]: libmraa version v2.0.0 initialised by user 'root' with EUID 0
libmraa[125]: gpio: platform doesn't support chardev, falling back to sysfs
libmraa[125]: libmraa initialised for platform 'Atmel SAMA5' of type 20
0.010000
0.020000
0.030000
0.040000
0.049995
0.059995
0.069995
0.079995
0.089995
0.099995
0.109995
0.119995
0.129995
0.139995
0.149995
0.160000
0.170000
0.180000
0.190000
0.200000
0.210000
0.220000
- Connect a pot(potentiometer) to rugged board a5d2x.
- a5d2x-rugged board
- USB cable
- potentiometer
- Connect the Pot (it will have three patch codes(wires), center one connect to "AN" (analog pin) of mikro bus connector.
- The remaining two you can connect one to ground (pin 60) & one to vcc (pin 01) on expansion header respectively.
import mraa
print(mraa.getVersion())
try:
# initialise AIO
x = mraa.Aio(6)
# read integer value
print(x.read())
# read float value
print("%.5f" % x.readFloat())
except:
print("Are you sure you have an ADC?")
​
Run the above code with below command in rugged board
[email protected]:/data# python3 aio.py
[email protected]:/data# python3 aio.py
random: python3: uninitialized urandom read (24 bytes read)
libmraa[128]: libmraa version v2.0.0 initialised by user 'root' with EUID 0
libmraa[128]: gpio: platform doesn't support chardev, falling back to sysfs
libmraa[128]: libmraa initialised for platform 'Atmel SAMA5' of type 20
v2.0.0
ADC A0 read 1FD - 509
ADC A0 read float - 0.49560
ADC A0 read 1FC - 508
ADC A0 read float - 0.49560
ADC A0 read 1FC - 508
ADC A0 read float - 0.49658
ADC A0 read 1FD - 509
ADC A0 read float - 0.49560
ADC A0 read 1FA - 506
ADC A0 read float - 0.49756
ADC A0 read 1FB - 507
ADC A0 read float - 0.49560
ADC A0 read 1FB - 507
ADC A0 read float - 0.49462
ADC A0 read 1FA - 506
ADC A0 read float - 0.49462
ADC A0 read 1FB - 507
ADC A0 read float - 0.49756
ADC A0 read 1FC - 508
ADC A0 read float - 0.49658
ADC A0 read 1FD - 509
ADC A0 read float - 0.49560
ADC A0 read 1FB - 507
ADC A0 read float - 0.49462
ADC A0 read 1FB - 507
ADC A0 read float - 0.49756
ADC A0 read 1FE - 510
ADC A0 read float - 0.49462
ADC A0 read 1FD - 509
ADC A0 read float - 0.49365
ADC A0 read 1FB - 507
ADC A0 read float - 0.49560
ADC A0 read 1FB - 507
ADC A0 read float - 0.49462
ADC A0 read 1FA - 506
ADC A0 read float - 0.49560
ADC A0 read 1FA - 506
ADC A0 read float - 0.49658
ADC A0 read 1FA - 506
ADC A0 read float - 0.49462
ADC A0 read 1F9 - 505
ADC A0 read float - 0.49658
ADC A0 read 1FC - 508
ADC A0 read float - 0.49462
ADC A0 read 1FB - 507
ADC A0 read float - 0.49560
ADC A0 read 1FA - 506
ADC A0 read float - 0.49365
ADC A0 read 1F2 - 498
ADC A0 read float - 0.48680
ADC A0 read 1F0 - 496
ADC A0 read float - 0.48485
ADC A0 read 1EF - 495
ADC A0 read float - 0.48387
ADC A0 read 1F2 - 498
ADC A0 read float - 0.48680
ADC A0 read 1F0 - 496
ADC A0 read float - 0.48680
ADC A0 read 1F2 - 498
ADC A0 read float - 0.48778
ADC A0 read 1F0 - 496
ADC A0 read float - 0.48583
ADC A0 read 1F2 - 498
ADC A0 read float - 0.48680
ADC A0 read 1F0 - 496
ADC A0 read float - 0.48680
ADC A0 read 1F0 - 496
ADC A0 read float - 0.48583
ADC A0 read 1F1 - 497
ADC A0 read float - 0.48485
ADC A0 read 1F0 - 496
ADC A0 read float - 0.48387
ADC A0 read 1EF - 495
ADC A0 read float - 0.48387
ADC A0 read 1F2 - 498
ADC A0 read float - 0.48485
ADC A0 read 1F1 - 497
ADC A0 read float - 0.48485
ADC A0 read 1F3 - 499
ADC A0 read float - 0.48680
​
- To test the SPI functionality in Kernel with loop-back test.
- a5d2x-rugged board
- USB cable
- patch cords
- Boot the board from MMC. After booting connect the one end of patch card to MOSI pin and other end to MISO pin.
- Copy the spi.py python code in data directory of your board.
- Run the below python code.
import mraa as m
import random as rand
import array
# intialise SPI
dev = m.Spi(0)
for x in range(0,100):
txbuf = bytearray(4)
for y in range(0,4):
txbuf[y] = rand.randrange(0, 256)
# send and receive data through SPI
rxbuf = dev.write(txbuf)
if rxbuf != txbuf:
print("Data mismatch!")
exit(1)
print(rxbuf)
- Open spi.py program given below in your board terminal.
- Open the spi.py program in /data directory.
[email protected]:/data# python3 spi.py
When MISO & MOSI are short.
[email protected]:/data# python3 spi.py
libmraa[149]: libmraa version v2.0.0 initialised by user 'root' with EUID 0
libmraa[149]: gpio: platform doesn't support chardev, falling back to sysfs
libmraa[149]: libmraa initialised for platform 'Atmel SAMA5' of type 20
bytearray(b'\xd1\xa2\x80\x93')
bytearray(b'z:l\x11')
bytearray(b'WC\xf5\xd9')
bytearray(b'\xcd\tq\xeb')
bytearray(b'IEs\xfa')
bytearray(b'\xbf\x1b\xe2b')
bytearray(b'3l\x80\xe9')
bytearray(b'\x8e\xf4\x05X')
bytearray(b'C\n\xb0\xa5')
bytearray(b'\x8f\xf5\xfe\xa1')
bytearray(b'\xf8LPi')
bytearray(b'"\xd5(z')
bytearray(b'\x10*F9')
bytearray(b'\xaf\xbef\xe9')
bytearray(b'\x80\xbd\x10C')
bytearray(b'\xb6\x8e\xdc8')
bytearray(b'k\xad\x96\xcc')
bytearray(b'\xb8y\xael')
bytearray(b'\xddwsT')
bytearray(b'\x16\xfc\xcf\x9f')
bytearray(b'\xddu\x0f\xf8')
bytearray(b'\x05\xbd\x06\xc7')
bytearray(b'yaW\x00')
bytearray(b'\xe7b\xfe\xf5')
bytearray(b'\xca0\xd0\xf6')
bytearray(b'\xbf\xdbH\xc5')
bytearray(b'Cb\xfau')
bytearray(b'\xc7`c\x9e')
bytearray(b'L\\\xec8')
bytearray(b'\x8a(\xc0\xad')
bytearray(b'\xeb\x9fm~')
bytearray(b'now\xc4')
bytearray(b'\xc7]\x9b\xc6')
bytearray(b'\x1c5W\xe7')
bytearray(b'\xa9\xd2\xce\xd1')
bytearray(b'\x95"\xd66')
bytearray(b'h|\xb9\xb4')
bytearray(b'\xff&/\xf9')
bytearray(b'\x8f\xee\xc0d')
bytearray(b'S=\xb5\x8b')
bytearray(b'.\x94\x91\x96')
bytearray(b'\x9c\xb0\x1fd')
bytearray(b'\x83(\x03+')
bytearray(b'\xee\xfb\x18\xde')
bytearray(b'\xfb\xf8\x01\xf4')
bytearray(b'[\x89_\x87')
bytearray(b'|\x98\x7f\x8c')
bytearray(b'n32\xe7')
bytearray(b'Y\xc7\x9b\xda')
bytearray(b'\xc0A\xc5p')
bytearray(b'\x0e\xf5\x1e\x0f')
bytearray(b'qse1')
bytearray(b'5\xf5\x07\x1a')
bytearray(b'\xf3\xe9y?')
bytearray(b'\xcf\xc5om')
bytearray(b'\x8c\xe3\x8d\xb9')
bytearray(b'M9\x88\xa9')
bytearray(b'\xcc\x80\x02\x1f')
bytearray(b'\xee\x05\x8a\x99')
bytearray(b'P8\x1ah')
bytearray(b'\x9cT\xcb\xd0')
bytearray(b'\xfa\x9c\xa1T')
bytearray(b'\x98\x85\xca\x0b')
bytearray(b'{\x0fS$')
bytearray(b'\x80\x15\x9a\x1e')
bytearray(b'\xd6c\xe2Q')
bytearray(b'.\xc0\x14\xbf')
bytearray(b'\xafV^G')
bytearray(b'\x9a\xfd\x0c\x84')
bytearray(b'\x8b\n\x03\x8a')
bytearray(b'z\x02[\xf4')
bytearray(b'\x11\xa5My')
bytearray(b'r<V\xa2')
bytearray(b'E\xb4\x1a\xec')
bytearray(b'\xbap\x9c\xc4')
bytearray(b'\xf5\x9eU\x85')
bytearray(b'\x91\x8b\x014')
bytearray(b'o\xf86\xcf')
bytearray(b'"a>\x9b')
bytearray(b'\x1e\x95\x86\x00')
bytearray(b'\x16+)\t')
bytearray(b'\x1f\xf7(E')
bytearray(b'c\xdd\x97\xf5')
bytearray(b'\x89\xbc\xfe\xb6')
bytearray(b'W\xd0\x07\x01')
bytearray(b'\x94?\x04Q')
bytearray(b'\xf1\xfa\xcc\x17')
bytearray(b'"8\xe7\xbc')
bytearray(b'<b\t\x0c')
bytearray(b'\xcc\x82x9')
bytearray(b'.\x05\\\x13')
bytearray(b'`;\xe9\xb0')
bytearray(b'\x91\x9e\x07]')
bytearray(b'\xb6.\xeaQ')
bytearray(b'\x88/\x15\xaf')
bytearray(b'\xc4\xc7^e')
bytearray(b'\x0bd~T')
bytearray(b'a5\x12\xb7')
bytearray(b'\xfe\x0f\xe2\x8b')
bytearray(b'\xaa\xf1L\xaa')
When MISO & MOSI are not short.
uninitialized urandom read (24 bytes read)
libmraa[135]: libmraa version v2.0.0 initialised by user 'root' with EUID 0
libmraa[135]: gpio: platform doesn't support chardev, falling back to sysfs
libmraa[135]: libmraa initialised for platform 'Atmel SAMA5' of type 20
random: python3: uninitialized urandom read (2500 bytes read)
Data mismatch!
​
- Toggling of 2 user LED's on a5d2x-rugged board.
- a5d2x-rugged board
- USB cable
- Open the below gpio.c source file in your host Terminal.
- follow the procedure given below the gpio.c file.
- Open the gpio.c program in your host terminal as given below.
/* standard headers */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* mraa header */
#include "mraa/gpio.h"
/* gpio declaration */
#define GPIO_PIN_1 61
#define GPIO_PIN_2 62
volatile sig_atomic_t flag = 1;
void
sig_handler(int signum)
{
if (signum == SIGINT) {
fprintf(stdout, "Exiting...\n");
flag = 0;
}
}
int
main(void)
{
mraa_result_t status = MRAA_SUCCESS;
mraa_gpio_context gpio_1, gpio_2;
/* install signal handler */
signal(SIGINT, sig_handler);
/* initialize mraa for the platform (not needed most of the times) */
mraa_init();
//! [Interesting]
/* initialize GPIO pin */
gpio_1 = mraa_gpio_init(GPIO_PIN_1);
if (gpio_1 == NULL) {
fprintf(stderr, "Failed to initialize GPIO %d\n", GPIO_PIN_1);
mraa_deinit();
return EXIT_FAILURE;
}
/* initialize GPIO pin */
gpio_2 = mraa_gpio_init(GPIO_PIN_2);
if (gpio_2 == NULL) {
fprintf(stderr, "Failed to initialize GPIO %d\n", GPIO_PIN_2);
mraa_deinit();
return EXIT_FAILURE;
}
/* set GPIO to output */
status = mraa_gpio_dir(gpio_1, MRAA_GPIO_OUT);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
/* set GPIO to output */
status = mraa_gpio_dir(gpio_2, MRAA_GPIO_OUT);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
/* toggle both GPIO's */
while (flag) {
status = mraa_gpio_write(gpio_1, 1);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
status = mraa_gpio_write(gpio_2, 0);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
sleep(1);
status = mraa_gpio_write(gpio_1, 0);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
status = mraa_gpio_write(gpio_2, 1);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
sleep(1);
}
/* release gpio's */
status = mraa_gpio_close(gpio_1);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
/* close GPIO */
status = mraa_gpio_close(gpio_2);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
//! [Interesting]
/* deinitialize mraa for the platform (not needed most of the times) */
mraa_deinit();
return EXIT_SUCCESS;
err_exit:
mraa_result_print(status);
/* deinitialize mraa for the platform (not needed most of the times) */
mraa_deinit();
return EXIT_FAILURE;
}
- Enable the a5d2x tool-chain for cross compilation of c code to generate a binary file
- For cross compilation type the following command given below
${CC} gpio.c -o gpiotoggle -lmraa
- The above command will generate a binary file with the name "gpiotoggle".
- Connect the Rugged Board with your system.
- Boot the board with SD card/NOR.
- Copy the above binary file to board mnt directory with tftp protocol.
- run the binary by typing the below command.
[email protected]:/data# ./gpiotoogle //Pin-D4,D7 toggle every 1 second
- Both Led's will toggle.
[email protected]:/data# ./gpiotoogle
libmraa[133]: libmraa version v2.0.0 initialised by user 'root' with EUID 0
libmraa[133]: gpio: platform doesn't support chardev, falling back to sysfs
libmraa[133]: libmraa initialised for platform 'Atmel SAMA5' of type 20
gpio 77
gpio pin 77
gpio 81
gpio pin 81
- User switch Led.
- a5d2x-rugged board
- USB cable
- Open the below button_gpio.c source file in your host Terminal.
- Follow the procedure given below the button_gpio.c file.
- Open the button_gpio.c program in your host terminal as given below.
#include <mraa.h>
#include <inttypes.h>
#define LED_PIN 63 /**< The pin where the LED is connected */
#define BTN_PIN 35 /**< Button is connected to this pin */
int main(void)
{
mraa_gpio_context ledPin; /* Will be used to represnt the LED pin */
mraa_gpio_context btnPin; /* Will be used to represnt the button pin */
uint32_t status; /* Used to toggle the LED */
uint32_t btnState; /* Used to capture the state of the button */
mraa_init();
ledPin = mraa_gpio_init(LED_PIN);
btnPin = mraa_gpio_init(BTN_PIN);
mraa_gpio_dir(ledPin, MRAA_GPIO_OUT);
mraa_gpio_dir(btnPin, MRAA_GPIO_IN);
while(1)
{
status = mraa_gpio_read(btnPin);
printf("STATUS = %d..\n\n",status);
if(status == 1)
{
mraa_gpio_write(ledPin, 1);
printf("LED ON \n");
}
else
{
printf("LED OFF \n");
mraa_gpio_write(ledPin, 0); // active low 0 is on the led
}
sleep(2);
}
return 0;
}
- Enable the a5d2x tool-chain for cross compilation of c code to generate a binary file.
- For cross compilation type the following command given below.
${CC} button_gpio.c -o button_gpio -lmraa
Execution :
- The above command will generate a binary file with the name "button_gpio".
- Connect the Rugged Board with your system.
- Boot the board with SD card/NOR.
- Copy the above binary file to board data directory with tftp protocol/mmc.
- Run the binary by typing the below command.
[email protected]:/data# ./button_gpio
[email protected]:/data# ./button_gpio
libmraa[147]: libmraa version v2.0.0 initialised by user 'root' with EUID 0
libmraa[147]: gpio: platform doesn't support chardev, falling back to sysfs
libmraa[147]: libmraa initialised for platform 'Atmel SAMA5' of type 20
gpio 83
gpio pin 83
gpio 76
gpio pin 76
STATUS = 1..
LED ON
STATUS = 1..
LED ON
STATUS = 0..
LED OFF
STATUS = 0..
LED OFF
STATUS = 0..
LED OFF
STATUS = 1..
LED ON
- Connect a pot(potentiometer) to rugged board a5d2x.
- a5d2x-rugged board
- USB cable
- potentiometer
- Connect the Pot (it will have three patch codes(wires)), center one connect to "AN" (analog pin) of mikro bus connector.
- The remaining two you can connect one to ground (pin 60) & one to vcc (pin 01) on expansion header respectively.
- Open the below aio.c source file in your host Terminal.
- follow the procedure given below the aio.c file.
- Open the aio.c program in your host terminal as given below.
/* standard headers */
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
/* mraa header */
#include "mraa/aio.h"
/* AIO port */
#define AIO_PORT 6
volatile sig_atomic_t flag = 1;
void
sig_handler(int signum)
{
if (signum == SIGINT) {
fprintf(stdout, "Exiting...\n");
flag = 0;
}
}
int
main()
{
mraa_result_t status = MRAA_SUCCESS;
mraa_aio_context aio;
uint16_t value = 0;
float float_value = 0.0;
signal(SIGINT, sig_handler);
/* initialize mraa for the platform (not needed most of the times) */
mraa_init();
//! [Interesting]
/* initialize AIO */
aio = mraa_aio_init(AIO_PORT);
if (aio == NULL) {
fprintf(stderr, "Failed to initialize AIO: %d\n",AIO_PORT);
mraa_deinit();
return EXIT_FAILURE;
}
while (flag) {
value = mraa_aio_read(aio);
float_value = mraa_aio_read_float(aio);
fprintf(stdout, "ADC A0 read %X - %d\n", value, value);
fprintf(stdout, "ADC A0 read float - %.5f\n", float_value);
}
/* close AIO */
status = mraa_aio_close(aio);
if (status != MRAA_SUCCESS) {
goto err_exit;
}
//! [Interesting]
/* deinitialize mraa for the platform (not needed most of the times) */
mraa_deinit();
return EXIT_SUCCESS;
err_exit:
mraa_result_print(status);
/* deinitialize mraa for the platform (not needed most of the times) */
mraa_deinit();
return EXIT_FAILURE;
}
- Enable the a5d2x tool-chain for cross compilation of c code to generate a binary file
- For cross compilation type the following command given below
${CC} aio.c -o aio -lmraa
Execution :
- The above command will generate a binary file with the name "aio".
- Connect the Rugged Board with your system.
- Boot the board with SD card/NOR.
- Copy the above binary file to board mnt directory with tftp protocol/mmc.
- run the binary by typing the below command.
[email protected]:/data# ./aio
Note : kindly note that there will be a screw present on the potentiometer if you rotate it clockwise the values of pot will decrease and if you rotate it anti-clockwise the values of pot should increase.
[email protected]:/data# ./aio
ADC A0 read 1FD - 509
ADC A0 read float - 0.49560
ADC A0 read 1FC - 508
ADC A0 read float - 0.49560
ADC A0 read 1FC - 508
ADC A0 read float - 0.49658
ADC A0 read 1FD - 509
ADC A0 read float - 0.49560
ADC A0 read 1FA - 506
ADC A0 read float - 0.49756
ADC A0 read 1FB - 507
ADC A0 read float - 0.49560
ADC A0 read 1FB - 507
ADC A0 read float - 0.49462
ADC A0 read 1FA - 506
ADC A0 read float - 0.49462
ADC A0 read 1FB - 507
ADC A0 read float - 0.49756
ADC A0 read 1FC - 508
ADC A0 read float - 0.49658
ADC A0 read 1FD - 509
ADC A0 read float - 0.49560
ADC A0 read 1FB - 507