{"id":1170,"date":"2015-09-16T12:29:10","date_gmt":"2015-09-16T16:29:10","guid":{"rendered":"http:\/\/blog.agilityfeat.com\/?p=1170"},"modified":"2015-09-16T12:29:10","modified_gmt":"2015-09-16T16:29:10","slug":"webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five","status":"publish","type":"post","link":"https:\/\/agilityfeatpanama.com\/en\/blog\/2015\/09\/webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five\/","title":{"rendered":"WebRTC Arduino DC Motor Control using PubNub, Electron, and Johnny-Five"},"content":{"rendered":"<p><script src=\"https:\/\/s3-us-west-2.amazonaws.com\/blogs-scripts\/util\/code-scripts-1.js\"><\/script><\/p>\n<p><script src=\"https:\/\/platform.vine.co\/static\/scripts\/embed.js\"><\/script><\/p>\n<p>A few weeks ago I wrote a post on how to use an Arduino to control a DC motor&#8217;s speed and direction as part of an on-going project of building a WebRTC controlled webcam. <\/p>\n<p>This week we&#8217;re taking that same build to the next level by adding the ability to control last week&#8217;s build remotely, and in real-time, using WebRTC.<\/p>\n<p>This IOT project will consist of a client coded on Electron (previously atom shell), and a NodeJS server to handle communications with PubNub&#8217;s implementation of WebRTC tying it all together.<\/p>\n<p>By dragging a slider left or right on our client, we&#8217;ll send to the server the direction in which the motor should spin, and depending on how far from the center of the slider we go, it will determine the speed value we will send to the server as well.<\/p>\n<p>For our server to be able to communicate with the Arduino board we are going to need a NodeJS library which allows for such abstractions, luckily, there&#8217;s an npm package called Johnny-Five which does just that.<\/p>\n<h2>Test code for Johnny-Five in NodeJS<\/h2>\n<p>To get started, as a proof of concept, I took the Arduino code I had originally used in Part I of this project and translated it into Johnny-Five. <\/p>\n<p>This is what the original code looked like:<\/p>\n<p>And after some trial and error I ended up with this code based on Johnny-Five&#8217;s API:<\/p>\n<pre><code class=\"javascript\">var five = require(\"johnny-five\");\nvar board = new five.Board();\n\nboard.on(\"ready\", function() {\n  \/\/pin 8 = direction\n  \/\/pin 11 = enable\n  this.pinMode(8, five.Pin.OUTPUT);\n  this.pinMode(11, five.Pin.PWM);\n  \n  back_n_forth(this);\n});\n\nfunction back_n_forth(target_board){\n  target_board.digitalWrite(8, 1);\/\/forward\n  target_board.analogWrite(11, 30);\/\/~12% PWM\n  \n  target_board.wait(2000,function(){\n    target_board.analogWrite(11, 0);\/\/turn enable pin off\n    \n    target_board.wait(1000,function(){\n      target_board.digitalWrite(8, 0);\/\/backward\n      target_board.analogWrite(11, 30);\/\/~12% PWM\n      \n      target_board.wait(2000,function(){\n        target_board.analogWrite(11, 0);\/\/turn enable pin off\n        \n        target_board.wait(1000,function(){\n          back_n_forth(target_board);\/\/loop\n        });\n      });\n    });\n  });\n}<\/code><\/pre>\n<p>It&#8217;s worth noting that Johnny-Five&#8217;s abstraction deviates quite a bit from Arduino&#8217;s original API. Especially the way loops are treated. In Johnny-Five, loops are more like intervals in that they have a set time in milliseconds for each iteration, which is why I ended up using this tree-like <code>wait<\/code> structure.<\/p>\n<p>In order to run the previous code, simply save it as <code>back_n_forth.js<\/code> and from your console, in the directory where the file is saved run the following:<\/p>\n<pre><code>npm install johnny-five\nnode back_n_forth.js<\/code><\/pre>\n<p>Just as in the previous installment of this tutorial, you should see this:<\/p>\n<p><script src=\"https:\/\/googledrive.com\/host\/0B6AfIBZThEJzfks0dFpJM19NNzA3VFg5THJFUFVYSDIxNnNyNi11STFacEtMWHRSWm9ZME0\/youtube-2015-08-001.js\"><\/script><\/p>\n<h2>Arduino controller server using NodeJS and PubNub&#8217;s WebRTC SDK<\/h2>\n<p>I have used PubNub&#8217;s implementation of WebRTC in a few projects before, including my <a href=\"http:\/\/goo.gl\/kuIxuQ\" target=\"_blank\" rel=\"noopener noreferrer\">Applying Effects to WebRTC Video in Real Time<\/a> tutorial.<\/p>\n<p>The original SDK can be found at:<\/p>\n<p><a href=\"https:\/\/github.com\/stephenlb\/webrtc-sdk\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.<\/a><\/p>\n<p>In order to use it with NodeJS for this project I had to go ahead and make the following npm package:<\/p>\n<p><a href=\"https:\/\/github.com\/jeanlescure\/node-pubnub-webrtc\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/jeanlescure\/node-pubnub-webrtc<\/a><\/p>\n<p>To get started creating our NodeJS server we&#8217;ll need the following files:<\/p>\n<ul>\n<li><code>package.json<\/code><\/li>\n<li><code>server.js<\/code><\/li>\n<\/ul>\n<p>In our <code>package.json<\/code> we&#8217;ll need <strong>at least<\/strong> the following:<\/p>\n<pre><code class=\"javascript\">{\n  \"name\": \"WebRTC-Arduino-Motor-Server-Demo\",\n  \"version\": \"0.0.1\",\n  \"description\": \"Some description...\",\n  \"dependencies\": {\n  }\n}<\/code><\/pre>\n<p><a href=\"http:\/\/browsenpm.org\/package.json\" target=\"_blank\" rel=\"noopener noreferrer\">Here&#8217;s a pretty neat interactive guide to <code>package.json<\/code> files.<\/a><\/p>\n<p>And to add the dependencies to our package we run:<\/p>\n<pre><code>$ npm install --save johnny-five\n...\n$ npm install --save node-pubnub-webrtc<\/code><\/pre>\n<p>Now that we are sure that our package and its dependencies are good to go we move on to the <code>server.js<\/code> file:<\/p>\n<p>First we instantiate our webrtc PubNub phone:<\/p>\n<pre><code class=\"javascript\">var phone = require('node-pubnub-webrtc')({\n  number        : 'pubduino.server',\n  publish_key   : PUBLISH_KEY,\n  subscribe_key : SUBSCRIBE_KEY,\n  ssl           : true\n});<\/code><\/pre>\n<p>Next we need access to the arduino board, so just as before, using johnny-five:<\/p>\n<pre><code class=\"javascript\">var five = require(\"johnny-five\");\nvar board = new five.Board();<\/code><\/pre>\n<p>A couple of global variables to communicate speed and direction between the <code>phone<\/code> and the <code>board<\/code>:<\/p>\n<pre><code class=\"javascript\">var direction = 0;\nvar speed = 0;<\/code><\/pre>\n<p>Here&#8217;s the code for the board where we see how easy it is to digest the direction and speed values:<\/p>\n<pre><code class=\"javascript\">board.on(\"ready\", function() {\n  \/\/pin 8 = direction\n  \/\/pin 11 = enable\n  this.pinMode(8, five.Pin.OUTPUT);\n  this.pinMode(11, five.Pin.PWM);\n  board.loop(250,function(){\n    board.digitalWrite(8, direction);\n    board.analogWrite(11, speed);\n  });\n});<\/code><\/pre>\n<p>And to add the cherry on top of our server code, the WebRTC implementation which grabs the direction and speed values off of a JSON we&#8217;ll be sending using the <code>RTCDataChannel<\/code>:<\/p>\n<pre><code class=\"javascript\">phone.message(function(session, message){\n  has_direction = (typeof message.direction !== 'undefined');\n  has_speed = (typeof message.speed !== 'undefined');\n  if (has_direction && has_speed){\n    if (message.speed >= 0 && message.speed <= 255){\n      direction = (message.direction) ? 1 : 0;\n      speed = message.speed;\n    }\n  }\n});<\/code><\/pre>\n<p>Easy as pie!<\/p>","protected":false},"excerpt":{"rendered":"<p>A few weeks ago I wrote a post on how to use an Arduino to control a DC motor&#8217;s speed and direction as part of an on-going project of building a WebRTC controlled webcam. This week we&#8217;re taking that same build to the next level by adding the ability to control last week&#8217;s build remotely, [&hellip;]<\/p>","protected":false},"author":11,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":""},"categories":[57],"tags":[148,117],"jetpack_featured_media_url":"","yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v15.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>WebRTC Arduino DC Motor Control using PubNub, Electron, and Johnny-Five - AgilityFeat Panama Software Test Center<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/agilityfeatpanama.com\/en\/blog\/2015\/09\/webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WebRTC Arduino DC Motor Control using PubNub, Electron, and Johnny-Five - AgilityFeat Panama Software Test Center\" \/>\n<meta property=\"og:description\" content=\"A few weeks ago I wrote a post on how to use an Arduino to control a DC motor&#8217;s speed and direction as part of an on-going project of building a WebRTC controlled webcam. This week we&#8217;re taking that same build to the next level by adding the ability to control last week&#8217;s build remotely, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/agilityfeatpanama.com\/en\/blog\/2015\/09\/webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five\/\" \/>\n<meta property=\"og:site_name\" content=\"AgilityFeat Panama Software Test Center\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-16T16:29:10+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"4 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/34.200.113.64\/#website\",\"url\":\"https:\/\/34.200.113.64\/\",\"name\":\"AgilityFeat Panama Software Test Center\",\"description\":\"AgilityFeat Panama offers customized, multilevel web and mobile software testing for a variety of industries.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/34.200.113.64\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/agilityfeatpanama.com\/blog\/2015\/09\/webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five\/#webpage\",\"url\":\"http:\/\/agilityfeatpanama.com\/blog\/2015\/09\/webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five\/\",\"name\":\"WebRTC Arduino DC Motor Control using PubNub, Electron, and Johnny-Five - AgilityFeat Panama Software Test Center\",\"isPartOf\":{\"@id\":\"https:\/\/34.200.113.64\/#website\"},\"datePublished\":\"2015-09-16T16:29:10+00:00\",\"dateModified\":\"2015-09-16T16:29:10+00:00\",\"author\":{\"@id\":\"https:\/\/34.200.113.64\/#\/schema\/person\/c34873e9bee22a4aab19b8a0e800aad0\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/agilityfeatpanama.com\/blog\/2015\/09\/webrtc-arduino-dc-motor-control-using-pubnub-electron-and-johnny-five\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/34.200.113.64\/#\/schema\/person\/c34873e9bee22a4aab19b8a0e800aad0\",\"name\":\"Jean\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/34.200.113.64\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"caption\":\"Jean\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/posts\/1170"}],"collection":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/comments?post=1170"}],"version-history":[{"count":0,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/posts\/1170\/revisions"}],"wp:attachment":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/media?parent=1170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/categories?post=1170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/tags?post=1170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}