A web developer playing with the Intel Galileo part 4: Buttons!

Buttons are one of the main components on even some of the simplest circuits. We want our program to know when a button has been pressed and take appropriate action.

While we could use our current code and check the value of a pin for changes every X seconds this approach probably has a toll on performance, especially with languages focused on single thread execution like javascript. There, we want to find a way where a callback is executed when a button is pressed.

GPIO are capable of handling interrupts, where a system event is triggered every time a change is detected in the voltage level of a pin. To achieve this we first export the pin connected to the button and set it as input using the functions we created previously.



galileo.setUpButton = function(gpio_nr, callback){
	exportGpio(gpio_nr,function(){
		setGpioDirection(gpio_nr,"in",function(){
			// Something is missing!
		});
	});
}

In order to make the pin work with interrupts we need to write to another file in the GPIO folder, the edge file, a change the default value of none (which generates no interruption) to both (which generates interruptions on both changes from 1 to 0 and 0 to 1). Technically, GPIO edge files should accept rising and falling values as well, but it does not seem like the Galileo supports it. The complete function looks like this:


galileo.setUpButton = function(gpio_nr, callback){
	exportGpio(gpio_nr,function(){
		setGpioDirection(gpio_nr,"in",function(){
			fs.writeFile("/sys/class/gpio/gpio" + gpio_nr + "/edge", "both", fileOptions, function (err) {
				if (err) { 
					console.log("edge error");
					console.log(err); 
				}
				callback();
			});
		});
	});
}

As for making a function execute on a button press, we will use a different low level library called epoll, and guiding ourselves with the examples create a function that will bind a callback on the interrupt


galileo.setButtonCallback = function(gpio_nr, callback){
	
	var  valuefd = fs.openSync('/sys/class/gpio/gpio'+gpio_nr+'/value', 'r');
	var  buffer = new Buffer(1);

// Create a new Epoll. The callback is the interrupt handler.

	var poller = new Epoll(function (err, fd, events) {

// Read GPIO value file. Reading also clears the interrupt.
  		fs.readSync(fd, buffer, 0, 1, 0);
  		callback(buffer.toString());
	});

// Read the GPIO value file before watching to
// prevent an initial unauthentic interrupt.
	fs.readSync(valuefd, buffer, 0, 1, 0);
// Start watching for interrupts.

	poller.add(valuefd, Epoll.EPOLLPRI);

	return poller;
}

Be sure to connect your button correctly when testing, or else you will get unpredictable results:

schemeit-project(1)

 

I am putting together all this functions in a library that can be downloaded from npm and used on the Galileo. Be sure to check it out and contribute if you can.

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: