The Arduino is a powerful development platform for hobbyists of all skill levels, as it allows any user to bring a project to life with just the Arduino board, a few key components, and some code.  The whole Arduino platform is built around the idea that it should always make projects easier to build and develop, yet inevitably, the hardest part of bringing Arduino projects to life is interfacing the Arduino with sensors and custom circuitry—how does one make the Arduino communicate and interact with these external electronics?  In this tutorial, I hope to introduce different ways to connect the Arduino to offboard sensors and electronic devices and explain the basics of communication between the Arduino and these devices.  

 

Before we dive into how the Arduino can communicate with other devices, we should first understand a microcontroller’s “input” and “output” pins and their functions.  Input pins are ports on the microcontroller that are specified to be listened to for data.  Output pins, on the other hand, are ports on the microcontroller that are specified for the microcontroller to write data to.  Input and Output pins on the Arduino come in two types: Digital and Analog, depending on the type of signal they send or receive.  

The Arduino’s Digital Pins (boxed in Red) and Analog Pins (boxed in Yellow).
The Arduino’s Digital Pins (boxed in Red) and Analog Pins (boxed in Yellow).

Digital pins have two states, “high” (a binary 1 represented by 5V at the pin) and “low” (a binary 0 represented by 0V at the pin).  This means that a digital pin can only be interpreted as being in one of these two states.  A simple example of Digital Pin manipulation is the “Blink” Arduino sketch, in which the Arduino pulses an LED at a given time interval.  The code and hardware for the “Blink” example is shown here:

void setup() {
pinMode(13, OUTPUT);
}


void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}

The LED’s anode is connected to Digital Pin 13, and its cathode is connected to Ground (GND). (Note that a current-limiting resistor is not necessary because the Arduino’s Digital Pin 13 already has a built-in resistor.)
The LED’s anode is connected to Digital Pin 13, and its cathode is connected to Ground (GND). Note that a current-limiting resistor is not necessary because the Arduino’s Digital Pin 13 already has a built-in resistor.

The LED is connected to Digital Pin 13, and digital “high” and “low” signals are represented as 5V and 0V at Pin 13 respectively.  When the Arduino sets the pin to “high,” current flows out at 5 Volts through the LED and to ground.  When the Arduino then sets the pin to “low,” 0V (no current) flows in the circuit.  To configure a digital pin as either input or output, one must use the pinMode method in void setup() as such: pinMode(int pin, INPUT) or pinMode(int pin, OUTPUT), where int pin is the integer number of the digital pin being defined.  In the “Blink” example, Digital Pin 13 is set up as an output by the method call “pinMode (13, OUTPUT);”  To then set the value of a digital pin to HIGH or LOW, Arduino provides the digitalWrite method, which can be used as “digitalWrite(int pin, HIGH)”; or “digitalWrite(int pin, LOW)”; to drive the pin high or low respectively.


Analog pins are slightly more complicated, as they are not limited to two on/off states.  Instead, signals at Analog pins vary anywhere between 0V and 5V and are accordingly interpreted by the Arduino.  In the Arduino documentation website’s own words, the Arduino will “map input voltages between 0 and 5 volts into integer values between 0 and 1023.”  This means that through some nifty programming, the Arduino can be made to recognize the strength of an incoming signal (the interpreted integer value) and react accordingly.  An example of reading an Analog signal may be determining the amount of sunlight present in a room using a photoresistor to accordingly light up or turn off an LED lamp when the room is too dark or too bright.

 

void setup() {
pinMode(13, OUTPUT);
}


void loop() {
int lightLevel = analogRead(3);
delay(100);
if (lightLevel < 20) { //20 is an arbitrary threshold to turn on LED
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}
}

The output voltage from the photoresistor-resistor pair voltage divider is an analog input translated by the Arduino as an integer value between 0 and 1023.
The output voltage from the photoresistor-resistor pair voltage divider is an analog input translated by the Arduino as an integer value between 0 and 1023.

The intensity of light is translated by the photoresistor-resistor voltage divider as a voltage between 0V and 5V, which is then interpreted by the Arduino through an Analog input pin.  The Arduino then sends an appropriate Digital signal (HIGH if the integer value from the Analog input is less than the threshold value, or LOW otherwise) through a Digital pin configured as an output to the connected LED.

 

Before I move on to the different ways the Arduino can communicate with attached devices, I first want to cover one of the most fundamental aspects of designing circuits that interface with the Arduino: the use of current-limiting resistors.  The current-limiting resistor is not a staple in all Arduino projectsthere are many devices and circuits that do not require the use of such setupsyet it plays an important role when the Arduino is connected to small components and electronics that can be damaged by overcurrent. 

 

It is at this point that many get confused by the different electrical terms thrown around by hobbyists, primarily Current versus Voltage.  Current, expressed in units called Amperes, is the actual flow of electrons through a closed circuit.  One can think of Current as how quickly electrons flow through a closed circuit from one end of a power source to another. Voltage, quantified in units called Volts, is the potential difference created chemically or by other means in the power supply that will cause an electrical current to flow through a conductor when a circuit is closed.  To protect electronic components from damage, we have to reduce the current—the amount of electrons—flowing through through the component, so that the current does not exceed the maximum ratings of the components.  

image05

At any known voltage—let’s say 5V in this example, because the Arduino’s output pins run at 5V—we can see from Ohm’s law, Voltage = Current * Resistance, that large amounts of current can flow through the components because of little to no resistance (hindering of the flow of charge) in the circuit. We must therefore use an electronic component called a resistor to provide resistance in the circuit and reduce the current that flows through our components. To calculate the value of resistance needed (the value of the resistor) based on the known voltage and maximum current allowable, we can use Ohm’s law again, this time in the form Resistance = Voltage / Current. Always use a current-limiting resistor when connecting external components to the Arduino.

 

Here’s a hardware example of using current-limiting resistors with components connected to an Arduino:

image02

Now that we’ve covered the basic overview of the Arduino’s onboard hardware and connection points, we can now go over the actual communication between the Arduino and external electronics, sensors, and more. Since we’ve covered the basics of Digital and Analog input/output on the Arduino, we’ll now focus on interfacing the Arduino with more complicated electronics such as sensors, peripheral devices, and communication electronics. This may involve using either communication protocols such as Serial or control methods such as PWM.

 

The first communication protocol on the Arduino introduced to users is Serial Communication (“Serial” for short). It is the way the Arduino communicates with the user’s computer via USB connection, and can be a way by which the Arduino can communicate with peripheral electronics as well. Serial is a simple communication protocol to implement because its implementation only requires one Transmitting (TX) and one Receiving (RX) line (essentially just two wires) connected between the Arduino and the peripheral device. On the Arduino, Digital Pin 0 can be used as the RX pin, and Digital Pin 1 can be used as the TX pin. Wires connected to these two pins can be attached on the other end to another circuit board or even another Arduino, but it is important to remember that the RX line for one device will become the TX line for the other (the two wires will be connected to an RX pin on one and and a TX pin on the other).

Arduino connected to XBee via serial
An example of wiring the Arduino to communicate via Serial with an XBEE RF module.

We can now focus on the software implementation of Serial on the Arduino.  Arduino provides a “Serial” library to implement communication over the default Serial pins (Digital Pins 0 and 1) and a “Software Serial” library to define and use two other Digital as Serial RX/TX pins.  For a detailed overview of the Serial library visit https://www.arduino.cc/en/Reference/Serial. Some basic functions that will almost always be used in the software include the following:

  • Serial.begin, which initializes communication at a specified integer baud rate (a measurement of signal transmission speed) in the void setup method
  • Serial.print and Serial.println, which print data to the Serial Monitor in the Arduino IDE
  • Serial.write and Serial.read, which write and read byte data over the TX/RX lines respectively
  • Serial.available(), which returns the number of bytes available to read over the serial connection

Here’s some code for communicating over an XBEE module connected to the Arduino’s Digital Pins 0 and 1.  In this example, the Arduino sends 1 or 0 over Serial to the XBEE module, which will then transfer that data to another paired module and in-turn to another Arduino.

 

//sending (Arduino 1)
void setup() {
Serial.begin(9600);
}


void loop() {
Serial.write(1);
delay(1000);
Serial.write(0);
delay(1000);
}


//receiving (Arduino 2)
void setup() {
Serial.begin(9600);
}


void loop() {
if (Serial.available() > 0) {
int data = Serial.read();
if (data==1) {
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}
}
}

 

Now that you’ve read through this tutorial on the basics of using an Arduino with other components and/or custom circuits, you can start developing your own simple Arduino projects based on the principles of Digital/Analog inputs and outputs and on Serial communication! In the next tutorial, I’ll introduce the I2C protocol, using pull-up and pull-down resistors on digital inputs where appropriate, and how to use the Arduino to control motors through Pulse-Width Modulation (PWM)!

 

Courtesy to Fritzing and Arduino for the images used in this article.

The following two tabs change content below.

Rahul Iyer

Author
I study Electrical Engineering at UCLA, and love to work on electronics and robotics projects as a hobby. I'm a strong believer in the engineer's motto: "If it ain't broken, take it apart and fix it."

Latest posts by Rahul Iyer (see all)