In this lab, you will use a potentiometer to control the speed of a toy DC motor from an Arduino.
A typical circuit for controlling a DC motor from Arduino would be something like the following. Note that this circuit assumes you are using a small enough motor that it can be run from a 5V power supply. Larger motors will need their own power supplies.
You will have to develop your own Arduino code and your own potentiometer circuit in order to complete this lab.
- make your own circuit and your own code
- read the potentiometer into Arduino, and output a PWM signal to the motor based on that reading
- see your ARDX kit motor documentation if you get stuck
This example shows how to use a Processing application to control a servo motor hooked up to an Arduino. You will control the movement of a servo motor by dragging a red circle left and right on your yellow computer screen.
The circuit used simply involves a servo motor connected to one of the Arduino’s analog output pins. Our code assumes we are using pin 5. If you need a refresher on how to connect a servo motor to an Arduino, check out this simple example of a servo controlled from Arduino code.
The Processing code
The Arduino code
In this lab, you will control a servo motor from a pushbutton switch. Holding down the momentary pushbutton switch turns the servo motor incrementally until it reaches its upper or lower limit (180° or 0°, respectively).
Once the servo reaches its upper or lower limit, it continues in the opposite direction.
- Design it yourself. There is no circuit for you to follow. -
- Write it yourself. There is no code for you to copy. -
This example shows how to control a servo motor by turning a potentiometer. The Arduino detects the changes to the rotation of the potentiometer and then maps those changes to rotations of the servo.
Other types of variable resistors can easily be used in place of the potentiometer, by using the variable resistor in a Voltage Divider circuit.
This simple example shows how to oscillate a servo motor back and forth automatically. Servos respond to the pulse width modulation (PWM) of a signal, meaning that changes in the width of DC current pulses cause changes in the rotation of the servo’s armature.
Whereas most applications of PWM deal with the duty cycle of the pulses (i.e. the relative duration of the signal, as compared to the duration of no signal), servos respond to the absolute width of the pulses. In other words, a pulse of a particular duration will always move the servo to a particular rotation angle, regardless of how much time exists between pulses (within limitations, of course).
- Why do we add a delay after rotating the servo?
- What is the pulse width that corresponds with a 45° rotation?
- Why doesn’t the Arduino reliably turn a servo motor at the same time as it plays a sound from a piezo speaker using the tone() function?
Note: much of this content has been adapted from the old robotics classic, Mobile Robots: From Inspiration to Implementation, 1st Edition, by Joseph Jones and Anita Flynn.
sensitivity and range: two important concepts when dealing with sensors
- all phenomena in the world are mapped in the microcontroller as a range of numbers between 0-1023 (for inputs), or 0-255 (for outputs).
- sometimes real-world phenomena have infinite degrees of subtlety, much of which can get lost
- so be careful how you do the mapping to make sure to enable maximum sensitivity across the range of real-world phenomena
- linear mapping
- works great for representing things like rotation of a motor
Linear mapping of a 90° range of rotations provides good sensitivity
- but not so great for light intensity ranges using a photodiode sensor… sensitivity is low in dark light
Linear mapping of 10,000 light intensity units skews sensitivity towards bright light
- the easiest (e.g. using the Arduino’s map() function in code, or simply taking voltage readings directly from analog input pins)
- logarithmic mappings
- provide better sensitivity across a range of light levels for photodiode sensors
Logarithmic mapping of 10,000 light intensity units to 8 bits provides more even sensitivity
- better for mapping acoustic pitches and sound frequencies
- require a bit more work (for example, using the log10 function from Arduino’s math.h library in your code, or using a logarithmic amplifier IC in your circuit)
Photoresistors… a good compromise between sensitivity and range
Speaking of light-sensing…. we often use photoresistors, and not photodiodes or photoresistors, because photoresistors are easer to hook up to our microcontroller circuits. Their sensitivity is generally worse than that of phototransistors and photodiodes (whose signals require amplification). But to get the decent sensitivity out of photoresistors while not compromising the range too much, it’s recommended to use them in a voltage divider circuit with a static resistor that has the same value resistance you expect the photoresistor to have when in the middle level of light you expect it to be exposed to. Then we use a linear mapping to analyze the levels.
Mathematically speaking (in case you’re interested)
- sensitivity is the degree to which the output signal of the sensor changes as the measured quantity changes
- Δr/r = S × Δx/x
- x is the measured quantity, r is the sensor output
- Δx is the change in measured quantity, Δr is the change in sensor output
- S is the specific sensitivity factor of the sensor