{"id":23162,"date":"2022-03-23T15:09:16","date_gmt":"2022-03-23T15:09:16","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=23162"},"modified":"2025-03-02T15:31:07","modified_gmt":"2025-03-02T23:31:07","slug":"create-images-with-iot","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/create-images-with-iot","title":{"rendered":"Create Images With IoT and Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><\/div>\n\n<div class=\"wp-block-cloudinary-markdown \"><\/div>\n\n<div class=\"wp-block-cloudinary-markdown \"><p>With the growing adoption of the Internet of Things (IoT), it\u2019s fun to build apps with IoT devices like Arduinos or Raspberry Pis. This tutorial shows you how to implement an interesting Arduino project, starting with using a photoresistor sensor to generate pictures in a JavaScript app. You\u2019ll then upload them to <a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a>, where you can monitor the images for changes in the input from the sensor.<\/p>\n<h2>Understanding the Use Cases<\/h2>\n<p>The Arduino app you\u2019ll build applies to several use cases, i.e., you could\u2014<\/p>\n<ul>\n<li>Swap out the photoresistor sensor for other sensors or motors.<\/li>\n<li>Create an app that displays the temperature changes in your house throughout the day.<\/li>\n<li>Build complex projects with the sensor data, like having a motor close your blinds if the temperature rises above a certain level.<\/li>\n<\/ul>\n<p>Even though gadgets geared for similar purposes are readily available at retail outlets, stepping through this tutorial will earn you hands-on experience with hardware and sharpen your JavaScript skills. Do give it a whirl.<\/p>\n<h2>Performing the Preparatory Steps<\/h2>\n<p>For this project, you\u2019ll need the following hardware along with electrical power:<\/p>\n<ul>\n<li>An Arduino Uno microcontroller board<\/li>\n<li>\n<a href=\"https:\/\/www.amazon.com\/Gikfun-Photoresistor-GL5516-Resistors-Arduino\/dp\/B00RLGFIEY\/ref=sr_1_4?crid=753Y8M5B5DSA&amp;keywords=photoresistor+sensor+arduino&amp;qid=1645064906&amp;sprefix=photoresistor+sensor+arduino%2Caps%2C91&amp;sr=8-4\">This sensor<\/a>\n<\/li>\n<li>A breadboard<\/li>\n<li>Wires<\/li>\n<\/ul>\n<h3>Establishing the Interface for the JavaScript App<\/h3>\n<ol>\n<li>Download the <a href=\"https:\/\/www.arduino.cc\/en\/software\">Arduino IDE<\/a>.<\/li>\n<li>Hook up the IDE to your computer and then copy and paste into the IDE the <a href=\"https:\/\/docs.arduino.cc\/hacking\/software\/FirmataLibrary\">Firmata code<\/a>, which enables interactions with JavaScript apps.<\/li>\n<li>In the Arduino IDE, choose <strong>Sketch &gt; Upload<\/strong>  to upload the Firmata code to your Arduino board.<\/li>\n<\/ol>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>Make a note of the number of the port your board is on. You\u2019ll need that number for setting up the app\u2019s server later.<\/p><\/div>\n<h3>Wiring the Arduino and Breadboard<\/h3>\n<p>To activate reading of data into your app, connect the sensor to the board, like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/lqodv4l8bzhjbsyhcp0j.png\" alt=\"A sensor connected to the Arduino and breadboard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"465.5\"\/><\/p>\n<p>As long as the connections are correct, feel free to organize the wires however you wish.<\/p>\n<h2>Building the JavaScript App<\/h2>\n<p>Now build a Node server for fetching data from the sensor and a front end for display. Instead of a framework, plain old <code>.html<\/code>, <code>.css<\/code>, and <code>.js<\/code> files would suffice.<\/p>\n<h3>Setting up the Connection to the Arduino<\/h3>\n<p>In a folder, create a file called <code>server.js<\/code> to house the code that sends the data from the sensor to the front end. Do the following:<\/p>\n<ol>\n<li>Run these commands in a terminal:<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ npm i express cors johnny-five\n<\/code><\/span><\/pre>\n<pre><code>The `express` and `cors` libraries are for creating the REST endpoint from which the front end collects the sensor data. The [`johnny-five` library](http:\/\/johnny-five.io\/), which facilitates interactions with the Arduino board, is a remarkably useful package. Have a look if you're interested in exploring IoT and in developing JavaScript apps.\n<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>In the <code>server.js<\/code> file, add the code below to set up the app. <strong>Be sure to update the <code>board<\/code> variable to reflect the port address of your Arduino board.<\/strong> That address is in or similar to one of these formats: <code>\/dev\/ttyUSB#<\/code>, <code>\/dev\/tty.usbmodem####<\/code>, or <code>COM#<\/code>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> five = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">\"johnny-five\"<\/span>);\n<span class=\"hljs-keyword\">const<\/span> cors = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'cors'<\/span>);\n<span class=\"hljs-keyword\">const<\/span> express = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'express'<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> PORT = process.env.PORT || <span class=\"hljs-number\">3000<\/span>;\n<span class=\"hljs-keyword\">const<\/span> app = express();\n\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">cors<\/span>());\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">express<\/span>.<span class=\"hljs-title\">json<\/span>());\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">express<\/span>.<span class=\"hljs-title\">urlencoded<\/span>({ <span class=\"hljs-title\">extended<\/span>: <span class=\"hljs-title\">false<\/span> }));\n\n<span class=\"hljs-keyword\">const<\/span> board = <span class=\"hljs-keyword\">new<\/span> five.Board({ port: <span class=\"hljs-string\">\"\/dev\/ttyUSB3\"<\/span> });\nlet photoresistor = {}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<\/ol>\n<p>The above code imports the packages you just installed and added variables.<\/p>\n<h3>Acquiring the Sensor Data<\/h3>\n<p>To pick up the sensor data, connect to the correct pin on the board in your code by placing these lines below the section on imports and variable declarations:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">board.on(<span class=\"hljs-string\">\"ready\"<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<span class=\"hljs-comment\">\/\/ Create a photoresistor hardware instance.<\/span>\n    photoresistor = <span class=\"hljs-keyword\">new<\/span> five.Sensor({\n        <span class=\"hljs-attr\">pin<\/span>: <span class=\"hljs-string\">\"A2\"<\/span>,\n        <span class=\"hljs-attr\">freq<\/span>: <span class=\"hljs-number\">250<\/span>\n    });\n\n    <span class=\"hljs-comment\">\/\/ Inject the sensor hardware into<\/span>\n    <span class=\"hljs-comment\">\/\/ the Repl instance's context and <\/span>\n    <span class=\"hljs-comment\">\/\/ allow direct command-line-access<\/span>\n    board.repl.inject({\n        <span class=\"hljs-attr\">pot<\/span>: photoresistor\n    });\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Subsequently, when ready to send you data following a sensor reading, the app inputs the data at pin A2. To change a value, e.g., the frequency, reconfigure the sensor in the command line.<\/p>\n<p>Next, add the endpoint from which to send the data to the front end with this code, placing it below the <code>board<\/code> method:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">app.get(<span class=\"hljs-string\">'\/api\/getSensorData'<\/span>, (req, res) =&gt; {\n    <span class=\"hljs-keyword\">let<\/span> data = {}\n    <span class=\"hljs-comment\">\/\/ \"data\" gets the current reading from the photoresistor<\/span>\n    photoresistor.on(<span class=\"hljs-string\">\"data\"<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-keyword\">this<\/span>.value);\n        data = <span class=\"hljs-keyword\">this<\/span>.value\n    });\n\n   res.send({\n       <span class=\"hljs-attr\">message<\/span>: data\n   });\n});\n\napp.listen(PORT, () =&gt; {\n <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`endpoints running on port <span class=\"hljs-subst\">${PORT}<\/span>`<\/span>);\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The above code does the following:<\/p>\n<ol>\n<li>\n<p>Get the photoresistor data and, in response to the <code>getSensorData<\/code> endpoint, send it to both the console and the front end.<\/p>\n<\/li>\n<li>\n<p>Start the server with the <code>app.listen<\/code> method. For the <code>PORT<\/code> variable, specify the port number of your choice in a <code>.env<\/code> file or let the number default to 3000.<\/p>\n<\/li>\n<\/ol>\n<h2>Creating a Simple Front End<\/h2>\n<p>As previously mentioned, you\u2019ll leverage packages instead of a framework to build the front end. Here\u2019s what to do:<\/p>\n<ol>\n<li>\n<p>In your project folder, create a subfolder called <code>client<\/code> in which to create two files: <code>client.html<\/code> and <code>client.js<\/code>. Want to tinker with styles? Add code to a <code>client.css<\/code> file.<\/p>\n<\/li>\n<li>\n<p>Import packages in skeleton HTML by adding the code below to the <code>client.html<\/code> file:<\/p>\n<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n   <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\".\/client.css\"<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@3.7.0\/dist\/chart.min.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html-to-image\/1.9.0\/html-to-image.js\"<\/span> <span class=\"hljs-attr\">integrity<\/span>=<span class=\"hljs-string\">\"sha512-8GQQGLSN+MYJfxnTNZm8HPIXz9TkAMeRcadyQO\/oFsk+OAHOH7uTz5dAafi1ADICwul44a3JpV2vsolsjVeVGg==\"<\/span> <span class=\"hljs-attr\">crossorigin<\/span>=<span class=\"hljs-string\">\"anonymous\"<\/span> <span class=\"hljs-attr\">referrerpolicy<\/span>=<span class=\"hljs-string\">\"no-referrer\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Real World Visuals<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n   <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n   <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>This reading originates directly from the sensor data.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">canvas<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"sensorVisual\"<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"500\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">canvas<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\".\/client.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n   <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Optionally, import the stylesheet and the <a href=\"https:\/\/www.chartjs.org\/docs\/latest\/\">ChartJS<\/a> package with HTML elements in the above snippet. You would then create a visual image from the data collected over time. Afterwards, take a picture with the <a href=\"https:\/\/www.npmjs.com\/package\/html-to-image\"><code>html-to-image<\/code><\/a> package and upload the picture to Cloudinary.<\/p>\n<h3>Displaying the Data as a Bar Graph<\/h3>\n<p>Now create the <code>client.js<\/code> file with <code>canvas<\/code> and <code>&lt;script&gt;<\/code> elements:<\/p>\n<ol>\n<li>\n<p>Add this code to the <code>client.js<\/code> file to gather the sensor data from the endpoint you built earlier:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-built_in\">window<\/span>.onload = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> ctx = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'sensorVisual'<\/span>).getContext(<span class=\"hljs-string\">'2d'<\/span>)\n\n    <span class=\"hljs-keyword\">let<\/span> data = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">'https:\/\/localhost:3000\/api\/getSensorData'<\/span>) \n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<li>\n<p>Create a chart to display the sensor data by placing this code below the request in step 1:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> chart = <span class=\"hljs-keyword\">new<\/span> Chart(ctx, {\n    <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'bar'<\/span>,\n    <span class=\"hljs-attr\">data<\/span>: {\n        <span class=\"hljs-attr\">labels<\/span>: data.x,\n        <span class=\"hljs-attr\">datasets<\/span>: &#91;{\n            <span class=\"hljs-attr\">label<\/span>: <span class=\"hljs-string\">'sensor'<\/span>,\n            <span class=\"hljs-attr\">data<\/span>: data.y,\n            <span class=\"hljs-attr\">borderWidth<\/span>: <span class=\"hljs-number\">1<\/span>\n        }]\n    },\n    <span class=\"hljs-attr\">options<\/span>: {\n        <span class=\"hljs-attr\">scales<\/span>: {\n            <span class=\"hljs-attr\">y<\/span>: {\n                <span class=\"hljs-attr\">beginAtZero<\/span>: <span class=\"hljs-literal\">true<\/span>\n            }\n        }\n    }\n})\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<\/li>\n<\/ol>\n<p>By way of explanation:<\/p>\n<ul>\n<li>The <code>Chart<\/code> object is a bar graph that conforms with the data format and that attaches to the <code>canvas<\/code> element. The data can also be displayed in other types of charts.<\/li>\n<li>The <code>data<\/code> properties denote the data values from the back end for the chart. To accurately scale the graph, the <code>y<\/code> axis starts at zero.<\/li>\n<\/ul>\n<p>Now open the <code>client.html<\/code> file in your browser for the graph:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/aeukbnqibrz4mm3u4vep.png\" alt=\"A bar graph of the sensor data\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"763\"\/><\/p>\n<h3>Uploading the Data Image<\/h3>\n<p>Finally, place this code below the snippet for the <code>Chart<\/code> object to add the <code>canvas<\/code> element, convert the data to an image, and upload the image to your Cloudinary account:<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>Be sure to replace the variable <code>cloudName<\/code> with the value of your account\u2019s <code>cloudName<\/code> for the correct location.<\/p><\/div>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> canvas = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'sensorVisual'<\/span>)\n\n<span class=\"hljs-keyword\">const<\/span> dataUrl = <span class=\"hljs-keyword\">await<\/span> toPng(canvas, { <span class=\"hljs-attr\">cacheBust<\/span>: <span class=\"hljs-literal\">true<\/span> })\n\n<span class=\"hljs-keyword\">const<\/span> uploadApi = <span class=\"hljs-string\">`https:\/\/api.cloudinary.com\/v1_1\/<span class=\"hljs-subst\">${cloudName}<\/span>\/image\/upload`<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> formData = <span class=\"hljs-keyword\">new<\/span> FormData()\nformData.append(<span class=\"hljs-string\">'file'<\/span>, dataUrl)\nformData.append(<span class=\"hljs-string\">'upload_preset'<\/span>, <span class=\"hljs-string\">'cwt1qiwn'<\/span>)\n\n<span class=\"hljs-keyword\">await<\/span> fetch(uploadApi, {\n    <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'POST'<\/span>,\n    <span class=\"hljs-attr\">body<\/span>: formData,\n})\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>From here on, loading <code>client.html<\/code> leads to a photoshoot of the data from the sensor connected to your Arduino board.<\/p>\n<h2>Checking Out the Code and Documentation<\/h2>\n<p>The final code for the app resides in <a href=\"https:\/\/github.com\/flippedcoder\/media-projects\/tree\/main\/iot-image-creator\">the <code>iot-image-generator<\/code> page on GitHub<\/a>. For troubleshooting help, see the <a href=\"https:\/\/docs.arduino.cc\/hardware\/uno-rev3\">documentation for Arduino<\/a> and details of the <a href=\"http:\/\/johnny-five.io\/api\/boards\/\"><code>Boards<\/code> class on the Johnny-Five community site<\/a>.<\/p>\n<h2>Applying to Other Sensor-Centric Apps<\/h2>\n<p>Sensors in various industries furnish data in a similar manner. Harnessing the data and passing it through a web app could offer fascinating insight so keep that idea and process in mind.<\/p>\n<\/div>\n\n<div class=\"wp-block-cloudinary-markdown \"><\/div>\n\n<div class=\"wp-block-cloudinary-markdown \"><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":18,"featured_media":23165,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[25,162,165],"class_list":["post-23162","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-asset-management","tag-image-processing","tag-image-transformation"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Create Images From Data With IoT Devices: A Tutorial<\/title>\n<meta name=\"description\" content=\"How to generate images with data from a photoresistor sensor and upload them to Cloudinary, where you can continually monitor for changes in the input.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create Images With IoT and Cloudinary\" \/>\n<meta property=\"og:description\" content=\"How to generate images with data from a photoresistor sensor and upload them to Cloudinary, where you can continually monitor for changes in the input.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-23T15:09:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-02T23:31:07+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1645051031\/Create-images-IoT\/Create-images-IoT-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Create Images With IoT and Cloudinary\",\"datePublished\":\"2022-03-23T15:09:16+00:00\",\"dateModified\":\"2025-03-02T23:31:07+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA\",\"keywords\":[\"Asset Management\",\"Image Processing\",\"Image Transformation\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\",\"url\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\",\"name\":\"Create Images From Data With IoT Devices: A Tutorial\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA\",\"datePublished\":\"2022-03-23T15:09:16+00:00\",\"dateModified\":\"2025-03-02T23:31:07+00:00\",\"description\":\"How to generate images with data from a photoresistor sensor and upload them to Cloudinary, where you can continually monitor for changes in the input.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/create-images-with-iot\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-images-with-iot#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create Images With IoT and Cloudinary\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Create Images From Data With IoT Devices: A Tutorial","description":"How to generate images with data from a photoresistor sensor and upload them to Cloudinary, where you can continually monitor for changes in the input.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/create-images-with-iot","og_locale":"en_US","og_type":"article","og_title":"Create Images With IoT and Cloudinary","og_description":"How to generate images with data from a photoresistor sensor and upload them to Cloudinary, where you can continually monitor for changes in the input.","og_url":"https:\/\/cloudinary.com\/blog\/create-images-with-iot","og_site_name":"Cloudinary Blog","article_published_time":"2022-03-23T15:09:16+00:00","article_modified_time":"2025-03-02T23:31:07+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1645051031\/Create-images-IoT\/Create-images-IoT-png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot"},"author":{"name":"","@id":""},"headline":"Create Images With IoT and Cloudinary","datePublished":"2022-03-23T15:09:16+00:00","dateModified":"2025-03-02T23:31:07+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA","keywords":["Asset Management","Image Processing","Image Transformation"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot","url":"https:\/\/cloudinary.com\/blog\/create-images-with-iot","name":"Create Images From Data With IoT Devices: A Tutorial","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA","datePublished":"2022-03-23T15:09:16+00:00","dateModified":"2025-03-02T23:31:07+00:00","description":"How to generate images with data from a photoresistor sensor and upload them to Cloudinary, where you can continually monitor for changes in the input.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/create-images-with-iot"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/create-images-with-iot#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create Images With IoT and Cloudinary"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1645051031\/Create-images-IoT\/Create-images-IoT.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/23162","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=23162"}],"version-history":[{"count":9,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/23162\/revisions"}],"predecessor-version":[{"id":37105,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/23162\/revisions\/37105"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/23165"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=23162"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=23162"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=23162"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}