Skip to content

Commit 7949940

Browse files
committed
gpio test now demonstrates led and button
1 parent a73e498 commit 7949940

File tree

5 files changed

+286
-135
lines changed

5 files changed

+286
-135
lines changed

coder-apps/tests/gpio_test/app/app.js

Lines changed: 137 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
var gpio = require("gpio");
22
gpio.logging = true;
33

4-
var gpioID = 4; //actually pin 7, 4 down on left header
5-
var gpioDevice;
6-
var connected = false; //ensure only one process talks to us at a time.
4+
5+
// The gpio ids we're using. Note that these aren't the pin numbers, but
6+
// the IDs exposed by the Pi. Search for Pi GPIO pinout for details.
7+
var ledGPIOID = 4; //actually pin 7, 4 down on left header
8+
var buttonGPIOID = 17;
9+
10+
// Handles for our connected gpio devices
11+
var ledDevice;
12+
var buttonDevice;
13+
14+
// A collection of all connected sockets.
15+
// Maps socketid => { socket: sockethandle, id: socketid }
16+
var connections = {};
717

818
exports.settings={};
919
//These are dynamically updated by the runtime
@@ -15,89 +25,66 @@ exports.settings={};
1525
//settings.coder_owner - name of the user, Ie. "Suzie Q."
1626
//settings.coder_color - hex css color given to this coder.
1727

28+
// Incoming get routes that our app knows how to respond to
1829
exports.get_routes = [
19-
{ path:'/', handler:'index_handler' },
30+
{ path:'/', handler:'index_handler' }, // Render out main html page
2031
];
2132

33+
// Incoming post routes that our app knows how to respond to
34+
// (None in this example)
2235
exports.post_routes = [
2336
];
2437

38+
// Incoming socket events that this module will expose.
2539
exports.socketio_routes = [
26-
{ key:'connect', handler:'on_socket_connect' },
27-
{ key:'gpio', handler:'on_socket_gpio' },
40+
{ key:'connect', handler:'on_socket_connect' }, // sent by client once socket is loaded
41+
{ key:'setled', handler:'on_socket_setled' }, // sent by client to turn on/off the led
2842
];
2943

3044

31-
var connections = {};
3245

46+
//
47+
// Handles sending the HTML page to the browser
48+
//
3349
exports.index_handler = function( req, res ) {
50+
// Set up some template variables that are substituted in our HTML.
51+
// Look in the HTML head tag to see where these are inserted.
3452
var tmplvars = {};
3553
tmplvars['static_url'] = exports.settings.staticurl;
3654
tmplvars['app_name'] = exports.settings.appname;
3755
tmplvars['app_url'] = exports.settings.appurl;
3856
tmplvars['device_name'] = exports.settings.device_name;
3957

58+
// Send the HTML document to the web browser.
4059
res.render( exports.settings.viewpath + '/index', tmplvars );
4160
};
4261

4362

44-
var enableGPIO = function() {
45-
console.log("Enabling GPIO " + gpioID );
46-
gpioDevice = gpio.export( gpioID, {
47-
ready: function() {
48-
//Pause briefly after pin is exported.
49-
//There seems to be an error if you try to immediately access it.
50-
setTimeout( function() {
51-
console.log("GPIO value: on");
52-
gpioDevice.setDirection("out");
53-
gpioDevice.set(1, function() {
54-
console.log("GPIO should be on");
55-
});
56-
//blinkLED();
57-
}, 100 );
58-
}
59-
});
60-
};
61-
var disableGPIO = function() {
62-
console.log("Disabling GPIO" + gpioID );
63-
gpioDevice.removeAllListeners();
64-
gpioDevice.reset();
65-
gpioDevice.unexport();
66-
};
67-
68-
var ledval = 0;
69-
var blinkLED = function() {
70-
if ( !connected ) {
71-
return;
72-
}
73-
74-
gpioDevice.set( ledval );
75-
if ( ledval == 0 ) {
76-
ledval = 1;
77-
} else {
78-
ledval = 0;
79-
}
80-
81-
//run this method again after half a second
82-
setTimeout( blinkLED, 500 );
83-
};
84-
85-
86-
63+
//
64+
// Respond to the "connect" message sent by a new socket client.
65+
//
66+
// We do two things here:
67+
// 1. save the socket object into the "connections" variable so we can talk to it later.
68+
// 2. initialize the GPIO pins if this is the first time a socket has connected.
69+
//
8770
exports.on_socket_connect = function( socket, data ) {
8871
console.log( 'socket connect from ID: ' + socket.socketID );
8972
console.log( data );
9073

91-
if ( !connected ) {
74+
// Enable the GPIO pins if this is the first connection
75+
if ( Object.keys( connections ).length <= 0 ) {
9276
enableGPIO();
93-
connected = true;
9477
}
9578

79+
// Store information about this socket so we can communicate with
80+
// all connected sockets in the future.
9681
connections[socket.socketID] = {
9782
socket: socket,
98-
name: data.name,
9983
id: socket.socketID
10084
};
85+
86+
// Watch for this socket to disconnect so that we can remove it from
87+
// our collection of connected sockets.
10188
socket.on('disconnect', function() {
10289
console.log( 'socket disconnect from ID: ' + socket.socketID );
10390
delete connections[socket.socketID];
@@ -111,41 +98,113 @@ exports.on_socket_connect = function( socket, data ) {
11198

11299
};
113100

101+
//
102+
// Respond to a "setled" message from a socket connection to update the LED value
103+
//
104+
exports.on_socket_setled = function( socket, data ) {
105+
if ( data.value !== "undefined" ) {
106+
setLED( data.value );
107+
}
108+
};
109+
110+
111+
112+
//
113+
// This is called once from our first socket connection.
114+
// - set up the LED GPIO as an output
115+
// - set up the Button GPIO as an input and tie it to send a "change" message
116+
//
117+
var enableGPIO = function() {
118+
119+
// Set up the LED output GPIO
120+
console.log("Setting up LED as an output on GPIO " + ledGPIOID );
121+
ledDevice = gpio.export( ledGPIOID, {
122+
direction: "out",
123+
ready: function() {
124+
}
125+
});
126+
127+
// Set up the button input GPIO
128+
console.log("Setting up Button as an input on GPIO" + buttonGPIOID);
129+
buttonDevice = gpio.export( buttonGPIOID, {
130+
direction: "in",
131+
ready: function() {
132+
133+
// Set up buttonDevice to call the buttonChange
134+
// function (below) whenever its value changes.
135+
buttonDevice.on("change", buttonChange);
136+
}
137+
});
138+
139+
};
140+
141+
//
142+
// This is called when the last socket disconnects.
143+
// It releases our GPIO pins so they can be used by another program.
144+
//
145+
var disableGPIO = function() {
146+
console.log("Disabling GPIO" + ledGPIOID );
147+
ledDevice.removeAllListeners();
148+
ledDevice.reset();
149+
ledDevice.unexport();
150+
151+
console.log("Disabling GPIO" + buttonGPIOID );
152+
buttonDevice.removeAllListeners();
153+
buttonDevice.reset();
154+
buttonDevice.unexport();
155+
};
114156

115-
exports.on_socket_gpio = function( socket, data ) {
116-
switch (data.command) {
117-
case "set":
118-
setGPIO( data.value );
119-
break;
120-
case "direction":
121-
setDirection( data.direction );
122-
break;
123-
case "value":
124-
sendValue( socket );
125-
break;
157+
//
158+
// This is triggered by the GPIO "change" event on buttonDevice. This was
159+
// set up inside emabledGPIO().
160+
//
161+
// The change event sends this function a value, either 0 (off) or 1 (on).
162+
//
163+
var buttonChange = function( val ) {
164+
// Recall that this code is running on the device. We need to send a
165+
// socket message with the button data to our javascript in the
166+
// web browser. In fact, we need to send this data to every connected
167+
// socket, since there may be more than one browser window looking at
168+
// this page.
169+
170+
console.log( "buttonChange event with value: " + val );
171+
172+
// Iterate through all of our socket connections
173+
for ( var socketid in connections ) {
174+
// Get the socket object for this socket
175+
var socket = connections[socketid].socket;
176+
177+
// The "appdata" event will be received by the Coder.socketConnection
178+
// object in the front end code and sent to the appropriate listener
179+
// that we've defined.
180+
// The "buttonupdate" key refers to a listener we set up on the front
181+
// end with the code:
182+
// Coder.socketConnection.addListener( "buttonupdate", function... )
183+
socket.emit( "appdata", {
184+
key: "buttonupdate",
185+
data: val
186+
});
126187
}
127188
};
128189

129-
var setGPIO = function( val ) {
190+
//
191+
// Set the value on the LED GPIO device, either 0 (off) or 1 (on).
192+
//
193+
var setLED = function( val ) {
130194
val = parseInt( val );
131195
if ( val != 0 ) {
132196
val = 1;
133197
}
134-
gpioDevice.set( val );
135-
};
136-
var setDirection = function( dir ) {
137-
if ( dir !== "in") {
138-
dir = "out";
139-
}
140-
gpioDevice.setDirection( dir );
141-
};
142-
var sendValue = function( socket ) {
143-
socket.emit( "apdata", {
144-
key: "gpiovalue",
145-
data: gpioDevice.value
146-
});
198+
ledDevice.set( val );
147199
};
148200

201+
//
202+
// Called by Coder whenever this module is reloaded. This usually happens when
203+
// you save your code in the editor. This is a good place to destroy any intervals
204+
// or clean up any long running code or handles.
205+
//
149206
exports.on_destroy = function() {
150207
};
151208

209+
210+

coder-apps/tests/gpio_test/app/meta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"created": "2013-11-30",
3-
"modified": "2013-12-08",
3+
"modified": "2014-01-09",
44
"color": "#2ecc71",
55
"author": "",
66
"name": "GPIO Test",
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,42 @@
11

22
.pagecontent {
33
padding: 24px;
4+
}
5+
6+
#buttonval {
7+
width: 100px;
8+
height: 100px;
9+
background-color: #000000;
10+
}
11+
#buttonval.on {
12+
background-color: #F03050;
13+
}
14+
15+
16+
.button {
17+
cursor: pointer;
18+
width: 200px;
19+
height: 150px;
20+
margin: 24px 0;
21+
background-color: #3498D8;
22+
line-height: 150px;
23+
text-align: center;
24+
color: #fff;
25+
font-weight: bold;
26+
}
27+
28+
.button.press {
29+
background-color: #2488A8;
30+
}
31+
32+
33+
#output {
34+
position: absolute;
35+
left:0;
36+
right:0;
37+
bottom:0;
38+
height: 150px;
39+
color: #fff;
40+
background-color: #000;
41+
overflow: hidden;
442
}

0 commit comments

Comments
 (0)