Raspberry Pi Speaks Arduino

For a project of mine, I needed to connect a Raspberry Pi’s output to an Arduino Uno’s input. The Raspberry Pi’s digital input/output uses 3.3-volt logic while the Arduino Uno digital input/output uses 5-volt logic. How does one convert from one logic level to the other? There are several ways to do this and most methods use a transistor switch controlled by 3.3-volt logic to drive 5-volt logic.

We must first define what constitutes a HIGH and a LOW on the Arduino Uno and the Raspberry Pi. For the Arduino Uno, a digital pin, whether input or output, is considered in a LOW state for voltages below 1.5 volts and in a HIGH state for voltages between 3 and 5 volts. The Raspberry Pi’s digital input and output pins are considered in a LOW state for voltages below 1 volt and in a HIGH state for voltages between 2 and 3.3 volts.

From 3.3 Volts to 5 Volts

In order to convert the Raspberry Pi’s digital output voltage levels to the Arduino’s digital input levels, we can use a transistor switch, similar to the one used to control a relay in a previous post. I will describe two transistor circuits: the logic inverter and the level converter using the transistor’s emitter as input.

Logic Inverter

In the circuit below, we want that if the input voltage is between 0 and 1 volt, the transistor be in cutoff mode, completely off, and the output voltage be between 3 to 5 volts. We also want that if the input voltage is between 2 and 3.3 volts, the transistor be in saturation mode, completely on, and the output voltage be between 0 to 1.5 volts. In other words, if the input is LOW, the output will be HIGH and if the input is HIGH, then the output will be LOW. This circuit is called a logic inverter. It converts logic levels but it inverts logical values. Because the input is considered LOW at or below 1 volt and HIGH at or above 2 volts, we want for the transistor to go from cutoff to saturation mode between input values of 1 volt and 2 volts. To ensure that LOW and HIGH values are met, let’s make the transistor be in cutoff mode for input values at of below 1.4 volts and let it be in saturation mode for values at or above 1.6 volts.

3.3V to 5V Inverted Transistor General

In cutoff mode, there is no transistor base current and the base-emitter voltage (Vbe) is at or below 0.7 volts. Hence, the current in Rbase and Rbias are the same and the voltage across Rbias is at or below 0.7 volts. When the input voltage is 1.4 volts, the following equation holds.

Vbe / RBias = (Vin – Vbe) / RBase

0.7 V / RBias = (1.4 V – 0.7 V) / RBase = 0.7 V / RBase

RBias = RBase

In saturation mode, the voltage across the collector and emitter is 0 volts and collector current is constant at Vcc / RLoad. We want the collector current to be large enough for the transistor to work properly, but small enough to consume the least power possible. Using a 10K resistor, the collector current is 5 V / 10K, or 0.5 mA which is within the BC337-40 bipolar junction transistor working values. According to its specification, the hfe value, the collector-base current amplification, is 400. The base current is thus

Ib = Ic / hfe

Ib = 0.5 mA / 400 = 1.25 μA

The current through RBase is equal to the currents through both RBias and the transistor’s base.  When the input voltage is 1.6 volts, the following equation holds.

(Vin – Vbe) / RBase = Vbe / RBias + Ib

(1.6 V – 0.7 V) / RBase = 0.7 V / RBias + 1.25 μA

Since, as we have seen above, RBias has the same value as RBase, the equation becomes

0.9 V / RBase = 0.7 V / RBase + 1.25 μA

RBase = RBias = 160K ≅ 220K

The circuit becomes

3.3V to 5V B input 2 base resistors Values

The following graph plots the input and output computed voltage values, in blue, and the values measured on an actual circuit implemented with the resistor values in the schematic above, in orange.

3.3V to 5V Biased Base Input

As can be seen, logical values are inverted and voltage values correspond to acceptable values for both the Raspberry Pi and Arduino’s HIGH and LOW voltage levels. Notice the shift of the target voltage values slightly to the left of 1.5 volts. This is caused by the fact that we are not using the exact resistor values as computed, because the saturated Vbe is not exactly 0.7 volts and the actual hfe is not exactly 400. Still, the results are more than acceptable, if we wanted an inverted signal.

Using the Emitter as Input

Let’s use the same circuit, but connect the base resistor to the Raspberry Pi’s supply, VccP, and the emitter to the Raspberry Pi digital output as in the following circuit.

3.3V to 5V Converted Transistor General

This is like rotating the previous circuit clockwise by 90 degrees. Now we want that if the input voltage is LOW, below 1 volt, that the transistor be in saturation and the output be at Vin, the Raspberry Pi digital output value.  We also want that if the input voltage is HIGH, at 2 volts or higher, that the transistor be in cutoff and the output be at the Arduino’s supply voltage. Because the permissible voltages for the LOW value on the Arduino, between 0 and 1.5 volts, are higher than those for the Raspberry Pi, between 0 and 1 volt, it is acceptable to use the Raspberry Pi digital output voltages as the Arduino’s input for LOW values.

In this circuit, as it was in the previous one, in cutoff mode there is no transistor base current and the base-emitter voltage is at or below 0.7 volts. Hence, the current in RBase and RBias are the same and the voltage across RBias is at or below 0.7 volts. Hence, when the input voltage is 1.6 volts, the following equation holds.

(VccP – Vbe – Vin) / RBase = Vbe / RBias

(3.3V – 0.7V – 1.6) / RBase = 0.7V / RBias

RBias = 0.7 • RBase

For saturation mode, the same reasoning as for the logic inverter holds about the base current to collector current relationship. Since we want saturation of the transistor to occur at 1.4 volts, the collector current is equal to the current going through RLoad.

Ic = (VccA – Vin) / RLoad

Ic = (5V – 1.4V) / 10K = 0.36 mA

The base current is thus

Ib = Ic / hfe

Ib = 0.36 mA / 400 = 0.9 μA

The current through the base is the current through RBase minus the current through RBias. When the input voltage is 1.4 volts, when we want transistor saturation to occur, the following equations hold.

Ib = (VccP – Vbe – Vin) / RBase – Vbe / RBias

0.9 μA = (3.3V – 0.7V – 1.4V) / RBase – 0.7V / RBias

Since, as we have seen above, RBias is 0.7 • RBase, we have

0.9 μA = (3.3V – 0.7V – 1.4V) / RBase – 0.7V / (0.7 • RBase)

0.9 μA = 1.2V / RBase – 1V / RBase

RBase = 0.2V / 0.9 μA = 222.222K ≅ 220K

We then compute RBias from the cutoff equations

RBias = 0.7 • RBase = 155.556K ≅ 150K

The circuit becomes

3.3V to 5V E input 2 base resistors Values

The following graph plots the input and output computed voltage values, in blue, and the values measured on an actual circuit implemented with the resistor values in the schematic above, in orange.

3.3V to 5V Biased Emitter Input

In the graph, logical values are converted to the same levels this time, and voltage values correspond to acceptable values for both the Raspberry Pi and Arduino’s HIGH and LOW voltage levels. Notice the shift of the target voltage values slightly to the right of 1.5 volts. This is caused by the fact that we are not using the exact resistor values as computed, because the saturated Vbe value is not exactly 0.7 volts and the actual transistor current amplification is not exactly 400. Nevertheless, results are more than acceptable.

Putting it Together

Now that we have a method to convert 3.3-volt logic to 5-volt logic, we can connect a Raspberry Pi 3 GPIO output to an Arduino digital input. As a test, we will program the Raspberry Pi to output Morse Code, read the output using an Arduino digital input and output the value read to the Arduino’s built-in LED. The code within this post can be found on GitHub by clicking here.

Breadboarding

First, let’s have a look at the complete circuit. The following picture depicts how to connect the different parts using a solderless breadboard, jump wires, a BC337-40 transistor, and a 10K, a 220K and a 150K resistor. Through one of the breadboard’s ground rail, we connect the Raspberry Pi and Arduino’s ground pins. The Raspberry Pi’s 3.3-volt supply is connected to the transistor’s base through the 220K resistor. The Raspberry Pi’s GPIO4 output is connected directly to the transistor’s emitter. The Arduino’s 5-volt supply is connected to the transistor’s collector through a 10K resistor. The Arduino’s digital input 8 is connected directly to the transistor’s collector.

3.3to5_bb

Morse Code Generator in Python

We have seen the morse code generator in a previous post. I have ported the Morse Code program to Python 3 for it to be run on the Raspberry Pi. I used IDLE (Integrated Development and Learning Environment) to code and run the Python 3 code on the Raspberry Pi. If you are new to the Raspberry Pi and want to set it up, please visit “Get started with Raspberry Pi” on the www.raspberrypi.org site.

# Morse Code Generator Python Program that translates a
# text string to Morse Code and outputs it to a GPIO pin.
# This program is used as part of a demonstration to show
# connectivity between a Raspberry Pi and an Arduino UNO.
# It is associated with the Raspberry Pi Speaks Arduino
# blog post on https://lagacemichel.com
# MIT License
# Copyright (c) 2019, Michel Lagace

import RPi.GPIO as IO
import time
UNIT_TIME = 0.1
BOARD_PIN = 7
# Characters to be encoded
characters = "abcdefghijklmnopqrstuvwxyz"

# Morse code sequences for each character
codedCharacters = [
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.",
"--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--.." ]

# Setup the board. Digital port LED_BUILTIN in output mode
def setup():
    IO.setwarnings(False)
    IO.setmode (IO.BOARD)
    IO.setup(BOARD_PIN,IO.OUT)

# Function to output a dot: one unit on, one unit off
def outputDot():
    IO.output(BOARD_PIN,1)
    time.sleep(UNIT_TIME)
    IO.output(BOARD_PIN,0)
    time.sleep(UNIT_TIME)

# Function to output a dash: three units on, one unit off
def outputDash():
    IO.output(BOARD_PIN,1)
    time.sleep(UNIT_TIME*3)
    IO.output(BOARD_PIN,0)
    time.sleep(UNIT_TIME)

# Function to output a single character
def outputCharacter(c):
    # Find index of character to encode
    index = characters.find(c)
    # Ignore unencodable characters
    if (index >= 0):
        # Encode morse codeand output it
        code = codedCharacters[index]
        for ch in code:
            if ch == '-':
                outputDash()
            else: # if not '-', must be '.'
                outputDot()
        # Wait 3 units at the end of the letter
        # (2 units assuming previous dot or dash)
        time.sleep(UNIT_TIME*2)

# Function to encode a whole string
def sentence (text):
    # Output each character in turn
    for ch in text:
        # Only lower-case characters are encoded
        if ch != ' ':
            outputCharacter(ch.lower())
        # Spaces are encoded as 7 units,
        # (4 units assuming a previous character)
        else:
            time.sleep(UNIT_TIME*4)

# Function looped indefinitely
def loop():
    sentence("Mikes Electro Shack")
    time.sleep(UNIT_TIME*25) # Wait 4 spaces at the end

# Main program. Setup board then loop forever
setup()
while(True):
    loop()

Raspberry Pi Reader on the Arduino

The code on the Arduino is quite simple. It loops forever, reading the digital input connected to the Raspberry Pi, writes the value to the built-in LED, then waits 10 milliseconds befor starting over.

// Main RaspberryPiReader sketch
// Program that reads a digital input from a Raspberry Pi
// GPIO pin and outputs its value to an Arduino digital output
// pin. This sketch is used as part of a demonstration to show
// connectivity between a Raspberry Pi and an Arduino UNO.
// It is associated with the Raspberry Pi Speaks Arduino
// blog post on https://lagacemichel.com
// MIT License
// Copyright (c) 2019, Michel Lagace

// Define input and output ports
#define INPORT 8    // Input port connected to Raspberry Pi
#define OUTPORT 13  // Output port to built-in 

// Time to wait in milliseconds between samples
#define SAMPLE_DELAY 10

// Setup the board.
void setup() {
    pinMode(INPORT, INPUT);
    pinMode(OUTPORT,OUTPUT);
    digitalWrite(OUTPORT,LOW);
}

// Repeat forever
void loop() {
    // Read value from Raspberry Pi
    bool value = digitalRead(INPORT);
    
    // Output value to built-in LED
    digitalWrite(OUTPORT, value);
    
    // Wait before next sample
    delay(SAMPLE_DELAY);
}

Download the sketch on the Arduino then run the Python program on the Raspberry Pi. You will notice Morse Code being output by the Arduino’s buit-in LED.

A Better Transistor Switch Circuit

In the previous post, we have seen how to drive a relay using an NPN bipolar junction transistor. The circuit allowed a digital input signal to activate and deactivate a relay coil. As seen previously, the following graph depicts what is happening to the relay coil voltage drop with respect to the input voltage from an Arduino digital output pin.

Simple Transistor Relay Switch Plot

Looking at the bottom horizontal band, the relay electrical characteristics guarantee that the relay is off for input values between 0 volts and 1 volt; and looking at the top horizontal band, the relay electrical characteristics guarantee that the relay activates when the input voltage is above approximately 2.75 volts. What if we wanted the relay to remain off until the input voltage to be at least 2 volts, and the relay to be on when the input voltage is at most 3 volts?

Biasing the Base of the Transistor

There is a way in our circuit for base-emitter voltage drop not to be equal to Vin when the transistor is in cut-off mode. Remember that the transistor requires a forward voltage drop of 0.7 volts, for silicon-based bipolar junction transistors, between the base and emitter before current can flow through the base and thus the collector. While current is not flowing through the base or base resistor, the voltage at the base is the same as the voltage at the input. How can we make the voltage at the input of the base resistor higher than the voltage at the base? By using a voltage divider.

The Voltage Divider

The voltage divider is a simple circuit where two resistors in series divide the voltage amongst them. According to Kirchhoff’s voltage law, as seen in the Blink post, the sum of the electromotive forces, as provided by batteries, in any closed loop is equivalent to the sum of the voltage drops in that loop. Thus, in the following circuit,

voltage divider

The sum of voltage drops across R1 and R2 is equal to VDC. The current IDC in the circuit is, according to Ohm’s law, I = V/R or

IDC = VR1/R1 = VR2/R2
IDC = (VR1 + VR2) / (R1 + R2)
IDC = VDC / (R1 + R2)

The voltage across R2 is

VR2 = IDC•R2
VR2 = VDC•R2 / (R1 + R2)

If VDC is 2 volts and we want VR2 to be 0.7 volts then

0.7 V = 2 V•R2 / (R1 + R2)
0.35•R1 + 0.35•R2 = R2
0.35•R1 = 0.65•R2

Lets apply this to the complete switch circuit from the previous post and add a resistor, RBias between the base of the transistor and ground.

Transistor Switch with Bias

In this circuit, as previously computed, in order for the Vin value of 2 volts to produce a voltage of 0.7 volts across the base and emitter of the transistor, RBase and RBias must satisfy the following equation

0.35•RBase = 0.65•RBias
RBase = 0.65•RBias / 0.35

When the base-emitter voltage reaches 0.7 volts, current starts flowing into the base of the transistor and the base-emitter voltage remains 0.7 volts. According to Kirchhoff’s current law the sum of currents flowing into the junction of the base resistor, the bias resistor and the base node is equal to the sum of currents flowing out of that junction. The current flowing into the junction through the base resistor is

I = (Vin – 0.7 V) / RBase

The current flowing out of the junction through the bias resistor and the transistor’s base is

I = 0.7 V / RBias + IBase

Hence,

IBase = (Vin – 0.7V) / RBase – 0.7 V / RBias

Now, assuming a resistive relay coil load of 70 Ω, a power supply of 5 V and a transistor hFE of 250, the base current at start of transistor saturation is

IBase = 5 V / (70 Ω•250) ≅ 0.286 mA

As stated earlier, we want Vin to be 3 volts at saturation and using the base current equation, we get

0.286 mA = (3 V – 0.7V) / RBase – 0.7V / RBias

Replacing RBase with the voltage divider circuit equation computed for the resistor values at cutoff we get

0.286 mA = (3V – 0.7V) / (0.35 RBias/0.65) – 0.7V / RBias
RBias = 1795 Ω ≅ 1.8K

Replacing RBias in the cutoff voltage divider equation we get

RBase = 0.65•RBias / 0.35 = 3333 Ω ≅ 3.3K

Resulting New Circuit

The following diagram depicts the transistor relay switch circuit with a voltage divider at the base of the transistor switch. The values of the resistors are 3.3K for the base resistor and 1.8K for the bias resistor.

Connected Biased Transistor Relay Switch

The following graph depicts what is now happening to the relay coil voltage with respect to the input voltage from an Arduino digital output pin when the voltage divider is used at the base of the transistor.

Biased Transistor Relay Switch Plot

Notice how we get a cleaner and sharper voltage transfer between the input signal and the voltage at the relay coil. This new circuit ensures that weaker input digital signals can be used to operate the transistor relay switch.

Breadboarding

The following picture depicts how to connect the different parts using a solderless breadboard, jumper wires, a transistor, a diode, a relay, a push button, a 10K resistor, a 1.8K resistor and a 3.3K resistor. Connections to the household appliance are not shown.

A better Transistor Switch Circuit_bb

WARNING:

The project in this post involves household mains high-voltages. Use caution whenever dealing with high-voltage wiring, including following directions carefully and following general safety practices. Safe assembly and operation of this project is the user’s responsibility. If unsure or if local laws prohibit the assembly of high-voltage circuits, get the help of a professional electrician. Do not make changes to the system while the device is plugged in.

Transistor Driven Relay Switch

Up to now, we have seen how to input digital (on and off) information from a simple electromechanical device, the push-button, and how to output a digital signal to an LED. What if, instead of an LED, we wanted to turn on and off an actual household light. There are obvious electrical differences between LEDs and household lights. LEDs only require a few milliamperes of current and work very well in low voltage circuits such as the 5 volts provided by an Arduino board. A household light, on the other hand, requires mains electricity, between 110 and 240 volts depending on your location, and higher currents, between 200 milliamperes and one ampere. A microcontroller digital output cannot directly provide enough power to light a household light.

Relays are electromechanical devices, like the push-button. Instead of requiring a mechanical force to push on the device to close or open a circuit, it relies on an electromagnet to pull on a metal plate to close the circuit with metal contacts with which the plate makes a connection. We can thus close or open a higher voltage and higher current circuit by applying a voltage to the relays electro-magnet that pulls on a metal plate to close the circuit.

It the following sections, we will have a look at a few electronic and electromechanical devices: the relay, the diode, and the transistor.

Relays

Relays have two distinct, electrically independent parts. The first part is an electromagnet, a coil of insulated copper wire wound around a metal bracket, the yoke, that becomes magnetic when a current is applied to it. The other part is a spring-loaded metallic plate or armature resting on metal contacts. When a current is applied to the electromagnet, enough force is applied to the armature for it to disconnect from its resting contacts and make an electrical connection with another set of metallic contacts on which the armature rests for as long as there is electrical current in the electromagnet. When current stops flowing in the electromagnet, the spring attached to the metallic armature forces it back to its initial resting position, making an electrical connection between the metallic plate and the resting contacts.

Relay Parts

Relays come in a variety of sizes and ratings. Ratings are used to select a relay to be used for specific applications. Automotive relays, for instance have rated coil voltages of 12 volts. Relays intended to be used in household appliances have rated coil voltages of 120 or 240 volts. Following is a list of relay coil ratings supplied by manufacturers.

  • Rated Coil Voltage – the voltage that is intended to be applied to the coil to operate the relay.
  • Pull-In Voltage – the minimum voltage that can be applied to the coil for it to operate the relay.
  • Drop-Out Voltage – the voltage below which an activated relay will return to its resting state.
  • Maximum Continuous Voltage – the maximum voltage to be applied to the coil above which permanent damage occurs.
  • Nominal Operating Current – current flowing through the coil when the rated coil voltage is applied.
  • Nominal Operating Power – the power used by the coil when the rated coil voltage is applied.
  • Coil Resistance – the continuous current resistance of the coil in ohms.

Within circuit diagrams, the electromechanical relay is represented as a coil and contacts as in the following diagram depicting normally open and normally closed relay forms.

Relays

Relay contacts have ratings stating the relay’s intended use. Following are relay contact ratings supplied by manufacturers.

  • Contact Forms – the contact mechanism and the number of contacts in the contact circuit.
    • Form A – normally open (N.O.) contact.
    • Form B – normally closed (N.C.) contact.
    • Form C – changeover contacts.
    • MBB – Make-Before-Break contacts where normally open contacts close before normally closed contacts break open.
  • Rated Switching Power – the intended use value in watts of the load that can switched by the contacts.
  • Maximum Switching Voltage – maximum voltage that can safely be switched by the contacts.
  • Maximum Switching Current – maximum current that can safely be switched by the contacts.
  • Maximum Switching Power – the maximum power to be switched by contacts above which damage may occur.

For the current project, we will use a 5 volts miniature relay, the FRS10C-S12, to turn on and off a household lamp. This relay has the following coil characteristics:

  • Rated coil voltage of 5 volts.
  • Pull-in voltage of 3.75 volts.
  • Pull-out voltage of 0.5 volts.
  • Nominal operating current of 70 mA.
  • Coil resistance of 70 Ω.

It has the following contact characteristics:

  • Form C contact form, changeover contacts.
  • Contact rating of 12A at 125VAC (1,500W) or 10A at 250VAC (2,500 W)

The chosen relay’s coil operates on 5 volts, suitable for an Arduino provided power supply, but requires 70 mA to operate, which is much larger than the rated output current of 20 mA that each Arduino digital output can provide. We need a device that can boost the current provided by the digital output pin to drive the relay coil. That device is a transistor.

Transistors

Transistors are semiconductor devices used to amplify or switch electronic signals and electrical power. There are many types of transistors, but the most common is the bipolar junction transistor (BJT). There are two types of bipolar junction transistors, the NPN and PNP types, describing the material and configuration used to build the device. For the current project and tutorial, we will use an NPN transistor. There are several configurations that transistor circuits may use. In order to explain how the transistor operates, I will be using the common-emitter configuration, that is a transistor circuit with its emitter directly connected to ground. Consider the following circuit.

NPN Transistor

The transistor, labelled Q1, is at the center of the diagram. It is represented by a circle with a vertical bar from which three branches are attached. The diagonal branch at the top is called the collector. It is connected to a resistor, RLoad, representing the device to be switched on or off. The branch to the left of the transistor symbol, perpendicular to the bar is called the base. It is connected to a resistor, RBase, that controls the current flowing into the base. Finally, the diagonal branch with the arrow pointing outward is the emitter. If the arrow had been pointing towards the bar inside the symbol, we would have a PNP transistor. In this circuit, the emitter is connected to ground. The principle of operation of the transistor is that a small current flowing from the base to the emitter of the transistor will allow a larger current flowing from the collector to the emitter, thus amplifying the base current.

Transistors, like other electronic devices, have specifications telling us about the electrical limitations of the devices as well as information about their capabilities. In the circuit that we will build later on, we will use a BC337-40 NPN Bipolar Junction Transistor. I have found the following information from the product data sheet provided at SparkFun.

  • Maximum Collector-Base Voltage |VCES| – 50 V, the maximum voltage drop between the collector and the base.
  • Maximum Collector-Emitter Voltage |VCEO| – 45 V, the maximum voltage drop between the collector and the emitter.
  • Maximum Emitter-Base Voltage |VEBO| – 5 V, the maximum reverse voltage drop between the emitter and the base.
  • Maximum Collector Current |IC| – 800 mA, the maximum amount of current that can flow through the collector.
  • Power Dissipation |PD| – 650 mW, the power dissipation of the device.
  • Forward Current Transfer Ratio |hFE|, minimum – 250, the minimum amount of current amplification between the base current and the collector current.
transistor cbe

Here is a picture of the BC337-40 transistor above. It comes in a TO-92 package, a small plastic half cylinder with a flat face on which the transistor markings are written and three metal pins sticking out at the bottom of the package. When the transistor’s flat face is facing the reader, the collector pin is at the left side of the transistor, the base is the center pin, and the emitter pin is at the right side of the transistor.

Transistor Operation

One characteristic that all silicon transistors have is the forward bias voltage required between the base and the emitter for the transistor to work. Remember that in a previous post titled the Blink circuit, we saw that the LED had a constant voltage drop across its anode and cathode. Similarly, transistor based on silicon have a voltage drop of approximately 0.7 volts between their base and emitter when in operation. Below that voltage, no current flows through the base nor the collector. When the base-emitter voltage (VBE) of the transistor is increased to 0.7 volts, current starts flowing through the base and through the collector. The base-emitter voltage remains at 0.7 volts while current flows through the base. The amount of current flowing through the collector (IC) is proportional to the current flowing through the base (IB) times the Forward Current Transfer Ratio (hFE) of the transistor.

IC = IB = 0,   if VBE < 0.7 V
IC = hFE•IB,  if VBE ≥ 0.7 V

Common Emitter

Looking at the circuit above, an increase of voltage at Vin will get VBE to increase until it reaches 0.7 volts. Since no current flows through RBase, the voltage drop across the resistor is 0 volts and VBE = Vin. While VBE is less than 0.7 volts, the transistor is said to be in cut-off mode. As Vin is increased beyond 0.7 volts, current starts flowing through the base and collector, making the transistor enter the normal amplification operation mode. Following Ohm’s law, I = V / R, and since the current going through the base is the same as the current through the base resistor

IB = (Vin – 0.7 V) / RBase

In the normal amplification operation mode, the voltage across the load resistance RLoad, VLoad, is proportional to the collector current, itself proportional to the base current.

VLoad = IC•RLoad
VLoad = IB•hFE•RLoad
VLoad = ((Vin – 0.7 V) / RBase)•hFE•RLoad

As the voltage across RLoad increases, the voltage across the transistor’s collector and emitter pins decreases until VCE reaches 0 volts. At that point, any increase in the base current has no effect on the collector current and the transistor is said to have reached saturation. At saturation, we have:

IC = VCC / RLoad

The load to be turned on and off is the relay described earlier with a coil resistance of 70 Ω for a supply of 5 volts. At saturation, the collector current is 5 V / 70 Ω or approximately 71 mA. When connecting the base of transistor to an Arduino digital output pin through the base resistor, Vin is 0 volts when a LOW is output to the digital output and 5 volts when a HIGH is output to the digital output. Another way of stating this could be that any input voltage below 2.5 volts is LOW and anything above 2.5 volts is HIGH. Hence, we want a saturated transistor when the input voltage is above 2.5 volts. Assuming a transistor hFE of 250, we can use the equation to compute VLoad from Vin to compute RBase

VLoad = ((Vin – 0.7 V)•hFE•RLoad / RBase)
RBase = (Vin – 0.7 V)•hFE•RLoad /  VLoad
RBase = (2.5 V – 0.7 V) •250•70 Ω / 5 V
RBase =  6,300 Ω

The closest resistor value in my kit is 10K, which should be close enough. Lets now build the circuit. First, we replace the resistive load by the relay coil and we replace the base resistor with a 10 K resistor. The Vin input is replaced with the Arduino’s digital output pin 11.

Transistor Relay Switch

Note the addition of a new device between the terminals of the relay’s coil. Its symbol resembles that of the LED that we saw in previous projects, but without the outward arrows. The device is called a diode. As for the LED, current flows in the direction of the arrow, from anode to cathode. The diode in this circuit serves as a protection for the transistor. The coil of the relay stores energy as it is turned on and it releases that energy when it is turned off as a voltage pulse that can damage the transistor by exceeding its maximum rated collector voltage. The diode acts as a short, preventing the spike from damaging the transistor. In normal operation, the diode does not let current through.

Let’s have a look at a graph plotting the voltage drop across the relay’s coil as a function of the voltage at the Arduino’s digital output pin.

Simple Transistor Relay Switch Plot

On the plot, we see that the voltage applied to the load is 0 volts for as long as the input voltage is below 0.7 volts. Then, as input voltage increases, voltage at the relay coil increases until the input voltage reaches approximately 3.5 volts, at which point the voltage drop across the relay’s coil reaches 5 volts and the transistor enters saturation.

The vertical blue bands represent the guaranteed LOW and HIGH voltage values output by the Arduino’s digital output pin. The top horizontal blue band represents the voltage zone in which the relay is on and the bottom blue horizontal band represents the voltage zone in which the relay is guaranteed to be off. In the diagram, we note that the relay is off for all guaranteed values for Arduino’s LOW output and that it is on for all guaranteed values for Arduino’s HIGH output.

The maximum base current is 5 V / 10 K, or 0.5 mA, a totally acceptable value for the Arduino’s digital output capability. The next step, is to connect a household device to the relay.

The Final Circuit

The relay contacts are exactly like wall switch contacts and can be used to turn on or off household appliances. In the final circuit, the relay contacts are inserted as a switch in one of the wires of a lamp’s power cord. A push-button is used to turn the lamp on and off using the Arduino program described in the LED Toggle with a Push-Button Switch post.

Connected Transistor Relay Switch

Breadboarding

The following picture depicts how to connect the different parts using a solderless breadboard, jumper wires, a transistor, a diode, a relay, a push button and two 10K resistors. Connections to the household appliance are not shown.

Transistor Driven Relay Switch_bb

The Program

The following Arduino program completes the post. Cut and paste the code in your Arduino IDE and download it to complete the project. It will toggle the lamp on and off at each press of the pus button.

/* Household Light Toggle
   Uses a transistor connected to pin LED_BUILTIN as
   a switch for a relay that toggles on and off a
   household lamp at the press of a button.
   This sketch was written by Michel Lagacé, 2018-10-08
   This code is in the public domain. */

// Button value will be read from pin 12
#define INPORT 12
#define OUTPORT 11

// Time to wait in milliseconds to consider switch debounced
#define DEBOUNCE_DELAY 10

// LED state kept across loops
static bool outputValue;

// Setup the board.
void setup() {
    pinMode(INPORT, INPUT);
    pinMode(OUTPORT,OUTPUT);
    outputValue = LOW;
    digitalWrite(OUTPORT,outputValue);
}

// Wait for an edge and return state
bool waitForEdge() {
    bool startValue = digitalRead(INPORT);
    bool newValue = startValue;
    while (newValue == startValue) {
        newValue = digitalRead(INPORT);
    }
    delay(DEBOUNCE_DELAY);
    return newValue;
}

// Repeat forever
void loop() {
    // Wait for a rising or falling edge
    bool value = waitForEdge();

    // Toggle output on dropping edge (input is LOW when button is pressed)
    if (!value) {
        outputValue = !outputValue;
        digitalWrite(OUTPORT, outputValue);
    }
}

WARNING:

The project in this post involves household mains high-voltages. Use caution whenever dealing with high-voltage wiring, including following directions carefully and following general safety practices. Safe assembly and operation of this project is the user’s responsibility. If unsure or if local laws prohibit the assembly of high-voltage circuits, get the help of a professional electrician. Do not make changes to the system while the device is plugged in.