Chapter 7: Analog Input Part 2 - Motion Control



Figure 1: Motion Control



In Chapter 6: Analog Input, we introduced concepts for reading analog data from the environment using the Arduino ADC (Analog to Digital Converter). And we learned how to use software to write a very simple way for us to use a PC to send commands and data to the Arduino and receive replies from the Arduino - a great tool for using and debugging applications. We also got a mile-high overview of a couple of the core concepts of electricity: Ohms Law and circuits. We kept it simple and hopefully didn't lose anyone along the way. My intent is that anyone should be able to understand these materials and if you didn't then it isn't your fault, it is mine for not being clear enough. I need to know that so that I can redo the lessons to make them absolutely crystal clear.] In this chapter we will learn a bit more about analog input using a device that lets us set a dial angle position to tell the computer what we want it to do. This device: the potentiometer, will also help reinforce our understanding of Ohm's Law and circuits, while providing a very useful tool for further work in both computing and electronics. The capstone lab for this chapter will be to create an application that lets us turn a dial on a breadboard and have the new dial position be reflected by a servomotor pointer as shown in Figure 1. And while this may seem like a simple thing to do, (and it is) it is also one of the fundamental tools for folks controlling electronic and computer systems.


 

Chapter 7: Analog Input Part 2 - Motion Control



Figure 1: Motion Control



In Chapter 6: Analog Input, we introduced concepts for reading analog data from the environment using the Arduino ADC (Analog to Digital Converter). And we learned how to use software to write a very simple way for us to use a PC to send commands and data to the Arduino and receive replies from the Arduino - a great tool for using and debugging applications. We also got a mile-high overview of a couple of the core concepts of electricity: Ohms Law and circuits. We kept it simple and hopefully didn't lose anyone along the way. My intent is that anyone should be able to understand these materials and if you didn't then it isn't your fault, it is mine for not being clear enough. I need to know that so that I can redo the lessons to make them absolutely crystal clear.] In this chapter we will learn a bit more about analog input using a device that lets us set a dial angle position to tell the computer what we want it to do. This device: the potentiometer, will also help reinforce our understanding of Ohm's Law and circuits, while providing a very useful tool for further work in both computing and electronics. The capstone lab for this chapter will be to create an application that lets us turn a dial on a breadboard and have the new dial position be reflected by a servomotor pointer as shown in Figure 1. And while this may seem like a simple thing to do, (and it is) it is also one of the fundamental tools for folks controlling electronic and computer systems.


Variable Resistance: the Potentiometer



Figure 2: Potentiometer



A potentiometer is a mechanical device that contains a strip of resistive material connected on each end to pins, and a third pin in the middle, a wiper. The wiper can be made to slide across the resistive material such that the resistance varies depending on the wiper’s position - in effect, it is a continuously variable voltage divider. Figure 2, shows this concept in the schematic symbol. Pin 2 is the wiper, pins 1 and 3 are on either end. They are usually called a pot because folks get really tired of typing ‘entiometer’ every time they want to talk about them (well, I do anyway).

When you turn the knob, the slider moves along the resistive material and the resistance between the slider pin and the end pins varies proportional to the slider position between the two end pins.

If we apply a voltage as shown in Figure 3, where we have 5 volts on the left pin and 0 volts on the right pin, then we have a voltage divider as discussed in Chapter 6 with the difference being that voltage divider in Chapter 6 was made with discrete 1000 ohm resistors, each having a constant value, while the pot voltage divider resistance varies smoothly as the slider moves with a portion of the resistance on one side and the remaining resistance on the other. With the discrete 1000 ohm resistors, you could access the divide in 11 steps, from 0 ohm to 10000 ohm. Each step above 0 is 10% of the total. However, in our case, you can move the slider to access a continuously variable resistance from 0 to 10000 ohm. The slider divides the total resistance such that the resistance on each side of the slider always adds up to 10000 ohm. If the slider is exactly in the center then there is 5000 ohm to the left and 5000 ohm to the right. If the slider is 3/4 of the way from the left to the right, then 7500 Ohm is to the left and 2500 ohm is to the righ as shown in the second to the last illustration in Figure 3.


Knob position and resistance


When we apply a voltage across the pot, 5 volts on the left and 0 volts on the right as shown in Figure 3, then the slider pin will have a voltage proportional to the angle position of the knob. Again if it is in the middle of the slider, the knob arrow will be pointed straight up at 90° (if we assume a half circle with 0 at the left and 180 at the right). If the position is 1/4 of the way from the left to the right (2500 ohm to the left and 7500 ohm to the right) then it is at the 45° position, and if it is 3/4 the way, then it is 135° (7500 ohm to the left and 2500 ohm to the right). This is also shown in Figure 3. We will use this relation between the angle and the voltage divider values to control the angle of our servomotor.

Figure 3: The pot wiper and voltage


Two modes of operation: voltage and current



In Figure 3, we see the pot operated in the voltage mode where the slider position reflects the proportion of the voltage divided between the left and right resistance. We would use this mode of operation when we want to manually set a voltage that is used in some other part of an electronic system. For instance we might have the pot hooked up to a voltage controlled audio amplifier. We would then adjust the audio volume by moving the knob to the left and right while listening to the sound volume change until it was where we want it. We might also want to communicate a magnitude to a computer and we could then have the wiper pin connected to an ADC that would measure the voltage and tell the computer what the voltage is, then the software would make decisions based on that voltage. An example of this would be to set the starting drill position in a CNC (Computerized Numeric Control) machine. You'd have one pot to set the drill X position and a second pot to set the Y position and when the drill is right where you want it, you could press a button telling the computer that the position is now where you want to start the drilling. The computer would read the X and Y voltages and 'know' the location of the zero points for both the X and Y directions in the work surface.

You can also use a pot to control an electric current as shown in Figure 4. If you only use the wiper pin and one of the other pins, you now have a variable resistor - not a resistor divider. If you apply the input voltage to the wiper pin, then as you move the wiper, that input voltage is across a varying resistance (from 10000 ohm when turned all the way to the left to 0 when turned all the way to the right). And since we know by Ohm's law that the current is set by the voltage and resistance we know that the current varies with the resistance which is set by the position of the wiper. This configuration is called a rheostat and is used to control current. Figure 4 show how this works, and in the case of the wiper being all the way to the right - how it doesn't work - boom! - a physical illustration of the old 'divide by zero' error. You can't divide by zero nor can you apply a voltage across zero ohms, you can try but the system will try to generate an infinite current - which, of course, it can't. Figure 5 shows this concept with a water current metaphor and a soon to be burned-out LED. To prevent this situation you will want to add a resistor in series with the side of the pot being used in the rheostat mode. Figure 6 shows a 100 ohm resistor used as a current limiting resistor. Never forget to add this resistor since as we've already seen, applying any voltage across zero resistance is a sure path to disaster. [Note that the omega character in Figure 4 means ohm.]


Figure 4: The pot wiper and current

 



Figure 5: Potentiometer current metaphor

 



Figure 6: Pot with current limiting resistor

 


Feedback


 In computers and electronics, feedback is a concept where one part of a system provides information for another part of the system that it uses to adjust something in the system. In essence the system uses events from the past or present to affect events in the present or future. There are whole areas of engineering that study feedback so it can get very complicated very quickly, but for our purposes it is really as simple as just described. An example of a system with feedback would be to take the faucet or LED in Figure 5 and consider a person as part of that system. That person uses eyes to observe the water flow or LED brightness and hands to turn the faucet handle or the pot knob to control the flow or brightness. We have also seen a feedback system with the servomotor, though it is hidden from our view inside the servomotor chassis. We saw in Chapter 5 when we dismantled a servomotor that the servomotor has a pot connected to the motor by gears so that it outputs a voltage that varies with the position of the motor shaft. An IC in the servomotor then uses that voltage to set the motor speed and direction to a value consistent with the input control system coming from the Arduino. The servomotor, of course, cannot see the angle of the motor shaft, it relies on an external sensor to determine the shaft angle and to tell it where to set that angle. And you are that sensor! Enough theory already, let's get our hands dirty in some labs.

Lab 1: Potentiometer analog control for LED brightness



Parts Required:
1 Arduino
1 USB cable
1 Arduino Proto Shield and jumper wires
1 LED
1 Pot
1 100 ohm resistor

Estimated time for this lab: 15 minutes

 Check off when complete:
Build the circuit shown in Figures 7 and 8.
Vary the pot angle and note the effect on the LED.
Draw this circuit with arrows showing current flow.
Calculate the current flow with the pot set at full right, 3/4 right, middle, 3/4 left and full left.
Calculate the voltage across the 100 ohm resistor at each of these currents.

Figure 7: Potentiometer LED breadboard drawing

 



Figure 8: Potentiometer LED breadboard schematic

 



Lab 2: Potentiometer digital voltage control - ADC


In the last lab we calculated the current with the pot set at full right, 3/4 right, middle, 3/4 left and full left. We then calculated the voltage across the 100 ohm resistor for each of those positions. Now we will verify those calculations by using the Arduino ADC to measure the voltage across the 100 ohm resistor.

Parts Required:
1 Arduino
1 USB cable
1 Arduino Proto Shield and jumper wires
1 LED
1 Pot
1 100 ohm resistor

Estimated time for this lab: 15 minutes

 Check off when complete:
Build the circuit shown in Figures 9, 10 and 11.

Figure 9: Pot as rheostat drawing

 



Figure 10: Pot as rheostat schematic

 



Figure 11: Pot as rheostat photo



Either copy and paste, or type in the following program into the Arduino IDE. 


  

// A101_ch7_pot_voltage 5/7/14 Joe Pardue



int sensorPin = A0;  // analog input pin

int sensorValue = 0;  // store the analog input value



void setup() {

  Serial.begin(57600);

  Serial.println("Measure potentiometer voltage rev 1.0");

}



void loop() {

  

  if(Serial.available())

  {

    char c = Serial.read();

    if(c == 'r')

    { 

      // read the value from the sensor:

      sensorValue = analogRead(sensorPin);

      

      Serial.print("Potentiometer voltage: ");

      Serial.println(sensorValue);      

      Serial.print("  Voltage: ");

      Serial.println(((5.0*(float)sensorValue)/1024.0), 3); 

    } 

  }                

}


Run the program and the Arduino Serial Monitor.
Observe the voltages reported for each of the angles suggested in Lab 1. Are these voltages close to what you calculated using Ohm's Law?

Lab 3: Dial - using a potentiometer to input a selected angle on a dial



Parts Required:
1 Arduino
1 USB cable
1 Arduino Proto Shield and jumper wires
1 Pot
1 100 ohm resistor
1 Pot dial angle image

Estimated time for this lab: 30 minutes

 Check off when complete:
Print the pot dial image shown in Figure 19. This image may be found in Arduino_101_Supplementatl.zip from the Nuts&Volts page for this article and from www.arduinoclassroom.com Chapter 7.
Use double sided sticky tape to stick the pot dial angle image to cardboard (cereal box thickness) and cut it out for use as shown for use in Figures 12, 13 and 14.
Build the circuit shown in Figures 12, 13 and 14.


Figure 12: Pot to ADC drawing.

 




Figure 13: Pot to ADC schematic

 




Figure 14 - Pot to ADC photo



Either copy and paste, or type in the following program into the Arduino IDE. 


// A101_ch7_pot_angle 5/7/14 Joe Pardue
  
int sensorPin = A0;  // analog input pin
int sensorValue = 0;  // store the analog input value
int zero = 0; // calibration reading for 0 degree
int oneeighty = 0; // calibrartion reading for 180 degree
  
void setup() {  
 
  Serial.begin(57600);
 
  Serial.println("Measure potentiometer angle rev 1.0");
}
 
void loop() {
  int val = 0;
if(Serial.available()) { char c = Serial.read(); if(c == 'a') // get the zero degree calibration value { // read the value from the sensor: zero = analogRead(sensorPin); Serial.print("You set 0 degree to: "); Serial.println(zero); } if(c == 'b') // get the 180 degree calibration value { // read the value from the sensor: oneeighty = analogRead(sensorPin); Serial.print("You set 180 degree to: "); Serial.println(oneeighty); } } delay(1000); Serial.print("Potentiometer voltage:"); val = analogRead(sensorPin); Serial.println(val); val = map(val,zero,oneeighty,0,180); Serial.print("Angle = "); Serial.println(val); }
This program calibrates the pot to the dial angles by accepting two commands: 'a' for the 0° position and 'b' for the 180° position.
Adjust the pot to point to 0° and enter and send 'a' in the Serial Monitor.
Adjust the pot to point to 180° and enter and send 'b' in the Serial Monitor.
Adjust the pot to various angle and read the angle with the Serial Monitor - note the accuracy or lack of it for these reading. You should get results similar to those in Figure 13.

Figure 15: Pot angle test

 

Lab 4: Pot motion control

Now that we have a way to read an angle (not precisely but close) we will add the servomotor with the angle dial and pointer and use the pot to control the position 10 times per second and thereby control the motion of the servomotor.

Parts Required:
1 Arduino
1 USB cable
1 Arduino Proto Shield and jumper wires
1 Pot
1 100 ohm resistor
1 Pot dial angle image
1 Servomotor
1 Servomotor angle dial image
1 Servomotor angle pointer image

Estimated time for this lab: 30 minutes

 Check off when complete:
The images for the pot dial and servomotor dial and pointer are shown in Figure 19. You can reuse the servomotor dial and pointer from Chapter 5, if you have it. If not, you can find the image in the file used for the previous lab to get the pot angle dial  Construct the dial and pointer as discussed in Chapter 5.
Assemble the servomotor dial and pointer and plug it into the Arduino Proto Shield breadboard as shown in Figures 1, 16 and 17.

Figure 16 - Pot motion control drawing

 

Figure 17 - Pot motion control schematic




Either copy and paste, or type in the following program into the Arduino IDE. 

  

// A101_ch7_pot_motion_control 5/7/14 Joe Pardue



#include  <Servo.h>



Servo myservo;  // create servo object to control a servo

int sensorPin = A0;  // analog input pin

int zero = 0; // calibration reading for 0 degree

int oneeighty = 0; // calibrartion reading for 180 degree



void setup() {

  // attaches the servo on pin 9 to the servo

  myservo.attach(9);   

  

  Serial.begin(57600);

  Serial.println("Pot motion control rev 1.0");

}



void loop() { 

  int val;

  

  if(Serial.available())

  {

    char c = Serial.read();



    if(c == 'a') // get the zero degree calibration value

    { 

      // read the value from the sensor:

      zero = analogRead(sensorPin);     

      Serial.print("You set 0 degree to: ");

      Serial.println(zero);      

    }     

    if(c == 'b') // get the 180 degree calibration value

    { 

      // read the value from the sensor:

      oneeighty = analogRead(sensorPin);    

      Serial.print("You set 180 degree to: ");

      Serial.println(oneeighty);      

    }        

  }  

  delay(100);

  val = analogRead(sensorPin);;

  val = map(val,zero,oneeighty,0,180);

      

  // the dial is reversed for what we want so we

  // reverse the value to get the angle

  val = 180 - val;
  myservo.write(val); // use converted angle     

}
Run the program and open the Serial Monitor. Set the left and right calibration points.
Set the pot angle to 90° and input 'r' to read the angle as shown in Figure 18.

Figure 18: Pot motion control test