• No results found

Intel Edison Development using C/C++

In document The Hands on Intel Edison Manual Lab (Page 98-123)

This chapter explains how to work and write program using C/C++ to access Intel Edison I/O from Linux.

5.1 Getting Started

Intel IoT distro provides mraa library which can be used for C/C++ development. In this chapter, we will focus on C development with GCC compiler. If you use C++, you can read this document, http://iotdk.intel.com/docs/master/mraa/ .

We will explore several scenario to illustrate how C work with Intel Edison board. The following is our lab scenario:

GPIO Analog I/O UART SP

I2C/TWI

Let's start working with mraa library. We will check mraa library version using mraa_get_version().

Write the following code.

#include <stdio.h>

#include <syslog.h>

#include <mraa.h>

int main(int argc, char **argv) {

mraa_result_t ret;

ret = mraa_set_log_level(LOG_DEBUG);

fprintf(stdout, "Mraa version: %s\n", mraa_get_version());

mraa_deinit();

return ret;

}

Save this code into a file, called testversion.c.

Now you can compile this file by typing the following command.

$ gcc -lmraa -o testversion testversion.c

Then, try to execute.

$ ./testversion

If success, you can obtain mraa library version.

5.2 GPIO

In this section, we learn how to access GPIO on Intel Edison using C. For illustration, I use 3 LEDs which are connected to digital input on the board. Please read section 4.2 for hardware configuration.

To access GPIO using C, we must declare header file, gpio.h. The following is a list of steps to access GPIO.

Initialize GPIO by calling mraa_init()

Getting mraa_gpio_context object by calling mraa_gpio_init() with passing GPIO pin. This parameter is similiar as digital I/O on Intel Edison. For instance, we connect to digital I/O 10.

Then, we pass 10 value to mraa_gpio_init(10)

We decide I/O direction which is possible as input or output. You can do it by calling mraa_gpio_dir()

To write value to digital Intel Edison, we can use mraa_gpio_write(). Otherwise, we can use mraa_gpio_read()

If you finish working with GPIO, you can close it by calling mraa_gpio_close()

Now we can start to write a program. Create a file, called gpiodemo.c, and write this code.

#include <stdio.h>

#include <signal.h>

#include <unistd.h>

#include <mraa/gpio.h>

sig_atomic_t volatile isrunning = 1;

void sig_handler(int signum);

int main () {

signal(SIGINT, &sig_handler);

mraa_init();

mraa_gpio_context led1;

mraa_gpio_context led2;

mraa_gpio_context led3;

led1 = mraa_gpio_init(10);

led2 = mraa_gpio_init(9);

led3 = mraa_gpio_init(8);

mraa_gpio_dir(led1, MRAA_GPIO_OUT);

mraa_gpio_dir(led2, MRAA_GPIO_OUT);

mraa_gpio_dir(led3, MRAA_GPIO_OUT);

while (isrunning){

fprintf(stdout, "LED 1\n");

mraa_gpio_write(led1,1);

mraa_gpio_write(led2,0);

mraa_gpio_write(led3,0);

sleep(1);

fprintf(stdout, "LED 2\n");

mraa_gpio_write(led1,0);

mraa_gpio_write(led2,1);

mraa_gpio_write(led3,0);

sleep(1);

fprintf(stdout, "LED 3\n");

mraa_gpio_write(led1,0);

mraa_gpio_write(led2,0);

mraa_gpio_write(led3,1);

sleep(1);

}

// reset all LEDS to 0 mraa_gpio_write(led1,0);

mraa_gpio_write(led2,0);

mraa_gpio_write(led3,0);

// close all gpio pins mraa_gpio_close(led1);

mraa_gpio_close(led2);

mraa_gpio_close(led3);

fprintf(stdout, "\nDone\n");

return MRAA_SUCCESS;

}

void sig_handler(int signum) {

if (signum == SIGINT) isrunning = 0;

}

Save this code and try to compile.

$ gcc -lmraa -o gpiodemo gpiodemo.c

If done, you can execute this program by typing the following command.

$ ./gpiodemo

If success, you can see the output as below.

You also can see 3 LEDs are blinking.

5.3 Analog I/O - Reading Analog Input

In this section, we learn how to read analog input on Intel Edison. We use the same problem on section 4.3. To read analog input we can use mraa_aio_read(). This function is a part of aio.h file.

The following is the algorithm to read analog input:

Initialize aio mraa library by calling mraa_aio_init() Set bit value for reading by calling mraa_aio_set_bit() Read analog input using mraa_aio_read()

Call mraa_aio_close() to release aio object usage

Now you can write the program by creating a file, called analog_read.c, and write this code.

#include <stdio.h>

#include <signal.h>

#include <unistd.h>

#include <mraa/aio.h>

sig_atomic_t volatile isrunning = 1;

void sig_handler(int signum);

int main () {

signal(SIGINT, &sig_handler);

mraa_aio_context adc_a0;

uint16_t adc_value = 0;

adc_a0 = mraa_aio_init(0);

if (adc_a0 == NULL) { return 1;

}

mraa_aio_set_bit(adc_a0,10);

while (isrunning){

adc_value = mraa_aio_read(adc_a0);

fprintf(stdout, "ADC A0 value: %X - %d\n", adc_value, adc_value);

sleep(1);

}

mraa_aio_close(adc_a0);

fprintf(stdout, "\nDone\n");

return MRAA_SUCCESS;

}

void sig_handler(int signum) {

if (signum == SIGINT) isrunning = 0;

}

Save this code and try to compile by the following command.

$ gcc -lmraa -o analog_read analog_read.c

Run the program.

$ ./analog_read

A sample output can be seen in Figure below.

5.4 UART

In this section, we will access Intel Edison UART using C. To access UART, we can implement termios, http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html . For illustration, we use the same scenario on section 4.4.

Create a file, called uart.c, and write this code.

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <unistd.h>

#include <fcntl.h>

#include <termios.h>

#include <string.h>

#include <errno.h>

void* handling_uart(void *arg) {

int length, value;

unsigned char buffer[256];

int *uart0 = (int *)arg;

value = 70;

errno = 0;

pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

while(1) {

pthread_testcancel();

sprintf(buffer,"%d",value);

printf("Write to UART: %d\n",value);

fflush(stdout);

// write to UART

length = write((*uart0), buffer, 2);

if (length < 0) {

printf("\n write() failed with error [%s]\n",strerror(errno));

break;

}

memset(buffer,0,256);

sleep(3);

value++;

if(value>80) value = 70;

}

printf("\r\n");

}

int main(void) {

int uart0 = -1;

pthread_t thread;

int ret, status;

char serial_port[] = "/dev/ttyMFD2";

errno = 0;

uart0 = open(serial_port, O_RDWR | O_NOCTTY );

if (uart0 == -1) {

printf("\n open() failed with error [%s]\n",strerror(errno));

return -1;

}

// configure UART

// check http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html struct termios options;

tcgetattr(uart0, &options);

// set 115200 baud both ways cfsetispeed(&options, B115200);

cfsetospeed(&options, B115200);

// 8 bits, no parity, no stop bits options.c_cflag &= ~PARENB;

options.c_cflag &= ~CSTOPB;

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS8;

// inter-character timer unused options.c_cc[VTIME] = 0;

// blocking read until x chars received options.c_cc[VMIN] = 1;

// Canonical mode

options.c_lflag |= ICANON;

// save the serial port settings tcflush(uart0, TCIFLUSH);

tcsetattr(uart0, TCSANOW, &options);

// create a thread for handling data on UART

ret = pthread_create (&thread, NULL, handling_uart, &uart0);

if (ret) {

printf("\n pthread_create() failed with error [%s]\n",strerror(errno));

return -1;

}

char c = getchar();

status = pthread_cancel(thread);

if (status) {

printf("\n pthread_cancel() failed with error [%s]\n",strerror(errno));

return -1;

}

close(uart0);

return 0;

}

This code will write data to UART /dev/ttyMFD2 . We use a thread for asynchronous writing.

Now you can compile this file as follows.

$ gcc -pthread -o uart uart.c

You can run the program.

$ ./uart

If success, you get program output, shown in Figure below.

I use PuTTY to connect /dev/ttyMFD2 from computer. The following is output of serial data using PuTTY.

5.5 SPI

We can implement the solution for problem on section 3.7 and 4.5 using C. Basically we can use mraa_spi_write() to write data and get a response on SPI channel.

Now you can write the program by creating a file, called spi.c, and write this code.

#include "mraa.h"

#include <unistd.h>

#include <stdint.h>

int main(int argc, char **argv) {

mraa_init();

mraa_spi_context spi;

spi = mraa_spi_init(5);

unsigned int response = 0;

uint8_t data[] = {0x00, 000};

uint8_t *recv;

printf("Reading and Writing SPI\n");

int i;

for (i = 10; i < 20; i++) { data[1] = i;

recv = mraa_spi_write_buf(spi, data, 2);

printf("Sent: %i\n",i);

printf("Received: %i-%i\n",recv[0],recv[1]);

usleep(100000);

} }

This program will write data from 10 to 19 using mraa_spi_write(). This function will return a response from SPI channel.

Save and compile the program.

$ gcc -lmraa -o spi spi.c

Then, you can execute the program.

$ ./spi

If success, you can get response as Figure below.

5.6 I2C/TWI

In this section we build a program as explained on section 4.6. We use Arduino as I2C source. To read data on I2C channel, we can use mraa_i2c_read().

Now you can start by creating a file, called i2c.c, and write this code.

#include <stdio.h>

#include <signal.h>

#include <unistd.h>

#include <mraa/i2c.h>

#define I2C_ADDR 0x15 // you can change it sig_atomic_t volatile isrunning = 1;

void sig_handler(int signum);

int main () {

signal(SIGINT, &sig_handler);

uint8_t * buff;

mraa_init();

mraa_i2c_context i2c;

i2c = mraa_i2c_init(1);

int n = 0;

mraa_i2c_address(i2c, I2C_ADDR);

while (isrunning){

int len = mraa_i2c_read(i2c,buff,1);

if(len>0){

fprintf(stdout, "Received: %x\n", buff[0]);

}else{

fprintf(stdout, "no data\n");

} n++;

if(n>=10){

isrunning = 0;

}

sleep(1);

}

mraa_i2c_stop (i2c);

fprintf(stdout, "\nDone\n");

return MRAA_SUCCESS;

}

void sig_handler(int signum) {

if (signum == SIGINT) isrunning = 0;

}

Explanation:

Initialize mraa library by calling mraa_init() Access I2C using mraa_i2c_init()

Set I2C address by calling mraa_i2c_address() Read I2C data using mraa_i2c_read()

Release all resource usage using mraa_i2c_stop()

Save this code and try to compile.

$ gcc -lmraa -o i2c i2c.c

Then, you can execute this program.

$ ./i2c

If success, you can get response on Terminal. The following is a sample output.

You can verify this output on Arduino via Serial Monitor.

6. Intel Edison Development using Node.js

This chapter explains how to work and write program using Node.js to access Intel Edison I/O from Linux.

6.1 Getting Started

Intel IoT distro provides mraa library which can be used for Node.js development. In this chapter, we will focus on Node.js development to access Intel Edison from Linux. We will use mraa library in our implementation. You can read mraa source code on https://github.com/intel-iot-devkit/mraa .

We will explore several scenario to illustrate how Node.js work with Intel Edison board. The following is our lab scenario:

GPIO Analog I/O UART SPI I2C/TWI

Intel also provides a tool, called Intel XDK IoT edition, https://software.intel.com/en-us/html5/xdk-iot . You can use this tool to write JavaScript. To access Intel Edison from Node.js, we can use mraa library which has already installed for you.

You can test mraa version by writing the following code.

var m = require('mraa');

console.log('MRAA Version: ' + m.getVersion());

Save this code into a file, called testversion.js. Now you can execute it.

$ node testversion.js

If success, you can see mraa version.

Next section we explore several scenario to access Intel Edison using mraa library.

6.2 GPIO

In this section, we learn how to access GPIO on Intel Edison using Node.js. For illustration, we use the same problem on section 5.2. To start to write a program, you can create a file, called gpiodemo.js, and write this code.

var m = require('mraa');

var led1 = new m.Gpio(10);

var led2 = new m.Gpio(9);

var led3 = new m.Gpio(8);

led1.dir(m.DIR_OUT);

led2.dir(m.DIR_OUT);

led3.dir(m.DIR_OUT);

var ledon = 1;

setInterval(function(){

blinkLED();

ledon++;

if(ledon>3) ledon = 1;

},1000);

function blinkLED() { switch(ledon){

case 1:

led1.write(1);

led2.write(0);

led3.write(0);

break;

case 2:

led1.write(0);

led2.write(1);

led3.write(0);

break;

case 3:

led1.write(0);

led2.write(0);

led3.write(1);

break;

}

console.log("LED " + String(ledon) + " ON");

}

process.on('SIGINT', function() { led1.write(0);

led2.write(0);

led3.write(0);

console.log("\nDone");

process.exit();

});

Explanation:

Open GPIO pin using mraa.Gpio() Set I/O direction via mraa.dir()

To write data to GPIO, we can use mraa.write()

Save this code and try to run.

$ node gpiodemo.js

A sample output is shown in Figure below.

6.3 Analog I/O - Reading Analog Input

In this section, we solve a problem on section 5.3 using Node.js. We can use mraa.Aio() to read analog input from Intel Edison board. Call Aio.read() to read incoming data on analog input pin.

For illustration, create a file, called analog_input.js, and write this code.

var m = require('mraa');

var a0 = new m.Aio(0);

a0.setBit(10);

console.log("reading analog input>>>");

setInterval(function(){

readAnalog() }, 1000);

function readAnalog() { var val = a0.read();

console.log(">> Analog A0 value: " + String(val));

}

Then, run this program.

$ node analog_input.js

If success, you will get analog input value on Terminal.

6.4 UART

To access UART, we can use node-serialport library, https://github.com/voodootikigod/node-serialport . Type the following command to install node-serialport.

$ npm install serialport

We use the same scenario on section 5.4. The program will write data to serial port, /dev/ttyMFD2, every a second.

Create a file, called uart.js, and write this code.

var SerialPort = require("serialport").SerialPort;

var port = "/dev/ttyMFD2";

var serialPort = new SerialPort(port, { baudrate: 115200

},false);

console.log("Open port: " + port);

serialPort.open(function (error) { if (error) {

console.log('failed to open: '+error);

} else {

// write data to serial port every a second var counter = 90;

setInterval(function () {

serialPort.write(String(counter) + "\r\n", function(err) { if(err){

console.log('err ' + err);

}else{

console.log('Write data ' + counter);

} });

counter++;

if(counter>100) counter = 90;

}, 1000);

} });

Save this code and try to run.

$ node uart.js

Program output can be seen in Figure below.

Open serial monitor, for instance PuTTY. Navigate to serial port which be connected to /dev/ttyMFD2 (micro USB).

6.5 SPI

mraa library provides Node.js interface to access SPI on Intel Edison. We can use mraa.Spi() to get mraa object. Then, we can use Spi.read() to read data on SPI channel.

For testing, we implement a problem on section 3.7, 4.5 and 5.5 using Node.js. Create a file, called spi.js, and write this code.

var m = require('mraa');

var spi = new m.Spi(5);

var counter = 0;

console.log("Writing and Reading SPI..");

setInterval(function(){

readAnalog() }, 1000);

function readAnalog() {

var recv = spi.write(String(counter));

console.log(">> SPI sent value: " + String(counter));

console.log(">> SPI received value: " + String(recv));

counter++;

if(counter>=10) counter = 0;

}

Run the program.

$ node spi.js

A sample output is shown in Figure below.

6.6 I2C/TWI

The last demo is to write a program to access I2C on Intel Edison. This is problem based on section 4.6.

Plug in your Arduino I2C to Intel Edison I2C. Then, write the following code.

var m = require('mraa');

var i2c = new m.I2c(1);

i2c.address(0x15); // change it based on I2C on Arduinop

console.log("Reading I2C..");

setInterval(function(){

readAnalog() }, 1000);

function readAnalog() { var val = i2c.read();

console.log(">> I2C value: " + String(val));

}

Explanation:

Open GPIO pin using mraa.I2c()

Set I2C address using i2c.address(0x15). Assume I2C address is 0x15 To write data to GPIO, we can use mraa.write()

Save this code into a file, called i2c.js, and run it.

$ node i2c.js

You can see the sample output in Figure below.

To verify the result on Arduino, you can use Serial Monitor from Arduino software.

In document The Hands on Intel Edison Manual Lab (Page 98-123)

Related documents