Skip to content

Commit

Permalink
Merge pull request ms-iot#10 from munyirik/master
Browse files Browse the repository at this point in the history
Updates for light sensor
  • Loading branch information
munyirik committed Jan 15, 2016
2 parents 9af92c6 + c54248e commit be19682
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 34 deletions.
4 changes: 2 additions & 2 deletions BigBrain/Node.js/Holobot/routes/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ Bot.prototype.upload = function (dist, res, sendRes) {
}
console.log('Uploading: Distance Moved [%d], Brightness [%d]', dist, brightnessValue);
var options = {
// Uncomment and add host/port values before using this function
// Uncomment and add host value (IP address of server to upload to) before using this function
//host: '',
//port: '',
port: '1338',
method: 'POST'
};

Expand Down
72 changes: 57 additions & 15 deletions BigBrain/Node.js/Holobot/views/drive.jade
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ block content
{
$.ajax({url: '/bot?cmd=upload&dst=' + value});
}

script(type='text/javascript').
function stop()
{
Expand All @@ -47,22 +47,64 @@ block content

h1="B15 Control"

button(onClick=('move(5)')) Forward<br> 5cm
button(onClick=('move(-5)')) Reverse<br> 5cm
button(onClick=('move(10)')) Forward<br> 10cm
button(onClick=('move(-10)')) Reverse<br> 10cm
button(onClick=('move(50)')) Forward<br> 50cm
button(onClick=('move(-50)')) Reverse<br> 50cm

button(onClick=('move(10)')) Go Forward<br> 10cm
button(onClick=('move(-10)')) Go Reverse<br> 10cm
button(onClick=('move(50)')) Go Forward<br> 50cm
button(onClick=('move(-50)')) Go Reverse<br> 50cm
button(onClick=('stop()')) Stop

<br>
button(onClick=('rotate(-15)')) Rotate left<br> 15deg
button(onClick=('rotate(15)')) Rotate right<br> 15deg
button(onClick=('rotate(-15)')) Rotate Left<br> 15deg
button(onClick=('rotate(15)')) Rotate Right<br> 15deg

button(onClick=('rotate(-45)')) Rotate Left<br> 45deg
button(onClick=('rotate(45)')) Rotate Right<br> 45deg

script(type='text/javascript').
// Uncomment and replace X.X.X.X with the IP address of the server with data before using the data buttons
// var server = "http://X.X.X.X:1337";

function getData(response)
{
var atpos = response.lastIndexOf('@');
return response.substr(0, atpos - 1);
}

function getExploreTime()
{
var xhttp = new XMLHttpRequest();
var exploreTimeParagraph = document.getElementById("exploreTimeParagraph");


xhttp.open("GET", server + "/time", true);
xhttp.onreadystatechange = function () {
if (xhttp.readyState === 4) {
exploreTimeParagraph.innerHTML = getData(xhttp.responseText);
}
};
xhttp.send(null);
}

button(onClick=('rotate(-45)')) Rotate left<br> 45deg
button(onClick=('rotate(45)')) Rotate right<br> 45deg
button(onClick=('rotate(-90)')) Rotate left<br> 90deg
button(onClick=('rotate(90)')) Rotate right<br> 90deg
function getAvgBrightness()
{
var xhttp = new XMLHttpRequest();
var avgBrightParagraph = document.getElementById("avgBrightParagraph");

button(onClick=('upload(0)')) Upload<br> Data
xhttp.open("GET", server + "/bright", true);
xhttp.onreadystatechange = function () {
if (xhttp.readyState === 4) {
avgBrightParagraph.innerHTML = getData(xhttp.responseText);
}
};
xhttp.send(null);
}

hr
h1="B15 Data"

button#avgBrightButton(onclick="getAvgBrightness()") Average Brightness
p#avgBrightParagraph
br
button#exploreTimeButton(onclick="getExploreTime()") Exploration Time
p#exploreTimeParagraph
br
69 changes: 52 additions & 17 deletions BigBrain/Node.js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,45 @@ Cylon.robot({
* When the device restarts, COM5 will be available for the app to use.



##Get Bootstrap code
* Download Bootstrap source zip file from http://getbootstrap.com/getting-started/ and unzip to your PC.
* Copy dist\js\bootstrap.min.js to &lt;Repo root&gt;\public\javascripts
* Copy docs\assets\js\vendor\jquery.min.js to &lt;Repo root&gt;\public\javascripts
* Copy dist\css\bootstrap.min.css to &lt;Repo root&gt;\public\stylesheets



#Node.js (ChakraCore) Console Application

###Set up your PC
* Install Node.js (ChakraCore) on your PC from [here](http://aka.ms/nodecc_msi).

###Install npm packages
* Clone this repository and open a command prompt in &lt;Repo root&gt;\BigBrain\Node.js\Holobot.
* Run `npm install` to download npm packages.
* Even though serialport is installed when Johnny-Five or Cylon is installed, you still need to get a version that:
* Run `npm install` to download the npm packages that are needed.

###Get serialport
Even though serialport is installed when Johnny-Five or Cylon is installed, you still need to get a version that:
* Corresponds with the processor architecture of the device you are targeting (in this case ARM for Raspberry Pi 2).
* Includes an [update](https://github.com/voodootikigod/node-serialport/pull/550) for serialport to work on Windows 10 IoT Core.

**Steps to get serialport:**

* Copy and unzip the file [here](http://aka.ms/spcc_zip) to your PC.
* Copy &lt;Unzipped folder&gt;\console\arm\serialport.node to &lt;Repo root&gt;\node_modules\serialport\build\Release\node-&lt;Node version&gt;-win32-arm\serialport.node
* Copy &lt;Unzipped folder&gt;\console\arm\serialport.node to &lt;Repo root&gt;\BigBrain\Node.js\Holobot\node_modules\serialport\build\Release\node-&lt;Node version&gt;-win32-arm\serialport.node
* Copy Node.js (ChakraCore) executable for ARM from [here](http://aka.ms/nodecc_arm) to `c:\Node.js (ChakraCore)` on the Raspberry Pi 2.
* Copy &lt;Repo root&gt;\BigBrain\Node.js\Holobot to `c:\Holobot` on the Raspberry Pi 2.
* In PowerShell, allow Node.js to communicate through the firewall with the following command:

###Copy the app to the Raspberry Pi 2
* Copy &lt;Repo root&gt;\BigBrain\Node.js\Holobot to `c:\Holobot` on the Raspberry Pi 2. You can use [Windows file sharing](http://ms-iot.github.io/content/en-US/win10/samples/SMB.htm),
[PowerShell](http://ms-iot.github.io/content/en-US/win10/samples/PowerShell.htm), or [SSH](http://ms-iot.github.io/content/en-US/win10/samples/SSH.htm) to do this.

###Open up the firewall for Node.js
* In PowerShell window connected to the Raspberry Pi 2, allow Node.js to communicate through the firewall with the following command:
`netsh advfirewall firewall add rule name="Node.js" dir=in action=allow program="C:\Node.js (ChakraCore)\Node.exe" enable=yes`

###Run the app!
* Finally, run `& 'C:\Node.js (ChakraCore)\Node.exe' C:\Holobot\bin\www`
* You can then use the web page `<IP Address of robot>:3000\drive` to move the robot with buttons or build your own app to send custom requests.



#Node.js (Chakra) UWP Application
Expand All @@ -80,20 +95,40 @@ Cylon.robot({
* Install the latest Node.js Tools for Windows IoT from [here](https://github.com/ms-iot/ntvsiot/releases).
* Install [Python 2.7](https://www.python.org/downloads/)


###Deploy Application
###Install npm packages
* Open .\Holobot.sln.
* Right click on the npm node in the Solution Explorer and then select "Install Missing npm Packages(s)".
* Right click on the node_modules folder in the Solution Explorer window. Then click on "Open Command Prompt Here...".
When the command window opens, run `npm dedupe`.
* Even though serialport is installed when Johnny-Five or Cylon is installed, you still need to get a version that:
When the command window opens, run `npm dedupe`. *Don't skip this step*.

###Get serialport
Even though serialport is installed when Johnny-Five or Cylon is installed, you still need to get a version that:
* Corresponds with the processor architecture of the device you are targeting (in this case ARM for Raspberry Pi 2).
* Is UWP (Universal Windows Platform) compatible (built from [this](https://github.com/ms-iot/node-serialport/tree/uwp) fork of serialport).

**Steps to get serialport:**

* Copy and unzip the file [here](http://aka.ms/spc_zip) to your PC.
* Copy &lt;Unzipped folder&gt;\uwp\arm\serialport.node to &lt;Repo root&gt;\node_modules\serialport\build\Release\node-&lt;Node version&gt;-win32-arm\serialport.node
* Copy &lt;Unzipped folder&gt;\uwp\serialport.js to &lt;Repo root&gt;\node_modules\serialport\serialport.js.
* Enter the IP address of the Raspberry Pi 2 in project properties.
* Press F5 to run and debug the application.
* Copy &lt;Unzipped folder&gt;\uwp\arm\serialport.node to &lt;Repo root&gt;\BigBrain\Node.js\Holobot\node_modules\serialport\build\Release\node-&lt;Node version&gt;-win32-arm\serialport.node
* Copy &lt;Unzipped folder&gt;\uwp\serialport.js to &lt;Repo root&gt;\BigBrain\Node.js\Holobot\node_modules\serialport\serialport.js.

###Deploy the app!
* Enter the IP address of the Raspberry Pi 2 in the project properties of Holobot.njsproj.
* Press F5 to run and debug the application.
* You can then use the web page `<IP Address of robot>:3000\drive` to move the robot with buttons or build your own app to send custom requests.



#Uploading light sensor data
You can attach a photoresistor (light sensor) to the Arduino on the Holobot and upload the data to the sample server in this repository.

###Hardware
The hardware required and setup can be found on [this page](https://www.arduino.cc/en/Tutorial/AnalogInput).

###To upload the data:
* In a command prompt, run `node <Repo root>\BigBrain\Node.js\Holobot\server.js`. This will start the server that listens and stores the data being uploaded by the robot.
* In [bot.js](https://github.com/ms-iot/holobot/blob/master/BigBrain/Node.js/Holobot/routes/bot.js):
* Set `doUpload` to true.
* In the upload function, enter the IP address of the host which matches the server you started.
* In [drive.jade](https://github.com/ms-iot/holobot/blob/master/BigBrain/Node.js/Holobot/views/drive.jade):
* Enter the IP address of the server (used in the step above) in the JavaScript code.
Now everytime the robot moves, it will upload the light sensor value to the server. You can use the "Average Brightness" and "Exploration Time" buttons in `<IP Address of robot>:3000\drive` to view the data.

113 changes: 113 additions & 0 deletions BigBrain/Node.js/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
Copyright(c) Microsoft Corp. All rights reserved.
The MIT License(MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

var http = require('http');

var responseCount = 0;
var robotData = [];

function handleDataUpload(data)
{
console.dir(data);
var objData = JSON.parse(data);
robotData.push(objData);
}

function handleUploadRequest(req, res)
{
var body = "";
req.on('data', function (chunk)
{
body += chunk;
});

req.on('end', function ()
{
handleDataUpload(body);

res.writeHead(200);
res.end();
});
}

function formatTime(d)
{
return d.getHours() + ":" + (d.getMinutes() < 10 ? "0" : "") + d.getMinutes() + ":" + d.getSeconds() + "." + d.getMilliseconds();
}

function handleRequest(req, res)
{
console.log(req.url);
var responseCode = 204;
if(robotData.length === 0)
{
res.writeHead(responseCode, { 'Content-Type': 'text/plain' });
res.write("No robot data yet.\n");
console.log("No robot data yet");
res.end();

return;
}

var responseStr = "";
var timeStamp = formatTime(new Date()) + "-#" + (responseCount++);

switch(req.url)
{
case "/time":
{
var startTime = robotData[0].sampleTime;
var endTime = robotData[robotData.length - 1].sampleTime;

responseCode = 200;
responseStr = "Samples collected between " + formatTime(new Date(startTime)) + " and " + formatTime(new Date(endTime));
break;
}
case "/bright":
{
var totalBrightness = 0;
for(var i = 0; i < robotData.length; ++i)
{
totalBrightness += robotData[i].brightness;
}

responseCode = 200;
responseStr = "Average brightness is " + (totalBrightness / robotData.length);
break;
}
default:
{
responseStr = "Error unknown data request " + req.url;
break;
}
}

res.writeHead(responseCode, { 'Content-Type': 'text/plain', 'Cache-control': 'no-cache', 'Access-Control-Allow-Origin': '*' });
res.write(responseStr + " @" + timeStamp + "\n");
res.end();
}

var server = http.createServer(handleRequest);
server.listen(1337);

var upServer = http.createServer(handleUploadRequest);
upServer.listen(1338);

0 comments on commit be19682

Please sign in to comment.