{"id":2331,"date":"2022-03-03T19:01:00","date_gmt":"2022-03-04T00:01:00","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2331"},"modified":"2022-04-04T16:11:04","modified_gmt":"2022-04-04T20:11:04","slug":"crit-1-using-the-outdoors-for-heating-cooling-jud","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2331","title":{"rendered":"Crit 1 (Using the outdoors for heating\/cooling) &#8211; Jud"},"content":{"rendered":"<h1>Idea:<\/h1>\n<p>The main idea behind this project is to open the window to cool or heat your room when the outside temperature is what you want your room temperature to be. For example, in the summer, if it is a super nice day out and your room is very hot, you could enter a temperature into the system and it would automatically open the window to let outside air in to adjust the room temperature. This also has a dual purpose in the winter for if your house is too hot and the system could open the window to let a cool breeze in.<\/p>\n<p>The main components of this system are two thermistors for measuring outside and inside temperature, a motor with an encoder to actuate the window, a motor driver to control the speed of the motor, and a p5 script animating the information from the Arduino in a helpful way. The Arduino sends the data over serial communication to the p5 script which then displays this information to the user and animates the virtual window corresponding to the current motor position.<\/p>\n<p>As shown in the demo video below, the system works very well detecting a need for opening the window and acting upon it. In addition, the p5 script very accurately shows the degree of openness of the window. While these component work very well together, the controller is still fairly simple. Currently, there is just one setting for open and closed meaning the window doesn&#8217;t open a certain degree based off the temperature difference between the room and the goal temp. With more time this feature could be implemented, but for demonstration purposes of this concept, the current controller works well.<\/p>\n<h1>Images:<\/h1>\n<p>Here are images of the final system concept. The first image is an overall image showing both the physical build and the virtual animation. The second image is a close up of the virtual animation screen showing the displayed outside and inside temperatures as well as the window itself. Finally, the third image shows a top view of the physical wiring for the system.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-2364\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-scaled.jpeg\" alt=\"\" width=\"2560\" height=\"1920\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-scaled.jpeg 2560w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-300x225.jpeg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-1024x768.jpeg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-768x576.jpeg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-1536x1152.jpeg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-2048x1536.jpeg 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0741-1200x900.jpeg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/> <img loading=\"lazy\" class=\"alignnone wp-image-2366 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-scaled.jpeg\" alt=\"\" width=\"2560\" height=\"1920\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-scaled.jpeg 2560w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-300x225.jpeg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-1024x768.jpeg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-768x576.jpeg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-1536x1152.jpeg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-2048x1536.jpeg 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0743-1200x900.jpeg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/> <img loading=\"lazy\" class=\"alignnone wp-image-2367 size-full\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-scaled.jpeg\" alt=\"\" width=\"2560\" height=\"1920\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-scaled.jpeg 2560w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-300x225.jpeg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-1024x768.jpeg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-768x576.jpeg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-1536x1152.jpeg 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-2048x1536.jpeg 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0744-1200x900.jpeg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\n<h1>Videos:<\/h1>\n<p>Video demonstration of the motor position feedback controlling the amount the virtual window is open.<\/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-2331-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\/03\/IMG_0745.MOV.mp4?_=1\" \/><a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0745.MOV.mp4\">https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0745.MOV.mp4<\/a><\/video><\/div>\n<p>Here is a video of the full system demo. As shown, when the outside temperature rises above the inside temperature, the window opens. When the outside temperature falls below the inside temperature, the window closes.<\/p>\n<div style=\"width: 840px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-2331-2\" 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\/03\/IMG_0746.MOV.mp4?_=2\" \/><a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0746.MOV.mp4\">https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/IMG_0746.MOV.mp4<\/a><\/video><\/div>\n<h1>Code:<\/h1>\n<h3>P5.js<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">let serial;\r\nlet latestData = \"waiting for data\";\r\nvar outData;\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\nvar squareWidth = 100;\r\n\r\nvar OuterWindowHeight = 800;\r\nvar OuterWindowLength = 600;\r\n\r\nvar InnerWindowHeight = OuterWindowHeight\/2;\r\nvar InnerWindowLength = OuterWindowLength;\r\n\r\nvar panelThickness = 10;\r\nvar RoomLength = 800;\r\n\r\nvar bottomInnerWindowY;\r\nvar y = 0;\r\n\r\nvar roomColor = '#f7c07c';\r\nvar skyColor = '#c2f9ff';\r\n\r\nvar outsideTemp = 100;\r\nvar insideTemp = 100;\r\n\r\nvar prevString;\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  bottomInnerWindowY = (height - OuterWindowHeight)\/2 + 50 + OuterWindowHeight - InnerWindowHeight\/2;\r\n\r\n  \/\/set up canvas\r\n  createCanvas(width, height);\r\n  noStroke();\r\n\r\n serial = new p5.SerialPort();\r\n\r\n serial.list();\r\n serial.open('\/dev\/tty.usbmodem144101');\r\n\r\n serial.on('connected', serverConnected);\r\n\r\n serial.on('list', gotList);\r\n\r\n serial.on('data', gotData);\r\n\r\n serial.on('error', gotError);\r\n\r\n serial.on('open', gotOpen);\r\n\r\n serial.on('close', gotClose);\r\n}\r\n\r\nfunction serverConnected() {\r\n print(\"Connected to Server\");\r\n}\r\n\r\nfunction gotList(thelist) {\r\n print(\"List of Serial Ports:\");\r\n\r\n for (let i = 0; i &lt; thelist.length; i++) {\r\n  print(i + \" \" + thelist[i]);\r\n }\r\n}\r\n\r\nfunction gotOpen() {\r\n print(\"Serial Port is Open\");\r\n}\r\n\r\nfunction gotClose(){\r\n print(\"Serial Port is Closed\");\r\n latestData = \"Serial Port is Closed\";\r\n}\r\n\r\nfunction gotError(theerror) {\r\n print(theerror);\r\n}\r\n\r\nfunction gotData() {\r\n  let currentString = serial.readLine();\r\n  trim(currentString);\r\n  if (!currentString) return;\r\n  console.log(currentString);\r\n  \/\/ latestData = currentString;\r\n  \/\/ currentString = Number(currentString) - 10000;\r\n  if ((Number(currentString) - 10000) &lt; 10000) {\r\n    insideTemp = (Number(currentString) - 10000);\r\n    return;\r\n  }\r\n  else if ((Number(currentString) - 20000) &lt; 10000) {\r\n    outsideTemp = (Number(currentString) - 20000);\r\n    return;\r\n  }\r\n  else if ((Number(currentString) - 30000) &lt; 10000) {\r\n    y = (Number(currentString) - 30000)\/1000;\r\n    return;\r\n  }\r\n}\r\n\r\nfunction draw() {\r\n\r\n  var outerWindowBottomY = (height - OuterWindowHeight)\/2 + 50;\r\n  var topInnerWindowY = outerWindowBottomY + InnerWindowHeight\/2;\r\n\r\n  \/\/Update bottom window position\r\n  bottomInnerWindowY = (height - OuterWindowHeight)\/2 + 50 + OuterWindowHeight - InnerWindowHeight\/2 - (y\/3.1415)*(OuterWindowHeight - InnerWindowHeight);\r\n  \r\n  background(0);\r\n\r\n  \/\/Draw canvas\r\n  strokeWeight(4);\r\n  stroke('white');\r\n  fill('black');\r\n  noStroke();\r\n\r\n  \/\/ \/\/Draw Room\r\n  strokeWeight(4);\r\n  stroke('black');\r\n  fill(roomColor);\r\n  rect((width - RoomLength)\/2, 0, RoomLength, height);\r\n\r\n  fill('black');\r\n  stroke(roomColor);\r\n  textSize(30);\r\n  textAlign(CENTER);\r\n  text(\"Window Opener\", width\/2, 80);\r\n  textSize(16);\r\n  text(\"Outside Temp: \" + outsideTemp + \"\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t Inside Temp: \" + insideTemp, width\/2, 125);    \/\/ displaying the input\r\n\r\n  \/\/Draw outer window\r\n  strokeWeight(4);\r\n  stroke('black');\r\n  fill(skyColor);\r\n  rect((width - OuterWindowLength)\/2, outerWindowBottomY, OuterWindowLength, OuterWindowHeight);\r\n\r\n  \/\/Draw top inner window\r\n  strokeWeight(4);\r\n  stroke('black');\r\n  strokeWeight(10);\r\n  noFill();\r\n  rect((width - InnerWindowLength)\/2, topInnerWindowY - InnerWindowHeight\/2, InnerWindowLength, InnerWindowHeight);\r\n  strokeWeight(10);\r\n  line((width - InnerWindowLength)\/2, topInnerWindowY, (width - InnerWindowLength)\/2 + InnerWindowLength, topInnerWindowY);\/\/y line\r\n  line(width\/2, outerWindowBottomY, width\/2, outerWindowBottomY + InnerWindowHeight);\/\/x line\r\n\r\n  \/\/Draw bottom inner window\r\n  strokeWeight(4);\r\n  stroke('black');\r\n  strokeWeight(10);\r\n  noFill();\r\n  rect((width - InnerWindowLength)\/2, bottomInnerWindowY - InnerWindowHeight\/2, InnerWindowLength, InnerWindowHeight);\r\n  strokeWeight(10);\r\n  line((width - InnerWindowLength)\/2, bottomInnerWindowY, (width - InnerWindowLength)\/2 + InnerWindowLength, bottomInnerWindowY);\/\/y line\r\n  line(width\/2, bottomInnerWindowY - InnerWindowHeight\/2, width\/2, bottomInnerWindowY + InnerWindowHeight\/2);\/\/x line\r\n\r\n}\r\n\r\n\r\nfunction mousePressed() {\r\n  \r\n}\r\n\r\nfunction mouseDragged() {\r\n\r\n}<\/pre>\n<h3>Arduino<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/*\r\n * Window Climate Controller\r\n * Judson Kyle\r\n * judsonk\r\n * \r\n * Collaboration:\r\n *  - Used thermistor code from this site: https:\/\/www.circuitbasics.com\/arduino-thermistor-temperature-sensor-tutorial\/\r\n *  \r\n *\/\r\n\r\n#define THERMISTOR1_PIN   A0\r\n#define THERMISTOR2_PIN   A1\r\n#define encoderPinA   18\r\n#define encoderPinB   19\r\n#define motorPin1     10\r\n#define motorPin2     11\r\n#define motorPWM      9\r\n\r\n#define P_I 3.14159\r\n\r\nint encoderCountRev = 48; \/\/48 encoder counts per revolution\r\nint incomingByte = 0;\r\n\r\n\/\/ https:\/\/www.pololu.com\/product\/4824\r\nfloat gearRatio = 2*(22.0*20.0*22.0*22.0*23.0)\/(12.0*12.0*10.0*10.0*10.0); \r\n\r\nbool motorSpinning = false;\r\n\r\n\/\/ Motor distance measuring variables\r\nvolatile long currentEncoder_pos_f = 0, prevEncoder_pos = 0, revs = 0;\r\nfloat motorCurPos = 0;\r\n\r\n\/\/PID Variables\r\nfloat ep = 0; \/\/Proportional error\r\nfloat ei = 0; \/\/Integral error\r\nfloat ed = 0; \/\/Derivative error\r\nfloat prev_ep = 0;\r\ndouble curTime = 0;\r\ndouble prevTime = 0;\r\n\r\nint pwmCommand = 0;\r\n\r\nfloat kp = 50; \/\/ P gain\r\nfloat ki = 0; \/\/ I gain\r\nfloat kd = 0; \/\/ D gain\r\nfloat motorGoalPos = P_I; \/\/ desired angle [radians]\r\n\r\nfloat temp1, temp2;\r\nfloat goalTemp = 480; \/\/Degrees F\r\n\r\nfloat insideOutsideDiff = 0;\r\nfloat insideGoalDiff = 0;\r\n\r\nfloat windowOpeningLength = P_I; \/\/radians at the moment\r\nfloat maxDiff = 100;\r\n\r\nvoid setup() {\r\n  \/\/Initialize motor control pins\r\n  pinMode(motorPin1, OUTPUT);\r\n  pinMode(motorPin2, OUTPUT);\r\n  pinMode(motorPWM, OUTPUT);\r\n\r\n  \/\/Initialize interrupts\r\n  attachInterrupt(digitalPinToInterrupt(encoderPinA), encoderA, CHANGE);\r\n  attachInterrupt(digitalPinToInterrupt(encoderPinB), encoderB, CHANGE);\r\n  \r\n  Serial.begin(9600);\r\n}\r\n\r\nvoid loop() {\r\n\r\n  \/\/Update motor current position\r\n  motorCurPos = (2*P_I*currentEncoder_pos_f) \/ (gearRatio*encoderCountRev);\r\n\r\n  temp1 = readTemp('v', THERMISTOR1_PIN);\r\n  temp2 = readTemp('v', THERMISTOR2_PIN);\r\n\r\n  insideOutsideDiff = temp1 - temp2; \/\/Add in conditionals for if temperature difference is negative\r\n  insideGoalDiff = temp1 - goalTemp; \/\/Add in conditionals for if temperature difference is negative\r\n\r\n  \/\/Update motor goal position based off of difference in temperature\r\n  if (insideGoalDiff &lt; 0) { \/\/Goal temp is higher than inside temp\r\n    if (insideOutsideDiff &lt; 0) { \/\/Outside temp higher than inside temp\r\n\/\/      int openDistance = abs(insideGoalDiff\/maxDiff)*windowOpeningLength;\r\n      motorGoalPos = P_I;\r\n    }\r\n    else { \/\/Ouside temp lower than or equal to inside temp\r\n      motorGoalPos = 0;\r\n    }\r\n  }\r\n  else if (insideGoalDiff &gt; 0) { \/\/Goal temp lower than inside temp\r\n    if (insideOutsideDiff &gt; 0) { \/\/Outside temp lower than inside temp\r\n\/\/      int openDistance = (insideGoalDiff\/maxDiff)*windowOpeningLength;\r\n      motorGoalPos = P_I;\r\n    }\r\n    else { \/\/Ouside temp higher than or equal to inside temp\r\n      motorGoalPos = 0;\r\n    }\r\n  }\r\n\r\n  updateMotorCmd(updatePID(motorGoalPos, motorCurPos));\r\n\r\n  \/\/Send data to p5 script for visualization\r\n  sendData();\r\n}\r\n\r\nfloat readTemp(char degreeType, int ThermistorPin) {\r\n  float logR2, R2, T;\r\n  float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;\r\n  \r\n  int R1 = 1000;\r\n  \r\n  int Vo = analogRead(ThermistorPin);\r\n  R2 = R1 * (1023.0 \/ (float)Vo - 1.0);\r\n  logR2 = log(R2);\r\n\r\n  T = (1.0 \/ (c1 + c2*logR2 + c3*logR2*logR2*logR2));\r\n\r\n  switch (degreeType){\r\n    case 'f':\r\n    case 'F':\r\n      T = T - 273.15;\r\n      T = (T * 9.0)\/ 5.0 + 32.0;\r\n      break;\r\n    case 'c':\r\n    case 'C':\r\n      T = T - 273.15;\r\n      break;\r\n    default:\r\n      return Vo;\r\n      break;\r\n  }\r\n\r\n  return T;\r\n}\r\n\r\nint updatePID(float goalPos, float curPos) {\r\n  int pwmCmd;\r\n  \r\n  \/\/ PID Controller\r\n  curTime = millis();\r\n  ep = (goalPos - curPos); \/\/ error in position (p)\r\n  ei = ei + ep; \/\/ integral error in position (i)\r\n  ed = (ep - prev_ep) \/ (curTime - prevTime); \/\/ derivative error in position (d)\r\n\r\n  prev_ep = ep;\r\n  prevTime = curTime;\r\n\r\n  pwmCmd = (ep*kp + ei*ki + ed*kd);\r\n\r\n  return pwmCmd;\r\n}\r\n\r\nvoid sendData() {\r\n  int temp1Send = 10000 + temp1;\r\n  Serial.println(temp1Send); \/\/Inside temp\r\n  int temp2Send = 20000 + temp2;\r\n  Serial.println(temp2Send); \/\/Outside temp\r\n  int sendData = 30000 + (int) (motorCurPos*1000);\r\n  Serial.println(sendData); \/\/Wnidow Opening\r\n}\r\n\r\nvoid updateMotorCmd(int pwmCmd) {\r\n  \/\/ switch directions if pass set point\r\n  if(ep &lt; 0) {\r\n    \/\/ Turn on motor A &amp; B\r\n    digitalWrite(motorPin1, LOW);\r\n    digitalWrite(motorPin2, HIGH);\r\n  }\r\n  else {\r\n    \/\/ Turn on motor A &amp; B\r\n    digitalWrite(motorPin1, HIGH);\r\n    digitalWrite(motorPin2, LOW);\r\n  }\r\n\r\n  pwmCmd = abs(pwmCmd);\r\n  if (pwmCmd &gt; 255) {\r\n    pwmCmd = 255;\r\n  }\r\n  analogWrite(motorPWM, pwmCmd);\r\n}\r\n\r\nvoid encoderA(){\r\n  \/\/ look for a low-to-high on channel A\r\n  if (digitalRead(encoderPinA) == HIGH) { \r\n    \/\/ check channel B to see which way encoder is turning\r\n    if (digitalRead(encoderPinB) == LOW) {  \r\n      \r\n        currentEncoder_pos_f = currentEncoder_pos_f + 1;         \/\/ CW\r\n    } \r\n    else {\r\n        currentEncoder_pos_f = currentEncoder_pos_f - 1;        \/\/ CCW\r\n    }\r\n  }\r\n  else   \/\/ must be a high-to-low edge on channel A                                       \r\n  { \r\n    \/\/ check channel B to see which way encoder is turning  \r\n    if (digitalRead(encoderPinB) == HIGH) {   \r\n      \r\n        currentEncoder_pos_f = currentEncoder_pos_f + 1;          \/\/ CW\r\n    } \r\n    else {\r\n        currentEncoder_pos_f = currentEncoder_pos_f - 1;          \/\/ CCW\r\n    }\r\n  }\r\n}\r\n\r\nvoid encoderB(){\r\n\r\n  \/\/ look for a low-to-high on channel B\r\n  if (digitalRead(encoderPinB) == HIGH) {   \r\n   \/\/ check channel A to see which way encoder is turning\r\n    if (digitalRead(encoderPinA) == HIGH) {  \r\n       \r\n        currentEncoder_pos_f = currentEncoder_pos_f + 1;         \/\/ CW\r\n    } \r\n    else {\r\n        currentEncoder_pos_f = currentEncoder_pos_f - 1;         \/\/ CCW\r\n    }\r\n  }\r\n  \/\/ Look for a high-to-low on channel B\r\n  else { \r\n    \/\/ check channel B to see which way encoder is turning  \r\n    if (digitalRead(encoderPinA) == LOW) {   \r\n        currentEncoder_pos_f = currentEncoder_pos_f + 1;          \/\/ CW\r\n    } \r\n    else {\r\n        currentEncoder_pos_f = currentEncoder_pos_f - 1;         \/\/ CCW\r\n    }\r\n  }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h1>Electrical Schematic:<\/h1>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-2374\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem.png\" alt=\"\" width=\"2205\" height=\"1710\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem.png 2205w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem-300x233.png 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem-1024x794.png 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem-768x596.png 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem-1536x1191.png 1536w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem-2048x1588.png 2048w, https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/wp-content\/uploads\/2022\/03\/Window-Cliamate-Control-Electrical-Schematic_schem-1200x931.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Idea: The main idea behind this project is to open the window to cool or heat your room when the outside temperature is what you want your room temperature to be. For example, in the summer, if it is a super nice day out and your room is very hot, you could enter a temperature &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/?p=2331\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Crit 1 (Using the outdoors for heating\/cooling) &#8211; Jud&#8221;<\/span><\/a><\/p>\n","protected":false},"author":30,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,1],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2331"}],"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\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2331"}],"version-history":[{"count":3,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2331\/revisions"}],"predecessor-version":[{"id":2375,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=\/wp\/v2\/posts\/2331\/revisions\/2375"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/s2022\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}