18 min read

Most systems using the Arduino have a similar architecture. They have a way of reading data from the environment—a sensor—they make decision using the code running inside the Arduino and then output those decisions to the environment using various actuators, such as a simple motor. Using three recipes from the book, Arduino Development Cookbook, by Cornel Amariei, we will build such a system, and quite a useful one—a fan controlled by the air temperature.

Let’s break the process into three key steps, the first and easiest will be to connect an LED to the Arduino, a few of them will act as a thermometer, displaying the room temperature. The second step will be to connect the sensor and program it, and the third will be to connect the motor.

Here, we will learn this basic skills.

(For more resources related to this topic, see here.)

Connecting an external LED

Luckily, the Arduino boards come with an internal LED connected to pin 13. It is simple to use and always there. But most times we want our own LEDs in different places of our system. It is possible that we connect something on top of the Arduino board and are unable to see the internal LED anymore. Here, we will explore how to connect an external LED.

Getting ready

For this step we need the following ingredients:

  • An Arduino board connected to the computer via USB
  • A breadboard and jumper wires
  • A regular LED (the typical LED size is 3 mm)
  • A resistor between 220–1,000 ohm

How to do it…

Follow these steps to connect an external LED to an Arduino board:

  1. Mount the resistor on the breadboard. Connect one end of the resistor to a digital pin on the Arduino board using a jumper wire.
  2. Mount the LED on the breadboard. Connect the anode (+) pin of the LED to the available pin on the resistor. We can determine the anode on the LED in two ways. Usually, the longer pin is the anode. Another way is to look for the flat edge on the outer casing of the LED. The pin next to the flat edge is the cathode (-).
  3. Connect the LED cathode (-) to the Arduino GND using jumper wires.

Schematic

This is one possible implementation on the second digital pin. Other digital pins can also be used.

Arduino Development Cookbook

Here is a simple way of wiring the LED:

Arduino Development Cookbook

Code

The following code will make the external LED blink:

// Declare the LED pin
int LED = 2;
void setup() {
// Declare the pin for the LED as Output
pinMode(LED, OUTPUT);
}
void loop(){
// Here we will turn the LED ON and wait 200 milliseconds
digitalWrite(LED, HIGH);
delay(200);
// Here we will turn the LED OFF and wait 200 milliseconds
digitalWrite(LED, LOW);
delay(200);
}

If the LED is connected to a different pin, simply change the LED value to the value of the pin that has been used.

How it works…

This is all semiconductor magic. When the second digital pin is set to HIGH, the Arduino provides 5 V of electricity, which travels through the resistor to the LED and GND. When enough voltage and current is present, the LED will light up. The resistor limits the amount of current passing through the LED. Without it, it is possible that the LED (or worse, the Arduino pin) will burn. Try to avoid using LEDs without resistors; this can easily destroy the LED or even your Arduino.

Code breakdown

The code simply turns the LED on, waits, and then turns it off again. In this one we will use a blocking approach by using the delay() function. Here we declare the LED pin on digital pin 2:

int LED = 2;

In the setup() function we set the LED pin as an output:

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

In the loop() function, we continuously turn the LED on, wait 200 milliseconds, and then we turn it off. After turning it off we need to wait another 200 milliseconds, otherwise it will instantaneously turn on again and we will only see a permanently on LED.

void loop(){
// Here we will turn the LED ON and wait 200 miliseconds
digitalWrite(LED, HIGH);
delay(200);
// Here we will turn the LED OFF and wait 200 miliseconds
digitalWrite(LED, LOW);
delay(200);
}

There’s more…

There are a few more things we can do. For example, what if we want more LEDs? Do we really need to mount the resistor first and then the LED?

LED resistor

We do need the resistor connected to the LED; otherwise there is a chance that the LED or the Arduino pin will burn. However, we can also mount the LED first and then the resistor. This means we will connect the Arduino digital pin to the anode (+) and the resistor between the LED cathode (-) and GND. If we want a quick cheat, check the following See also section.

Multiple LEDs

Each LED will require its own resistor and digital pin. For example, we can mount one LED on pin 2 and one on pin 3 and individually control each. What if we want multiple LEDs on the same pin? Due to the low voltage of the Arduino, we cannot really mount more than three LEDs on a single pin. For this we require a small resistor, 220 ohm for example, and we need to mount the LEDs in series. This means that the cathode (-) of the first LED will be mounted to the anode (+) of the second LED, and the cathode (-) of the second LED will be connected to the GND. The resistor can be placed anywhere in the path from the digital pin to the GND.

See also

For more information on external LEDs, take a look at the following recipes and links:

Now that we know how to connect an LED, let’s also learn how to work with a basic temperature sensor, and built the thermometer we need.

Temperature sensor

Almost all sensors use the same analog interface. Here, we explore a very useful and fun sensor that uses the same. Temperature sensors are useful for obtaining data from the environment. They come in a variety of shapes, sizes, and specifications. We can mount one at the end of a robotic hand and measure the temperature in dangerous liquids. Or we can just build a thermometer.

Here, we will build a small thermometer using the classic LM35 and a bunch of LEDs.

Getting ready

The following are the ingredients required:

  • A LM35 temperature sensor
  • A bunch of LEDs, different colors for a better effect
  • Some resistors between 220–1,000 ohm

How to do it…

The following are the steps to connect a button without a resistor:

  1. Connect the LEDs next to each other on the breadboard.
  2. Connect all LED negative terminals—the cathodes—together and then connect them to the Arduino GND.
  3. Connect a resistor to each positive terminal of the LED. Then, connect each of the remaining resistor terminals to a digital pin on the Arduino. Here, we used pins 2 to 6.
  4. Plug the LM35 in the breadboard and connect its ground to the GND line. The GND pin is the one on the right, when looking at the flat face.
  5. Connect the leftmost pin on the LM35 to 5V on the Arduino.
  6. Lastly, use a jumper wire to connect the center LM35 pin to an analog input on the Arduino. Here we used the A0 analog pin.

Schematic

This is one possible implementation using the pin A0 for analog input and pins 2 to 6 for the LEDs:

Arduino Development Cookbook

Here is a possible breadboard implementation:

Arduino Development Cookbook

Code

The following code will read the temperature from the LM35 sensor, write it on the serial, and light up the LEDs to create a thermometer effect:

// Declare the LEDs in an array
int LED [5] = {2, 3, 4, 5, 6};
int sensorPin = A0; // Declare the used sensor pin
void setup(){
   // Start the Serial connection
Serial.begin(9600);
// Set all LEDs as OUTPUTS
for (int i = 0; i < 5; i++){
   pinMode(LED[i], OUTPUT);
}
}
 
void loop(){
// Read the value of the sensor
int val = analogRead(sensorPin);
Serial.println(val); // Print it to the Serial
// On the LM35 each degree Celsius equals 10 mV
// 20C is represented by 200 mV which means 0.2 V / 5 V * 1023 = 41
// Each degree is represented by an analogue value change of   approximately 2
// Set all LEDs off
for (int i = 0; i < 5; i++){
   digitalWrite(LED[i], LOW);
}
if (val > 40 && val < 45){ // 20 - 22 C
   digitalWrite( LED[0], HIGH);
} else if (val > 45 && val < 49){ // 22 - 24 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
} else if (val > 49 && val < 53){ // 24 - 26 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( LED[2], HIGH);
} else if (val > 53 && val < 57){ // 26 - 28 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( LED[2], HIGH);
   digitalWrite( LED[3], HIGH);
} else if (val > 57){ // Over 28 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( LED[2], HIGH);
   digitalWrite( LED[3], HIGH);
   digitalWrite( LED[4], HIGH);
}
delay(100); // Small delay for the Serial to send
}

Blow into the temperature sensor to observe how the temperature goes up or down.

How it works…

The LM35 is a very simple and reliable sensor. It outputs an analog voltage on the center pin that is proportional to the temperature. More exactly, it outputs 10 mV for each degree Celsius. For a common value of 25 degrees, it will output 250 mV, or 0.25 V. We use the ADC inside the Arduino to read that voltage and light up LEDs accordingly.

If it’s hot, we light up more of them, if not, less. If the LEDs are in order, we will get a nice thermometer effect.

Code breakdown

First, we declare the used LED pins and the analog input to which we connected the sensor. We have five LEDs to declare so, rather than defining five variables, we can store all five pin numbers in an array with 5 elements:

int LED [5] = {2, 3, 4, 5, 6};
int sensorPin = A0;

We use the same array trick to simplify setting each pin as an output in the setup() function. Rather than using the pinMode() function five times, we have a for loop that will do it for us. It will iterate through each value in the LED[i] array and set each pin as output:

void setup(){
Serial.begin(9600);
for (int i = 0; i < 5; i++){
   pinMode(LED[i], OUTPUT);
}
}

In the loop() function, we continuously read the value of the sensor using the analogRead() function; then we print it on the serial:

int val = analogRead(sensorPin);
Serial.println(val);

At last, we create our thermometer effect. For each degree Celsius, the LM35 returns 10 mV more. We can convert this to our analogRead() value in this way: 5V returns 1023, so a value of 0.20 V, corresponding to 20 degrees Celsius, will return 0.20 V/5 V * 1023, which will be equal to around 41.

We have five different temperature areas; we’ll use standard if and else casuals to determine which region we are in. Then we light the required LEDs.

There’s more…

Almost all analog sensors use this method to return a value. They bring a proportional voltage to the value they read that we can read using the analogRead() function.

Here are just a few of the sensor types we can use with this interface:

Temperature

Humidity

Pressure

Altitude

Depth

Liquid level

Distance

Radiation

Interference

Current

Voltage

Inductance

Resistance

Capacitance

Acceleration

Orientation

Angular velocity

Magnetism

Compass

Infrared

Flexing

Weight

Force

Alcohol

Methane and other gases

Light

Sound

Pulse

Unique ID such as fingerprint

Ghost!

The last building block is the fan motor. Any DC fan motor will do for this, here we will learn how to connect and program it.

Controlling motors with transistors

We can control a motor by directly connecting it to the Arduino digital pin; however, any motor bigger than a coin would kill the digital pin and most probably burn Arduino. The solution is to use a simple amplification device, the transistor, to aid in controlling motors of any size.

Here, we will explore how to control larger motors using both NPN and PNP transistors.

Getting ready

To execute this recipe, you will require the following ingredients:

  • A DC motor
  • A resistor between 220 ohm and 10K ohm
  • A standard NPN transistor (BC547, 2N3904, N2222A, TIP120)
  • A standard diode (1N4148, 1N4001, 1N4007)

All these components can be found on websites such as Adafruit, Pololu, and Sparkfun, or in any general electronics store.

How to do it…

The following are the steps to connect a motor using a transistor:

  1. Connect the Arduino GND to the long strip on the breadboard.
  2. Connect one of the motor terminals to VIN or 5V on the Arduino. We use 5V if we power the board from the USB port. If we want higher voltages, we could use an external power source, such as a battery, and connect it to the power jack on Arduino. However, even the power jack has an input voltage range of 7 V–12 V. Don’t exceed these limitations.
  3. Connect the other terminal of the motor to the collector pin on the NPN transistor. Check the datasheet to identify which terminal on the transistor is the collector.
  4. Connect the emitter pin of the NPN transistor to the GND using the long strip or a long connection.
  5. Mount a resistor between the base pin of the NPN transistor and one digital pin on the Arduino board.
  6. Mount a protection diode in parallel with the motor. The diode should point to 5V if the motor is powered by 5V, or should point to VIN if we use an external power supply.

Schematic

This is one possible implementation on the ninth digital pin. The Arduino has to be powered by an external supply. If not, we can connect the motor to 5V and it will be powered with 5 volts.

Arduino Development Cookbook

Here is one way of hooking up the motor and the transistor on a breadboard:

Arduino Development Cookbook

Code

For the coding part, nothing changes if we compare it with a small motor directly mounted on the pin. The code will start the motor for 1 second and then stop it for another one:

// Declare the pin for the motor
int motorPin = 2;
void setup() {
// Define pin #2 as output
pinMode(motorPin, OUTPUT);
}
void loop(){
// Turn motor on
digitalWrite(motorPin, HIGH);
// Wait 1000 ms
delay(1000);
// Turn motor off
digitalWrite(motorPin, LOW);
// Wait another 1000 ms
delay(1000);
}

If the motor is connected to a different pin, simply change the motorPin value to the value of the pin that has been used.

How it works…

Transistors are very neat components that are unfortunately hard to understand. We should think of a transistor as an electric valve: the more current we put into the valve, the more water it will allow to flow. The same happens with a transistor; only here, current flows. If we apply a current on the base of the transistor, a proportional current will be allowed to pass from the collector to the emitter, in the case of an NPN transistor. The more current we put on the base, the more the flow of current will be between the other two terminals.

Arduino Development Cookbook

When we set the digital pin at HIGH on the Arduino, current passes from the pin to the base of the NPN transistor, thus allowing current to pass through the other two terminals. When we set the pin at LOW, no current goes to the base and so, no current will pass through the other two terminals. Another analogy would be a digital switch that allows current to pass from the collector to the emitter only when we ‘push’ the base with current.

Transistors are very useful because, with a very small current on the base, we can control a very large current from the collector to the emitter. A typical amplification factor called b for a transistor is 200. This means that, for a base current of 1 mA, the transistor will allow a maximum of 200 mA to pass from the collector to the emitter.

An important component is the diode, which should never be omitted. A motor is also an inductor; whenever an inductor is cut from power it may generate large voltage spikes, which could easily destroy a transistor. The diode makes sure that all current coming out of the motor goes back to the power supply and not to the motor.

There’s more…

Transistors are handy devices; here are a few more things that can be done with them.

Pull-down resistor

The base of a transistor is very sensitive. Even touching it with a finger might make the motor turn. A solution to avoid unwanted noise and starting the motor is to use a pull-down resistor on the base pin, as shown in the following figure. A value of around 10K is recommended, and it will safeguard the transistor from accidentally starting.

Arduino Development Cookbook

PNP transistors

A PNP transistor is even harder to understand. It uses the same principle, but in reverse. Current flows from the base to the digital pin on the Arduino; if we allow that current to flow, the transistor will allow current to pass from its emitter to its collector (yes, the opposite of what happens with an NPN transistor). Another important point is that the PNP is mounted between the power source and the load we want to power up. The load, in this case a motor, will be connected between the collector on the PNP and the ground.

Arduino Development Cookbook

A key point to remember while using PNP transistors with Arduino is that the maximum voltage on the emitter is 5 V, so the motor will never receive more than 5 V. If we use an external power supply for the motor, the base will have a voltage higher than 5 V and will burn the Arduino. One possible solution, which is quite complicated, has been shown here:

Arduino Development Cookbook

MOSFETs

Let’s face it; NPN and PNP transistors are old. There are better things these days that can provide much better performance. They are called Metal-oxide-semiconductor field-effect transistors. Normal people just call them MOSFETs and they work mostly the same. The three pins on a normal transistor are called collector, base, and emitter. On the MOSFET, they are called drain, gate, and source. Operation-wise, we can use them exactly the same way as with normal transistors. When voltage is applied at the gate, current will pass from the drain to the source in the case of an N-channel MOSFET. A P-channel is the equivalent of a PNP transistor.

However, there are some important differences in the way a MOSFET works compared with a normal transistor. Not all MOSFETs can be properly powered on by the Arduino. Usually logic-level MOSFETs will work. Some of the famous N-channel MOSFETs are the FQP30N06, the IRF510, and the IRF520. The first one can handle up to 30 A and 60 V while the following two can handle 5.6 A and 10 A, respectively, at 100 V.

Here is one implementation of the previous circuit, this time using an N-channel MOSFET:

Arduino Development Cookbook

We can also use the following breadboard arrangement:

Arduino Development Cookbook

Different loads

A motor is not the only thing we can control with a transistor. Any kind of DC load can be controlled. An LED, a light or other tools, even another Arduino can be powered up by an Arduino and a PNP or NPN transistor. Arduinoception!

See also

Putting it all together

Now that we have the three key building blocks, we need to assemble them together. For the code, we only need to briefly modify the Temperature Sensor code, to also output to the motor:

// Declare the LEDs in an array
int LED [5] = {2, 3, 4, 5, 6};
int sensorPin = A0; // Declare the used sensor pin
int motorPin = 9; // Declare the used motor pin
void setup(){
   // Start the Serial connection
Serial.begin(9600);
// Set all LEDs as OUTPUTS
for (int i = 0; i < 5; i++){
   pinMode(LED[i], OUTPUT);
}
// Define motorPin as output
pinMode(motorPin, OUTPUT);
 
}
 
void loop(){
// Read the value of the sensor
int val = analogRead(sensorPin);
Serial.println(val); // Print it to the Serial
// On the LM35 each degree Celsius equals 10 mV
// 20C is represented by 200 mV which means 0.2 V / 5 V * 1023 = 41
// Each degree is represented by an analogue value change of   approximately 2
// Set all LEDs off
for (int i = 0; i < 5; i++){
   digitalWrite(LED[i], LOW);
}
if (val > 40 && val < 45){ // 20 - 22 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( motorPIN, LOW); // Fan OFF
} else if (val > 45 && val < 49){ // 22 - 24 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( motorPIN, LOW); // Fan OFF
} else if (val > 49 && val < 53){ // 24 - 26 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( LED[2], HIGH);
   digitalWrite( motorPIN, LOW); // Fan OFF
} else if (val > 53 && val < 57){ // 26 - 28 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( LED[2], HIGH);
   digitalWrite( LED[3], HIGH);
   digitalWrite( motorPIN, LOW); // Fan OFF
} else if (val > 57){ // Over 28 C
   digitalWrite( LED[0], HIGH);
   digitalWrite( LED[1], HIGH);
   digitalWrite( LED[2], HIGH);
   digitalWrite( LED[3], HIGH);
   digitalWrite( LED[4], HIGH);
   digitalWrite( motorPIN, HIGH); // Fan ON
}
delay(100); // Small delay for the Serial to send
}

Summary

In this article, we learned the three basic skills—to connect an LED to the Arduino, to connect a sensor, and to connect a motor.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here