{"id":2593,"date":"2022-05-04T15:16:45","date_gmt":"2022-05-04T19:16:45","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2593"},"modified":"2022-05-04T15:16:45","modified_gmt":"2022-05-04T19:16:45","slug":"final-project","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2593","title":{"rendered":"Final Project"},"content":{"rendered":"<p>For the final project, I installed light sensors and ultrasonic sensors in and around a lasercut chipboard topography model to achieve several different objectives.<\/p>\n<figure id=\"attachment_2600\" aria-describedby=\"caption-attachment-2600\" style=\"width: 2323px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2600 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-scaled.jpg\" alt=\"\" width=\"2323\" height=\"2560\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-scaled.jpg 2323w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-272x300.jpg 272w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-929x1024.jpg 929w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-768x846.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-1394x1536.jpg 1394w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-1858x2048.jpg 1858w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped-1200x1323.jpg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2600\" class=\"wp-caption-text\">Landscape Topography Model<\/figcaption><\/figure>\n<p>My final project consists of 4 parts:<\/p>\n<ol>\n<li>Visualizing Light Sensor Data on a Digital Model<\/li>\n<\/ol>\n<p>This exercise builds on previous work in the visual crit, in which data coming from light sensors influenced the visual patterns of the topography model in Rhino. In this version, light sensor data is used to create a gradient from white to black in Rhino\/Grasshopper, which can either be viewed as a plan in 2d, or projected over the digital topography surface to be viewed in 3d. The data has been smoothed and remapped over a cellular grid, with data points mapped onto the digital topography model to correspond with the locations of the sensors on the physical model.<\/p>\n<p>Views of 2d and 3d visualizations of the light gradient below:<\/p>\n<figure id=\"attachment_2597\" aria-describedby=\"caption-attachment-2597\" style=\"width: 840px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2597 size-large\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop-1024x1021.jpg\" alt=\"\" width=\"840\" height=\"838\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop-1024x1021.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop-300x300.jpg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop-150x150.jpg 150w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop-768x766.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop-1200x1196.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/light_gradient_color_crop.jpg 1245w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2597\" class=\"wp-caption-text\">2d Visualization of Light Sensor Gradient<\/figcaption><\/figure>\n<figure id=\"attachment_2598\" aria-describedby=\"caption-attachment-2598\" style=\"width: 811px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2598 size-large\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-811x1024.jpg\" alt=\"\" width=\"811\" height=\"1024\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-811x1024.jpg 811w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-237x300.jpg 237w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-768x970.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-1216x1536.jpg 1216w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-1621x2048.jpg 1621w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop-1200x1516.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/3d_projection_color_crop.jpg 1796w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption id=\"caption-attachment-2598\" class=\"wp-caption-text\">3d Visualization of Light Sensor Gradient<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_2612\" aria-describedby=\"caption-attachment-2612\" style=\"width: 2560px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2612 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-scaled.jpg\" alt=\"\" width=\"2560\" height=\"902\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-scaled.jpg 2560w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-300x106.jpg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-1024x361.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-768x271.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-1536x541.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-2048x721.jpg 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/canvas_gh_part1-1200x423.jpg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2612\" class=\"wp-caption-text\">Part 1: GH Code<\/figcaption><\/figure>\n<p>Demonstration of 2d visualization of light sensor data below:<\/p>\n<p><iframe loading=\"lazy\" title=\"Final Project - Light Sensor Visualization\" width=\"840\" height=\"630\" src=\"https:\/\/www.youtube.com\/embed\/uw6q0RUHumw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<p>2. Turning LED Lights on Below a Given Light Level<\/p>\n<p>When one of the light sensors falls below a certain threshold of light, the code shown below in Grasshopper will turn on the LED light corresponding to that particular sensor. When the light sensor value rises above this threshold, the LED light turns off. Depending on the way light is cast across the physical topography, one light may be turned on due to the surrounding low light levels, while the others are off. In this way, additional light is only provided when it is deemed necessary, based on the surrounding light conditions.<\/p>\n<figure id=\"attachment_2601\" aria-describedby=\"caption-attachment-2601\" style=\"width: 1551px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"wp-image-2601 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds.jpg\" alt=\"\" width=\"1551\" height=\"1221\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds.jpg 1551w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds-300x236.jpg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds-1024x806.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds-768x605.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds-1536x1209.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/20220428_202912_cropped_leds-1200x945.jpg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2601\" class=\"wp-caption-text\">Model with mounted sensors and corresponding LED lights beyond<\/figcaption><\/figure>\n<figure id=\"attachment_2615\" aria-describedby=\"caption-attachment-2615\" style=\"width: 3236px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2615 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2.png\" alt=\"\" width=\"3236\" height=\"1670\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2.png 3236w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2-300x155.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2-1024x528.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2-768x396.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2-1536x793.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2-2048x1057.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151141_part2-1200x619.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2615\" class=\"wp-caption-text\">Part 2: GH Code<\/figcaption><\/figure>\n<p>3. Digital Drawing with Ultrasonic Sensors<\/p>\n<p>Using ultrasonic sensors mounted above the topography model, a pointer (such as a long dowel rod) can be moved across the physical terrain of the model. As the ultrasonic sensors pick up the location of the dowel, these locations are read in Grasshopper, logged, and construct points across the digital Rhino model, which can then be used to generate linework. One of the challenges with this project is the limited peripheral detection abilities of the ultrasonic sensors. Two were used in this demonstration, and when the dowel rod moved out of the range of one of the sensors, the code would interpret the coordinates in this area as \u201c0\u201d and the points and associated linework will \u201cjump\u201d to the edges of the model. One possible remedy would be to remove coordinates with \u201c0\u201d from the log, but this would not resolve the sensor range issue. Another possible solution could be to add more sensors. This would likely require multiple Arduinos, unless more complicated Arduino code could be developed to handle multiple ultrasonic sensors at a time (my preliminary attempts to combine 2 ultrasonic sensors on one Arduino were unsuccessful).<\/p>\n<figure id=\"attachment_2616\" aria-describedby=\"caption-attachment-2616\" style=\"width: 3236px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2616 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3.png\" alt=\"\" width=\"3236\" height=\"1670\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3.png 3236w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3-300x155.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3-1024x528.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3-768x396.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3-1536x793.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3-2048x1057.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151212_part3-1200x619.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2616\" class=\"wp-caption-text\">Part 3: GH Code<\/figcaption><\/figure>\n<figure id=\"attachment_2606\" aria-describedby=\"caption-attachment-2606\" style=\"width: 608px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2606 size-large\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-608x1024.jpg\" alt=\"\" width=\"608\" height=\"1024\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-608x1024.jpg 608w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-178x300.jpg 178w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-768x1294.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-911x1536.jpg 911w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-1215x2048.jpg 1215w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop-1200x2022.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_color_crop.jpg 1379w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption id=\"caption-attachment-2606\" class=\"wp-caption-text\">Ultrasonic Sketch: 3d Projection, Drawing in Green<\/figcaption><\/figure>\n<figure id=\"attachment_2607\" aria-describedby=\"caption-attachment-2607\" style=\"width: 840px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2607 size-large\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_plan_color_crop-960x1024.jpg\" alt=\"Ultrasonic Sensors Sketch: 2d Drawing in Green\" width=\"840\" height=\"896\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_plan_color_crop-960x1024.jpg 960w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_plan_color_crop-281x300.jpg 281w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_plan_color_crop-768x819.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_plan_color_crop-1200x1279.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/ultrasonic_plan_color_crop.jpg 1208w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2607\" class=\"wp-caption-text\">Ultrasonic Sensors Sketch: 3d Projection, Drawing in Green<\/figcaption><\/figure>\n<p>4. Digital Drawing with Potentiometers<\/p>\n<p>To explore a second technique for digital drawing, I used potentiometers to guide the drawing across the physical model. This method allowed for greater range and control over the digital drawing (provided one is accustomed to the controls), but it is less intuitive than gesturing with a dowel rod.<\/p>\n<figure id=\"attachment_2617\" aria-describedby=\"caption-attachment-2617\" style=\"width: 3236px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2617 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4.png\" alt=\"\" width=\"3236\" height=\"1670\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4.png 3236w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4-300x155.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4-1024x528.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4-768x396.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4-1536x793.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4-2048x1057.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/Canvas-at-151255_part4-1200x619.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2617\" class=\"wp-caption-text\">Part 4: GH Code<\/figcaption><\/figure>\n<figure id=\"attachment_2619\" aria-describedby=\"caption-attachment-2619\" style=\"width: 1185px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2619 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_plan_crop.jpg\" alt=\"\" width=\"1185\" height=\"1307\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_plan_crop.jpg 1185w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_plan_crop-272x300.jpg 272w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_plan_crop-928x1024.jpg 928w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_plan_crop-768x847.jpg 768w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2619\" class=\"wp-caption-text\">Drawing with Potentiometers, 2d Plan<\/figcaption><\/figure>\n<figure id=\"attachment_2618\" aria-describedby=\"caption-attachment-2618\" style=\"width: 1403px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-2618 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop.jpg\" alt=\"\" width=\"1403\" height=\"2326\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop.jpg 1403w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop-181x300.jpg 181w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop-618x1024.jpg 618w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop-768x1273.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop-926x1536.jpg 926w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop-1235x2048.jpg 1235w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/05\/potentiometer_3d_color_crop-1200x1989.jpg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-2618\" class=\"wp-caption-text\">Drawing with Potentiometers, 3d Projection<\/figcaption><\/figure>\n<p>The Arduino set up for the light sensors and the potentiometer uses Firmata, written by Andrew Payne and Jason Kelly Johnson to facilitate communication between the Arduino and Rhino\/Grasshopper\/Firefly. A modification is required for 2022 Arduino:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/* \r\n Created by Andrew Payne and Jason Kelly Johnson\r\n Latest Update March 25th, 2015 \r\n Copyright 2015 | All Rights Reserved\r\n version below modified for 2022 Arduino\r\n \r\n This Firmata allows you to control an Arduino board from Rhino\/Grasshopper\/Firefly.\r\n Updates, Questions, Suggestions visit: http:\/\/www.fireflyexperiments.com\r\n \r\n 1. Plug Arduino boards into your USB port; confirm that your Arduino's green power LED in on\r\n 2. Select your specific Arduino Board and Serial Port (Tools &gt; Board; Tools &gt; Serial Port) *Take note of your Serial Port COM #\r\n 3. Verify (play button) and Upload (upload button) this program to your Arduino, close the Arduino program\r\n 4. then open ... Rhino\/Grasshopper\/Firefly\r\n \r\n Note: The Firefly Firmata sets the following pins to perform these functions:\r\n \r\n *****ON STANDARD BOARDS (ie. Uno, Diecimila, Duemilanove, Lillypad, Mini, etc.)*****\r\n ANALOG IN pins 0-5 are set to return values (from 0 to 1023) for analog sensors\r\n DIGITAL IN pins 2,4,7 will return 0's or 1's; for 3 potential digital sensors (buttons, switches, on\/off, true\/false, etc.)\r\n DIGITAL\/ANALOG OUT pins 3,5,6,11 (marked with a ~) can be used to digitalWrite, analogWrite, or Servo.write depending on the input status of that Firefly pin\r\n DIGITAL OUT pins 8,9,10,12,13 can be used to digitalWrite, Servo.write, or analogWrite depending on the input status of that Firefly pin\r\n \r\n *****ON MEGA BOARDS (ie. ATMEGA1280, ATMEGA2560)*****\r\n ANALOG IN pins 0-15 will return values (from 0 to 1023) for 16 analog sensors \r\n DIGITAL IN pins 22-31 will return 0's or 1's; for digital sensors (buttons, switches, on\/off, true\/false, etc.) \r\n DIGITAL\/ANALOG OUT pins 2-13 can be used to digitalWrite, analogWrite, or Servo.write depending on the input status of that Firefly pin\r\n DIGITAL OUT pins 32-53 can be used to digitalWrite, Servo.write, or analogWrite depending on the input status of that Firefly pin\r\n \r\n *****ON LEONARDO BOARDS*****\r\n ANALOG IN pins 0-5 are set to return values (from 0 to 1023) for analog sensors\r\n DIGITAL IN pins 2,4,7 will return 0's or 1's; for 3 potential digital sensors (buttons, switches, on\/off, true\/false, etc.)\r\n DIGITAL\/ANALOG OUT pins 3,5,6,11 (marked with a ~) can be used to digitalWrite, analogWrite, or Servo.write depending on the input status of that Firefly pin\r\n DIGITAL OUT pins 8,9,10,12,13 can be used to digitalWrite, Servo.write, or analogWrite depending on the input status of that Firefly pin\r\n \r\n  *****ON DUE BOARDS (ie. SAM3X8E)*****\r\n ANALOG IN pins 0-11 will return values (from 0 to 4095) for 12 analog sensors \r\n DIGITAL IN pins 22-31 will return 0's or 1's; for digital sensors (buttons, switches, on\/off, true\/false, etc.) \r\n DIGITAL\/ANALOG OUT pins 2-13 can be used to digitalWrite, analogWrite, or Servo.write depending on the input status of that Firefly pin\r\n DIGITAL OUT pins 32-53 can be used to digitalWrite, Servo.write, or analogWrite depending on the input status of that Firefly pin\r\n DAC0 and DAC1 can be used to output an analog voltage on those pins (only available on DUE boards)\r\n *\/\r\n\r\n#include &lt;Servo.h&gt;            \/\/ attach Servo library (http:\/\/www.arduino.cc\/playground\/ComponentLib\/Servo)\r\n#include &lt;pins_arduino.h&gt;     \/\/ attach arduino pins header file to determine which board type is being used\r\n\r\n#define BAUDRATE 115200       \/\/ Set the Baud Rate to an appropriate speed\r\n#define BUFFSIZE 512          \/\/ buffer one command at a time\r\n\r\n\/*==============================================================================\r\n * GLOBAL VARIABLES\r\n *============================================================================*\/\r\n\r\nchar buffer[BUFFSIZE];        \/\/ declare buffer\r\nuint8_t bufferidx = 0;        \/\/ a type of unsigned integer of length 8 bits\r\nchar *parseptr;\r\nchar buffidx;\r\n\r\nint counter = 0;\r\nint numcycles = 1000;\r\n\r\n#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)                                                \/\/ declare variables for STANDARD boards\r\n  Servo Servo13, Servo12, Servo11, Servo10, Servo9, Servo8, Servo6, Servo5, Servo3;\r\n  Servo SERVO_CONFIG[] = {Servo13, Servo12, Servo11, Servo10, Servo9, Servo8, Servo6, Servo5, Servo3};       \/\/ declare array of Servo objects\r\n  int WRITE_PIN_CONFIG[] = {13,12,11,10,9,8,6,5,3}; \r\n  int READ_APIN_CONFIG[] = {0,1,2,3,4,5};\r\n  int READ_DPIN_CONFIG[] = {2,4,7}; \r\n#endif\r\n\r\n#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)                                               \/\/ declare variables for LEONARDO board\r\n  Servo Servo13, Servo12, Servo11, Servo10, Servo9, Servo8, Servo6, Servo5, Servo3;       \r\n  Servo SERVO_CONFIG[] = {Servo13, Servo12, Servo11, Servo10, Servo9, Servo8, Servo6, Servo5, Servo3};       \/\/ declare array of Servo objects\r\n  int WRITE_PIN_CONFIG[] = {13,12,11,10,9,8,6,5,3}; \r\n  int READ_APIN_CONFIG[] = {0,1,2,3,4,5};\r\n  int READ_DPIN_CONFIG[] = {2,4,7};\r\n#endif\r\n\r\n#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)                        \/\/ declare variables for MEGA boards\r\n  Servo Servo2, Servo3, Servo4, Servo5, Servo6, Servo7, Servo8, Servo9, Servo10, Servo11, Servo12, Servo13, Servo32, Servo33, Servo34, Servo35, Servo36, Servo37, Servo38, Servo39, Servo40, Servo41, Servo42, Servo43, Servo44, Servo45, Servo46, Servo47, Servo48, Servo49, Servo50, Servo51, Servo52, Servo53;\r\n  Servo SERVO_CONFIG[] = {Servo2, Servo3, Servo4, Servo5, Servo6, Servo7, Servo8, Servo9, Servo10, Servo11, Servo12, Servo13, Servo32, Servo33, Servo34, Servo35, Servo36, Servo37, Servo38, Servo39, Servo40, Servo41, Servo42, Servo43, Servo44, Servo45, Servo46, Servo47, Servo48, Servo49, Servo50, Servo51, Servo52, Servo53};  \/\/ declare array of Servo objects\r\n  int WRITE_PIN_CONFIG[] = {2,3,4,5,6,7,8,9,10,11,12,13,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; \r\n  int READ_APIN_CONFIG[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};\r\n  int READ_DPIN_CONFIG[] = {22,23,24,25,26,27,28,29,30,31};\r\n#endif\r\n\r\n#if defined(__SAM3X8E__)                 \/\/ declare variables for DUE boards\r\n  Servo FDAC0, FDAC1, Servo2, Servo3, Servo4, Servo5, Servo6, Servo7, Servo8, Servo9, Servo10, Servo11, Servo12, Servo13, Servo32, Servo33, Servo34, Servo35, Servo36, Servo37, Servo38, Servo39, Servo40, Servo41, Servo42, Servo43, Servo44, Servo45, Servo46, Servo47, Servo48, Servo49, Servo50, Servo51, Servo52, Servo53;  \r\n  Servo SERVO_CONFIG[] = {FDAC0, FDAC1, Servo2, Servo3, Servo4, Servo5, Servo6, Servo7, Servo8, Servo9, Servo10, Servo11, Servo12, Servo13, Servo32, Servo33, Servo34, Servo35, Servo36, Servo37, Servo38, Servo39, Servo40, Servo41, Servo42, Servo43, Servo44, Servo45, Servo46, Servo47, Servo48, Servo49, Servo50, Servo51, Servo52, Servo53};  \/\/ declare array of Servo objects\r\n  int WRITE_PIN_CONFIG[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; \/\/Note: first two values correspond to the DAC pins\r\n  int READ_APIN_CONFIG[] = {0,1,2,3,4,5,6,7,8,9,10,11};\r\n  int READ_DPIN_CONFIG[] = {22,23,24,25,26,27,28,29,30,31};\r\n#endif\r\n\r\n\/*==============================================================================\r\n * SETUP() This code runs once\r\n *============================================================================*\/\r\nvoid setup()\r\n{ \r\n  Init();                       \/\/set initial pinmodes\r\n  Serial.begin(BAUDRATE);       \/\/ Start Serial communication\r\n  #if defined(__SAM3X8E__)      \/\/if the connected board is an Arduino DUE\r\n    analogReadResolution(12);   \/\/Set the analog read resolution to 12 bits (acceptable values between 1-32 bits).  This is only for DUE boards\r\n    analogWriteResolution(12);  \/\/ Set the analog write resolution to 12 bits (acceptable values between 1-32 bits).  This is only for DUE boards\r\n  #endif\r\n}\r\n\r\n\/*==============================================================================\r\n * LOOP() This code loops\r\n *============================================================================*\/\r\nvoid loop()\r\n{\r\n  if(Serial){\r\n    ReadSerial();                       \/\/ read and parse string from serial port and write to pins\r\n    if (counter &gt;= numcycles){          \/\/ Wait every nth loop \r\n      ReadInputs();                     \/\/ get input data and print data to the serial port\r\n      counter = 0;                      \/\/ reset the counter\r\n    }\r\n    counter ++;                         \/\/ increment the writecounter\r\n  }\r\n}\r\n\r\n\/*==============================================================================\r\n * FUNCTIONS()\r\n *============================================================================*\/\r\n\r\n\/*\r\n* Initializes the digital pins which will be used as inputs\r\n*\/\r\nvoid Init(){\r\n  int len = sizeof(READ_DPIN_CONFIG)\/sizeof(READ_DPIN_CONFIG[0]); \/\/get the size of the array\r\n  for(int i = 0; i &lt; len; i++){\r\n    pinMode(READ_DPIN_CONFIG[i], INPUT);\r\n  }\r\n}\r\n\r\n\/* \r\n* Reads the incoming ADC or digital values from the corresponding analog and digital input  \r\n* pins and prints the value to the serial port as a formatted commma separated string\r\n*\/\r\nvoid ReadInputs(){ \r\n  int len = sizeof(READ_APIN_CONFIG)\/sizeof(READ_APIN_CONFIG[0]); \/\/get the size of the array\r\n  for(int i = 0; i &lt; len; i++){\r\n    int val = analogRead(READ_APIN_CONFIG[i]);  \/\/read value from analog pins\r\n    Serial.print(val); Serial.print(\",\");   \r\n  }\r\n  len = sizeof(READ_DPIN_CONFIG)\/sizeof(READ_DPIN_CONFIG[0]); \/\/get the size of the array\r\n  for(int i = 0; i &lt; len; i++){\r\n    int val = digitalRead(READ_DPIN_CONFIG[i]); \/\/read value from digital pins\r\n    Serial.print(val); Serial.print(\",\");   \r\n  }\r\n  Serial.println(\"eol\");  \/\/end of line marker\r\n}\r\n\r\n\/*\r\n* Retrieve the latest incoming serial value and split the string at the comma delimeter.\r\n* When a comma is found, the value is offloaded to a temporary variable and written\r\n* to the corresponding digital pin.\r\n*\/\r\nvoid ReadSerial(){\r\n  char c;    \/\/ holds one character from the serial port\r\n  if (Serial.available()) {\r\n    c = Serial.read();         \/\/ read one character\r\n    buffer[bufferidx] = c;     \/\/ add to buffer\r\n    if (c == '\\n') {  \r\n      buffer[bufferidx+1] = 0; \/\/ terminate it\r\n      parseptr = buffer;       \/\/ offload the buffer into temp variable\r\n      int len = sizeof(WRITE_PIN_CONFIG)\/sizeof(WRITE_PIN_CONFIG[0]); \/\/get the size of the array\r\n      for(int i = 0; i &lt; len; i++){\r\n        \/\/parse all incoming values and assign them to the appropriate variable\r\n        int val = parsedecimal(parseptr);       \/\/ parse the incoming number\r\n        if(i != len - 1) parseptr = strchr(parseptr, ',')+1;   \/\/ move past the \",\"\r\n        WriteToPin(WRITE_PIN_CONFIG[i], val, SERVO_CONFIG[i]);         \/\/send value out to pin on arduino board\r\n      }    \r\n      bufferidx = 0;                             \/\/ reset the buffer for the next read\r\n      return;                                    \/\/ return so that we don't trigger the index increment below\r\n    }                                            \/\/ didn't get newline, need to read more from the buffer\r\n    bufferidx++;                                 \/\/ increment the index for the next character\r\n    if (bufferidx == BUFFSIZE-1) bufferidx = 0;  \/\/ if we get to the end of the buffer reset for safety\r\n  }\r\n}\r\n\r\n\/*\r\n* Send the incoming value to the appropriate pin using pre-defined logic (ie. digital, analog, or servo)\r\n*\/\r\nvoid WriteToPin(int _pin, int _value, Servo _servo){\r\n  if (_value &gt;= 10000 &amp;&amp; _value &lt; 20000)            \/\/ check if value should be used for Digital Write (HIGH\/LOW)\r\n  {      \r\n    if (_servo.attached()) _servo.detach();         \/\/ detach servo is one is attached to pin\r\n    pinMode(_pin, OUTPUT);                       \r\n    _value -= 10000;                                \/\/ subtract 10,000 from the value sent from Grasshopper \r\n    if (_value == 1) digitalWrite(_pin, HIGH);     \r\n    else digitalWrite(_pin, LOW);   \r\n  }   \r\n  else if (_value &gt;= 20000 &amp;&amp; _value &lt; 30000)       \/\/ check if value should be used for Analog Write (0-255)\r\n  {\r\n    if (_servo.attached()) _servo.detach();         \/\/ detach servo is one is attached to pin\r\n    pinMode(_pin, OUTPUT);               \r\n    _value -= 20000;                                \/\/ subtract 20,000 from the value sent from Grasshopper\r\n    analogWrite(_pin, _value);                     \r\n  }\r\n  else if (_value &gt;= 30000 &amp;&amp; _value &lt; 40000)       \/\/ check if value should be used for Servo Write (0-180)\r\n  {\r\n    _value -= 30000;                                \/\/ subtract 30,000 from the value sent from Grasshopper\r\n    if (!_servo.attached())_servo.attach(_pin);     \/\/ attaches a Servo to the PWM pin (180 degree standard servos)                                    \r\n    _servo.write(_value);                          \r\n  }\r\n  else if (_value &gt;= 40000 &amp;&amp; _value &lt; 50000)       \/\/ check if value should be used for Analog Write (0-4096) for DACs\r\n  {\r\n    if (_servo.attached()) _servo.detach();         \/\/ detach servo is one is attached to pin\r\n    pinMode(_pin, OUTPUT);               \r\n    _value -= 40000;                                \/\/ subtract 40,000 from the value sent from Grasshopper\r\n    WriteToDAC(_pin, _value);                     \r\n  }\r\n}\r\n\r\n\/*\r\n* Parse a string value as a decimal\r\n*\/\r\nuint32_t parsedecimal(char *str){\r\n  uint32_t d = 0;\r\n  while (str[0] != 0) {\r\n    if ((str[0] &gt; '50') || (str[0] &lt; '0'))\r\n      return d;\r\n    d *= 10;\r\n    d += str[0] - '0';\r\n    str++;\r\n  }\r\n  return d;\r\n}\r\n\r\n\/*\r\n* Send the incoming value to the appropriate DAC for DUE boards. \r\n* Note: analogWrite resolution (default is 12 bits) is defined in the Setup function.\r\n*\/\r\n\/\/modification to original sketch to work with 2022 firefly and arduino\r\n  void WriteToDAC(int _pin, int _value){\r\n    #if defined(__SAM3X8E__) \r\n    if(_pin == 0) analogWrite(DAC0, _value);\r\n    else if (_pin == 1) analogWrite(DAC1, _value);\r\n    #endif\r\n  }<\/pre>\n<p>&nbsp;<\/p>\n<p>To use the ultrasonic sensors with Rhino\/Grasshopper\/Firefly, the NewPing library was used:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/\/ ---------------------------------------------------------------------------\r\n\/\/ Example NewPing library sketch that does a ping about 20 times per second.\r\n\/\/ ---------------------------------------------------------------------------\r\n\r\n#include &lt;NewPing.h&gt;\r\n\r\n#define TRIGGER_PIN  12  \/\/ Arduino pin tied to trigger pin on the ultrasonic sensor.\r\n#define ECHO_PIN     11  \/\/ Arduino pin tied to echo pin on the ultrasonic sensor.\r\n#define MAX_DISTANCE 30 \/\/ Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.\r\n\r\nNewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); \/\/ NewPing setup of pins and maximum distance.\r\n\r\nvoid setup() {\r\n  Serial.begin(115200); \/\/ Open serial monitor at 115200 baud to see ping results.\r\n}\r\n\r\nvoid loop() {\r\n  delay(50);                     \/\/ Wait 50ms between pings (about 20 pings\/sec). 29ms should be the shortest delay between pings.\r\n  Serial.print(\"Ping: \");\r\n  Serial.print(sonar.ping_cm()); \/\/ Send ping, get distance in cm and print result (0 = outside set distance range)\r\n  Serial.println(\"cm\");\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For the final project, I installed light sensors and ultrasonic sensors in and around a lasercut chipboard topography model to achieve several different objectives. My final project consists of 4 parts: Visualizing Light Sensor Data on a Digital Model This exercise builds on previous work in the visual crit, in which data coming from light &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2593\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Final Project&#8221;<\/span><\/a><\/p>\n","protected":false},"author":28,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[21],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2593"}],"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\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2593"}],"version-history":[{"count":14,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2593\/revisions"}],"predecessor-version":[{"id":2620,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2593\/revisions\/2620"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}