A web developer playing with the Intel Galileo part 2: Digital Input-Output

Our next step is manipulating the hardware ports from a language we feel comfortable, like JavaScript, so we can do future experimentation on it. Since this seems to have some potential, we may turn this into a library so future developers can build apps on Galileo using JavaScript with ease. We will be posting our results over github and publishing at npm. Should be fun.

First we must figure out how to get the digital input working.

Physically, the Galileo uses an Arduino compatible layout of pins, which gives us 14 digital pins to play with.

galileohiresmin

Since the Galileo runs a full Linux the pins are manipulated trough the General Purpose Input Output (GPIO), which is a very fancy way of saying we control it by writing and reading to some very specific files. Every pin gets its own set of files in /sys/class/gpio.

A word of warning tough, do not start playing randomly with the gpio files. Many of the gpio files are associated with electronic components in the Galileo that have nothing to do with the digital pins and could generate catastrophic results if changed.

Now you may notice files in the gpio folder are classified by number and may think the numbers correspond to the printed pin number. Sadly, you are very wrong. The powers that be had it so the printed numbers and GPIO number had absolutely no connection whatsoever, making the warning I just gave sound much more alarming. A quick google of the GPIO mapping will easily lead to tables that describe to which GPIO each pin is connected. But since we do not want to deal with that every time we write or read from a pin we take a preventive solution and create variable that maps every printed pin to the actual GPIO number.


var digitalMapping = {
	"0": 50,
	"1": 51,
	"2": 32,
	"3": 18,
	"4": 28,
	"5": 17,
	"6": 24,
	"7": 27,
	"8": 26,
	"9": 19,
	"10": 16,
	"11": 25,
	"12": 38,
	"13": 39,
}

There! Much easier!

Now, following the guidance of Sergey Kiselev super informative blog we discover that using a pin is a 3 step process:

  1. Write to the export file on the gpio folder the number of the gpio we wish to use, which creates the necessary files
  2. Set if the pin is meant to be read or write (in or out) using the direction file in the pin’s folder
  3. Write or read a value from the value file in the pin’s folder

We are interested on making this into a Javascript function, so we can use the fs module to read and write from the files.

First, to export:


exportGpio = function(gpio_nr, callback) {
	fs.writeFile('/sys/class/gpio/export', gpio_nr, fileOptions, function (err) {
		if (err) { 
			console.log("export error");
			console.log(err);
		}
		if(callback){
				callback();
			}
});
};

Then to set the direction:


setGpioDirection = function(gpio_nr, direction, callback) {
	fs.writeFile("/sys/class/gpio/gpio" + gpio_nr + "/direction", direction, fileOptions, function (err) {
		if (err) { 
			// console.log("Could'd set gpio" + gpio_nr + " direction to " + direction + " - probably gpio not available via sysfs");
			console.log("direction error");
			console.log(err); 
		}
		callback();
	});
}

galileo.setGpioIn = function(gpio_map, callback) {
	setGpioDirection(gpio_map, 'in', callback);
}

galileo.setGpioOut = function(gpio_map, callback) {
	setGpioDirection(gpio_map, 'out', callback);
}

And finally, to write or read values:



galileo.readGpio = function(gpio_nr, callback) {
	fs.readFile("/sys/class/gpio/gpio" + gpio_nr + "/value", fileOptions, function(err, data) {
		if (err) { console.log("Error reading gpio" + gpio_nr); }
		var value = data;
		callback(value);
	});
};

galileo.writeGpio = function(gpio_nr, value, callback) {

	if(value != 0 && value !=1){
		console.log("gpio write only supports binary values");
		return;
	}

	fs.writeFile("/sys/class/gpio/gpio" + gpio_nr + "/value", value, fileOptions, function(err, data) {
		if (err) { console.log("Writing " + gpio_nr + " " + value); }
		if (callback){ callback();}
	});
};

Please remember that you can only read from pins set as input (in) an write to pins set as output (out) and that only 0 and 1 are allowed as values, with 0 being 0 volts and 1 being 5 volts. Every function is run asynchronously so you need to pass a callback in order to chain it all together. In order to simplify the process a little further we add a “preparePin” function that does the export and direction setting in succession, taking a boolean value as the direct, true for input, false for output:


galileo.preparePin = function(gpio_map, direction, callback) {
	exportGpio(gpio_map, function(){
		if(direction){
			galileo.setGpioIn(gpio_map, callback);
		}else{
			galileo.setGpioOut(gpio_map, callback);
		}
	});
}

So, for a simple example, let us load the library into a test object, connect a led to pin 0, turn it on and the off after 2 seconds:



var led_pin = test.digitalMapping[0]; 

test.galileo.preparePin(led_pin,false,function(){
     test.galileo.writeGpio(led_pin, 1, function(){

     setInterval(function(){
		 	test.galileo.writeGpio(led_pin, 0);
	},2000);

     });
});

Advertisements

An upcoming web developer and android app-maker with an interest on using reliable tech in creative ways, open source projects and start-ups.

Tagged with: , , ,
Posted in devices

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: