How to use Geospatial Indexing in mongo using nodejs and mongoose

A couple of weeks ago I build a mobile app for school that shows you cultural stuff todo around you. It’s called randomapp (the assignment was to build an app using the Artsholland API. Therefor it only works in the Netherlands).

I’ve decided to build the backend in Mongo because of the recently added support for geospatial. I’ve got more experience in MySQL but the idea of having to write all the logic involved with querying location data myself alone was enough for me to choose for Mongo.

The backend for the app is a very simple API written in Node to query the Mongo collection location data. In this tutorial I’ll show you how some easy steps to get started asking Mongo questions about locations. I definitely recommend you check out the official documentation which covers everything I’m about to explain plus a lot more. Though this tutorial is more of an introduction to the subject.

more

How to control your HTML5 game using Arduino

Yesterday I made a mini HTML5 game based on the retro game Asteroids (here is a flashversion) without the asteroids, so I just made a ship with those controls. You can check it out on my personal site and the code is at my Github.

What about instead of using the keyboard for controls, using a potentiometer for the controls? Here is a video with me explaining it (the demo is at 8:30 into the video).

Here is the code to get it working:

The arduino code is straight from the node duino module. Read more about it in my article about duino.

Nodejs script

dependencies: node, duino, socket.io

var l = console.log;

var http = require('http');
var url  = require('url');

var io = require('socket.io').listen(1337);
io.set('log level', 1);

var arduino = require('duino');
var board = new arduino.Board({
  // debug: true
});
// defaults to a01
var pot = new arduino.Sensor({
  board: board,
});
var init = function() {
  broadcast();
}
board.on( 'ready', function() {
  // still not ready somehow
  setTimeout( init, 100 );
});

HTML file

<?php 
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: *");
    header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
?>
<!doctype html>
<!--#

          Insert coin(s)

    &lt;Push any button to start&gt;

-->
<html lang=en>
    <head>
        <meta charset=utf-8>
        <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
        <title>ardiono game</title>
        <style>
            body {
                background-color:black;
            }
            #game {
              position: absolute;
              top: 0px;
              left: 0px;
              z-index: -1;
            }
        </style>
    </head>
    <body>
        <canvas id=game></canvas>
        <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js">
        <script src="game.js"></script>
    </body>
</html>
<!--#

    GAME OVER

front end javascript (game)

(function(d, c){
  //helpers
  var getHeight = function() {
    var D = document;
    return Math.max(
        Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
        Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
        Math.max(D.body.clientHeight, D.documentElement.clientHeight)
    );
  };
  var getWidth = function() {
    var D = document;
    return Math.max(
        Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),
        Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),
        Math.max(D.body.clientWidth, D.documentElement.clientWidth)
    );
  };
  // polyfill: set the window.requestAnimationFrame to the browsers specific version.
  (function() {
    var lastTime = 0
      , vendors = ['ms', 'moz', 'webkit', 'o']
      , x
      , length
      , currTime
      , timeToCall;

for(x = 0, length = vendors.length; x < length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = 
      window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
        currTime = new Date().getTime();
        timeToCall = Math.max(0, 16 - (currTime - lastTime));
        lastTime = currTime + timeToCall;
        return window.setTimeout(function() { callback(currTime + timeToCall); }, 
          timeToCall);
    };
if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
        clearTimeout(id);
    };

}());
  var angle = 0;
  // socket io hook
  var socket = io.connect('http://localhost:1337');
   socket.on('news', function (data) {
     // console.log(data.v);
     angle = data.v / 1024 * 8;
   });

var canvas = document.getElementById("game");
  canvas.height = getHeight();
  canvas.width = getWidth();
  // draw function is in a closure
  var draw = (function() {
    var PI = Math.PI
      , twoPI = PI * 2
      , speed = 5
      , shipX = 100
      , shipY = 100
      , degrees
      , cap = function( n, cap ) {
        return n < 0 ? n + cap : n % cap;
      }
    return function() {
      // clear the stage
      ctx.clearRect( 0, 0, canvas.width, canvas.height );
      ctx.save();
      // calc new position
      shipX += Math.sin( angle ) * speed;
      shipY -= Math.cos( angle ) * speed;
      shipX = cap( shipX, canvas.width );
      shipY = cap( shipY, canvas.height );
      // draw the changes
      // position
      ctx.translate( shipX, shipY );
      // rotate
      ctx.rotate( angle );
      // draw
      ctx.beginPath();
      ctx.fillStyle   = 'white';
      ctx.strokeStyle = 'white';
      // ship
      ctx.lineTo(0, -15);
      ctx.lineTo(10, 15);
      ctx.lineTo(0, 13);
      ctx.lineTo(-10, 15);
      // finish
      ctx.fill();
      ctx.stroke();
      ctx.closePath();
      ctx.restore();
    }
  })();
  if( canvas.getContext ) {
    var ctx = canvas.getContext("2d");
    // the loop
    (function animloop(){
        requestAnimationFrame( animloop );
        draw();
      })();
  }

Introduction to Node.js and what I find so great about it

My knowledge of the inner workings of node.js and threading is pretty basic. I can’t guarantee everything written here is accurate. If you spot an error, please let me know!

I’ve been playing around with Node.js for a while now and even though the community behind it is getting bigger, there are a lot of people disliking a lot of things about Node.js. In this post I will explain some of the different inner workings and what I like about them.

I hear you ask yourself: “Why Javascript?”. Even though a lot of people think Javascript is slow, it’s not so bad actually. Note that a lot of things that make it slow in the browser (like the really slow DOM api) are non existent on the server.

From the Node.js homepage:

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Node.js allows you to write your server side scripts in javascript. The V8 engine of Google (which is also a part of Chrome, and is one of the big reasons on why Chrome is so fast) will take your javascript scripts and compile them on the fly to machine code.

But the thing that is most different from Node to traditional server sided languages for doing web stuff is the way it works.

more

How to connect your Arduino to nodejs using duino

In this video I’ll explain how to set up your Arduino and Duino so you can interact with your Arduino using nodejs (and javascript).

  • The Arduino software package is downloadable from the Arduino website.
  • You can find the Duino module here.
  • Installing Duino is as simple as running npm install duino.
  • My custom bleep function:

    var arduino = require(‘duino’),

    board = new arduino.Board();
    

    var led = new arduino.Led({ board: board, pin: 13 });

    var bleep = function() {

    led.on();
    setTimeout(function() {
        led.off();
    }, 100);
    

    }

Troubleshooting:

  • You need a recent version of nodejs (0.4.x was not working) for the Duino module.
  • If you can’t upload the Arduino program, make sure the right model is selected at Tools -> Board.

Visualizing our running progress

You’ve found a dinosaur, this post is only here for archiving purposes. The content is outdated and is not applicable anymore.

While I was running a couple of weeks back I was thinking about Nike’s new slogan for it’s Nike+ campaign. “Make it count!” it says, but for what? So I hacked up a little website that fetches all tweets send by the Nike+ app and bundles all our runs together per hour.

Make it count! is the result. It holds a realtime visualisation which displays all runs reported by Twitter as circles. Big circles are big runs, etc.. You can also see the top hour of today (since midnight GMT). Every hour get’s a score and our goal is to top that score every hour!

The site is built almost entirely in javascript, node.js catches all tweets and sends them over realtime by using web sockets (socket.io). You can read more about that in my previous blogpost.

The site does need some improvement in the design, I’ve already talked to some people about helping me out here. So stay tuned for even more awesomeness!