Skip to content

Commit de79971

Browse files
committed
adding test for spi module
1 parent 49c9743 commit de79971

File tree

6 files changed

+376
-0
lines changed

6 files changed

+376
-0
lines changed

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

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
var SPI = require('pi-spi');
2+
3+
4+
// The SPI linux device. Either /dev/spidev0.0 or /dev/spidev0.1
5+
var spidev = '/dev/spidev0.0';
6+
7+
// The handle to the device driver
8+
var spiDevice = null;
9+
10+
11+
12+
// A collection of all connected sockets.
13+
// Maps socketid => { socket: sockethandle, id: socketid }
14+
var connections = {};
15+
16+
exports.settings={};
17+
//These are dynamically updated by the runtime
18+
//settings.appname - the app id (folder) where your app is installed
19+
//settings.viewpath - prefix to where your view html files are located
20+
//settings.staticurl - base url path to static assets /static/apps/appname
21+
//settings.appurl - base url path to this app /app/appname
22+
//settings.device_name - name given to this coder by the user, Ie."Billy's Coder"
23+
//settings.coder_owner - name of the user, Ie. "Suzie Q."
24+
//settings.coder_color - hex css color given to this coder.
25+
26+
// Incoming get routes that our app knows how to respond to
27+
exports.get_routes = [
28+
{ path:'/', handler:'index_handler' }, // Render out main html page
29+
];
30+
31+
// Incoming post routes that our app knows how to respond to
32+
// (None in this example)
33+
exports.post_routes = [
34+
];
35+
36+
// Incoming socket events that this module will expose.
37+
exports.socketio_routes = [
38+
{ key:'connect', handler:'on_socket_connect' }, // sent by client once socket is loaded
39+
];
40+
41+
42+
43+
//
44+
// Handles sending the HTML page to the browser
45+
//
46+
exports.index_handler = function( req, res ) {
47+
// Set up some template variables that are substituted in our HTML.
48+
// Look in the HTML head tag to see where these are inserted.
49+
var tmplvars = {};
50+
tmplvars['static_url'] = exports.settings.staticurl;
51+
tmplvars['app_name'] = exports.settings.appname;
52+
tmplvars['app_url'] = exports.settings.appurl;
53+
tmplvars['device_name'] = exports.settings.device_name;
54+
55+
// Send the HTML document to the web browser.
56+
res.render( exports.settings.viewpath + '/index', tmplvars );
57+
};
58+
59+
60+
//
61+
// Respond to the "connect" message sent by a new socket client.
62+
//
63+
// We do two things here:
64+
// 1. save the socket object into the "connections" variable so we can talk to it later.
65+
// 2. initialize the SPI device if this is the first time a socket has connected.
66+
//
67+
exports.on_socket_connect = function( socket, data ) {
68+
console.log( 'socket connect from ID: ' + socket.socketID );
69+
console.log( data );
70+
71+
// Enable the SPI device if this is the first connection
72+
if ( Object.keys( connections ).length <= 0 ) {
73+
enableSPI();
74+
}
75+
76+
// Store information about this socket so we can communicate with
77+
// all connected sockets in the future.
78+
connections[socket.socketID] = {
79+
socket: socket,
80+
id: socket.socketID
81+
};
82+
83+
// Watch for this socket to disconnect so that we can remove it from
84+
// our collection of connected sockets.
85+
socket.on('disconnect', function() {
86+
console.log( 'socket disconnect from ID: ' + socket.socketID );
87+
delete connections[socket.socketID];
88+
89+
//Free up the GPIO when the last socket disconnects
90+
if ( Object.keys( connections ).length <= 0 ) {
91+
disableSPI();
92+
connected = false;
93+
spiDevice = null;
94+
}
95+
});
96+
97+
};
98+
99+
100+
101+
102+
103+
//
104+
// This is called once from our first socket connection.
105+
// - set up the SPI device
106+
// - read input from the device and send spiupdate events
107+
//
108+
var updateInterval;
109+
var enableSPI = function() {
110+
111+
// Set up the SPI device
112+
console.log("Setting up SPI on " + spidev );
113+
spiDevice = SPI.initialize( spidev );
114+
115+
116+
//Poll the device for updates once a second.
117+
updateInterval = setInterval( readADCData, 1000 );
118+
119+
120+
};
121+
122+
//
123+
// This is called when the last socket disconnects.
124+
// It releases our GPIO pins so they can be used by another program.
125+
//
126+
var disableSPI = function() {
127+
128+
console.log("Disabling SPI device" + spidev );
129+
130+
clearInterval( updateInterval );
131+
spiDevice.close();
132+
133+
};
134+
135+
var toBin = function( d ) {
136+
return ("00000000" + d.toString(2)).substr( -8 );
137+
};
138+
139+
//
140+
// Reads channel 0 analog value from an MCP3008 ADC chip
141+
//
142+
var readADCData = function() {
143+
// Recall that this code is running on the device. We need to send a
144+
// socket message with the data to our javascript in the
145+
// web browser. In fact, we need to send this data to every connected
146+
// socket, since there may be more than one browser window looking at
147+
// this page.
148+
149+
// The message used to tell an MCP3008 ADC chip to return the
150+
// analog reading of channel 0;
151+
var channel = 0;
152+
var message = new Buffer([1, (8+channel)<<4, 0]);
153+
154+
spiDevice.transfer( message, message.length, function( error, data ) {
155+
if ( error ) {
156+
console.log( "read error " + error );
157+
} else {
158+
159+
//last 2 bits of 2nd byte, shifted left 8 bits, added to all 8 bits of third byte = 10 data bits.
160+
var val = ((data[1]&3) << 8) + data[2];
161+
//val = data[2];
162+
console.log( "raw data: " + toBin( data[0] ) + " " + toBin( data[1] ) + " " + toBin( data[2] ) );
163+
//console.log( "value: " + val );
164+
165+
// Iterate through all of our socket connections
166+
for ( var socketid in connections ) {
167+
// Get the socket object for this socket
168+
var socket = connections[socketid].socket;
169+
170+
// The "appdata" event will be received by the Coder.socketConnection
171+
// object in the front end code and sent to the appropriate listener
172+
// that we've defined.
173+
// The "buttonupdate" key refers to a listener we set up on the front
174+
// end with the code:
175+
// Coder.socketConnection.addListener( "buttonupdate", function... )
176+
socket.emit( "appdata", {
177+
key: "analogdata",
178+
data: val
179+
});
180+
}
181+
182+
183+
}
184+
});
185+
186+
};
187+
188+
189+
//
190+
// Called by Coder whenever this module is reloaded. This usually happens when
191+
// you save your code in the editor. This is a good place to destroy any intervals
192+
// or clean up any long running code or handles.
193+
//
194+
exports.on_destroy = function() {
195+
if ( spiDevice !== null ) {
196+
disableSPI();
197+
}
198+
199+
};
200+
201+
202+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"created": "2013-11-30",
3+
"modified": "2014-04-02",
4+
"color": "#2ecc71",
5+
"author": "",
6+
"name": "SPI Test",
7+
"hidden": false
8+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
.pagecontent {
3+
padding: 24px;
4+
min-width: 880px;
5+
}
6+
7+
.buttons {
8+
float: left;
9+
width: 240px;
10+
}
11+
.diagram {
12+
width: 640px;
13+
float: left;
14+
padding-bottom: 100px;
15+
}
16+
.clear {
17+
clear: both;
18+
}
19+
20+
.reading {
21+
margin-top: 20px;
22+
}
23+
24+
#buttonval {
25+
width: 200px;
26+
height: 150px;
27+
margin: 24px 0;
28+
color: #fff;
29+
background-color: #000000;
30+
text-align: center;
31+
font-weight: bold;
32+
line-height: 150px;
33+
}
34+
#buttonval.on {
35+
background-color: #F03050;
36+
}
37+
38+
39+
.button {
40+
cursor: pointer;
41+
width: 200px;
42+
height: 150px;
43+
margin: 24px 0;
44+
background-color: #3498D8;
45+
line-height: 150px;
46+
text-align: center;
47+
color: #fff;
48+
font-weight: bold;
49+
}
50+
51+
.button.press {
52+
background-color: #2488A8;
53+
}
54+
55+
56+
#output {
57+
position: fixed;
58+
left:0;
59+
right:0;
60+
bottom:0;
61+
height: 100px;
62+
color: #fff;
63+
background-color: #000;
64+
overflow: hidden;
65+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
///////////////////////
2+
// SPI Test
3+
// Sample code to interact with Raspberry Pi hardware, talk to an
4+
// MCP3008 ADC chip and return the analog value of channel 0.
5+
//
6+
// This part of the code runs in your web browser. It's responsible
7+
// for handling user input from the web browser, sending commands
8+
// to the Raspberry Pi, and listening for updates that the device
9+
// sends back.
10+
//
11+
// The code here communicates with another program that runs directly
12+
// on the Pi (not in your browser). That device-side code can be found
13+
// in the Node tab.
14+
////////////////////////
15+
16+
$(document).ready( function() {
17+
18+
// Connection can take a second. Let the user know what's happening.
19+
addOutputMessage( "Connecting... see the debug console for log messages." );
20+
21+
// This establishes a socket connection to the Coder device. A
22+
// socket conection stays open while the user is viewing this page,
23+
// which allows us to send a receive data very quickly from the device
24+
// instead of checking for updates multiple times a second.
25+
//
26+
// Coder.socketConnection.init takes a callback function that will
27+
// be executed once the connection is established. Anything that
28+
// requires an established connection in order to function
29+
// correctly should be placed in here.
30+
Coder.socketConnection.init(function(){
31+
32+
// Each connection gets a unique ID.
33+
addOutputMessage( "Connected with ID: " + Coder.socketConnection.socketID );
34+
35+
// Send a "connect" message to our Node page when we first connect.
36+
Coder.socketConnection.sendData( 'connect', {} );
37+
38+
39+
40+
Coder.socketConnection.addListener( 'analogdata', function( d ){
41+
console.log("analog value: " + d);
42+
$('#analogdata').text( d );
43+
//addOutputMessage( "Analog value: " + d );
44+
});
45+
46+
47+
48+
});
49+
50+
});
51+
52+
53+
54+
55+
// Append a new P tag to the #output DIV
56+
var addOutputMessage = function( text ) {
57+
var $output = $("#output");
58+
$output.append( $("<p/>").text( text ) );
59+
console.log( text );
60+
};
61+

coder-apps/tests/spi_test/static/media/.gitignore

Whitespace-only changes.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Coder</title>
5+
<meta charset="utf-8">
6+
<!-- Standard Coder Includes -->
7+
<script>
8+
var appname = "{{app_name}}"; //app name (id) of this app
9+
var appurl = "{{&app_url}}";
10+
var staticurl = "{{&static_url}}"; //base path to your static files /static/apps/yourapp
11+
</script>
12+
<link href="/static/apps/coderlib/css/index.css" media="screen" rel="stylesheet" type="text/css"/>
13+
<script src="/static/common/js/jquery.min.js"></script>
14+
<script src="/static/common/ace-min/ace.js" type="text/javascript" charset="utf-8"></script>
15+
<script src="/static/apps/coderlib/js/index.js"></script>
16+
<script>
17+
Coder.addBasicNav();
18+
</script>
19+
<!-- End Coder Includes -->
20+
21+
<!-- This app's includes -->
22+
<link href="{{&static_url}}/css/index.css" media="screen" rel="stylesheet" type="text/css"/>
23+
<script src="{{&static_url}}/js/index.js"></script>
24+
<!-- End apps includes -->
25+
</head>
26+
<body class="">
27+
<div class="pagecontent">
28+
<h1>SPI Test</h1>
29+
<div class="reading">Analog value: <span id="analogdata"></span></div>
30+
<div class="buttons">
31+
</div>
32+
<div class="diagram">
33+
</div>
34+
<div class="clear"></div>
35+
<div id="output">
36+
37+
</div>
38+
</div>
39+
</body>
40+
</html>

0 commit comments

Comments
 (0)