This project will run on the Intel Edison and incorporate the following elements:
1) MRAA / UPM libraries from Intel to run a LCD screen and stepper motor driver
2) Twit – a Twitter API client written for Node.js
3) Google Maps API
4) Node-geolocation – A geolocation client written for Node.js
5) Socket.io – a JavaScript real-time communication library
6) Express.js – a web application server framework for JavaScript
We will step through combining these elements to create a real time Twitter monitor that will react to specific hashtags, display information on an LCD, move the stepper motor, and display the location, user and tweet text on a website served by the Intel Edison.
Assemble the hardware:Assemble the Edison as shown:
1) Insert the sensor shield into the Arduino breakout board
2) Plug the LCD into one of the I2C ports, all of them will work
3) Plug the stepper motor into the stepper motor driver board
4) Insert the jumper wires into the stepper motor driver:
5) Insert the jumper wires from IN1, IN2, IN3, IN4 into GPIOs 8,9,10,11 – you must match these to have the stepper motor work
6) Insert the jumper wire from GND to the GND pin and the jumper wire from VCC into the 5V pin – once again make sure you match these pins
At the start of the tutorial you saw a photo of the setup that was made for this project. You are encouraged to create your own version! I found that a ziptie works really well to attach things to the stepper motor stem:
In order to read from the Twitter stream you will have to create a Twitter App and get API keys that you will insert into your code. Follow the tutorial at: https://dev.twitter.com/oauth/overview/application-owner-access-tokens
For more information on the streaming Twitter API see: https://dev.twitter.com/streaming/overview
Create Google Maps API tokens:In order to incorporate Google maps into your project and use the Google Geolocation service (translate city names into longitude and latitude coordinates) you will have to set up a google dev account and generate API keys. Go to the following link and follow the quick start steps halfway down the page: https://developers.google.com/maps/documentation/javascript/
Load the Code:We will be using the Intel XDK IoT Edition to program the Intel Edison for the rest of the tutorial. First you will load the XDK project into the XDK. Open the XDK, navigate to the project tab, and click “Open an Intel XDK Project
”. Navigate to the project folder you received and select TwitterDogs.xdk
. Your project folder should now contain a main.js
and package.json
as well as a folder called public containing index.html
and script.js
.
If you want to use another IDE, transfer the code to the Edison using Filezilla or something similar. You will also have to run "npm install
" through the Edison console in order to install the npm packages needed.
Now that you have the API tokens generated and code loaded onto the Edison you need to go through and add your tokens.
1) In main.js line 12: Replace with your Google API key...here
2) In main.js line 33-36: Replace the Twitter API placeholders with the appropriate keys.
3) In /public/index.html
line 22: Replace with your Google API key
In main.js on lines 4 and 5 the variables dog1
and dog2
set the hashtags that are searched for in the twitter stream. Change these to reflect your project.
Click upload and wait for the npm packages to be installed. When the console shows “Upload Done
” click run to launch the project. If asked select “Upload and Run
”.
If you are running a different IDE launch the code from the Edison command line with "node main.js
".
Once the script is running navigate to port 3000 at your Intel Edison IP - This can be found by entering ifconfig
in the Edison console. In my case the Edison was assigned 192.168.1.66
so I would navigate to 192.168.1.66:3000
in my browser.
Here you will see the Google Map front end that will display the location, name, and tweet text of any tweets that use the hashtags you specified.
Whenever dog1
gets a tweet the stepper will move counter clockwise 50 steps and the LCD will display the running total for both dogs. dog2
tweets will move the stepper 50 steps in clockwise direction. When one of the dogs gets 10 tweets the LCD changes color to green and displays the winner.
Below I will describe the code in greater detail in order to help you understand and modify it to fit your project.
Stepper and LCDThe stepper and LCD are controlled using the UPM library which is a higher level abstraction of MRAA library, more info can be found here: https://github.com/intel-iot-devkit/upm
In main.js:
- Import the modules for the LCD and Stepper with require('jsupm_uln200xa') and require('jsupm_i2clcd').
- Instantiate the Stepper object with new Uln200xa_lib.ULN200XA(4096, 8, 9, 10, 11) – 4096 is the steps per revolution and 8,9,10,11 are the pins.
- Create functions for myUln200xa_obj.forward, myUln200xa_obj.reverse, and myUln200xa_obj.stop – change the speed with myUln200xa_obj.setSpeed(x).
- Instantiate the LCD object with new lcd.Jhd1313m1(0, 0x3E, 0x62) – leave these as is.
- The behavior of the LCD for each tweet hashtag is hard coded with display.setColor , display.setCursor, and display.write commands inside each if loop.
- The behavior of the stepper is also hard coded inside each if loop with myUln200xa_obj.forward, myUln200xa_obj.reverse, and myUln200xa_obj.stop calls. NOTE: The dog_side variable is in place to record what side the arrow is on.
- When dog1_tweets or dog2_tweets reaches 10 total the victory condition is triggered with a display.write("Is cutest dog!").
NOTE: The way that the stepper library is written makes the process a BLOCKING process. This means that the main loop will be blocked while the stepper is running. Essentially this means that while the motor is moving the script will not read in new tweets.
Twitter APITo interface with the Twitter API the project leverages the npm twit module. This is simply a node.js client for the Twitter API.
In main.js:
- Import the twit module with var Twit = require('twit').
- var T = new Twit({…}) creates a new twit object with your specific API keys.
- var stream = T.stream(…) creates a new twitter stream that monitors for dog1 and dog2 hashtags.
- if (text_body.toLowerCase().indexOf(dog1) != -1) starts the if loop for tweets containing a dog1 hashtag, similarly for dog2.
- tweet.user['location'], tweet.user['name'], tweet['text'] – the location, name, and tweet body are fed into the get_coord geolocation function along with the emitsocket as a callback.
Express.js is an server application framework that serves the webpage displaying the Google Map.
In main.js:
- Import the module with var express = require('express').
- Start the express app with var app = express().
- app.use(express.static('/home/root/.node_app_slot/public/')) sets the directory where the public files to be served are located. NOTE: the .node_app_slot is specific to the Intel Edison file structure. If you run the script from a different folder the absolute path will have to be changed.
- app.get('/', function(req, res) {…}) serves the index.html page whenever a get request is received at the root URL.
- server.listen(3000, function() {…}) starts the http server listening on port 3000 of the localhost.
Socket.io is a real time communication protocol that is used to pass the tweet data between main.js that runs on the Edison runtime and public/script.js which runs in the browser runtime and renders the Google Map.
In main.js:
- import the socket package and create a socket.io server object with var io = require('socket.io')(server).
- The function emitsocket is defined and contains io.emit('location', {..}) which emits the JSON { lat: tweet_lat …} to the location event. Socket.io listens for a location event to be emitted on the client side app.
- io.on('connection', function(socket) {…}) opens the socket.io connection.
In script.js:
- socket.on('location', function (data) {…}) listens for a location event and streams data from the server side app to the Google Maps API.
In order to create a map front end Google Maps API is leveraged.
In index.html:
- Indicates where the map is displayed on the page.
In order to get latitude and longitude coordinates from the city name supplied by the Twitter API.
In main.js:
- var geocoderProvider = 'google' , var httpAdapter = 'https', and var extra = {…} set the variables to be used in creating the node-geolocation object. Enter you Google Maps API key in apiKey: “…”.
- var geocoder = require('node-geocoder')(geocoderProvider, httpAdapter, extra) creates the geocoder object with the defined variables.
- geocoder.geocode(location, function(err, res) {…} uses the location sent by the tweet API to find latitude and longitude with res[0].latitude and res[0].longitude.
Comments