Analog and Digital Write
Analog and Digital Write
Introduction
The Arduino’s ability to sense digital and analog inputs allows it to respond to you and to the
world around you. This section introduces techniques you can use to do useful things with these
inputs.
The Arduino function to detect digital input is digitalRead and it tells your sketch if a voltage
on a pin is HIGH (5 volts) or LOW (0 volts). The Arduino function to configure a pin for
reading input is pinMode(pin, INPUT).
Unlike a digital value, which is only ON or OFF, analog values are continuously
variable. The volume setting of a device is a good example; it is not just ON or OFF, but it can
have a range of values in between. Many sensors provide information by varying the voltage to
correspond to the sensor measurement. Arduino code uses a function called analogRead to get
a value proportional to the voltage it sees on one of its analog pins. The value will be 0 if there
are 0 volts on the pin and 1,023 for 5 volts. The value in between will be proportional to the
voltage on the pin, so 2.5 volts (half of 5 volts) will result in a value of roughly 511 (half of
1,023). You can see the six analog input pins (marked A0 to A5) at the Arduino UNO. These
pins can also be used as digital pins 14 to 19 if they are not needed for analog.
Using a Switch
Problem
You want your sketch to respond to the closing of an electrical contact; for example, a
pushbutton or other switch or an external device that makes an electrical connection.
Solution
Use digitalRead to determine the state of a switch connected to an Arduino digital pin set as
input. The following code lights an LED when a switch is pressed.
/*
Pushbutton sketch a switch connected to pin 2 lights the LED on pin 13
*/
const int ledPin = 13; // choose the pin for the LED
const int inputPin = 2; // choose the input pin (for a pushbutton)
void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare pushbutton as input
}
void loop(){
int val = digitalRead(inputPin); // read input value
if (val == HIGH) // check if the input is HIGH
{
digitalWrite(ledPin, HIGH); // turn LED ON if switch is pressed
}
else
{
digitalWrite(ledPin, LOW); // turn LED OFF
}
}
Problem
You want to simplify your wiring by eliminating external pull-up resistors when connecting
switches.
The switch is only connected between pin 2 and Gnd. Gnd is short for ground and is
at 0 volts by definition:
/*
Pullup sketch a switch connected to pin 2 lights the LED on pin 13
*/
const int ledPin = 13; // output pin for the LED
const int inputPin = 2; // input pin for the switch
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
digitalWrite(inputPin,HIGH); // turn on internal pull-up on the inputPin
}
void loop(){
int val = digitalRead(inputPin); // read input value
if (val == HIGH) // check if the input is HIGH
{
digitalWrite(ledPin, HIGH); // turn LED OFF
}
else
{
digitalWrite(ledPin, LOW); // turn LED ON
}
}
Reading a Keypad
Problem
You have a matrix keypad and want to read the key presses in your sketch. For example, you
have a telephone-style keypad similar to the SparkFun 12-button keypad.
Solution
Wire the rows and columns from the keypad connector to the Arduino, as shown in figure
below.
If you’ve wired your Arduino and keypad as shown in the above figure, the following sketch
will print key presses to the Serial Monitor:
/*
Keypad sketch
prints the key pressed on a keypad to the serial port
*/
const int numRows = 4; // number of rows in the keypad
const int numCols = 3; // number of columns
const int debounceTime = 20; // number of milliseconds for switch to be stable
// keymap defines the character returned when the corresponding key is pressed
const char keymap[numRows][numCols] = {
{ '1', '2', '3' } ,
{ '4', '5', '6' } ,
{ '7', '8', '9' } ,
{ '*', '0', '#' }
};
// this array determines the pins used for rows and columns
const int rowPins[numRows] = { 7, 2, 3, 6 }; // Rows 0 through 3
const int colPins[numCols] = { 5, 8, 4 }; // Columns 0 through 2
void setup()
{
Serial.begin(9600);
for (int row = 0; row < numRows; row++)
{
pinMode(rowPins[row],INPUT); // Set row pins as input
digitalWrite(rowPins[row],HIGH); // turn on Pull-ups
}
for (int column = 0; column < numCols; column++)
{
pinMode(colPins[column],OUTPUT); // Set column pins as outputs for writing
digitalWrite(colPins[column],HIGH); // Make all columns inactive
}
}
void loop()
{
char key = getKey();
if( key != 0) { // if the character is not 0 then it's a valid key press
Serial.print("Got key ");
Serial.println(key);
}
}
// returns with the key pressed, or 0 if no key is pressed
char getKey()
{
char key = 0; // 0 indicates no key pressed
for(int column = 0; column < numCols; column++)
{
digitalWrite(colPins[column],LOW); // Activate the current column.
for(int row = 0; row < numRows; row++) // Scan all rows for a key press.
{
if(digitalRead(rowPins[row]) == LOW) // Is a key pressed?
{
delay(debounceTime); // debounce
while(digitalRead(rowPins[row]) == LOW)
; // wait for key to be released
key = keymap[row][column]; // Remember which key was pressed.
}
}
digitalWrite(colPins[column],HIGH); // De-activate the current column.
}
return key; // returns the key pressed or 0 if none
}
This sketch will only work correctly if the wiring agrees with the code. Table below shows how
the rows and columns should be connected to Arduino pins. If you are using a different keypad,
check your data sheet to determine the row and column connections. Check carefully, as
incorrect wiring can short out the pins, and that could damage your controller chip.
Mapping Table of Arduino pins to SparkFun connector and keypad rows and columns.
Problem
You want to read the voltage on an analog pin. Perhaps you want a reading from a potentiometer
(pot) or a device or sensor that provides a voltage between 0 and 5 volts.
Problem
You want to change the range of a value, such as the value from analogRead obtained by
connecting a potentiometer or other device that provides a variable voltage. For example,
suppose you want to display the position of a potentiometer knob as a percentage from 0 percent
to 100 percent.
/*
Map sketch map the range of analog values from a pot to scale from 0 to 100 resulting
in an LED blink rate ranging from 0 to 100 milliseconds and Pot rotation percent is
written to the serial port
*/
const int potPin = 0; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
void setup()
{
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
Serial.begin(9600);
}
void loop() {
int val; // The value coming from the sensor
int percent; // The mapped value
val = analogRead(potPin); // read the voltage on the pot (val ranges from 0 to 1023)
percent = map(val,0,1023,0,100); // percent will range from 0 to 100.
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(percent); // On time given by percent value
digitalWrite(ledPin, LOW); // turn the ledPin off
delay(100 - percent); // Off time is 100 minus On time
Serial.println(percent); // show the % of pot rotation on Serial Monitor
}
Displaying Voltages Up to 5V
Problem
You want to monitor and display the value of a voltage between 0 and 5 volts. For example,
suppose you want to display the voltage of a single 1.5V cell on the Serial Monitor.
Solution
Use analogRead to measure the voltage on an analog pin. Convert the reading to a voltage by
using the ratio of the reading to the reference voltage (5 volts), as shown in Figure below.
Measuring voltages up to 5 volts using 5V board
The simplest solution uses a floating-point calculation to print the voltage; this example sketch
calculates and prints the ratio as a voltage:
/*
Display 5v Or less sketch
prints the voltage on analog pin to the serial port
Warning - do not connect more than 5 volts directly to an Arduino pin.
*/
const int referenceVolts = 5; // the default reference on a 5-volt board
const int batteryPin = 0; // battery is connected to analog pin 0
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = analogRead(batteryPin); // read the value from the sensor
float volts = (val / 1023) * referenceVolts; // calculate the ratio
Serial.println(volts); // print the value in volts
}
The formula is: Volts = (analog reading / analog steps) × Reference voltage
Printing a floating-point value to the serial port with println will format the value to two decimal
places.