<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AlexanderLeung</id>
	<title>Mech - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AlexanderLeung"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/AlexanderLeung"/>
	<updated>2026-04-28T02:14:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8645</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8645"/>
		<updated>2008-03-21T08:23:29Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Circuit Components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|350px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Explanation ===&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
=== Other features ===&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
=== PIC Inputs ===&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
=== PIC Outputs ===&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Circuit Components ===&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parts List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
=== Modular Code ===&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Full Code ===&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Moves the motor to a pre-defined angle&lt;br /&gt;
void GoToAngle(int xangle,int yangle) {&lt;br /&gt;
   while ((Encoder1 &amp;lt; (angleref[xangle]-100)) &amp;amp;&amp;amp; (Encoder1 &amp;gt; (angleref[xangle]+100)) ) {      &lt;br /&gt;
      if (Encoder1&amp;lt;angleref[xangle]) set_pwm1_duty(78);&lt;br /&gt;
      if (Encoder1&amp;gt;angleref[xangle]) set_pwm1_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   while ((Encoder2 &amp;gt; (angleref[yangle]-100)) &amp;amp;&amp;amp; (Encoder2 &amp;gt; (angleref[yangle]+100)) ) {          &lt;br /&gt;
      if (Encoder2&amp;lt;angleref[yangle]) set_pwm2_duty(78);&lt;br /&gt;
      if (Encoder2&amp;gt;angleref[yangle]) set_pwm2_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int angleref[51] = {0, 91, 182, 273, 364, 455, 546, 637, 728, 819, 910, 1000, 1091, 1182, 1273, 1364, 1455, 1546, 1637, 1728, 1819, 1910, &lt;br /&gt;
                     2001, 2091, 2182, 2273, 2364, 2455, 2546, 2637, 2727, 2818, 2909, 3000, 3091, 3181, 3272, 3363, 3454, 3545, 3635, 3726, &lt;br /&gt;
                      3817, 3907, 3998, 4089, 4179, 4270, 4361, 4451, 4542}; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first box is the function that takes a desired x-angle and a desired y-angle and tells the motor to move to that position as fast as possible. The angles passed to the function are actually a value 10 times the angle (e.g. to move the screen to 2.5 degrees on the x-axis and 3.7 on the y-axis one would type &amp;lt;pre&amp;gt;GoToAngle(25,37)&amp;lt;/pre&amp;gt;). The second box is an array containing the encoder values associated with the the angle of one tenth of their index. For example, to encrease a tilt by 1.0 degrees, the encoder count would have to increase by the value of angleref[10], which is 910.&lt;br /&gt;
&lt;br /&gt;
The main problem with using this method was that we were having hard times reading the encoders, and it was very difficult to manually make the screen flat before every use, as would be necessary for this to work, as there was no other way to establish a base encounter count.&lt;br /&gt;
&lt;br /&gt;
Finally, the big problem we needed to tackle was a way to get a more consistent reading from the touchscreen, as this method led to a lot of false zeros. Putting a simple analog RC low pass filter did not work because the speed at which the PIC sampled the signal was too high, and the shaping of the curve would throw off the readings. A more complex analog filter might have improved this situation, but we chose to instead explore software filters. The software filters were moderately more successful, but they weren&amp;#039;t perfect and they caused our code to severely lack resolution in the readings, as too many of the values were thrown out. The problem might be fixed mechanically if a game piece with a higher friction coefficient were used than the steel ball, such as a square slider. Alternatively, a different [http://en.wikipedia.org/wiki/Touchscreen#Technologies type of touchscreen] could be used, such as an infrared touchscreen.&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8644</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8644"/>
		<updated>2008-03-21T08:23:08Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Circuit Components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|350px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Explanation ===&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
=== Other features ===&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
=== PIC Inputs ===&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
=== PIC Outputs ===&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Circuit Components ===&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parts List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
=== Modular Code ===&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Full Code ===&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Moves the motor to a pre-defined angle&lt;br /&gt;
void GoToAngle(int xangle,int yangle) {&lt;br /&gt;
   while ((Encoder1 &amp;lt; (angleref[xangle]-100)) &amp;amp;&amp;amp; (Encoder1 &amp;gt; (angleref[xangle]+100)) ) {      &lt;br /&gt;
      if (Encoder1&amp;lt;angleref[xangle]) set_pwm1_duty(78);&lt;br /&gt;
      if (Encoder1&amp;gt;angleref[xangle]) set_pwm1_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   while ((Encoder2 &amp;gt; (angleref[yangle]-100)) &amp;amp;&amp;amp; (Encoder2 &amp;gt; (angleref[yangle]+100)) ) {          &lt;br /&gt;
      if (Encoder2&amp;lt;angleref[yangle]) set_pwm2_duty(78);&lt;br /&gt;
      if (Encoder2&amp;gt;angleref[yangle]) set_pwm2_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int angleref[51] = {0, 91, 182, 273, 364, 455, 546, 637, 728, 819, 910, 1000, 1091, 1182, 1273, 1364, 1455, 1546, 1637, 1728, 1819, 1910, &lt;br /&gt;
                     2001, 2091, 2182, 2273, 2364, 2455, 2546, 2637, 2727, 2818, 2909, 3000, 3091, 3181, 3272, 3363, 3454, 3545, 3635, 3726, &lt;br /&gt;
                      3817, 3907, 3998, 4089, 4179, 4270, 4361, 4451, 4542}; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first box is the function that takes a desired x-angle and a desired y-angle and tells the motor to move to that position as fast as possible. The angles passed to the function are actually a value 10 times the angle (e.g. to move the screen to 2.5 degrees on the x-axis and 3.7 on the y-axis one would type &amp;lt;pre&amp;gt;GoToAngle(25,37)&amp;lt;/pre&amp;gt;). The second box is an array containing the encoder values associated with the the angle of one tenth of their index. For example, to encrease a tilt by 1.0 degrees, the encoder count would have to increase by the value of angleref[10], which is 910.&lt;br /&gt;
&lt;br /&gt;
The main problem with using this method was that we were having hard times reading the encoders, and it was very difficult to manually make the screen flat before every use, as would be necessary for this to work, as there was no other way to establish a base encounter count.&lt;br /&gt;
&lt;br /&gt;
Finally, the big problem we needed to tackle was a way to get a more consistent reading from the touchscreen, as this method led to a lot of false zeros. Putting a simple analog RC low pass filter did not work because the speed at which the PIC sampled the signal was too high, and the shaping of the curve would throw off the readings. A more complex analog filter might have improved this situation, but we chose to instead explore software filters. The software filters were moderately more successful, but they weren&amp;#039;t perfect and they caused our code to severely lack resolution in the readings, as too many of the values were thrown out. The problem might be fixed mechanically if a game piece with a higher friction coefficient were used than the steel ball, such as a square slider. Alternatively, a different [http://en.wikipedia.org/wiki/Touchscreen#Technologies type of touchscreen] could be used, such as an infrared touchscreen.&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8643</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8643"/>
		<updated>2008-03-21T08:22:47Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Circuit Components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|350px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Explanation ===&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
=== Other features ===&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
=== PIC Inputs ===&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
=== PIC Outputs ===&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Circuit Components ===&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Parts List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
=== Modular Code ===&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Full Code ===&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Moves the motor to a pre-defined angle&lt;br /&gt;
void GoToAngle(int xangle,int yangle) {&lt;br /&gt;
   while ((Encoder1 &amp;lt; (angleref[xangle]-100)) &amp;amp;&amp;amp; (Encoder1 &amp;gt; (angleref[xangle]+100)) ) {      &lt;br /&gt;
      if (Encoder1&amp;lt;angleref[xangle]) set_pwm1_duty(78);&lt;br /&gt;
      if (Encoder1&amp;gt;angleref[xangle]) set_pwm1_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   while ((Encoder2 &amp;gt; (angleref[yangle]-100)) &amp;amp;&amp;amp; (Encoder2 &amp;gt; (angleref[yangle]+100)) ) {          &lt;br /&gt;
      if (Encoder2&amp;lt;angleref[yangle]) set_pwm2_duty(78);&lt;br /&gt;
      if (Encoder2&amp;gt;angleref[yangle]) set_pwm2_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int angleref[51] = {0, 91, 182, 273, 364, 455, 546, 637, 728, 819, 910, 1000, 1091, 1182, 1273, 1364, 1455, 1546, 1637, 1728, 1819, 1910, &lt;br /&gt;
                     2001, 2091, 2182, 2273, 2364, 2455, 2546, 2637, 2727, 2818, 2909, 3000, 3091, 3181, 3272, 3363, 3454, 3545, 3635, 3726, &lt;br /&gt;
                      3817, 3907, 3998, 4089, 4179, 4270, 4361, 4451, 4542}; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first box is the function that takes a desired x-angle and a desired y-angle and tells the motor to move to that position as fast as possible. The angles passed to the function are actually a value 10 times the angle (e.g. to move the screen to 2.5 degrees on the x-axis and 3.7 on the y-axis one would type &amp;lt;pre&amp;gt;GoToAngle(25,37)&amp;lt;/pre&amp;gt;). The second box is an array containing the encoder values associated with the the angle of one tenth of their index. For example, to encrease a tilt by 1.0 degrees, the encoder count would have to increase by the value of angleref[10], which is 910.&lt;br /&gt;
&lt;br /&gt;
The main problem with using this method was that we were having hard times reading the encoders, and it was very difficult to manually make the screen flat before every use, as would be necessary for this to work, as there was no other way to establish a base encounter count.&lt;br /&gt;
&lt;br /&gt;
Finally, the big problem we needed to tackle was a way to get a more consistent reading from the touchscreen, as this method led to a lot of false zeros. Putting a simple analog RC low pass filter did not work because the speed at which the PIC sampled the signal was too high, and the shaping of the curve would throw off the readings. A more complex analog filter might have improved this situation, but we chose to instead explore software filters. The software filters were moderately more successful, but they weren&amp;#039;t perfect and they caused our code to severely lack resolution in the readings, as too many of the values were thrown out. The problem might be fixed mechanically if a game piece with a higher friction coefficient were used than the steel ball, such as a square slider. Alternatively, a different [http://en.wikipedia.org/wiki/Touchscreen#Technologies type of touchscreen] could be used, such as an infrared touchscreen.&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8612</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8612"/>
		<updated>2008-03-21T07:52:56Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results and Reflections==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Moves the motor to a pre-defined angle&lt;br /&gt;
void GoToAngle(int xangle,int yangle) {&lt;br /&gt;
   while ((Encoder1 &amp;lt; (angleref[xangle]-100)) &amp;amp;&amp;amp; (Encoder1 &amp;gt; (angleref[xangle]+100)) ) {      &lt;br /&gt;
      if (Encoder1&amp;lt;angleref[xangle]) set_pwm1_duty(78);&lt;br /&gt;
      if (Encoder1&amp;gt;angleref[xangle]) set_pwm1_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   while ((Encoder2 &amp;gt; (angleref[yangle]-100)) &amp;amp;&amp;amp; (Encoder2 &amp;gt; (angleref[yangle]+100)) ) {          &lt;br /&gt;
      if (Encoder2&amp;lt;angleref[yangle]) set_pwm2_duty(78);&lt;br /&gt;
      if (Encoder2&amp;gt;angleref[yangle]) set_pwm2_duty(0);&lt;br /&gt;
   }&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int angleref[51] = {0, 91, 182, 273, 364, 455, 546, 637, 728, 819, 910, 1000, 1091, 1182, 1273, 1364, 1455, 1546, 1637, 1728, 1819, 1910, &lt;br /&gt;
                     2001, 2091, 2182, 2273, 2364, 2455, 2546, 2637, 2727, 2818, 2909, 3000, 3091, 3181, 3272, 3363, 3454, 3545, 3635, 3726, &lt;br /&gt;
                      3817, 3907, 3998, 4089, 4179, 4270, 4361, 4451, 4542}; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first box is the function that takes a desired x-angle and a desired y-angle and tells the motor to move to that position as fast as possible. The angles passed to the function are actually a value 10 times the angle (e.g. to move the screen to 2.5 degrees on the x-axis and 3.7 on the y-axis one would type &amp;lt;pre&amp;gt;GoToAngle(25,37)&amp;lt;/pre&amp;gt;). The second box is an array containing the encoder values associated with the the angle of one tenth of their index. For example, to encrease a tilt by 1.0 degrees, the encoder count would have to increase by the value of angleref[10], which is 910.&lt;br /&gt;
&lt;br /&gt;
The main problem with using this method was that we were having hard times reading the encoders, and it was very difficult to manually make the screen flat before every use, as would be necessary for this to work, as there was no other way to establish a base encounter count.&lt;br /&gt;
&lt;br /&gt;
Finally, the big problem we needed to tackle was a way to get a more consistent reading from the touchscreen, as this method led to a lot of false zeros. Putting a simple analog RC low pass filter did not work because the speed at which the PIC sampled the signal was too high, and the shaping of the curve would throw off the readings. A more complex analog filter might have improved this situation, but we chose to instead explore software filters. The software filters were moderately more successful, but they weren&amp;#039;t perfect and they caused our code to severely lack resolution in the readings, as too many of the values were thrown out. The problem might be fixed mechanically if a game piece with a higher friction coefficient were used than the steel ball, such as a square slider. Alternatively, a different type of touchscreen could be used, such as an [http://en.wikipedia.org/wiki/Touchscreen#Infrared infrared touchscreen].&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8590</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8590"/>
		<updated>2008-03-21T06:52:34Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Results */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results and Reflections==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8589</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8589"/>
		<updated>2008-03-21T06:52:16Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Reflections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8588</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8588"/>
		<updated>2008-03-21T06:49:15Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Faulhaber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8587</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8587"/>
		<updated>2008-03-21T06:48:15Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Useful Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8586</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8586"/>
		<updated>2008-03-21T06:47:35Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.bergquistcompany.com/objects/touch_drawings/DRW_TS_400206_123rev.pdf BER237-ND]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8585</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8585"/>
		<updated>2008-03-21T06:46:26Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ti.com/lit/gpn/sn74hc04 SN74HC04]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8584</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8584"/>
		<updated>2008-03-21T06:45:32Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8583</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8583"/>
		<updated>2008-03-21T06:45:05Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[javascript:openreq(&amp;#039;http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pdf&amp;#039;) L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8582</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8582"/>
		<updated>2008-03-21T06:44:38Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.ortodoxism.ro/datasheets/texasinstruments/l293d.pd L293D] &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8581</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8581"/>
		<updated>2008-03-21T06:42:43Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://ww1.microchip.com/downloads/en/DeviceDoc/39631D.pdf PIC18F4520]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Although we got our project to the point where it worked well enough to show that we were able to create a working game, we definitely fell short of our goal of implementing a control system of not only stabilizing the ball, but also controlling its position and responding to disturbances. Listed below are our successes that greatly contributed to this project, as well as how they could be improved upon.&lt;br /&gt;
&lt;br /&gt;
*A robust mechanical design that allowed for more than adequate range of screen tilting, as well as good choices of equipment and materials for not only the job at hand, but also future implementations.&lt;br /&gt;
**The one shortcoming in this department is we should have had a higher threading ratio in that the linear motion of the screen should be greater per motor revolution in order to have a faster response.&lt;br /&gt;
*We were able to have proportional control between the position of the joystick and the speed of the motors.&lt;br /&gt;
**For automatic control we should have the tilting of the joystick proportional to the angle of the screen instead of the speed. We got this working to an extent before we scrapped the automatic contol. It is further explained below.&lt;br /&gt;
*We had a successful electric design that allowed for great flexibility within the software to do what we needed, while using a minimal amount of PIC inputs.&lt;br /&gt;
*The source code we wrote ended up being clean, well commented, and easy to modify and experiment with. The modular approach that we took with it will be helpful to future groups who will easily be able to glean portions of the code.&lt;br /&gt;
**Unfortunately the code had a couple bugs in it that were only able to be ironed out after the equipment was returned, including a poorly placed delay that caused a terrible refresh rate in the touchscreen and joystick response. These bugs caused a lot of gameplay issues, but although we have not been able to test the improved code, the changes we made were definitely harmless and would have greatly improved the gameplay.&lt;br /&gt;
*The game ended up being fun to play, and allowed for true interaction between man and machine. We were also able to successfully use the touchscreen, adding valuable information to the wiki about a previously unused technology.&lt;br /&gt;
**The responses of the game were clunky, the results of the game were somewhat unpredictable, and our coin slot didn&amp;#039;t work as seamlessly with the rest of the system as we would have liked.&lt;br /&gt;
&lt;br /&gt;
===Future Action===&lt;br /&gt;
&lt;br /&gt;
The main thing that would have been improved in our project if we had more time is the PIC control of the touchscreen. We put a great deal of effort into getting it working, but we simply ran out of time and had to scrap that idea not long before the project was due. Mechanically, we needed to have a better threading ratio on the bolts, and a more powerful motor would probably help as well. The rest of the work would be done on paper and in software.&lt;br /&gt;
&lt;br /&gt;
On paper, the first thing we would need to figure out a PD control system to control this ball. This would consist of an equation that relates the tilting angle necessary to counteract proportionally both the position of the ball on the touchscreen as well as the velocity of the ball. Counteracting the position of the ball would be very easy, and could simply be worked in software by telling the motors to tilt the screen so that it would roll towards the center, or whatever point we tell it to go to. Counteracting the velocy would be more tricky, as we would have to calculate the momentum of the ball, and then figure out the force necessary for counteracting the momentum. The screen would then have to be tilted so that the sine of the tilting angle times the gravitational constant would equal the necessary stopping force. We drafted some code for finding the velocity of the ball:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   //Measure velocity readings for motor encoder&lt;br /&gt;
   if (xcount&amp;gt;40 &amp;amp;&amp;amp; ycount&amp;gt;40) {         &lt;br /&gt;
      xold=xnew;&lt;br /&gt;
      xnew = (xmeasure/xcount);&lt;br /&gt;
      yold=ynew;         &lt;br /&gt;
      ynew = (ymeasure/ycount);&lt;br /&gt;
      xvelocity = (xnew-xold);&lt;br /&gt;
      yvelocity = (ynew-yold);&lt;br /&gt;
      xcount=0;&lt;br /&gt;
      ycount=0;&lt;br /&gt;
      xmeasure=0;&lt;br /&gt;
      ymeasure=0;&lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code averages good values (not misreadings) of each axis readings and then subtracts the from the old average to get a number that corresponds to a velocity. The main problem with this is that the occurence of misreadings was generally very high because of the small contact point between the steel ball and the screen.&lt;br /&gt;
&lt;br /&gt;
We also drafted some code to read the encoders and tilt the screen to the correct angle:&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8579</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8579"/>
		<updated>2008-03-21T06:34:50Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors, LED &amp;quot;strike&amp;quot; array, and buzzer. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8578</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8578"/>
		<updated>2008-03-21T06:33:37Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls and LED display|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8577</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8577"/>
		<updated>2008-03-21T06:31:40Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Team Members */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering MS 2009&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls to PIC|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8576</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8576"/>
		<updated>2008-03-21T06:27:46Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls to PIC|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
Toggle switches were added to allow easy powering on and off of our system. Also, a switch for automatic and manual control was implemented which was designed to have the purpose of switching the design from joystick control to automatic system control (self-adjusting touchscreen). The reset button was implemented to end the game at any time and end the main loop so that the motors would be inactive.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8575</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8575"/>
		<updated>2008-03-21T06:23:56Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
[[Image:TouchscreenControlpanel.JPG|left|thumb|Touch screen controls to PIC|200px]]&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:TouchscreenControlpanel.JPG&amp;diff=8574</id>
		<title>File:TouchscreenControlpanel.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:TouchscreenControlpanel.JPG&amp;diff=8574"/>
		<updated>2008-03-21T06:22:30Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8573</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8573"/>
		<updated>2008-03-21T06:21:12Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via [http://hades.mech.northwestern.edu/wiki/index.php/Pulse_Width_Modulation pulse width modulation], the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8572</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8572"/>
		<updated>2008-03-21T06:16:29Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two [http://hades.mech.northwestern.edu/wiki/index.php/Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder Falhauber motors] mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8571</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8571"/>
		<updated>2008-03-21T06:14:48Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two [http://hades.mech.northwestern.edu/wiki/index.php/Potentiometers potentiometers]) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8566</id>
		<title>Resistive Touchscreen</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8566"/>
		<updated>2008-03-21T06:05:27Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Bergquist hand ball balancing.jpg|[[A small Bergquist resistive touchscreen]]|right]]&lt;br /&gt;
&lt;br /&gt;
Resistive touchscreens are useful for measuring the position of an object on top of them, or as an interesting user interface feature.  The [http://www.bergquistcompany.com/touchscreens.cfm Bergquist] company sells them in a variety of sizes, ranging from 3.5 to 23 inches diagonal.  &lt;br /&gt;
&lt;br /&gt;
The 12.1 inch version was used in the [[Ball Balancing Challenge]] project.  Its [http://www.bergquistcompany.com/to_technical_specs.cfm specifications] can be found on the Bergquist website.  The screens are transparent and are meant to be installed over an LCD display; however, they are also useful in a horizontal orientation (as in the &amp;quot;Ball Balancing Challenge&amp;quot; project) for sensing the position of an object resting above.  &lt;br /&gt;
&lt;br /&gt;
According to the technical specifications, the activation force for this touch screen is 50g.  From experience, activation is more reliable with a heavier weight. The area of contact may also play a role in activation; metal balls rolling on the screen produced a slightly noisy signal which needed to be filtered for reliable use in a real-time system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
A resistive touchscreen is essentially a large variable resistor.  When a potential is put across two opposite sides of the touch screen, an output voltage can be read that is proportional to the touching distance between the activated sides.  The Bergqist screen is a 5-wire resistive screen; its connections consist of four wires going to each of the corners (upper left, upper right, lower left, lower right) and one that goes to the surface.  A potential across two opposite sides of the screen results in a gradient across the screen in that direction.  When the surface is pushed in at a certain point, it forms a circuit, the output voltage of which can be read as an analog input into a PIC chip.&lt;br /&gt;
&lt;br /&gt;
There are several ways to read a 5-wire resistive touchscreen.  In the &amp;quot;Ball Balancing Challenge&amp;quot; project, the voltage gradient in one direction was created by placing +5 volts on two adjacent corners (for example the upper right and upper left) and grounding the other two.  The position in the vertical direction was then read as proportional to the voltage on the middle (surface) wire.&lt;br /&gt;
&lt;br /&gt;
Of course, this method only allows for the reading of one axis of the screen at a time.  In order to read both the X and Y positions of the touchscreen, it is possible to use an interrupt service routine to switch rapidly between X and Y readings.  For example, the +5V side can be switched between X and Y positions by alternating the voltage between the upper left (UL) and upper right (UR) corners and the upper left and lower left (LL) corners.  Correspondingly, grounding will be switched between the lower left and lower right (LR) corners, and the upper right and lower right corners.  This results in a type of square wave output on the screen wire, with its voltage representing the vertical and horizontal positions alternatively.  &lt;br /&gt;
&lt;br /&gt;
The voltage gradient in both the X and Y directions is linearly distributed from +5V to ground.  Because the touch screens are typically rectangular, it may be necessary to multiply one of the readings by the screen&amp;#039;s aspect ratio in order to create an equal coordinate system.&lt;br /&gt;
&lt;br /&gt;
[[Image:Touchscreen.JPG|left|thumb|Touchscreen|200px]]&lt;br /&gt;
[[Image:Touchscreenribbon.JPG|right|thumb|Touchscreen cable for output|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
The voltage switching described above must be accomplished quickly and precisely (so as to avoid a shortage).  One way to accomplish this is to permanently power opposite corners with +5V and ground, and then switch the other two according to an ISR.  The alternating PIC output signal is sent to one of the corners, and the other one gets its opposite signal through an inverter.  The inverter ensures that only one axis of the touch screen is activated at a time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Touchscreen-circuit-diagram.JPG|center|thumb|Touchscreen Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
This code will power the touchscreen and take readings of the x and y axes. It might be a good idea when reading this code to put the touchscreen reading into an interrupt service routine so the screen can be read regardless of what else is going on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
touchscreen.c &lt;br /&gt;
Reads the touchscreen individually as two axes. &lt;br /&gt;
PIC powers either the Upper Left (Y-axis reading) or the Lower Right (X-axis reading) and grounds what it doesn&amp;#039;t power.&lt;br /&gt;
Output reading is the value on that axis.&lt;br /&gt;
Upper Left (UL) corner is PIN_C1, and Lower Left (LR) corner is always its inverse.&lt;br /&gt;
Upper Right (UR) corner is always high, and lower right (LL) is always ground, its inverse.&lt;br /&gt;
Peak voltage: Top reading voltage=4V and bottom reading voltage=1.2V&lt;br /&gt;
Reading is 0V when nothing is touching the screen.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }               &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.bergquistcompany.com/to_flexibility.cfm Bergquist Resistive Touchscreen Reference] &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8565</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8565"/>
		<updated>2008-03-21T06:02:13Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  [[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame). By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8564</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8564"/>
		<updated>2008-03-21T06:01:47Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  &lt;br /&gt;
[[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]] By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8563</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8563"/>
		<updated>2008-03-21T06:01:21Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
[[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]]&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8562</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8562"/>
		<updated>2008-03-21T06:00:50Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
[[Image:Coinslotopen.JPG|left|thumb|Coinslot with top off|200px]]&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8560</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8560"/>
		<updated>2008-03-21T05:58:49Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
[[Image:Coinslot.JPG|left|thumb|Coinslot|200px]]&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
[[Image:Coinslotopen.JPG|right|thumb|Coinslot with top off|200px]]&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8559</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8559"/>
		<updated>2008-03-21T05:58:29Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Coinslot.JPG|left|thumb|Coinslot|200px]]&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
[[Image:Coinslotopen.JPG|right|thumb|Coinslot with top off|200px]]&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8557</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8557"/>
		<updated>2008-03-21T05:56:20Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Coinslot.JPG|right|thumb|Coinslot|200px]]&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
[[Image:Coinslotopen.JPG|right|thumb|Coinslot with top off|200px]]&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
This project was programmed using [[CCS C]] on a PIC 18F4520. See the page on [[4520 Board use]] for more information on using the boards we used.&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8555</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8555"/>
		<updated>2008-03-21T05:52:37Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|thumb|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8554</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8554"/>
		<updated>2008-03-21T05:52:16Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Mechanical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|thumb|200px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Motorandconnection.JPG.JPG|right|thumb|Faulhaber Motor with epoxy connection to metal frame|200px]]&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Motorandconnection.JPG&amp;diff=8552</id>
		<title>File:Motorandconnection.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Motorandconnection.JPG&amp;diff=8552"/>
		<updated>2008-03-21T05:49:00Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Coinslotopen.JPG&amp;diff=8549</id>
		<title>File:Coinslotopen.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Coinslotopen.JPG&amp;diff=8549"/>
		<updated>2008-03-21T05:47:14Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Coinslot.JPG&amp;diff=8547</id>
		<title>File:Coinslot.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Coinslot.JPG&amp;diff=8547"/>
		<updated>2008-03-21T05:45:38Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8546</id>
		<title>Resistive Touchscreen</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8546"/>
		<updated>2008-03-21T05:42:27Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Bergquist hand ball balancing.jpg|[[A small Bergquist resistive touchscreen]]|right]]&lt;br /&gt;
&lt;br /&gt;
Resistive touchscreens are useful for measuring the position of an object on top of them, or as an interesting user interface feature.  The [http://www.bergquistcompany.com/touchscreens.cfm Bergquist] company sells them in a variety of sizes, ranging from 3.5 to 23 inches diagonal.  &lt;br /&gt;
&lt;br /&gt;
The 12.1 inch version was used in the [[Ball Balancing Challenge]] project.  Its [http://www.bergquistcompany.com/to_technical_specs.cfm specifications] can be found on the Bergquist website.  The screens are transparent and are meant to be installed over an LCD display; however, they are also useful in a horizontal orientation (as in the &amp;quot;Ball Balancing Challenge&amp;quot; project) for sensing the position of an object resting above.  &lt;br /&gt;
&lt;br /&gt;
According to the technical specifications, the activation force for this touch screen is 50g.  From experience, activation is more reliable with a heavier weight. The area of contact may also play a role in activation; metal balls rolling on the screen produced a slightly noisy signal which needed to be filtered for reliable use in a real-time system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
A resistive touchscreen is essentially a large variable resistor.  When a potential is put across two opposite sides of the touch screen, an output voltage can be read that is proportional to the touching distance between the activated sides.  The Bergqist screen is a 5-wire resistive screen; its connections consist of four wires going to each of the corners (upper left, upper right, lower left, lower right) and one that goes to the surface.  A potential across two opposite sides of the screen results in a gradient across the screen in that direction.  When the surface is pushed in at a certain point, it forms a circuit, the output voltage of which can be read as an analog input into a PIC chip.&lt;br /&gt;
&lt;br /&gt;
There are several ways to read a 5-wire resistive touchscreen.  In the &amp;quot;Ball Balancing Challenge&amp;quot; project, the voltage gradient in one direction was created by placing +5 volts on two adjacent corners (for example the upper right and upper left) and grounding the other two.  The position in the vertical direction was then read as proportional to the voltage on the middle (surface) wire.&lt;br /&gt;
&lt;br /&gt;
Of course, this method only allows for the reading of one axis of the screen at a time.  In order to read both the X and Y positions of the touchscreen, it is possible to use an interrupt service routine to switch rapidly between X and Y readings.  For example, the +5V side can be switched between X and Y positions by alternating the voltage between the upper left (UL) and upper right (UR) corners and the upper left and lower left (LL) corners.  Correspondingly, grounding will be switched between the lower left and lower right (LR) corners, and the upper right and lower right corners.  This results in a type of square wave output on the screen wire, with its voltage representing the vertical and horizontal positions alternatively.  &lt;br /&gt;
&lt;br /&gt;
The voltage gradient in both the X and Y directions is linearly distributed from +5V to ground.  Because the touch screens are typically rectangular, it may be necessary to multiply one of the readings by the screen&amp;#039;s aspect ratio in order to create an equal coordinate system.&lt;br /&gt;
&lt;br /&gt;
[[Image:Touchscreen.JPG|left|thumb|Touchscreen|200px]]&lt;br /&gt;
[[Image:Touchscreenribbon.JPG|right|thumb|Touchscreen cable for output|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
The voltage switching described above must be accomplished quickly and precisely (so as to avoid a shortage).  One way to accomplish this is to permanently power opposite corners with +5V and ground, and then switch the other two according to an ISR.  The alternating PIC output signal is sent to one of the corners, and the other one gets its opposite signal through an inverter.  The inverter ensures that only one axis of the touch screen is activated at a time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Touchscreen-circuit-diagram.JPG|center|thumb|Touchscreen Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
This code will power the touchscreen and take readings of the x and y axes. It might be a good idea when reading this code to put the touchscreen reading into an interrupt service routine so the screen can be read regardless of what else is going on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
touchscreen.c &lt;br /&gt;
Reads the touchscreen individually as two axes. &lt;br /&gt;
PIC powers either the Upper Left (Y-axis reading) or the Lower Right (X-axis reading) and grounds what it doesn&amp;#039;t power.&lt;br /&gt;
Output reading is the value on that axis.&lt;br /&gt;
Upper Left (UL) corner is PIN_C1, and Lower Left (LR) corner is always its inverse.&lt;br /&gt;
Upper Right (UR) corner is always high, and lower right (LL) is always ground, its inverse.&lt;br /&gt;
Peak voltage: Top reading voltage=4V and bottom reading voltage=1.2V&lt;br /&gt;
Reading is 0V when nothing is touching the screen.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }               &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. [http://en.wikipedia.org/wiki/Microphone Microphone - From Wikipedia, the free encyclopedia] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://www.national.com/nationaledge/dec02/article.html Integrated Circuits for High Performance Electret Microphones] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.bergquistcompany.com/to_flexibility.cfm Bergquist Resistive Touchscreen Reference] &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Touchscreenribbon.JPG&amp;diff=8545</id>
		<title>File:Touchscreenribbon.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Touchscreenribbon.JPG&amp;diff=8545"/>
		<updated>2008-03-21T05:41:27Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Touchscreen.JPG&amp;diff=8544</id>
		<title>File:Touchscreen.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Touchscreen.JPG&amp;diff=8544"/>
		<updated>2008-03-21T05:39:58Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8543</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8543"/>
		<updated>2008-03-21T05:34:04Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
The coin slot box was simply a ramp that would lead the dropped coin onto a conducting plate. The plate was supported by a weak spring that would bend under the weight of the coin to briefly touch another conducting plate below it before the coin rolled off. The brief contact between the two plates would send a high voltage to the PIC microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found [http://hades.mech.northwestern.edu/wiki/index.php/Resistive_Touchscreen here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8541</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8541"/>
		<updated>2008-03-21T05:32:12Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found here. [[Resistive Touchscreen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8540</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8540"/>
		<updated>2008-03-21T05:31:41Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Electrical Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
Information about the specifics, implementation and code that was used for the reading of the resistive touchscreen can be found here. [[Resistive Touchscreen]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8539</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8539"/>
		<updated>2008-03-21T05:28:49Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm resistive touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=ME_333_final_projects&amp;diff=8538</id>
		<title>ME 333 final projects</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=ME_333_final_projects&amp;diff=8538"/>
		<updated>2008-03-21T05:26:21Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;[[ME 333 end of course schedule]]&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== ME 333 Final Projects 2008 ==&lt;br /&gt;
&lt;br /&gt;
=== [[IR Tracker]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:IR_Tracker_Main.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
The IR Tracker (aka &amp;quot;Spot&amp;quot;) is a device that follows a moving infrared light. It continuously detects the position of an infrared emitter in two axes, and then tracks the emitter with a laser. [http://depot.northwestern.edu/mht363/public_html/IR%20Track/Mar%2019%20IR%20tracker.mp4 See Spot Run.]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Robot Snake]] ===&lt;br /&gt;
[[Image:HLSSnakeMain.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
This remote control robotic snake uses servo motors with a traveling sine wave motion profile to mimic serpentine motion.  The robotic snake is capable of moving forward, left, right and in reverse.   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Programmable Stiffness Joint]] === &lt;br /&gt;
&lt;br /&gt;
[[Image:SteelToePic2.jpg|thumb|200px|The &amp;#039;Steel Toe&amp;#039; programmable stiffness joint|right]]&lt;br /&gt;
&lt;br /&gt;
The Programmable Stiffness Joint varies rotational stiffness as desired by the user.  It is the first step in modeling the mechanical impedance of the human ankle joint (both stiffness and damping) for the purpose of determining the respective breakdown of the two properties over the gait cycle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Magnetic based sample purification]] ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [[Continuously Variable Transmission]] ===&lt;br /&gt;
&lt;br /&gt;
[[image:CVT_setup1.jpg|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
This prototype is a proof of concept model of a variable ratio transmission to be implemented in the 2008-2009 Formula SAE competition vehicle.  The gear ratio is determined by the distances between the pulley halves which are controllable electronically.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Granular Flow Rotating Sphere]] ===&lt;br /&gt;
&lt;br /&gt;
This device will be used to study the granular flow of particles within a rotating sphere. The sphere is filled with grains of varying size and then rotated about two different axes according to a series of position and angular velocity inputs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Vibratory Clock]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Vibratory_Clock.jpg|right|thumb|Vibratory Clock|200px]]&lt;br /&gt;
&lt;br /&gt;
The Vibratory Clock allows a small object to act as an hour &amp;quot;hand&amp;quot; on a horizontal circular platform that is actuated from underneath by three speakers.  The object slides around the circular platform, impelled by friction forces due to the vibration.  [http://www.youtube.com/watch?v=KhgTNCfdwZw Check it out!]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[WiiMouse]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:HPIM1027.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
The WiiMouse is a handheld remote that can be used to move a cursor on a windows-based PC, via accelerometer input captured through device movement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Intelligent Oscillation Controller]] ===&lt;br /&gt;
&lt;br /&gt;
[[image:ME333_learning_oscillator.jpg|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
This device &amp;quot;learns&amp;quot; a forcing function that is applied to a spring and mass system to match an arbitrary, periodic acceleration profile.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Baseball]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Baseball_Playfield.jpg|Sweet Baseball Game|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
An interactive baseball game inspired by pinball, featuring pitching, batting, light up bases and a scoreboard to keep track of the game.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Ball Balancing Challenge]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Ballbalancechallenge.JPG|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
An interactive game involving ball balancing on a touchscreen with touchscreen feedback and joystick action. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Ballbalancechallenge.JPG&amp;diff=8537</id>
		<title>File:Ballbalancechallenge.JPG</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Ballbalancechallenge.JPG&amp;diff=8537"/>
		<updated>2008-03-21T05:23:11Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8536</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8536"/>
		<updated>2008-03-21T05:04:30Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm touchscreen] with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8535</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8535"/>
		<updated>2008-03-21T05:04:18Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Based off an original idea of ball juggling, the purpose of our project was to test and gauge the capability of using a [http://www.bergquistcompany.com/touchscreens.cfm touchscreen]with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that would keep a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we would design a control system that would use a two-axis actuator system to move the touchscreen up and down depending on disturbances to keep the metal ball in the same place. Automatic control and manual control elements were to be implemented with the manual control element.&lt;br /&gt;
&lt;br /&gt;
However, due to complications with our touchscreen readings, our group decided to focus on the essentials of our project and have it focus on both the touchscreen capabilities and try to make the project as interactive as possible. A joystick (made from two potentiometers) was used to control the two motors which would lift the table up in either axis. The game begins with a coin machine which, when a coin is slided in, would set off a contact and initiate the motor control. The design of our game was so that the player would attempt to keep the ball in a restricted region in the middle of the touchscreen, which was marked in black. The outside region of the touchscreen, marked in red, would set off LED&amp;#039;s that would go off if the player stayed in the red region for an extended time. The player would lose after 4 LED&amp;#039;s light up and the buzzer goes off. The player can reset the game but the motor control would cease to function and a coin is needed to reactivate the game again.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
Our team weighed several alternatives for a mechanical system that could turn the screen in two axes.  Potential solutions included a gimble system with a double-frame design and a pully-operated system that would lift up on two sides of the screen.  Eventually, we decided on a system that was theoretically less precise, but much simpler and requiring less power (since one motor does not need to lift another).  The system worked well under joystick control, but is only reliable for small tilting angles.&lt;br /&gt;
&lt;br /&gt;
A sheet metal frame was built around the frame for protection, supported at its center of gravity by a pillar attached to the wooden base.  The frame can freely tilt in two directions, allowing all possible ball movements.  By raising and lowering two adjacent sides of the frame, the touch screen can be tilted in two directions.  This motion is provided by two Falhauber motors mounted underneath the screen.  The output shaft of the motors&amp;#039; gear boxes are attached to a threaded rod by couplers that we machined for the purpose.  The couplers are attached to the motor shaft by a radial set screw and to the threaded rods by locking nuts.  Riding on these rods are two threaded aluminum pieces, which are attached to the bottom of the frame via flexible tubing and epoxy.  As the angle of the screen changes in one direction, the location of the attachment of the other motor moves slightly relative to the base of the motor.  The flexible coupling allows for this motion, while providing vertical stability and transferring the up and down motion of the threaded pieces to the sides of the frame.  Provided that the tilt angle remains small, its value can be approximated by the inverse tangent of the vertical motion of the threaded rod divided by 9cm (the horizontal distance from the tubing connection to the center of the frame).  By controlling the speed of the motors via pulse width modulation, the tilt angles of the touch screen can be changed at a variety of speeds.&lt;br /&gt;
&lt;br /&gt;
Other features include adjustable legs for stabilizing the wooden base on an uneven surface, and an upper frame above the touchscreen that prevents the ball from rolling onto the non-sensing regions at the periphery of the touchscreen.  The mechanical design for this project was the simplest and most inexpensive option for this application; if a greater level of precision were required, a more complicated mechanism may have been necessary.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electrical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. This went to one of the PIC&amp;#039;s analog inputs. The coin would simply fall on a simple switch, connecting 5V to the PIC. The touchscreen input looks like a square wave, except the two values being received correspond to the voltage from each axis. Separating these two values is done in software.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the motors corresponds directly to the joystick input. The PIC output goes both to the H-bridge and an inverter for each motor, so that the motor sees not a PWM signal and ground, but a PWM signal with its inverse PWM signal. As a result of this, both poles of the motor see the same thing when the high and low pulses of the signal are equal. The motors turn one way proportionally to the joystick position when the PWM has more time high than low (when that joystick potentiometer is sending a higher signal)and the other way when the PWM is more low than high.&lt;br /&gt;
&lt;br /&gt;
The PIC output to the touchscreen is very simple. Although we had it go through an H-bridge to amplify the current, this is probably not necessary. Because the diagonally opposite corners of the touchscreen always have an opposite voltage going into them, we just ran the signal through an inverter so that we could control all four corners with only two PIC outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[media:T14-source-code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8428</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8428"/>
		<updated>2008-03-21T00:41:10Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The purpose of our project was to test and gauge the ability of using a touchscreen with a PIC Microcontroller. Our original projected means for testing the touchscreen for our project was to attempt to design and implement a system that keeps a round metal ball in the center of the touchscreen. Using the touchscreen&amp;#039;s analog outputs of position, we could use a two-axis actuator system to  to keep the ball stable. It will respond to disturbances to keep a metal ball in the same place.&lt;br /&gt;
&lt;br /&gt;
Our project is to use an infrared touch-screen to balance and move a ball in a controlled manner.  The ball will be balanced on top of the horizontally oriented screen and will be moved by tilting the screen in two axes.  &lt;br /&gt;
&lt;br /&gt;
To operate the device, a user would select a point on the screen (likely by touching it), and then would place a ball on the screen’s surface.  The ball’s position would be continually tracked by the touch screen’s infrared intersection array.  This information would be sent to a processor, which would control two motors and tilt the screen in order to move the ball to the selected location as quickly as possible. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The purpose of our project is to undertake the design and fabrication of a computer mouse that controls the on-computer cursor with hand movements in two dimensions -- roll and pitch (in the style of the WiiMote). We will accomplish this through the use of a two-axis accelerometer to determine the angle (x and y) of the remote relative to a preset (0, 0) and a XBee module for communication between the device and the computer. One of our primary goals will be to optimize the user’s experience by creating a device of reasonable size and weight, and focusing on an intuitive interface, in terms of cursor resolution and a tracking (cursor hold) button that is analogous to lifting a traditional mouse off a surface and relocating it.&lt;br /&gt;
&lt;br /&gt;
We built a horizontal circular platform that is actuated from underneath by three speakers placed in an equilateral triangle. The vibration of the platform causes a small object (e.g., an IC socket or a coin) to act as an hour &amp;quot;hand&amp;quot; on top of the platform.  The object slides around the circular platform, impelled by friction forces due to the vibration.  By placing the speakers at different phases and amplitudes, we got the objects to move to desired positions.  Due to the nodes created by the speaker vibrations, the object will move back to the correct hour if it is moved away.  Our project was given to us by Professor Colgate and was based upon the research of Professor Lynch.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
The Vibratory clock consists of a wooden base, held up by adjustable legs, three speakers, and a circular platform.  The following material were used to create the design:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Base:&amp;#039;&amp;#039;&lt;br /&gt;
*wood: 16&amp;quot; diameter, 0.75&amp;quot; thick&lt;br /&gt;
*holes: 6&amp;quot; diameter (3 total)&lt;br /&gt;
*adjustable legs: 3 rods: 3/8&amp;quot;-16; 4&amp;quot; long; 6 nuts total&lt;br /&gt;
&lt;br /&gt;
[[Image:speaker_supports.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Speakers:&amp;#039;&amp;#039;&lt;br /&gt;
*3 Pyramid Power PW677X: 300W, 4 Ohms, 6.5&amp;quot; Chrome Subwoofer&lt;br /&gt;
**previously adapted speakers replaced center of speaker with attachments 3&amp;quot; in height and 1/2&amp;quot; hole on top&lt;br /&gt;
**1/2&amp;quot; diameter PVC used to attach previous attachment to platform with a screw&lt;br /&gt;
***held in place by 2 set screws each&lt;br /&gt;
**centers placed 7.125&amp;quot; apart&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Circular Platform&amp;#039;&amp;#039;&lt;br /&gt;
*PVC/Acrylic: 11.75&amp;quot; diameter, 0.25&amp;quot; thick &lt;br /&gt;
**machined on the LaserJet&lt;br /&gt;
**screw holes counter-sunk at 7.125&amp;quot; apart&lt;br /&gt;
*2.875&amp;quot; above wooden base&lt;br /&gt;
*Silver Sharpie used for numbers&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Reasoning for Geometry of Design&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Equilateral Triangle:&amp;#039;&amp;#039;&lt;br /&gt;
By having the speakers equidistant from each other, we were able to create symmetry in our design, which made programming the various nodes much easier.  For example, we were able to use the same theory to find the node at 12 o&amp;#039;clock, 4 o&amp;#039;clock, and 8 o&amp;#039;clock.  If the speakers were not placed equidistant from each other, two speakers placed at equal amplitudes and opposite phases would not have created a sink in the exact middle of the two speakers.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Adjustable Legs:&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We needed to make the legs adjustable since it is essential that the platform be perfectly level in order for the objects placed on the platform to move in expected patterns.  For example, if one leg is slightly shorter than the other two, the objects placed on the platform would tend to move towards that leg and we could no longer rely on symmetry to program the various nodes due to the effects of gravity.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Height of Platform:&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Through our own experimentation and from [http://lims.mech.northwestern.edu/projects/frictioninducedforcefields/index.htm Professor Lynch&amp;#039;s research], we found that we needed to have the pivot point (i.e. the speaker diaphragm) significantly below the platform in order to create sinks.  At one point in the design process, we attempted to create a different pivot point by replacing the PVC with 1/2&amp;quot; outer diameter, 1/4&amp;quot; inner diameter Tygon 2001 tubing that only was able to bend in one point since it had stand-offs and screws inside the tube.  However, this replacement in a sense created two pivot points (the speaker diaphragm and the Tygon), causing the platform to only create sources and not sinks.  In addition, the different height of the pivot point may have also led to the plate acting differently.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-electronics-photo-closeup.JPG|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
The opening lines are necessary for establishing that we are using a PIC 18F4520, analog inputs, a clock, connecting with an ICD, and that we are using pin 36 instead of 16 for the second PWM output. This is also where we establish all of our variables and functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#DEVICE ADC=8                      // set ADC to 8 bit accuracy&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3      // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1)&lt;br /&gt;
#device icd=true&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int yread,xread,m,j=0;&lt;br /&gt;
int read1pwm,read2pwm=0;&lt;br /&gt;
int read1,read2=0;&lt;br /&gt;
int coin,strike,ball=0;&lt;br /&gt;
signed int16 counter=0;&lt;br /&gt;
&lt;br /&gt;
void buzz();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main function starts with setting the correct initial values to the variables, and setting up the timers and analog ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main() {&lt;br /&gt;
   //Flash 3 times to let us know we&amp;#039;re running&lt;br /&gt;
   for (j=0;j&amp;lt;3;j++){&lt;br /&gt;
      output_d(0b11111111);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(250);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter=0;&lt;br /&gt;
  &lt;br /&gt;
   output_high(PIN_C1);          //Start with UL high, LR low ***THESE WILL CHANGE***&lt;br /&gt;
   output_high(PIN_C0);          //This is the pin for UR. It will be run through an inverter for LL&lt;br /&gt;
                                 //the bottom left corner. ***THESE ARE PERMANENT***&lt;br /&gt;
  &lt;br /&gt;
   setup_adc_ports(AN0_TO_AN2);        // Enable analog inputs; choices run from just AN0, up to AN0_TO_AN11&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      // the range selected has to start with AN0&lt;br /&gt;
  &lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 77, 16);        // clock at 16KHz, interrupt every 4*50nS * 4 * (155+1) * 16 = 2.00mS&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_TIMER2);&lt;br /&gt;
   enable_interrupts(GLOBAL);  &lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(CCP_PWM);       // PWM output on CCP1/RC2, pin 17   this goes to y-axis motor&lt;br /&gt;
   setup_ccp2(CCP_PWM);       // PWM output on CCP2/RB3, pin 36   this goes to x-axis motor&lt;br /&gt;
&lt;br /&gt;
   set_pwm1_duty(39);&lt;br /&gt;
   set_pwm2_duty(39);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following portion of code shows what happens when the game is continuously played. First the game waits for a coin, then it plays the game until the user strikes out, then it stops the motors from spinning and again waits for a coin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
  &lt;br /&gt;
      set_pwm1_duty(39);&lt;br /&gt;
      set_pwm2_duty(39);&lt;br /&gt;
     &lt;br /&gt;
      //Wait for coin to be inserted&lt;br /&gt;
      while (coin==0) {                &lt;br /&gt;
         if (input(PIN_E1)) coin=1;&lt;br /&gt;
         else delay_ms(100);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Gameplay begins. Controls go dead when strikes go too high; &lt;br /&gt;
      while (coin==1) {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The touchscreen is read by having the PIC send alternating signals to 2 of the corners that are diagonal to each other while keeping the other two signals constant. This allows the touchscreen to read both axes each run through, and then display them in a manner where the x-axis reading corresponds to PIC LED outputs D0-D3, and the y-axis reading corresponds to outputs D4-D7. Although this gives visually a very poor resolution on the reading, it serves well enough as a debugging tool to make sure the reading is working. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Touchscreen reading, looks at the touchscreen readings&lt;br /&gt;
         if (m==0) {&lt;br /&gt;
            output_high(PIN_C1);       //UL goes high, thus LR goes low; y-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            yread = read_adc();       //Read y axis           &lt;br /&gt;
            m++;&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_low(PIN_C1);        //UL goes low, thus LR goes high; x-axis can be read&lt;br /&gt;
            set_adc_channel(0);&lt;br /&gt;
            delay_us(10);          &lt;br /&gt;
            xread = read_adc();       //Read x axis&lt;br /&gt;
            m=0;&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         //LED readings for XY locations of the touchscreen&lt;br /&gt;
         if (xread&amp;lt;75) {                &lt;br /&gt;
            output_low(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_low(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_low(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else if (xread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_low(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D0);     &lt;br /&gt;
            output_high(PIN_D1);&lt;br /&gt;
            output_high(PIN_D2);&lt;br /&gt;
            output_high(PIN_D3);&lt;br /&gt;
         }&lt;br /&gt;
         if (yread&amp;lt;75) {&lt;br /&gt;
            output_low(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;110) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_low(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;145) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_low(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else if (yread&amp;lt;180) {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_low(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
         else  {&lt;br /&gt;
            output_high(PIN_D4);     &lt;br /&gt;
            output_high(PIN_D5);&lt;br /&gt;
            output_high(PIN_D6);&lt;br /&gt;
            output_high(PIN_D7);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To find the &amp;quot;winning&amp;quot; ranges of the black area on the touchscreen, we measured the voltage output on each axis on each boundary line, and converted it from the 0V to 5V scale to the quantized 8 bit (0 to 255) scale. Our code then checks to see if the ball is not in this zone before assigning a strike to the user. The counter variable is to ensure that the ball is outside the range enough times  in a row, and a low reading is not simply the result of inconsistencies in the touchscreen reading.&lt;br /&gt;
To stop the machine from simply running up the strikes while the ball is in the red, the code ensures that a &amp;quot;strike&amp;quot; cannot be assigned until a &amp;quot;ball&amp;quot; is assigned before hand.&lt;br /&gt;
&lt;br /&gt;
For each strike, a corresponding LED is lit up, and upon the last strike, the buzz function is set off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Check to see if the Ball is outide the allowed range of values to be &amp;quot;in the black&amp;quot; of the touchscreen&lt;br /&gt;
         if ((yread&amp;lt; 90) | (yread &amp;gt;150) | (xread &amp;lt;90) | (xread &amp;gt; 150)) {&lt;br /&gt;
            counter++;&lt;br /&gt;
            if ((counter==3) &amp;amp;&amp;amp; (strike==ball)) {&lt;br /&gt;
               strike++;         //If ball is &amp;quot;in the red&amp;quot; for a sufficiently long time, a strike is added.&lt;br /&gt;
            }&lt;br /&gt;
         }       &lt;br /&gt;
         else {&lt;br /&gt;
            counter--;&lt;br /&gt;
            //Check to see if the ball has returned from being &amp;quot;in the red.&amp;quot;&lt;br /&gt;
            if ((counter==-1)  &amp;amp;&amp;amp; (strike&amp;gt;ball)) {&lt;br /&gt;
               ball++;&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
        &lt;br /&gt;
         if ((counter==3) | (counter == -2)) counter=0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
         if (strike==2) {&lt;br /&gt;
            output_high(PIN_A3);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==3) {&lt;br /&gt;
            output_high(PIN_A4);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==4) {&lt;br /&gt;
            output_high(PIN_A5);&lt;br /&gt;
         }&lt;br /&gt;
         if (strike==5) {&lt;br /&gt;
            output_high(PIN_E2);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
            buzz();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
 &lt;br /&gt;
        &lt;br /&gt;
     &lt;br /&gt;
The PIC reads the joystick and quantizes the input from the analog 0V to 5V to the 8 bit quantized 0 to 255. It then scales that number to be between 0 and 78, the PWM extremes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         //Joystick Control&lt;br /&gt;
         if (input(PIN_C7) != 0) {  // toggle switch that switches between Joystick control system and Touchscreen control system&lt;br /&gt;
            set_adc_channel(2);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN1&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read1 = read_adc();                       //x-axis&lt;br /&gt;
            if (read1&amp;lt;145 &amp;amp;&amp;amp; read1&amp;gt;115) read1pwm=39;&lt;br /&gt;
            else read1pwm=(read1*.3);&lt;br /&gt;
            set_pwm1_duty(read1pwm);&lt;br /&gt;
           &lt;br /&gt;
            set_adc_channel(1);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN2&lt;br /&gt;
            delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
            read2 = read_adc();                      //y-axis&lt;br /&gt;
            if (read2&amp;lt;145 &amp;amp;&amp;amp; read2&amp;gt;115) read2pwm=39;&lt;br /&gt;
            else read2pwm=(read2*.3);&lt;br /&gt;
            set_pwm2_duty(read2pwm);&lt;br /&gt;
         }&lt;br /&gt;
         else {&lt;br /&gt;
            output_d(0);&lt;br /&gt;
            set_pwm1_duty(39);&lt;br /&gt;
            set_pwm2_duty(39);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The buzz() function resets the counting variables to zero and sets the buzzer off by oscillating a PIC output into a basic buzzer speaker at an audible frequency.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void buzz() {&lt;br /&gt;
&lt;br /&gt;
   coin=0;&lt;br /&gt;
   strike=0;&lt;br /&gt;
   ball=0;&lt;br /&gt;
   counter = 0;&lt;br /&gt;
   output_low(PIN_A3);&lt;br /&gt;
   output_low(PIN_A4);  &lt;br /&gt;
   output_low(PIN_A5);&lt;br /&gt;
   output_low(PIN_E2);&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
   while (input(PIN_C6)==0) {&lt;br /&gt;
      output_high(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
      output_low(PIN_C4);&lt;br /&gt;
      delay_us(100);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
[[Image:VibratoryClock.jpg|right|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
We were able to get our project working so that the plate moves an object placed anywhere on the plate to the correct time and then moves the objects around the clock face, acting as the hour &amp;quot;hand&amp;quot; of a clock.  However, we increased the speed so that it takes about 2 minutes for objects placed on the clock to move around so that it is easy to demonstrate.  Check out the working Vibratory Clock [http://www.youtube.com/watch?v=KhgTNCfdwZw here].&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;br /&gt;
&lt;br /&gt;
[http://lims.mech.northwestern.edu/projects/frictioninducedforcefields/index.htm Vibration-Induced Frictional Force Fields for Part Manipulation]&lt;br /&gt;
&lt;br /&gt;
[http://www.cs.berkeley.edu/~jfc/dreznik/UPM2000/index.html Universal Planar Manipulator]&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8411</id>
		<title>Ball Balancing Challenge</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8411"/>
		<updated>2008-03-20T23:54:08Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:T14-project-action-08.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==Team Members==&lt;br /&gt;
[[Image:T14-project-group-08.jpg|right|Left to right: JJ Darling, Alex Leung, Ben Schriesheim|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
*JJ Darling - Electrical Engineering Class of 2009&lt;br /&gt;
*Ben Schriesheim - Manufacturing Engineering Class of 2008&lt;br /&gt;
*Alex Leung - Biomedical Engineering Graduate Student&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
We built a horizontal circular platform that is actuated from underneath by three speakers placed in an equilateral triangle. The vibration of the platform causes a small object (e.g., an IC socket or a coin) to act as an hour &amp;quot;hand&amp;quot; on top of the platform.  The object slides around the circular platform, impelled by friction forces due to the vibration.  By placing the speakers at different phases and amplitudes, we got the objects to move to desired positions.  Due to the nodes created by the speaker vibrations, the object will move back to the correct hour if it is moved away.  Our project was given to us by Professor Colgate and was based upon the research of Professor Lynch.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
The Vibratory clock consists of a wooden base, held up by adjustable legs, three speakers, and a circular platform.  The following material were used to create the design:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Base:&amp;#039;&amp;#039;&lt;br /&gt;
*wood: 16&amp;quot; diameter, 0.75&amp;quot; thick&lt;br /&gt;
*holes: 6&amp;quot; diameter (3 total)&lt;br /&gt;
*adjustable legs: 3 rods: 3/8&amp;quot;-16; 4&amp;quot; long; 6 nuts total&lt;br /&gt;
&lt;br /&gt;
[[Image:speaker_supports.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Speakers:&amp;#039;&amp;#039;&lt;br /&gt;
*3 Pyramid Power PW677X: 300W, 4 Ohms, 6.5&amp;quot; Chrome Subwoofer&lt;br /&gt;
**previously adapted speakers replaced center of speaker with attachments 3&amp;quot; in height and 1/2&amp;quot; hole on top&lt;br /&gt;
**1/2&amp;quot; diameter PVC used to attach previous attachment to platform with a screw&lt;br /&gt;
***held in place by 2 set screws each&lt;br /&gt;
**centers placed 7.125&amp;quot; apart&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Circular Platform&amp;#039;&amp;#039;&lt;br /&gt;
*PVC/Acrylic: 11.75&amp;quot; diameter, 0.25&amp;quot; thick &lt;br /&gt;
**machined on the LaserJet&lt;br /&gt;
**screw holes counter-sunk at 7.125&amp;quot; apart&lt;br /&gt;
*2.875&amp;quot; above wooden base&lt;br /&gt;
*Silver Sharpie used for numbers&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Reasoning for Geometry of Design&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Equilateral Triangle:&amp;#039;&amp;#039;&lt;br /&gt;
By having the speakers equidistant from each other, we were able to create symmetry in our design, which made programming the various nodes much easier.  For example, we were able to use the same theory to find the node at 12 o&amp;#039;clock, 4 o&amp;#039;clock, and 8 o&amp;#039;clock.  If the speakers were not placed equidistant from each other, two speakers placed at equal amplitudes and opposite phases would not have created a sink in the exact middle of the two speakers.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Adjustable Legs:&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We needed to make the legs adjustable since it is essential that the platform be perfectly level in order for the objects placed on the platform to move in expected patterns.  For example, if one leg is slightly shorter than the other two, the objects placed on the platform would tend to move towards that leg and we could no longer rely on symmetry to program the various nodes due to the effects of gravity.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Height of Platform:&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Through our own experimentation and from [http://lims.mech.northwestern.edu/projects/frictioninducedforcefields/index.htm Professor Lynch&amp;#039;s research], we found that we needed to have the pivot point (i.e. the speaker diaphragm) significantly below the platform in order to create sinks.  At one point in the design process, we attempted to create a different pivot point by replacing the PVC with 1/2&amp;quot; outer diameter, 1/4&amp;quot; inner diameter Tygon 2001 tubing that only was able to bend in one point since it had stand-offs and screws inside the tube.  However, this replacement in a sense created two pivot points (the speaker diaphragm and the Tygon), causing the platform to only create sources and not sinks.  In addition, the different height of the pivot point may have also led to the plate acting differently.&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
The Electical Design was fairly simple for this project. The inputs to the PIC were the joystick, coin slot, and the touchscreen. The outputs were the motors and the LED &amp;quot;strike&amp;quot; array. The touchscreen was also an output as it was controlled by the PIC.&lt;br /&gt;
&lt;br /&gt;
The user would control the joystick that was simply two potentiometers that would output a value between 0V and 5V, corresponding to both the x-axis and the y-axis. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Circuit_Photo_Team22.jpg|right|thumb|Circuit Board|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Component List:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Vendor&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price (Total)&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller (U1)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Quadruple Half-H Drivers&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293D &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.93&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$0.47&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Touchscreen&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;BER237-ND&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[http://www.digikey.com Digi-Key]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$62.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Joystick&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Circuit Diagram:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:T14-schematic 1.JPG|center|thumb|Ball Balancing Circuit Diagram|600px]]&lt;br /&gt;
&lt;br /&gt;
==Software Design==&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
[[Image:VibratoryClock.jpg|right|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
We were able to get our project working so that the plate moves an object placed anywhere on the plate to the correct time and then moves the objects around the clock face, acting as the hour &amp;quot;hand&amp;quot; of a clock.  However, we increased the speed so that it takes about 2 minutes for objects placed on the clock to move around so that it is easy to demonstrate.  Check out the working Vibratory Clock [http://www.youtube.com/watch?v=KhgTNCfdwZw here].&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
==Useful Resources==&lt;br /&gt;
&lt;br /&gt;
[http://lims.mech.northwestern.edu/projects/frictioninducedforcefields/index.htm Vibration-Induced Frictional Force Fields for Part Manipulation]&lt;br /&gt;
&lt;br /&gt;
[http://www.cs.berkeley.edu/~jfc/dreznik/UPM2000/index.html Universal Planar Manipulator]&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microphones&amp;diff=7061</id>
		<title>Microphones</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microphones&amp;diff=7061"/>
		<updated>2008-02-19T23:45:01Z</updated>

		<summary type="html">&lt;p&gt;AlexanderLeung: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
This project is to demonstrate a &amp;quot;clapper&amp;quot; device using an electret microphone (e.g., the 423-1024-ND from digikey).  Build an appropriate circuit and write a program to continuously display the volume of the sound it receives as a &amp;quot;light bar&amp;quot; on the PIC board LEDs.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;clapper&amp;quot; device was built using a PIC 18F4520 and an [http://en.wikipedia.org/wiki/Electret_microphone electret condenser microphone] (in this case, the [http://www.knowles.com/search/prods_pdf/MD9745APA-1.pdf 423-1024-ND] from digikey) as an analog input. The device operates on the principle that the microphone will convert the sound into an analog input to the PIC and, as the sound increases in volume, the analog input&amp;#039;s amplitude will increase. This input is then converted into an output on the set of LEDs soldered onto the PIC&amp;#039;s circuit board. This output works as a light bar; it displays the minimum one LED for quiet sound levels and activates additional LEDs as the sound becomes louder -- up to a maximum of eight.  The sensitivity of the microphone is adjustable through a gain potentiometer. &lt;br /&gt;
&lt;br /&gt;
[[image:ElectretMicrophone.gif|thumb|300px|[[Interior of Electret Microphone]]|right]]&lt;br /&gt;
[[image:Electret_condenser_microphone_capsules.jpg|thumb|350px|[[Electret condenser microphone capsules]]|left]]&lt;br /&gt;
&lt;br /&gt;
The most commonly used microphones for audio use capacitance charge (condenser microphones), electromagnetic generation (dynamic microphones), or piezoelectric generation.  In a [http://en.wikipedia.org/wiki/Condenser_microphone#Condenser.2C_capacitor_or_electrostatic_microphones condenser microphone], a thin membrane of the microphone acts as one plate of a capacitor and a nearly constant charge is maintained on the capacitor. The voltage maintained across the capacitor plates changes with the vibrations in the air, according to the capacitance equation: &lt;br /&gt;
:&amp;lt;math&amp;gt;Q = C \cdot V&amp;lt;/math&amp;gt;  where Q = charge in coulombs, C = capacitance in farads and V = potential difference in volts, resulting in a change in output voltage. Power is necessary for establishing the capacitor plate voltage, and is also needed for internal amplification of the signal to a useful output level. Electret microphones, a type of condenser microphone, replace the externally-applied charge with a permanently fixed-charged material.  The electret is a stable dielectric material with a permanently-embedded static charge. Electret microphones require no polarizing voltage but, due to their integrated pre-amplifier, require a small amount of power either from microphone inputs as phantom power or from a small battery. Due to mass-production of these devices, electret microphones lack the precision needed for high-quality microphones.&lt;br /&gt;
&lt;br /&gt;
Due to the variable nature of ambient noise, a calibration &amp;quot;reset&amp;quot; button was included that would reset the output LEDs based on the environment&amp;#039;s baseline noise level. This calibration was done via software averaging of the ambient volume level. The device that is built currently follows the principles of the clapper device in that the higher the analog input is received, the more LEDs will be shown. However, due to the brevity of the audio input peak for shorter signals such as a clap, it is sometimes difficult to see the correspondingly brief output.  A further step would be to install a software switch that would detect the characteristic sound pattern of a clap and activate a digital output upon recognition.&lt;br /&gt;
&lt;br /&gt;
Of the three microphones tested for the clapper device (Electret Microphone, [http://www.sonystyle.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=10551&amp;amp;storeId=10151&amp;amp;langId=-1&amp;amp;productId=11037550 Sony F-V100], and a small dynamic microphone), the electret microphone showed the greatest sensitivity to varying noise levels.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
The circuit built for this example uses an electret microphone to listen to external sound and displays the volume level as a light bar on the PIC board LEDs.  The microphone uses a single analog input pin of the PIC.&lt;br /&gt;
&lt;br /&gt;
Optional features present in the shown circuit diagram include a potentiometer gain knob for adjusting the microphone&amp;#039;s sensitivity and a calibration button for setting the baseline ambient noise level.  The code governing the operation of the calibration button is included below; the button itself is wired into a digital input of the PIC. Refer to the photo and diagram for details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:400px-Microphone_circuit.JPG|thumb|400px|[[Microphone Circuit and PIC photo]]|right]] [[image:Mic_circuit_diagram4.JPG|thumb|400px|[[Microphone Circuit and PIC diagram]]|left]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
microphone.c by JJ Darling, Alex Leung, Ben Schriesheim&lt;br /&gt;
This code will take an analog microphone input and display the power of the single &lt;br /&gt;
as an easily read LED array. One light on means the input matches the ambient noise,&lt;br /&gt;
and all eight lights on means the microphone is receiving a loud noise.&lt;br /&gt;
&lt;br /&gt;
The reset button can be used to match the lowest output to the ambient noise.&lt;br /&gt;
&lt;br /&gt;
This code was derived off of the analog input code written by Prof. Michael Peshkin, which&lt;br /&gt;
can be found in the source code repository on this wiki.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#DEVICE ADC=8                  // set ADC to 8 bit accuracy.&lt;br /&gt;
&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=20000000)&lt;br /&gt;
&lt;br /&gt;
signed int16 value;&lt;br /&gt;
int16 valueinit=0;&lt;br /&gt;
int k=0;&lt;br /&gt;
void initialize();&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
   setup_adc_ports(AN0);        // Enable analog inputs AN0;&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);     &lt;br /&gt;
   initialize(); &lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
   while (TRUE) {&lt;br /&gt;
   &lt;br /&gt;
      set_adc_channel(0);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN0&lt;br /&gt;
      delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
      &lt;br /&gt;
      if (input(PIN_C0)&amp;gt;0)  initialize();   //Initialize the base output to match ambient noise&lt;br /&gt;
      &lt;br /&gt;
      value = read_adc();     // now you can read ADC as frequently as you like&lt;br /&gt;
      &lt;br /&gt;
      //Create a gain to dramatically differentiate the input level from ambient noise&lt;br /&gt;
      if ((value-valueinit)&amp;lt;0) value=0;   &lt;br /&gt;
      value=(value-valueinit)*20;&lt;br /&gt;
      &lt;br /&gt;
   if (value&amp;lt;32)              //Easy to read volume meter&lt;br /&gt;
      output_d(0b1);&lt;br /&gt;
   else if (value&amp;lt;64)&lt;br /&gt;
      output_d(0b11);&lt;br /&gt;
   else if (value&amp;lt;96)&lt;br /&gt;
      output_d(0b111);&lt;br /&gt;
   else if (value&amp;lt;128)&lt;br /&gt;
      output_d(0b1111);&lt;br /&gt;
   else if (value&amp;lt;160)&lt;br /&gt;
      output_d(0b11111);&lt;br /&gt;
   else if (value&amp;lt;192)&lt;br /&gt;
      output_d(0b111111);&lt;br /&gt;
   else if (value&amp;lt;224)&lt;br /&gt;
      output_d(0b1111111);&lt;br /&gt;
   else&lt;br /&gt;
      output_d(0b11111111);           &lt;br /&gt;
      &lt;br /&gt;
   if (value&amp;gt;128) delay_ms(200);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Take samples to establish an initial value to &amp;#039;tare&amp;#039; the ambient noise.&lt;br /&gt;
void initialize() {&lt;br /&gt;
   &lt;br /&gt;
   delay_ms(1000);       //Give enough time for the user to release the &amp;quot;reset&amp;quot; button     &lt;br /&gt;
   &lt;br /&gt;
   valueinit=0;&lt;br /&gt;
   &lt;br /&gt;
   //Read 100 input levels and take their average. This a measure of the ambient noise&lt;br /&gt;
   for (k=0;k&amp;lt;100;k++) &lt;br /&gt;
   {&lt;br /&gt;
      set_adc_channel(0);     // there&amp;#039;s only one ADC so select which input to connect to it; here pin AN0&lt;br /&gt;
      delay_us(10);           // wait 10uS for ADC to settle to a newly selected input&lt;br /&gt;
      valueinit+=read_adc();&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   valueinit = (valueinit/100);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. [http://en.wikipedia.org/wiki/Microphone Microphone - From Wikipedia, the free encyclopedia] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://www.national.com/nationaledge/dec02/article.html Integrated Circuits for High Performance Electret Microphones] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.hosiden.co.jp/web/english/web/products/pdf/e_on06_mic.pdf Guide for Electret Condenser Microphones] &amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.soundonsound.com/sos/1995_articles/jun95/microphones.html CHOOSING A MICROPHONE: Microphone types and uses] &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>AlexanderLeung</name></author>
	</entry>
</feed>