Description

This double transducer is designed to convert light intensity to magnetic field strength, which in turn is converted to rotational speed. The photocell on the far left side of the stage measures surrounding light intensity. This value is then inputted into a 180-degree hobby servo motor that moves the attached magnet to different angle values. At higher light intensity, the magnet is at a lower position angle and is thus closer to the triple-axis magnetometer positioned in the middle of the breadboard. At lower light intensity, the magnet is positioned farther away from the compass. Only the magnetic field strength in the  y-axis is measured because of the more linear correlation between the readings in the y-axis and the servo’s angle position. The magnetic field value then serves as an input for the 360-degree servo motor positioned at the far right of the stage. The rotational speed of the 360-degree servo motor increases as the magnet gets closer to the compass and the magnetic field strength is greater. Thus, increasing light intensity on the left side of the stage increases the rotational speed on the far right side.

Top view of Double Transducer: Light Intensity -> Magnetic Field -> Rotational Speed

Light intensity input values are obtained using a photoresistor

I2C LCD displays the input and output values of the double transducer

The servo with the magnet attached adjusts its position depending on light intensity. Position is measured using a triple-axis compass.

Position of the magnet varies the rotational speed of this 360 hobby servo.

 

Progress Images

Project before components were positioned onto the board.

The first few components are zip tied to the board.

Wires are rearranged because the LCD was facing the wrong decision.

Battery is added so that it doesn’t rely on a laptop.

Discussion

Working with some of the components were easy, as we had worked with them before. We had no problems working with the photoresistor or servo motors. The challenge came from working with the magnetometer. Neither of us had ever worked with a compass before. Learning how it worked required research, and finding the right library was a difficult process. The library we initially found was unnecessarily complicated and only worked part of the time. It required a lot of fiddling with to determine what exactly was the problem.  Figuring out how a new component worked and finding an appropriate library for the device was a new experience for us.

The project required a lot of tweaking to the maximum and minimum values in our code. Ensuring the inputs never went out of range and that the outputs were exactly what we wanted required us to constantly make slight edits and see how that affected the project. In addition to that, we had to make temporary code to test the range of values. Slight shifts in max and min values completely changed the rotation speed output, requiring us to carefully puzzle out the perfect range. The process gave us a new appreciation for constants in our code and valuable experience in testing a project.

 

Schematic

 

Code

  1. <span class="com">/*
  2. Project 1: Light Intensity to Rotation Speed
  3. Leah Walko
  4. Gracia Genero
  5. Description: A double transducer that turns light intensity into
  6. magnetic fields into rotation speed. A photoresistor picks up the
  7. intensity of the light. That value changes the location of a magnet.
  8. In turn, this affects the magnetic fields read by a compass, and based
  9. off that value a servo motor rotates at a faster or slower speed.
  10. Credit: QMC5883LCompass library creator, MRPrograms, for their xyz
  11. example code, and to the course's lectures and website.
  12. Pin mapping:
  13. pin | mode | description
  14. ------|--------|--------------------------------------------
  15. A1 | input | photocell to measure light intensity
  16. A4 | input | triple axis compass SDA input
  17. A5 | input | triple axis compass SCL input
  18. 10 | output | Servo motor that moves the magnet around
  19. 11 | output | 360 degrees servo motor with variable rotation speed
  20. SCL | output | I2C LCD
  21. SDA | output | I2C LCD
  22. */</span><span class="pln">
  23. </span><span class="com">// servo library</span><span class="pln">
  24. </span><span class="com">#include</span><span class="pln"> </span><span class="str"><Servo.h></span><span class="pln">
  25. </span><span class="com">// compass and lcd libraries</span><span class="pln">
  26. </span><span class="com">#include</span><span class="pln"> </span><span class="str"><Wire.h></span><span class="pln">
  27. </span><span class="com">#include</span><span class="pln"> </span><span class="str"><LiquidCrystal_I2C.h></span><span class="pln">
  28. </span><span class="com">#include</span><span class="pln"> </span><span class="str"><QMC5883LCompass.h></span><span class="pln">
  29. </span><span class="com">// pin values</span><span class="pln">
  30. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PHOTOPIN </span><span class="pun">=</span><span class="pln"> A1</span><span class="pun">;</span><span class="pln">
  31. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MOTORMAGPIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pun">;</span><span class="pln">
  32. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MOTORPIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">11</span><span class="pun">;</span><span class="pln">
  33. </span><span class="com">// range of possible values</span><span class="pln">
  34. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> ROTVAL_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">89</span><span class="pun">;</span><span class="pln">
  35. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> ROTVAL_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  36. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGANGLE_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">50</span><span class="pun">;</span><span class="pln">
  37. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGANGLE_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  38. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LIGHT_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1023</span><span class="pun">;</span><span class="pln">
  39. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LIGHT_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  40. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGVAL_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2700</span><span class="pun">;</span><span class="pln">
  41. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGVAL_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">7500</span><span class="pun">;</span><span class="pln">
  42. </span><span class="com">// timer for updating LCD</span><span class="pln">
  43. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> INTERVAL </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">;</span><span class="pln">
  44. </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> timer </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  45. </span><span class="com">// LCD values</span><span class="pln">
  46. </span><span class="kwd">int</span><span class="pln"> screenInput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  47. </span><span class="kwd">int</span><span class="pln"> screenMInput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  48. </span><span class="kwd">int</span><span class="pln"> screenMOutput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  49. </span><span class="kwd">int</span><span class="pln"> screenOutput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  50. </span><span class="com">// compass values</span><span class="pln">
  51. </span><span class="kwd">int</span><span class="pln"> x</span><span class="pun">;</span><span class="pln">
  52. </span><span class="kwd">int</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
  53. </span><span class="kwd">int</span><span class="pln"> z</span><span class="pun">;</span><span class="pln">
  54. </span><span class="com">// motor objects</span><span class="pln">
  55. </span><span class="typ">Servo</span><span class="pln"> magnetMotor</span><span class="pun">;</span><span class="pln"> </span><span class="com">// create a motor "object" called magnetMotor</span><span class="pln">
  56. </span><span class="typ">Servo</span><span class="pln"> rotatingMotor</span><span class="pun">;</span><span class="pln"> </span><span class="com">// create a motor "object" called rotatingMotor</span><span class="pln">
  57. </span><span class="com">// compass and LCD objects</span><span class="pln">
  58. QMC5883LCompass compass</span><span class="pun">;</span><span class="pln"> </span><span class="com">// create a compass "object" called compass</span><span class="pln">
  59. </span><span class="typ">LiquidCrystal_I2C</span><span class="pln"> screen</span><span class="pun">(</span><span class="lit">0x27</span><span class="pun">,</span><span class="pln"> </span><span class="lit">16</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">);</span><span class="pln"> </span><span class="com">// create a LCD "object" called screen</span><span class="pln">
  60. </span><span class="kwd">void</span><span class="pln"> setup</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  61. </span><span class="com">// setup the screen</span><span class="pln">
  62. screen</span><span class="pun">.</span><span class="pln">init</span><span class="pun">();</span><span class="pln">
  63. screen</span><span class="pun">.</span><span class="pln">backlight</span><span class="pun">();</span><span class="pln"> </span><span class="com">// turn on the backlight to start</span><span class="pln">
  64. screen</span><span class="pun">.</span><span class="pln">home</span><span class="pun">();</span><span class="pln"> </span><span class="com">// set cursor to home position</span><span class="pln">
  65. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"i:"</span><span class="pun">);</span><span class="pln"> </span><span class="com">// print out the unchanging parts of the values</span><span class="pln">
  66. screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
  67. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"m:"</span><span class="pun">);</span><span class="pln">
  68. screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">12</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  69. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"o:"</span><span class="pun">);</span><span class="pln">
  70. delay</span><span class="pun">(</span><span class="lit">2000</span><span class="pun">);</span><span class="pln"> </span><span class="com">// do nothing for 2 seconds</span><span class="pln">
  71. </span><span class="com">// setup the input pin -> photocell</span><span class="pln">
  72. pinMode</span><span class="pun">(</span><span class="pln">PHOTOPIN</span><span class="pun">,</span><span class="pln"> INPUT</span><span class="pun">);</span><span class="pln">
  73. </span><span class="com">// Initializing compass</span><span class="pln">
  74. compass</span><span class="pun">.</span><span class="pln">init</span><span class="pun">();</span><span class="pln">
  75. </span><span class="com">// setup the output -> motor moving the magnet + motor rotating</span><span class="pln">
  76. magnetMotor</span><span class="pun">.</span><span class="pln">attach</span><span class="pun">(</span><span class="pln">MOTORMAGPIN</span><span class="pun">);</span><span class="pln">
  77. rotatingMotor</span><span class="pun">.</span><span class="pln">attach</span><span class="pun">(</span><span class="pln">MOTORPIN</span><span class="pun">);</span><span class="pln">
  78. rotatingMotor</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="lit">90</span><span class="pun">);</span><span class="pln">
  79. </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">
  80. </span><span class="pun">}</span><span class="pln">
  81. </span><span class="kwd">void</span><span class="pln"> loop</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  82. </span><span class="com">// get info on light intensity</span><span class="pln">
  83. </span><span class="kwd">int</span><span class="pln"> lightVal </span><span class="pun">=</span><span class="pln"> analogRead</span><span class="pun">(</span><span class="pln">PHOTOPIN</span><span class="pun">);</span><span class="pln">
  84. </span><span class="com">// calculate the location of the magnet and move the motor to that angle</span><span class="pln">
  85. </span><span class="kwd">int</span><span class="pln"> magAngle </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">lightVal</span><span class="pun">,</span><span class="pln"> LIGHT_MIN</span><span class="pun">,</span><span class="pln"> LIGHT_MAX</span><span class="pun">,</span><span class="pln"> MAGANGLE_MIN</span><span class="pun">,</span><span class="pln"> MAGANGLE_MAX</span><span class="pun">);</span><span class="pln">
  86. magnetMotor</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">magAngle</span><span class="pun">);</span><span class="pln">
  87. </span><span class="com">// get the compass value </span><span class="pln">
  88. </span><span class="com">// Read compass values</span><span class="pln">
  89. compass</span><span class="pun">.</span><span class="pln">read</span><span class="pun">();</span><span class="pln">
  90. </span><span class="com">// Return XYZ readings from the compass</span><span class="pln">
  91. x </span><span class="pun">=</span><span class="pln"> compass</span><span class="pun">.</span><span class="pln">getX</span><span class="pun">();</span><span class="pln">
  92. y </span><span class="pun">=</span><span class="pln"> compass</span><span class="pun">.</span><span class="pln">getY</span><span class="pun">();</span><span class="pln">
  93. z </span><span class="pun">=</span><span class="pln"> compass</span><span class="pun">.</span><span class="pln">getZ</span><span class="pun">();</span><span class="pln">
  94. </span><span class="com">// calculate magnetic value</span><span class="pln">
  95. </span><span class="kwd">int</span><span class="pln"> magVal </span><span class="pun">=</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
  96. </span><span class="com">// calculate rotation speed</span><span class="pln">
  97. </span><span class="kwd">int</span><span class="pln"> rotateVal </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">magVal</span><span class="pun">,</span><span class="pln"> MAGVAL_MIN</span><span class="pun">,</span><span class="pln"> MAGVAL_MAX</span><span class="pun">,</span><span class="pln"> ROTVAL_MIN</span><span class="pun">,</span><span class="pln"> ROTVAL_MAX</span><span class="pun">);</span><span class="pln">
  98. </span><span class="com">// servo rotates at a speed of rotateVal (0 is faster, 90 is slower)</span><span class="pln">
  99. rotatingMotor</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">rotateVal</span><span class="pun">);</span><span class="pln">
  100. </span><span class="com">// Update LCD screen values</span><span class="pln">
  101. screenInput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">lightVal</span><span class="pun">,</span><span class="pln"> LIGHT_MIN</span><span class="pun">,</span><span class="pln"> LIGHT_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  102. screenMInput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">magAngle</span><span class="pun">,</span><span class="pln"> MAGANGLE_MIN</span><span class="pun">,</span><span class="pln"> MAGANGLE_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  103. screenMOutput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">magVal</span><span class="pun">,</span><span class="pln"> MAGVAL_MIN</span><span class="pun">,</span><span class="pln"> MAGVAL_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  104. screenOutput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">rotateVal</span><span class="pun">,</span><span class="pln"> ROTVAL_MIN</span><span class="pun">,</span><span class="pln"> ROTVAL_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  105. </span><span class="com">// Display updated LCD screen values only at specific time intervals</span><span class="pln">
  106. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">millis</span><span class="pun">()</span><span class="pln"> </span><span class="pun">>=</span><span class="pln"> timer</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  107. </span><span class="com">// print light val input</span><span class="pln">
  108. screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
  109. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenInput</span><span class="pun">);</span><span class="pln">
  110. </span><span class="com">// print the magnetic field output value</span><span class="pln">
  111. screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
  112. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenMInput</span><span class="pun">);</span><span class="pln">
  113. </span><span class="com">// print the magnetic field input value</span><span class="pln">
  114. screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  115. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenMOutput</span><span class="pun">);</span><span class="pln">
  116. </span><span class="com">// print the rotation speed output value</span><span class="pln">
  117. screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">14</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  118. screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenOutput</span><span class="pun">);</span><span class="pln">
  119. </span><span class="com">// reset timer</span><span class="pln">
  120. timer </span><span class="pun">=</span><span class="pln"> millis</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> INTERVAL</span><span class="pun">;</span><span class="pln">
  121. </span><span class="com">// serial output for testing purposes</span><span class="pln">
  122. </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">((</span><span class="typ">String</span><span class="pun">)</span><span class="str">"X: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> x </span><span class="pun">+</span><span class="pln">
  123. </span><span class="str">"; Y: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> y </span><span class="pun">+</span><span class="pln">
  124. </span><span class="str">"; Z: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> z</span><span class="pun">);</span><span class="pln">
  125. </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">((</span><span class="typ">String</span><span class="pun">)</span><span class="str">"room brightness: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> lightVal </span><span class="pun">+</span><span class="pln">
  126. </span><span class="str">"; magVal: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> magVal </span><span class="pun">+</span><span class="pln">
  127. </span><span class="str">"; rotateVal: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> rotateVal </span><span class="pun">+</span><span class="pln">
  128. </span><span class="str">"; magAngle: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> magAngle </span><span class="pun">);</span><span class="pln">
  129. </span><span class="pun">}</span><span class="pln">
  130. </span><span class="pun">}</span>
<span class="com">/*
   Project 1: Light Intensity to Rotation Speed
   Leah Walko
   Gracia Genero

   Description: A double transducer that turns light intensity into 
   magnetic fields into rotation speed. A photoresistor picks up the 
   intensity of the light. That value changes the location of a magnet. 
   In turn, this affects the magnetic fields read by a compass, and based 
   off that value a servo motor rotates at a faster or slower speed.

   Credit: QMC5883LCompass library creator, MRPrograms, for their xyz 
   example code, and to the course's lectures and website. 

   Pin mapping:

   pin   | mode   | description
   ------|--------|--------------------------------------------
   A1    | input  | photocell to measure light intensity
   A4    | input  | triple axis compass SDA input
   A5    | input  | triple axis compass SCL input
   10    | output | Servo motor that moves the magnet around
   11    | output | 360 degrees servo motor with variable rotation speed
   SCL   | output | I2C LCD
   SDA   | output | I2C LCD

*/</span><span class="pln">

</span><span class="com">// servo library</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str"><Servo.h></span><span class="pln">

</span><span class="com">// compass and lcd libraries</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str"><Wire.h></span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str"><LiquidCrystal_I2C.h></span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str"><QMC5883LCompass.h></span><span class="pln">


</span><span class="com">// pin values</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PHOTOPIN </span><span class="pun">=</span><span class="pln"> A1</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MOTORMAGPIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MOTORPIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">11</span><span class="pun">;</span><span class="pln">

</span><span class="com">// range of possible values</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> ROTVAL_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">89</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> ROTVAL_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> 
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGANGLE_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">50</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGANGLE_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> 
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LIGHT_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1023</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LIGHT_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> 
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGVAL_MAX </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2700</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MAGVAL_MIN </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">7500</span><span class="pun">;</span><span class="pln">

</span><span class="com">// timer for updating LCD</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> INTERVAL </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">;</span><span class="pln"> 
</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> timer </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">

</span><span class="com">// LCD values</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> screenInput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> screenMInput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> screenMOutput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> screenOutput </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> 

</span><span class="com">// compass values</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> x</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> z</span><span class="pun">;</span><span class="pln">

</span><span class="com">// motor objects</span><span class="pln">
</span><span class="typ">Servo</span><span class="pln"> magnetMotor</span><span class="pun">;</span><span class="pln"> </span><span class="com">// create a motor "object" called magnetMotor</span><span class="pln">
</span><span class="typ">Servo</span><span class="pln"> rotatingMotor</span><span class="pun">;</span><span class="pln"> </span><span class="com">// create a motor "object" called rotatingMotor</span><span class="pln">

</span><span class="com">// compass and LCD objects</span><span class="pln">
QMC5883LCompass compass</span><span class="pun">;</span><span class="pln"> </span><span class="com">// create a compass "object" called compass</span><span class="pln">
</span><span class="typ">LiquidCrystal_I2C</span><span class="pln"> screen</span><span class="pun">(</span><span class="lit">0x27</span><span class="pun">,</span><span class="pln"> </span><span class="lit">16</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">);</span><span class="pln"> </span><span class="com">// create a LCD "object" called screen</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> setup</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

  </span><span class="com">// setup the screen</span><span class="pln">
  screen</span><span class="pun">.</span><span class="pln">init</span><span class="pun">();</span><span class="pln">
  screen</span><span class="pun">.</span><span class="pln">backlight</span><span class="pun">();</span><span class="pln"> </span><span class="com">// turn on the backlight to start</span><span class="pln">
  screen</span><span class="pun">.</span><span class="pln">home</span><span class="pun">();</span><span class="pln"> </span><span class="com">// set cursor to home position</span><span class="pln">
  screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"i:"</span><span class="pun">);</span><span class="pln"> </span><span class="com">// print out the unchanging parts of the values</span><span class="pln">
  screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
  screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"m:"</span><span class="pun">);</span><span class="pln">
  screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">12</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"o:"</span><span class="pun">);</span><span class="pln">
  delay</span><span class="pun">(</span><span class="lit">2000</span><span class="pun">);</span><span class="pln"> </span><span class="com">// do nothing for 2 seconds</span><span class="pln">
  
  </span><span class="com">// setup the input pin -> photocell</span><span class="pln">
  pinMode</span><span class="pun">(</span><span class="pln">PHOTOPIN</span><span class="pun">,</span><span class="pln"> INPUT</span><span class="pun">);</span><span class="pln">

  </span><span class="com">// Initializing compass</span><span class="pln">
  compass</span><span class="pun">.</span><span class="pln">init</span><span class="pun">();</span><span class="pln">

  </span><span class="com">// setup the output -> motor moving the magnet + motor rotating</span><span class="pln">
  magnetMotor</span><span class="pun">.</span><span class="pln">attach</span><span class="pun">(</span><span class="pln">MOTORMAGPIN</span><span class="pun">);</span><span class="pln">
  rotatingMotor</span><span class="pun">.</span><span class="pln">attach</span><span class="pun">(</span><span class="pln">MOTORPIN</span><span class="pun">);</span><span class="pln">
  rotatingMotor</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="lit">90</span><span class="pun">);</span><span class="pln">

  </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">

</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> loop</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

  </span><span class="com">// get info on light intensity</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> lightVal </span><span class="pun">=</span><span class="pln"> analogRead</span><span class="pun">(</span><span class="pln">PHOTOPIN</span><span class="pun">);</span><span class="pln">

  </span><span class="com">// calculate the location of the magnet and move the motor to that angle</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> magAngle </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">lightVal</span><span class="pun">,</span><span class="pln"> LIGHT_MIN</span><span class="pun">,</span><span class="pln"> LIGHT_MAX</span><span class="pun">,</span><span class="pln"> MAGANGLE_MIN</span><span class="pun">,</span><span class="pln"> MAGANGLE_MAX</span><span class="pun">);</span><span class="pln">
  magnetMotor</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">magAngle</span><span class="pun">);</span><span class="pln">

  </span><span class="com">// get the compass value </span><span class="pln">
  </span><span class="com">// Read compass values</span><span class="pln">
  compass</span><span class="pun">.</span><span class="pln">read</span><span class="pun">();</span><span class="pln">
  </span><span class="com">// Return XYZ readings from the compass</span><span class="pln">
  x </span><span class="pun">=</span><span class="pln"> compass</span><span class="pun">.</span><span class="pln">getX</span><span class="pun">();</span><span class="pln">
  y </span><span class="pun">=</span><span class="pln"> compass</span><span class="pun">.</span><span class="pln">getY</span><span class="pun">();</span><span class="pln">
  z </span><span class="pun">=</span><span class="pln"> compass</span><span class="pun">.</span><span class="pln">getZ</span><span class="pun">();</span><span class="pln">

  </span><span class="com">// calculate magnetic value</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> magVal </span><span class="pun">=</span><span class="pln"> y</span><span class="pun">;</span><span class="pln"> 

  </span><span class="com">// calculate rotation speed</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> rotateVal </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">magVal</span><span class="pun">,</span><span class="pln"> MAGVAL_MIN</span><span class="pun">,</span><span class="pln"> MAGVAL_MAX</span><span class="pun">,</span><span class="pln"> ROTVAL_MIN</span><span class="pun">,</span><span class="pln"> ROTVAL_MAX</span><span class="pun">);</span><span class="pln">

  </span><span class="com">// servo rotates at a speed of rotateVal (0 is faster, 90 is slower)</span><span class="pln">
  rotatingMotor</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">rotateVal</span><span class="pun">);</span><span class="pln">
  
  </span><span class="com">// Update LCD screen values</span><span class="pln">
  screenInput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">lightVal</span><span class="pun">,</span><span class="pln"> LIGHT_MIN</span><span class="pun">,</span><span class="pln"> LIGHT_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  screenMInput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">magAngle</span><span class="pun">,</span><span class="pln"> MAGANGLE_MIN</span><span class="pun">,</span><span class="pln"> MAGANGLE_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  screenMOutput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">magVal</span><span class="pun">,</span><span class="pln"> MAGVAL_MIN</span><span class="pun">,</span><span class="pln"> MAGVAL_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln">
  screenOutput </span><span class="pun">=</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">rotateVal</span><span class="pun">,</span><span class="pln"> ROTVAL_MIN</span><span class="pun">,</span><span class="pln"> ROTVAL_MAX</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99</span><span class="pun">);</span><span class="pln"> 

  </span><span class="com">// Display updated LCD screen values only at specific time intervals</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">millis</span><span class="pun">()</span><span class="pln"> </span><span class="pun">>=</span><span class="pln"> timer</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// print light val input</span><span class="pln">
    screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
    screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenInput</span><span class="pun">);</span><span class="pln">
  
    </span><span class="com">// print the magnetic field output value</span><span class="pln">
    screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
    screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenMInput</span><span class="pun">);</span><span class="pln">
  
    </span><span class="com">// print the magnetic field input value</span><span class="pln">
    screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
    screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenMOutput</span><span class="pun">);</span><span class="pln">
  
    </span><span class="com">// print the rotation speed output value</span><span class="pln">
    screen</span><span class="pun">.</span><span class="pln">setCursor</span><span class="pun">(</span><span class="lit">14</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
    screen</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">screenOutput</span><span class="pun">);</span><span class="pln">

    </span><span class="com">// reset timer</span><span class="pln">
    timer </span><span class="pun">=</span><span class="pln"> millis</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> INTERVAL</span><span class="pun">;</span><span class="pln">

    </span><span class="com">// serial output for testing purposes</span><span class="pln">
    </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">((</span><span class="typ">String</span><span class="pun">)</span><span class="str">"X: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> x </span><span class="pun">+</span><span class="pln">
                         </span><span class="str">"; Y: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> y </span><span class="pun">+</span><span class="pln">
                         </span><span class="str">"; Z: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> z</span><span class="pun">);</span><span class="pln">
    
    </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">((</span><span class="typ">String</span><span class="pun">)</span><span class="str">"room brightness: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> lightVal </span><span class="pun">+</span><span class="pln">
                         </span><span class="str">"; magVal: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> magVal </span><span class="pun">+</span><span class="pln">
                         </span><span class="str">"; rotateVal: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> rotateVal </span><span class="pun">+</span><span class="pln">
                         </span><span class="str">"; magAngle: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> magAngle </span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span>