{"id":2547,"date":"2022-04-27T12:40:49","date_gmt":"2022-04-27T16:40:49","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2547"},"modified":"2022-04-27T12:40:49","modified_gmt":"2022-04-27T16:40:49","slug":"crit-3-visual","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2547","title":{"rendered":"Crit 3: Visual"},"content":{"rendered":"<p>For the Visual Crit, I used Arduino, Rhino, Grasshopper, and GH plug-in Firefly to visualize sensor data over a topographical landscape. The topography model was initially generated digitally with Rhino and Grasshopper, so it could be used later in the model visualization. Contours were exported to 2d CAD to cut the physical model.<\/p>\n<p>The physical model was constructed of lasercut chipboard, with enough variation in height to imitate a landscape that could plausibly have multiple microclimates, which can form due to differences in light, drainage, and airflow. Changes in topography can drive these shifts in environmental conditions. Light sensors will installed in different areas of the model.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-medium wp-image-2554\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-225x300.jpg\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-225x300.jpg 225w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-768x1024.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-1152x1536.jpg 1152w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-1536x2048.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-1200x1600.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194600-scaled.jpg 1920w\" sizes=\"(max-width: 225px) 85vw, 225px\" \/><\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-medium wp-image-2553\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-225x300.jpg\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-225x300.jpg 225w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-768x1024.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-1152x1536.jpg 1152w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-1536x2048.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-1200x1600.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_185300-scaled.jpg 1920w\" sizes=\"(max-width: 225px) 85vw, 225px\" \/><\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-medium wp-image-2555\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-225x300.jpg\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-225x300.jpg 225w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-768x1024.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-1152x1536.jpg 1152w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-1536x2048.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-1200x1600.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/20220419_194611-1-scaled.jpg 1920w\" sizes=\"(max-width: 225px) 85vw, 225px\" \/><\/p>\n<p>Uploaded to the arduino is this Firmata code (which has been edited since the 2015 version to account for some differences in 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 \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>Next, with Grasshopper\/Firefly, the serial data from the light sensors is read. This data is used to generate points, which act as attractors in a domain field. The brighter the light, the smaller the circle illustrated in the domain field.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-2548\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-300x136.png\" alt=\"\" width=\"657\" height=\"298\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-300x136.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-1024x463.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-768x347.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-1536x694.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-2048x926.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/GH_Code_Visual_Crit-1200x542.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/p>\n<p>The final results can be viewed as a plan, or project onto the digital model surface to be viewed in 3d.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-2549\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d-300x286.png\" alt=\"\" width=\"300\" height=\"286\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d-300x286.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d-1024x977.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d-768x733.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d-1536x1465.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d-1200x1145.png 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d.png 1625w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/p>\n<p>Light Readings, plan view, v1<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-medium wp-image-2551\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-300x212.png\" alt=\"\" width=\"300\" height=\"212\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-300x212.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-1024x723.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-768x542.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-1536x1084.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-2048x1446.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d-1200x847.png 1200w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/p>\n<p>Light Readings, 3d, v1<\/p>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-2550\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2-300x271.png\" alt=\"\" width=\"299\" height=\"270\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2-300x271.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2-1024x925.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2-768x693.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2-1536x1387.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2-1200x1083.png 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/light_sensors_as_attractors_2d_2.png 1658w\" sizes=\"(max-width: 299px) 85vw, 299px\" \/><\/p>\n<p>Light Readings, plan view, v2<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-medium wp-image-2552\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2-300x227.png\" alt=\"\" width=\"300\" height=\"227\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2-300x227.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2-1024x774.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2-768x580.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2-1536x1161.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2-1200x907.png 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/04\/Light_Sensors_asAttractors_3d_2.png 1997w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/p>\n<p>Light Readings, plan view, v2<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For the Visual Crit, I used Arduino, Rhino, Grasshopper, and GH plug-in Firefly to visualize sensor data over a topographical landscape. The topography model was initially generated digitally with Rhino and Grasshopper, so it could be used later in the model visualization. Contours were exported to 2d CAD to cut the physical model. The physical &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2547\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Crit 3: Visual&#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":[20],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2547"}],"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=2547"}],"version-history":[{"count":8,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2547\/revisions"}],"predecessor-version":[{"id":2563,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2547\/revisions\/2563"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}