{"id":1626,"date":"2019-10-07T17:00:20","date_gmt":"2019-10-07T17:00:20","guid":{"rendered":"https:\/\/bitcows.com\/?p=1626"},"modified":"2024-05-10T17:58:56","modified_gmt":"2024-05-10T17:58:56","slug":"alexa-controlled-matrix","status":"publish","type":"post","link":"https:\/\/bitcows.com\/?p=1626","title":{"rendered":"Amazon Alexa and Blynk Controlled Neopixel Matrix"},"content":{"rendered":"<style>img{border:1px solid #ccc;}<\/style>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/alexa-e1570468072869-761x1024.jpg\" alt=\"\" width=\"761\" height=\"1024\" class=\"alignnone size-large wp-image-1711\" \/><\/p>\n<h2>\nPrerequisites<br \/>\n<\/h2>\n<p>&#8211; Basic understanding of Node.js<br \/>\n&#8211; AWS Account (this is easy)<br \/>\n&#8211; Blynk.io account<br \/>\n&#8211; Amazon Echo<br \/>\n&#8211; DC5V LED WS2812B panel (found on ebay)<\/p>\n<h2>\nBlynk.io<br \/>\n<\/h2>\n<p>The first thing you will want to do is <a href=\"https:\/\/blynk.io\/en\/getting-started\" rel=\"noopener noreferrer\" target=\"_blank\">sign up for a blynk account<\/a>. This is a great place to allow you to connect of hundreds of IoT device including ESP32, ESP8266, Arduino and <a href=\"https:\/\/github.com\/blynkkk\/blynkkk.github.io\/blob\/master\/SupportedHardware.md\" rel=\"noopener noreferrer\" target=\"_blank\">much much more<\/a>.<\/p>\n<p>Once you have done that you will have a Auth Token that you will need to connect to your device. For more on what this site can do for you there is a ton of <a href=\"https:\/\/examples.blynk.cc\" rel=\"noopener noreferrer\" target=\"_blank\">example code<\/a> and <a href=\"http:\/\/docs.blynk.cc\/#intro-how-blynk-works\" rel=\"noopener noreferrer\" target=\"_blank\">documentation<\/a> on there. <\/p>\n<p>They also have a <a href=\"https:\/\/blynkapi.docs.apiary.io\" rel=\"noopener noreferrer\" target=\"_blank\">ReST API<\/a> that you can use to call your sketches with. This is how we will be connecting our Alexa skill to our code. (more on that later).<\/p>\n<h2>\nAlexa Skill<br \/>\n<\/h2>\n<p>To create an Alexa Skill you will need an <a href=\"https:\/\/developer.amazon.com\/alexa\/console\/ask\" rel=\"noopener noreferrer\" target=\"_blank\">account<\/a>. Sign up or sign in and proceed to the Alexa Developer Console. Once you are there you will need to create a new skill (Create Skill button).<\/p>\n<p>You&#8217;ll need to next name your skill. I named mine Light Frame but you can name it what ever you like. Choose the custom model and continue. The we will choose the &#8220;Start from scratch&#8221; template and continue.<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-2.02.03-PM.png\" alt=\"\" width=\"300\" class=\"alignnone size-full wp-image-1649\"style=\"float:left;margin-right:10px\" \/><img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-2.03.08-PM.png\" alt=\"\" width=\"300\" class=\"alignnone size-full wp-image-1650\" style=\"float:left\"\/><\/p>\n<div style=\"clear:both\">\nNow you have the basic framework for an Alexa Skill. There are tons of <a href=\"https:\/\/developer.amazon.com\/en-US\/alexa\/alexa-skills-kit\/resources\/training-resources\/cake-walk\/cake-walk-3\" rel=\"noopener noreferrer\" target=\"_blank\">example<\/a> of how to make an Alexa skill so I&#8217;m not going to take a deep dive into that. I would encourage you to <a href=\"https:\/\/lmgtfy.com\/?q=how+to+create+an+alexa+skill\" rel=\"noopener noreferrer\" target=\"_blank\">search<\/a> for those if you. <\/p>\n<p>How we are going to make this skill is you can simply copy my JSON code into your skill. <a href=\"https:\/\/gist.github.com\/djmason9\/3f02f3b518192d11ffeca9109116cbae#file-alexa-skill-json\" rel=\"noopener noreferrer\" target=\"_blank\">Start by copying this code<\/a>.<\/p>\n<p>Basically this is all the code that is needed to make a fully formed Alexa Skill. You will want to look for the JSON Editor and paste that code into it.<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-2.19.31-PM-428x1024.png\" alt=\"\" width=\"300\" class=\"alignnone size-large wp-image-1667\" \/><br \/>\nMake sure you hit Save Model at the top of the screen. Then click on the build tab at the top of the screen. This should bring you back to the home page.\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-2.23.35-PM-300x269.png\" alt=\"\" width=\"300\" height=\"269\" class=\"alignnone size-medium wp-image-1670\" \/><br \/>\nYoure going to want to make sure all those check boxes are green. To do this you have to click on each one that is gray. The build does just that, it builds your project. The end point is where you are going to connect to your Lambda. Lets click on the Endpoint box and go to where we will link our Lambda. For this we will want to choose the radio button AWS Lambda ARN you should now see your alexa skill id (something like this: <code>amzn1.ask.skill.7dad778f-30b2-4c88-b48e-dc9dc1bc2f6b<\/code>) Copy that or save hold on to it somewhere.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-2.27.39-PM-300x165.png\" alt=\"\" width=\"300\" height=\"165\" class=\"alignnone size-medium wp-image-1672\" \/><br \/>\nNow lets make our Lambda. Open a new tab in your browser to do this becasue we have to jump back and forth from Alexa skill to Lambda so we can put in the correct endpoint and Id information. <\/p>\n<h2>\nAWS Lambda Code<br \/>\n<\/h2>\n<p>Next we need to set up an <a href=\"https:\/\/console.aws.amazon.com\" rel=\"noopener noreferrer\" target=\"_blank\">AWS Account<\/a>. Theres nothing much to this just sign up its free and the Lambda&#8217;s are free to use (within reason).<\/p>\n<p>Once you get your account set up you will need to go to the console and filter down to the Lambda functions.<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-1.48.17-PM-1024x755.png\" alt=\"\" width=\"300\" class=\"alignnone size-large wp-image-1639\" \/><\/p>\n<p>Once you are there you should see a Create function button<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-1.49.11-PM.png\" alt=\"\" width=\"300\"  class=\"alignnone size-full wp-image-1641\" \/><\/p>\n<p>Choose Author from scratch, give your function a name and keep the default Node version.<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-1.51.06-PM-1024x991.png\" alt=\"\" width=\"300\"  class=\"alignnone size-large wp-image-1644\" \/><\/p>\n<p>Once you are done with that you will want to add a trigger. You should see that <code>+ Add trigger<\/code> button on the left side of the screen. Click that and locate the Alexa Skill Kit. Choose that and under the Skill Id you will want to put the Id of your Skill you created. (see above something like this: <code>amzn1.ask.skill.7dad778f-30b2-4c88-b48e-dc9dc1bc2f6b<\/code> remember?)<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-06-at-1.53.14-PM-1024x815.png\" alt=\"\" width=\"300\" class=\"alignnone size-large wp-image-1646\" \/><\/p>\n<p>Once thats done you can put your ARN endpoint into your Alexa skill you should see it at the top left of the screen (looks like this: <code>arn:aws:lambda:us-east-1:27971444449:function:MyNeopixelFrame<\/code>) So hope back over to your Alexa tab and put it in the Endpoint Default Region input field, then save the endpoint.<\/p>\n<p>Ok for now we will just leave the default code there because for this we will be writing all the code on our local machine zipping it up and putting it on the Lambda. <\/p>\n<h2>\nWriting the Lambda Locally<br \/>\n<\/h2>\n<p>For this I recommend <a href=\"https:\/\/github.com\/djmason9\/AlexaEnableNeopixelMatrix\" rel=\"noopener noreferrer\" target=\"_blank\">downloading the git project<\/a> and opening the index.js file.<\/p>\n<p>There is really only two files that matter here. The <code>index.js<\/code> and the <code>package.json<\/code> file. Lets start with the easy one package.json. This file containts two things we need the alxea core and the alexa model. Add those and do an <code>npm install<\/code> and thats it. <\/p>\n<pre class=\"prettyprint\">{\n  \"name\": \"alexa-skill-kit-sdk-neopixel\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"ask-sdk-core\": \"^2.7.0\",\n    \"ask-sdk-model\": \"^1.19.0\"\n  }\n}<\/pre>\n<p>Next we can look at the index.js. This file is mostly a <a href=\"https:\/\/github.com\/alexa\/skill-sample-nodejs-first-skill\/blob\/master\/module-1\/index.js\" rel=\"noopener noreferrer\" target=\"_blank\">boilerplate skill<\/a> so we will only look at the important stuff.<\/p>\n<p>This function is the custom function we made in our skil under Intents called <code>NeoINtent<\/code> Basically we are looking to see if our intent was called. &#8220;Alexa ask light frame to blah blah.. &#8221; you get it. The important thing to notice here is the <code>async<\/code> handler. This allows us to call an API and wait for it to return results before Alexa returns a response to the person asking for the task. This <code>async<\/code> <code>await<\/code> is a javascript <code>promise<\/code>. Its like a fancy callback basically. You will notice in the <code>makeRequest<\/code> function there is a <code>new Promise<\/code> created. Once this function is called the calling function &#8220;awaits&#8221; its response. It will either resolve or reject the request. <\/p>\n<pre class=\"prettyprint\">const NeoIntentHandler = {\n    canHandle(handlerInput) {\n        return handlerInput.requestEnvelope.request.type === 'IntentRequest'\n            && handlerInput.requestEnvelope.request.intent.name === 'NeoIntent';\n    },\n    async handle(handlerInput) {  \n            let lightName = handlerInput.requestEnvelope.request.intent.slots.animation.value;\n            let lightVal = (valuesMap[lightName] === 6) ? (getRandomInt(3)+1) : valuesMap[lightName];\n            \n            await makeRequest(`\/update\/v0?value=${lightVal}`);\n                const speakOutput = `Let's get this ${lightName} light show started.`;\n                return handlerInput.responseBuilder\n                    .speak(speakOutput)\n                    .getResponse();\n    }\n};<\/pre>\n<pre class=\"prettyprint\">function makeRequest(path) {\n    return new Promise(((resolve, reject) => {\n        http.get(`${baseDomain}${path}`, (resp) => {\n            let data = '';\n\n            \/\/ A chunk of data has been recieved.\n            resp.on('data', (chunk) => {\n                data += chunk;\n            });\n\n            \/\/ The whole response has been received. Print out the result.\n            resp.on('end', () => {\n                resolve();\n            });\n\n        }).on(\"error\", (err) => {\n            reject(err);\n        });\n    }));\n}<\/pre>\n<p>Once you have your code writen or used mine you would now run <code>npm install<\/code>. this creates the modules folder. Next zip up all your code and we need to push it up to the lambda function. Make sure you have your folder stucture set up with your index.js in the root folder.<br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-07-at-9.22.52-AM.png\" alt=\"\" width=\"200\" class=\"alignnone size-full wp-image-1701\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/Screen-Shot-2019-10-07-at-9.17.55-AM.png\" alt=\"\" width=\"400\" class=\"alignnone size-full wp-image-1696\" \/><br \/>\nNow save this and you should have a completed Lambda.<\/p>\n<h2>\nArduino Code<br \/>\n<\/h2>\n<p><a href=\"https:\/\/github.com\/djmason9\/AlexaEnableNeopixelMatrix\/blob\/master\/Arduino%20Code\/ESP32-Wifi-LEDPanel-lightshow\/ESP32-Wifi-LEDPanel-lightshow.ino\" rel=\"noopener noreferrer\" target=\"_blank\">Get the code<\/a><br \/>\nFor the Arduino Code I&#8217;m only going to talk about a few key funcitions.<br \/>\n<code>int ledControl(String command)<\/code><br \/>\nThis is the main function that sets up all the lights.<\/p>\n<p><code>TimedAction timedAction = TimedAction(5, checkforRestCall);<\/code><br \/>\nIt is created to help hide the mechanics of how to implement Protothreading and general millis() timing. It is sutied for those actions that needs to happen approximately every x milliseconds.<\/p>\n<p><code>BLYNK_WRITE(VIRTUAL_PIN)<\/code><br \/>\nBLYNK_WRITE(vPIN) is a code function that gets called when the associated vPIn has new data<\/p>\n<p><code>void checkforRestCall()<\/code><br \/>\nThis is the function that&#8217;s called during the TimedAction and sets the next light animation.<\/p>\n<p>The rest of the code in the ESP32-Wifi-LEDPanel-lightshow.ino file is all about the different colors. Most of this I didn&#8217;t write so I&#8217;m not going to go deep into it. The other important file you need to know is the <code>config.h<\/code> file. <\/p>\n<p>In this file look for the following and set them up accordingly.<\/p>\n<pre class=\"prettyprint\">\/\/ You should get Auth Token in the Blynk App.\n\/\/ Go to the Project Settings (nut icon).\nchar auth[] = \"[YOUR KEY HERE]\";\n\n\/\/ WiFi parameters\nconst char *ssid = \"[YOUR SSID HERE]\";\nconst char *password = \"[YOUR NETWORK PASSWORD HERE]\";\n<\/pre>\n<p>The other file <code>arcade.h<\/code> is just arrays of the arcade animations. <\/p>\n<h2>\nWiring<br \/>\n<\/h2>\n<p>&#8211; <strong>IO05<\/strong> Data Pin<br \/>\n&#8211; <strong>IO02<\/strong> Ready light<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bitcows.com\/wp-content\/uploads\/2019\/10\/newopixelwifi_bb-1024x593.png\" alt=\"\" width=\"1024\" height=\"593\" class=\"alignnone size-large wp-image-1630\" \/><br \/>\nThe ESP32 chip requires a strong 3.3V so when you hook this up you will need to provide the 5v power with something in the order of 5-10 amps to push the lights.<\/p>\n<h2>\nLastly<br \/>\n<\/h2>\n<p>Lastly you will need to add the skill to your alexa. This can be done on your phone under Skills &#038; Games. Just look for &#8220;Your skills&#8221; then Dev. <\/p>\n<h2>\nFull Code<br \/>\n<\/h2>\n<p><a href=\"https:\/\/github.com\/djmason9\/AlexaEnableNeopixelMatrix\" rel=\"noopener noreferrer\" target=\"_blank\">Get the full code here.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Prerequisites &#8211; Basic understanding of Node.js &#8211; AWS Account (this is easy) &#8211; Blynk.io account &#8211; Amazon Echo &#8211; DC5V LED WS2812B panel (found on ebay) Blynk.io The first thing you will want to do is sign up for a blynk account. This is a great place to allow you to connect of hundreds of&hellip;<\/p>\n<p class=\"more-link\"><a href=\"https:\/\/bitcows.com\/?p=1626\" class=\"themebutton\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":2267,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,9,12,14,24],"tags":[36],"class_list":["post-1626","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-alexa","category-coding","category-electronics","category-hacking","category-node","tag-blynk"],"_links":{"self":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts\/1626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1626"}],"version-history":[{"count":1,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts\/1626\/revisions"}],"predecessor-version":[{"id":2290,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/posts\/1626\/revisions\/2290"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=\/wp\/v2\/media\/2267"}],"wp:attachment":[{"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bitcows.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}