<?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=BenjaminSchriesheim</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=BenjaminSchriesheim"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/BenjaminSchriesheim"/>
	<updated>2026-05-19T01:38:26Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8468</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=8468"/>
		<updated>2008-03-21T02:43:25Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: &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 interfacing a [[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 keeps a round metal ball in the center of the touchscreen. Using the touchscreen&#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;
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&#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&#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&#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&#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&#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>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8467</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=8467"/>
		<updated>2008-03-21T02:42:21Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: &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 interfacing a [[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 keeps a round metal ball in the center of the touchscreen. Using the touchscreen&#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;
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&#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&#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&#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&#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&#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>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Ball_Balancing_Challenge&amp;diff=8466</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=8466"/>
		<updated>2008-03-21T02:39:01Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: worked on mechanical design section&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&#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;
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&#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&#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&#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&#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&#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>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8425</id>
		<title>Resistive Touchscreen</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8425"/>
		<updated>2008-03-21T00:36:50Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: &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&#039;s aspect ratio in order to create an equal coordinate system.&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;
== 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>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8414</id>
		<title>Resistive Touchscreen</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8414"/>
		<updated>2008-03-20T23:55:14Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: &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;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:mems accelerometer.png|right]]&lt;br /&gt;
&lt;br /&gt;
Accelerometers measure linear acceleration and also gravity; the two are indistinguishable.  Thus they unavoidably function as tilt sensors as well.   Inexpensive 1, 2, and 3-axis accelerometers are available which are constructed with MEMS techniques.  &lt;br /&gt;
MEMS gyroscopes are also available, for measuring angular velocity, but are more expensive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:carrier.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The LIS2L02AS4-TR accelerometer gives you a choice of +/-2g or +/-6g full scale.  It needs only a single +5V supply.  Its bandwidth is from DC to 1.5KHz.  The output is usually low-pass filtered in applications which do not need the full 1.5KHz bandwidth, using an external capacitor.&lt;br /&gt;
&lt;br /&gt;
The chip is available only in a surface-mount SO-24 package.  Fortunately an adapter socket (Digikey A322-ND) can be used to give the chip convenient DIP-24 legs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:somesoldered.jpg|right]]&lt;br /&gt;
Soldering the chip into the adapter socket is a little challenging.   Here are some tricks that make it easier.  The more of these you can take advantage of, the easier it will be.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Use a very fine pointed soldering iron and fine solder.&lt;br /&gt;
* Apply a bead of liquid flux to the pads, which will make the solder flow in between the pin and the pad enthusiastically.&lt;br /&gt;
* Tape the chip down onto its socket adapter.&lt;br /&gt;
* Have a magnifying lens or loupe available.&lt;br /&gt;
* Know which pins are not used.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The last point is especially useful.  Start with pin 1 which is NC (Not Connected), so that even if you get a solder blob connecting pins 1 &amp;amp; 2 that&#039;s ok.  If the other pins are all aligned with their pads, pin 1&#039;s solder will now hold them there.  If not, melt pin 1&#039;s solder and adjust.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:chip.gif|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now solder only the other pins that are in use, as shown in red on the diagram.   Solder one or two on the opposite edge as well, for mechanical stability.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pins marked &amp;quot;reserved&amp;quot; should not be solder-blobbed to their neighbors because we don&#039;t know what they connect to inside the chip.  Reserved is not the same thing as NC.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
[[Image:circuit.gif|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use a supply shunt near the chip (1uF) from +5 to ground).  Use low-pass filter capacitors on the outputs (called Cload in the diagram).  The output impedance of the chip is 110Kohm, so a 0.1uF capacitor gives a low pass time constant of ~10mS.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tie ST, PD low, and FS low for +/-2g full scale operation.  The output voltage ranges 0-5V, well matched to PIC inputs.  2.5V is the output when acceleration is zero and and the chip is horizontal (not tilted.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The circuit shows some optional buffer amplifiers to produce a low impedance output.&lt;/div&gt;</summary>
		<author><name>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Bergquist_hand_ball_balancing.jpg&amp;diff=8407</id>
		<title>File:Bergquist hand ball balancing.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Bergquist_hand_ball_balancing.jpg&amp;diff=8407"/>
		<updated>2008-03-20T23:49:04Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: Hand holding a resistive touch screen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hand holding a resistive touch screen&lt;/div&gt;</summary>
		<author><name>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8405</id>
		<title>Resistive Touchscreen</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Resistive_Touchscreen&amp;diff=8405"/>
		<updated>2008-03-20T23:46:37Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:mems accelerometer.png|right]]&lt;br /&gt;
&lt;br /&gt;
Accelerometers measure linear acceleration and also gravity; the two are indistinguishable.  Thus they unavoidably function as tilt sensors as well.   Inexpensive 1, 2, and 3-axis accelerometers are available which are constructed with MEMS techniques.  &lt;br /&gt;
MEMS gyroscopes are also available, for measuring angular velocity, but are more expensive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:carrier.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The LIS2L02AS4-TR accelerometer gives you a choice of +/-2g or +/-6g full scale.  It needs only a single +5V supply.  Its bandwidth is from DC to 1.5KHz.  The output is usually low-pass filtered in applications which do not need the full 1.5KHz bandwidth, using an external capacitor.&lt;br /&gt;
&lt;br /&gt;
The chip is available only in a surface-mount SO-24 package.  Fortunately an adapter socket (Digikey A322-ND) can be used to give the chip convenient DIP-24 legs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:somesoldered.jpg|right]]&lt;br /&gt;
Soldering the chip into the adapter socket is a little challenging.   Here are some tricks that make it easier.  The more of these you can take advantage of, the easier it will be.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Use a very fine pointed soldering iron and fine solder.&lt;br /&gt;
* Apply a bead of liquid flux to the pads, which will make the solder flow in between the pin and the pad enthusiastically.&lt;br /&gt;
* Tape the chip down onto its socket adapter.&lt;br /&gt;
* Have a magnifying lens or loupe available.&lt;br /&gt;
* Know which pins are not used.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The last point is especially useful.  Start with pin 1 which is NC (Not Connected), so that even if you get a solder blob connecting pins 1 &amp;amp; 2 that&#039;s ok.  If the other pins are all aligned with their pads, pin 1&#039;s solder will now hold them there.  If not, melt pin 1&#039;s solder and adjust.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:chip.gif|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now solder only the other pins that are in use, as shown in red on the diagram.   Solder one or two on the opposite edge as well, for mechanical stability.   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pins marked &amp;quot;reserved&amp;quot; should not be solder-blobbed to their neighbors because we don&#039;t know what they connect to inside the chip.  Reserved is not the same thing as NC.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
[[Image:circuit.gif|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use a supply shunt near the chip (1uF) from +5 to ground).  Use low-pass filter capacitors on the outputs (called Cload in the diagram).  The output impedance of the chip is 110Kohm, so a 0.1uF capacitor gives a low pass time constant of ~10mS.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tie ST, PD low, and FS low for +/-2g full scale operation.  The output voltage ranges 0-5V, well matched to PIC inputs.  2.5V is the output when acceleration is zero and and the chip is horizontal (not tilted.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The circuit shows some optional buffer amplifiers to produce a low impedance output.&lt;/div&gt;</summary>
		<author><name>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microphones&amp;diff=6763</id>
		<title>Microphones</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microphones&amp;diff=6763"/>
		<updated>2008-02-06T18:52:43Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: edited overview section&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 will be built using a PIC 18F4520 and an electret microphone (in this case, the 423-1024-ND from digikey) as an analog input. The device operates on the principle that as the sound increases in volume, the audio input&#039;s amplitude will increase. This input is received by the PIC and converted into an output on the set of LEDs soldered onto the PIC&#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;
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&#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 &amp;quot;clapper&amp;quot; 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;
== 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&#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:microphone_circuit.JPG|left|400px|[[help:contents|Microphone Circuit and PIC photo]]]] [[image:mic_circuit_diagram.JPG|right|400px|[[help:contents|Microphone Circuit and PIC diagram]]]]&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;
&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;
int16 valuebuff[100];      // Initialize variables&lt;br /&gt;
signed int16 value;&lt;br /&gt;
int32 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;
   initialize(); &lt;br /&gt;
   setup_adc_ports(AN0);        // Enable analog inputs AN0;&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      &lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
   while (TRUE) {&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;
      set_adc_channel(0);     // there&#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;
      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)*4;&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 if (value&amp;lt;1000)&lt;br /&gt;
      output_d(0b11111111);           &lt;br /&gt;
      &lt;br /&gt;
   delay_ms(10);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Take samples to establish an initial value to &#039;tare&#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;
      set_adc_channel(0);     &lt;br /&gt;
      delay_us(10);           &lt;br /&gt;
      valuebuff[k] = read_adc();    &lt;br /&gt;
      valueinit+=valuebuff[k];&lt;br /&gt;
   }&lt;br /&gt;
   valueinit = (valueinit/100);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>BenjaminSchriesheim</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microphones&amp;diff=6399</id>
		<title>Microphones</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microphones&amp;diff=6399"/>
		<updated>2008-02-05T01:48:27Z</updated>

		<summary type="html">&lt;p&gt;BenjaminSchriesheim: began writing the &amp;#039;circuit&amp;#039; section&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;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
The circuit built for this example uses an electret microphone (in this case, the 423-1024-ND from digikey) 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&#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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;(Insert circuit diagram, labeled photo here)&#039;&#039;&#039;&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;
int16 valuebuff[100];      // Initialize variables&lt;br /&gt;
signed int16 value;&lt;br /&gt;
int32 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;
   initialize(); &lt;br /&gt;
   setup_adc_ports(AN0);        // Enable analog inputs AN0;&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);      &lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
   while (TRUE) {&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;
      set_adc_channel(0);     // there&#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;
      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)*4;&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 if (value&amp;lt;1000)&lt;br /&gt;
      output_d(0b11111111);           &lt;br /&gt;
      &lt;br /&gt;
   delay_ms(10);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Take samples to establish an initial value to &#039;tare&#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;
      set_adc_channel(0);     &lt;br /&gt;
      delay_us(10);           &lt;br /&gt;
      valuebuff[k] = read_adc();    &lt;br /&gt;
      valueinit+=valuebuff[k];&lt;br /&gt;
   }&lt;br /&gt;
   valueinit = (valueinit/100);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>BenjaminSchriesheim</name></author>
	</entry>
</feed>