{"id":2214,"date":"2022-02-07T22:55:46","date_gmt":"2022-02-08T03:55:46","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2214"},"modified":"2022-02-07T22:57:21","modified_gmt":"2022-02-08T03:57:21","slug":"assignment-4-james-kyle","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2214","title":{"rendered":"Assignment 4 &#8211; James Kyle"},"content":{"rendered":"<h2 style=\"text-align: center\"><span style=\"text-decoration: underline\"><strong>Automatic Blinds Adjuster:<\/strong><\/span><\/h2>\n<p><span style=\"text-decoration: underline\"><strong>Description:<\/strong><\/span><\/p>\n<p>The device I decided to make is an automatic blinds adjuster for people who may have a hard time maneuvering to a window to adjust their blinds. The user can either use a theoretical slider on a wall somewhere that would change the slide position on the webpage or they could use the webpage to adjust the blinds height.<\/p>\n<p>I had some trouble integrating both ways into one script so I have split the Arduino to p5.js and p5.js to Arduino parts for the purpose of this post.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline\"><img loading=\"lazy\" class=\"alignnone wp-image-2216\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-300x190.png\" alt=\"\" width=\"1036\" height=\"656\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-300x190.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-1024x649.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-768x487.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-1536x974.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-2048x1298.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.57-PM-1200x761.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><img loading=\"lazy\" class=\"alignnone wp-image-2215\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM-300x243.png\" alt=\"\" width=\"856\" height=\"693\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM-300x243.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM-1024x829.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM-768x622.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM-1536x1244.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM-1200x972.png 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/Screen-Shot-2022-02-07-at-10.25.05-PM.png 1790w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline\"><strong>Arduino to p5.js:<\/strong><\/span><\/p>\n<p>The user can adjust the slider on the webpage with a theoretical slider represented by a potentiometer.<\/p>\n<p><strong>Video Demo:<\/strong><\/p>\n<div style=\"width: 840px;\" class=\"wp-video\"><!--[if lt IE 9]><script>document.createElement('video');<\/script><![endif]-->\n<video class=\"wp-video-shortcode\" id=\"video-2214-1\" width=\"840\" height=\"473\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/IMG_7111.mp4?_=1\" \/><a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/IMG_7111.mp4\">https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/02\/IMG_7111.mp4<\/a><\/video><\/div>\n<p>&nbsp;<\/p>\n<p><strong>p5.js Code:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var serial;   \/\/ variable to hold an instance of the serialport library\r\n\r\n\/\/ for macos and *nix, you'll do something like this:\r\n\/\/var portName = '\/dev\/cu.usbserial-DN01DW79';    \/\/ fill in your serial port name here\r\n\r\n\/\/ for windows, just the COM port you're using\r\nvar portName = '\/dev\/tty.usbmodem14101';\r\n\r\nvar inData = 0;   \/\/ variable to hold the input data from Arduino\r\n\r\nvar minWidth = 600;   \/\/set min width and height for canvas\r\nvar minHeight = 400;\r\nvar width, height;    \/\/ actual width and height for the sketch\r\n\r\nvar sliderWidth = 30;\r\nvar sliderHeight = 200;\r\nvar slideLength = 400;\r\nvar outlineWeight = 10;\r\nvar sliderStartX;\r\nvar sliderX;\r\nvar sliderY = 200;\r\nvar sliderClicked = 0;\r\n\r\n\r\n\r\nfunction setup() {\r\n  \/\/ set the canvas to match the window size\r\n  if (window.innerWidth &gt; minWidth){\r\n    width = window.innerWidth;\r\n  } else {\r\n    width = minWidth;\r\n  }\r\n  if (window.innerHeight &gt; minHeight) {\r\n    height = window.innerHeight;\r\n  } else {\r\n    height = minHeight;\r\n  }\r\n\r\n  sliderStartX = width\/2 - slideLength\/2;\r\n  sliderX = sliderStartX;\r\n\r\n  \/\/set up canvas\r\n  createCanvas(width, height);\r\n  noStroke();\r\n\r\n  \/\/set up communication port\r\n  serial = new p5.SerialPort();       \/\/ make a new instance of the serialport library\r\n  serial.on('list', printList);  \/\/ set a callback function for the serialport list event\r\n  serial.on('connected', serverConnected); \/\/ callback for connecting to the server\r\n  serial.on('open', portOpen);        \/\/ callback for the port opening\r\n  serial.on('data', serialEvent);     \/\/ callback for when new data arrives\r\n  serial.on('error', serialError);    \/\/ callback for errors\r\n  serial.on('close', portClose);      \/\/ callback for the port closing\r\n\r\n  serial.list();                      \/\/ list the serial ports\r\n  serial.open(portName);              \/\/ open a serial port\r\n}\r\n\r\nfunction draw() {\r\n  \/\/ set background to black\r\n  background(0);\r\n  fill(255);\r\n  textSize(24);\r\n  textAlign(CENTER, BOTTOM);\r\n  text(\"Curtain Height\", sliderStartX + slideLength\/2, sliderY - outlineWeight);\r\n\r\n\r\n\r\n  \/\/-----Draw Slider-----\/\/\r\n  updateSlider();\r\n\r\n}\r\n\r\n\/\/ Following functions print the serial communication status to the console for debugging purposes\r\n\r\nfunction printList(portList) {\r\n \/\/ portList is an array of serial port names\r\n for (var i = 0; i &lt; portList.length; i++) {\r\n \/\/ Display the list the console:\r\n print(i + \" \" + portList[i]);\r\n }\r\n}\r\n\r\nfunction serverConnected() {\r\n  print('connected to server.');\r\n}\r\n\r\nfunction portOpen() {\r\n  print('the serial port opened.')\r\n}\r\n\r\nfunction serialEvent() {\r\n    \/\/ on the arduino we are using Serial.write to send an inteer\r\n    \/\/ so we have to use Number() to convert it to a number.\r\n    \/\/ otherwise it would be a string\r\n    inData = serial.readLine();\r\n    \/\/  if you do this, the inData value will be a string, not a number\r\n    \/\/ \r\n    \/\/inData = serial.read();\r\n    \/\/\r\n    \/\/ in arduino terms it's\r\n    \/\/ int inData = 1;\r\n    \/\/ vs\r\n    \/\/ String inData = \"1';\r\n\r\n}\r\n\r\nfunction serialError(err) {\r\n  print('Something went wrong with the serial port. ' + err);\r\n}\r\n\r\nfunction portClose() {\r\n  print('The serial port closed.');\r\n}\r\n\r\nfunction updateSlider() {\r\n\r\n  serial.write(parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)));\r\n  text(\"Value: \" + parseInt(map(sliderX, sliderStartX, sliderStartX+slideLength-sliderWidth, 0, 1023)), sliderStartX + slideLength\/2, 70);\r\n\r\n\r\n  \/\/This section is commented out for the p5.js to arduino configuration\r\n\r\n  \/\/ if (!sliderClicked &amp;&amp; inData != sliderX){\r\n  \/\/   sliderX = map(inData, 0, 180, sliderStartX, sliderStartX+slideLength);\r\n  \/\/ }\r\n\r\n  \/\/Background\r\n  fill(100);\r\n  rect(sliderStartX - outlineWeight\/2, sliderY - outlineWeight\/2, slideLength + outlineWeight, sliderHeight + outlineWeight,30);\r\n  fill(255);\r\n  rect(sliderStartX, sliderY, slideLength, sliderHeight,30);\r\n\r\n  \/\/Slider\r\n  fill(100, 10, 10);\r\n  rect(sliderX, sliderY, sliderWidth, sliderHeight,30);\r\n\r\n}\r\n\r\n\r\nfunction mousePressed() {\r\n\r\n  sliderClicked = isInRectangle(mouseX, mouseY, sliderY, (sliderY + sliderHeight), sliderX, (sliderX + sliderWidth));\r\n\r\n  if (sliderClicked) {\r\n    if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){\r\n      sliderX = mouseX;\r\n    }\r\n  }\r\n\r\n}\r\n\r\n\r\nfunction mouseDragged() {\r\n\r\n  if (sliderClicked) {\r\n    if (inBounds(mouseX, sliderStartX, sliderStartX + slideLength - sliderWidth)){\r\n      sliderX = mouseX;\r\n    }\r\n  }\r\n}\r\n\r\n\r\nfunction inBounds(value, lowerBound, upperBound) {\r\n  if ((value &gt; lowerBound) &amp;&amp; (value &lt; upperBound)) {\r\n    return 1;\r\n  } else {\r\n    return 0;\r\n  }\r\n}\r\n\r\n\r\nfunction isInRectangle(x, y, topBound, bottomBound, leftBound, rightBound) {\r\n\r\n  let xInRect = inBounds(x, leftBound, rightBound);\r\n  let yInRect = inBounds(y, topBound, bottomBound);\r\n\r\n  if (xInRect &amp;&amp; yInRect) {\r\n\r\n    return 1;\r\n\r\n  } else {\r\n\r\n    return 0;\r\n  }\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Arduino Code:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">#include &lt;Servo.h&gt;\r\n\r\nconst int POT_PIN = A0;\r\nconst int SERVO_PIN = 10;\r\n\r\nint incomingData = 0;\r\nint potVal;\r\nint newHeight;\r\nint prevHeight = 0;\r\n\r\nServo curtainHeight;\r\n\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n\r\n  pinMode(LED_PIN, OUTPUT);\r\n  pinMode(POT_PIN, INPUT);\r\n\r\n  curtainHeight.attach(SERVO_PIN);\r\n\r\n\r\n}\r\n\r\nvoid loop() {\r\n  \/\/ this sends the sensorValue as a raw int\r\n\r\n  \/\/LED state changes\r\n  if (Serial.available() &gt; 0) {\r\n    incomingData = Serial.parseInt();\r\n    newHeight = map(incomingData, 0, 1023, 0, 180);\r\n    curtainHeight.write(newHeight);\r\n\r\n  } else {\r\n    newHeight = map(analogRead(POT_PIN), 0, 1023, 0, 180);\r\n    if (abs(prevHeight - newHeight) &gt; 2) {\r\n      curtainHeight.write(newHeight);\r\n      Serial.println(newHeight);\r\n      prevHeight = newHeight;\r\n    }\r\n  }\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3><span style=\"text-decoration: underline\"><strong>p5.js to Arduino:<\/strong><\/span><\/h3>\n<p>The user can also use the slider on the interface to adjust the blind height from a potential website. I was not able to get this part to work as I was having a little trouble figuring out how to read data from p5.js in Arduino. The code and setup are the same as for the Arduino to p5.js case.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Automatic Blinds Adjuster: Description: The device I decided to make is an automatic blinds adjuster for people who may have a hard time maneuvering to a window to adjust their blinds. The user can either use a theoretical slider on a wall somewhere that would change the slide position on the webpage or they could &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2214\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Assignment 4 &#8211; James Kyle&#8221;<\/span><\/a><\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2214"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2214"}],"version-history":[{"count":5,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2214\/revisions"}],"predecessor-version":[{"id":2233,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2214\/revisions\/2233"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}