Taillieu.Info

More Than a Hobby..

Adding a PCF 8591 ADC/DAC to ESP8266-01

The ESP8266-01 is a great WiFi enabled  microcontroller but it only has 4 I/O pins broken out. Fortunately it does support I2C protocol so in spite of  the low number of pins, there still is a lot of hardware that can be added.
As the ESP8266-01 has no analog inputs at all, adding an ADC to it is something I wanted to do. After all,  sensors as LDR or NTC are still analog.
The PCF8591 is such an ADC: it is  a single-chip, single‑supply low‑power 8‑bit CMOS data acquisition device with four analog inputs, one analog output and a serial I²C‑bus interface. Three address pins A0, A1 and A2 are used for programming the hardware address, allowing the use of up to eight devices connected to the I²C‑bus without additional hardware. I doubt whether I need more than 8 of those chips. Lets just start with one. Although one can get the individual chip, I have chosen for a module that actually already has some sensors on it:

  • AIN0 – Jumper P5 – Light Dependent Resistor (LDR)
  • AIN1 – Jumper P4 – Thermistor
  • AIN2 – Not connected
  • AIN3 – Jumper P6 – Potentiometer
pcf8591-circhttps://arduinodiy.files.wordpress.com/2016/10/pcf8591-circ1.jpg?w=150 150w, https://arduinodiy.files.wordpress.com/2016/10/pcf8591-circ1.jpg?w=300 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" style="box-sizing: inherit; border: 0px; height: auto; max-width: 100%; vertical-align: middle; display: block; margin: 0px;">
YL-40 circuit

The I2C address of the PCF8591 is determined by the pins A0-A2. As they are close to the Ground pin, let’s start with grounding them (as they are on the module).
pcf8591adreshttps://arduinodiy.files.wordpress.com/2016/10/pcf8591adres.png?w=150 150w, https://arduinodiy.files.wordpress.com/2016/10/pcf8591adres.png?w=300 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" style="box-sizing: inherit; border: 0px; height: auto; max-width: 100%; vertical-align: middle; float: right; margin: 0.375em 0px 1.75em 1.75em; display: block;">The address is 1001A2A1A0. With A2-A0 being LOW, that is 1001000=0x48.

base A2A1A0 Hex Dec
1001 000 48 72
1001 001 49 73
1001 010 4A 74
1001 011 4B 75
1001 100 4C 76
1001 101 4D 77
1001 110 4E 78
1001 111 4F 79

In some programs you will see the address as “0x90>>1” Which is 48 as well. The “0x90” counts the LSB of the 8 bit address, which is the R/W bit. With the Write Bit Low (=active) the full address is 10010000=0x90, but the rightshift 1 removes the LSB again, making it 0x48.
The module is hardwired to 0x48 as the three address lines are soldered to ground. So if you would want to use more than one module on the same I2C port you would need to do some de-soldering (or use   bare PCF8591 chips ofcourse).

https://arduinodiy.files.wordpress.com/2016/10/pcf8591.jpg?w=150&h=136 150w, https://arduinodiy.files.wordpress.com/2016/10/pcf8591.jpg?w=300&h=271 300w, https://arduinodiy.files.wordpress.com/2016/10/pcf8591.jpg?w=768&h=694 768w, https://arduinodiy.files.wordpress.com/2016/10/pcf8591.jpg 912w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" style="box-sizing: inherit; border: 0px; height: auto; max-width: 100%; vertical-align: middle; display: block; margin: 0px;">
Sunfounder board (expensive)

A similar but needlessly more expensive, non configurable board without the sensors is the sunfounder board.

https://arduinodiy.files.wordpress.com/2016/10/pcf8591-ad-da-board-pcf8591-module-8-bit-a-d-d-a-converter-with-i2c-connector_640x640.jpg?w=150 150w, https://arduinodiy.files.wordpress.com/2016/10/pcf8591-ad-da-board-pcf8591-module-8-bit-a-d-d-a-converter-with-i2c-connector_640x640.jpg?w=300 300w" sizes="(max-width: 597px) 85vw, 597px" style="box-sizing: inherit; border: 0px; height: auto; max-width: 100%; vertical-align: middle; display: block; margin: 0px;">
Mini PCF8591 AD DA Shell Module

There is a (more expensive)  fully configurable module, that allows to set the  I2C address with jumpers. That module is daisy chainable with other I2C modules in the same range (there is for example a PCF8547 digital I/O module with similar connections). Making a module yrself is not hard either:

PCF8591https://arduinodiy.files.wordpress.com/2017/10/img_20171011_190303.jpg?w=1604&h=2048 1604w, https://arduinodiy.files.wordpress.com/2017/10/img_20171011_190303.jpg?w=117&h=150 117w, https://arduinodiy.files.wordpress.com/2017/10/img_20171011_190303.jpg?w=235&h=300 235w, https://arduinodiy.files.wordpress.com/2017/10/img_20171011_190303.jpg?w=768&h=981 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" style="box-sizing: inherit; border: 0px; height: auto; max-width: 100%; vertical-align: middle; display: block; margin: 0px;">
PCF8591 configured as 0x48

The control byte sets the operating mode of the PCF8591 and is described in section 7.2 of the datasheet, The upper nibble of the control register is used for enabling the analog output, and for programming the analog inputs as single-ended or differential inputs.
The lower nibble selects one of the analog input channels defined by the upper nibble. If the auto-increment flag is set the channel number is incremented automatically after each A/D conversion.
If the auto-increment mode is desired in applications where the internal oscillator is used, the analog output enable flag in the control byte (bit 6) should be set. This allows the internal oscillator to run continuously, thereby preventing conversion errors resulting from oscillator start-up delay. The analog output enable flag may be reset at other times to reduce quiescent power consumption.

As it is not my intention to explain the full innerworkings of the PCF8591, but just to show it is working with the ESP8266-01, I will skip a full technical discussion. For now it is enough to know that the PCF8591 can be read byte for byte, but it can also be read in ‘burst mode’, in which we read the 4 analog values all at once. The program I present is burstmode with autoincrement of the address. The reason we read 5 bytes instead of 4 is because the first byte contains old data. As the datasheet states in paragraph 8.4: “The first byte transmitted in a read cycle contains the conversion result code of the previous read cycle.”

#include "Wire.h"
int PCF8591=0x48; // I2C bus address
byte ana0, ana1, ana2, ana3;
void setup()
{
 Wire.pins(0,2);// just to make sure
 Wire.begin(0,2);// the SDA and SCL
}
void loop()
{
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x04); // control byte: reads ADC0 then auto-increment
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 5);
 ana0=Wire.read();// throw this one away
 ana0=Wire.read();
 ana1=Wire.read();
 ana2=Wire.read();
 ana3=Wire.read();
}

Obviously when you have these values read you will need to do something with them: print them out, put them on yr own webpage or upload them to e.g. Thingspeak. As printing from the ESP8266-01  is not always easy, I will show you how to upload the values to Thingspeak:

#include  // ESP8266WiFi.h library
#include "Wire.h"
int PCF8591=0x48; // I2C bus address
byte ana0, ana1, ana2, ana3;

const char* ssid     = "YourNetworkSSID";
const char* password = "YourPassword";
const char* host = "api.thingspeak.com";
const char* writeAPIKey = "YourWriteAPI";

void setup() {
  // Initialize sensor
 Wire.pins(0,2);// just to make sure
 Wire.begin(0,2);// the SDA and SCL

//  Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void loop() {
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x04); // control byte: reads ADC0 then auto-increment
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 5);
 ana0=Wire.read();
 ana0=Wire.read();
 ana1=Wire.read();
 ana2=Wire.read();
 ana3=Wire.read();

// make TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    return;
  }

  String url = "/update?key=";
  url+=writeAPIKey;
  url+="&field1=";
  url+=String(ana0);
  url+="&field2=";
  url+=String(ana1);
  url+="&field3=";
  url+=String(ana2);
  url+="&field3=";
  url+=String(ana3);
  url+="\r\n";
  
  // Request to the server
  client.print(String("GET url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
    delay(1000);
}

DAC
The PCF8591 does not only have  4 ADC channels but also 1 DAC channel. Writing to the DAC is as follows:

#define PCF8591 (0x48) // I2C bus address
void setup()
{
 Wire.pins(0,2);// just to make sure
 Wire.begin(0,2);
}
void loop()
{
 for (int i=0; i<255; ++i)
 {
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x40); // turn on DAC b1000000
 Wire.write(i); 
 Wire.endTransmission();
 }
}

Calculations
A the board normally uses the 3.3v supply as the reference voltage:
The input voltage is determined with:
vIn = value * (3.3 / 255)
and the output voltage is:
vOut = (value / 255) * 3.3
or to find the value for a given voltage:
value = (vOut / 3.3) * 255

So if for instance I would write  the value of 50 to the DAC. The voltage would be: 0.64V
In order to test that, I hooked up Aout to the A0 of an ESP 8266-12 and found a value of 192.
To calculate that to a voltage that is  (192/1023)=0.18V.  (Remember, the ESP gives readings from 0-1023, whereas 1023 being 1 Volt.)  So that is not particularly close.
Oddly though when I hooked up the Aout to AIN2 or AIN1 that didn seem to give reliable readings. A value of 50 written to Aout should give a value of 50 on AIN, but oddly it didnt

In my version of the board the NTC channel only varied between 255 and 254, changing the temperatuur didnt seem to have any influence, but removing jumper P4 made the value go all over the place so i presume the channel is ok, and only the NTC might not be OK.

Differential Input
The PCF8591 is capable of more, it is  for instance possible to do differential measurements.
Suppose you want to  measure the difference between AIN0 and AIN1.
You do that as follows:

#include "Wire.h"
int PCF8591=0x48; // I2C bus address 
int Raw = 0;
float Voltage = 0.0;

void setup()
{
 Wire.pins(0,2);// just to make sure
 Wire.begin(0,2);
  Serial.begin(9600); //Not on an ESP8266-01 
  Wire.beginTransmission(PCF8591); // Wake up PCF8591
  Wire.write(0x11); // control Byte for differential input mode 
  Wire.endTransmission(); //
}
void loop()
{
  Wire.requestFrom(PCF8591, 1); // Get Data from channel 1

 RawValue=Wire.read();
 Voltage = (Raw * 3.3 )/ 255.0;
 Serial.print("Raw= ");
 Serial.print(Raw);
 Serial.print(" Voltage = ");
 Serial.println(Voltage,3);
 delay(1000);
}

If you want to hook up this chip to a Raspbery Pi, have a look here.
There are other ways of expanding the ADC capabilities of the ESP8266:

Using EAGLE

Introduction

PCB design in EAGLE is a two-step process. First you design your schematic, then you lay out a PCB based on that schematic. EAGLE’s board and schematic editors work hand-in-hand. A well-designed schematic is critical to the overall PCB design process. It will help you catch errors before the board is fabricated, and it’ll help you debug a board when something doesn’t work.

This tutorial is the first of a two-part Using EAGLE series, and it’s devoted entirely to the schematic-designing side of EAGLE. In part 2, Using EAGLE: Board Layout, we’ll use the schematic designed in this tutorial as the basis for our example board layout.

Schematic and board layout from Using EAGLE tutorials

Suggested Reading

If you’d like to follow along with this tutorial, make sure you’ve installed and setup the EAGLE software. Our How to Install and Setup EAGLE tutorial goes over this process step-by-step, and it also covers the basics of what EAGLE is and what makes it great. It also covers how to download and install the SparkFun EAGLE libraries we’ll be using in this tutorial. Definitely read through that tutorial before you continue on.

Create a Project

We’ll start by making a new project folder for our design. In the control panel, under the “Projects” tree, right click on the directory where you want the project to live (by default EAGLE creates an “eagle” directory in your home folder), and select “New Project”.

How to create a project folder

Give the newly created, red project folder a descriptive name. How about “Bare Bones Arduino”.

Project folder created

Project folders are like any regular file system folder, except they contain a file named “eagle.epf”. The EPF file links your schematic and board design together, and also stores any settings you may have set especially for the project.

Create a Schematic

The project folder will house both our schematic and board design files (and eventually our gerber files too). To begin the design process, we need to lay out a schematic.

To add a schematic to a project folder, right-click the folder, hover over “New” and select “Schematic”.

Creating a new schematic

A new, blank window should immediately pop up. Welcome to the schematic editor!

Adding Parts to a Schematic

Schematic design is a two step process. First you have to add all of the parts to the schematic sheet, then those parts need to be wired together. You can intermix the steps – add a few parts, wire a few parts, then add some more – but since we already have a reference design we’ll just add everything in one swoop.

Using the ADD Tool

The ADD tool –  (on the left toolbar, or under the Edit menu) – is what you’ll use to place every single component on the schematic. The ADD tool opens up a library navigator, where you can expand specific libraries and look at the parts it holds. With a part selected on the left side, the view on the right half should update to show both the schematic symbol of the part and its package.

An example of navigating the ADD tool

The ADD tool also has search functionality – very helpful when you have to navigate through dozens of libraries to find a part. The search is very literal, so don’t misspell stuff! You can add wildcards to your search by placing an asterisk (*) before and/or after your search term. For example if you search for atmega328 you should find a single part/package combo in the SparkFun-DigitalIC library, but if you search *atmega328* (note asterisks before and after), you’ll discover two more versions of the IC (because they’re actually named “ATMEGA328P”). You’ll probably want to get accustomed to always adding an asterisk before and after your search term.

Searching the ADD tool. Wildcards!

To actually add a part from a library either select the part you want and click “OK”, or double-click your part.

Step 1: Add a Frame

The frame isn’t a critical component for what will be the final PCB layout, but it keeps your schematic looking clean and organized. The frame we want should be in the SparkFun-Aesthetics library, and it’s named FRAME-LETTER. Find that by either searching or navigating and add it to your schematic.

Adding the frame

After selecting the part you want to add, it’ll “glow” and start hovering around following your mouse cursor. To place the part, left-click (once!). Let’s place the frame so its bottom-left corner runs right over our origin (the small dotted cross, in a static spot on the schematic).

Frame added

After placing a part, the add tool will assume you want to add another – a new frame should start following your cursor. To get out of the add-mode either hit escape (ESC) twice or just select a different tool.

Step 2: Save (And Save Often)

Right now your schematic is an untitled temporary file living in your computer’s ether. To save either go to File > Save, or just click the blue floppy disk icon – . Name your schematic something descriptive. How about “BareBonesArduino.sch” (SCH is the file format for all EAGLE schematics).

As a bonus, after saving, your frame’s title should update accordingly (you may have to move around the screen, or go to View > Redraw).

Step 3: Adding the Power Input

Next we’ll add four different parts all devoted to our voltage supply input. Use the add tool for these parts:

Part DescriptionLibraryPart NameQuantity
5.5mm Barrel Jack (PTH) SparkFun-Connectors POWER_JACKPTH 1
0.1µF Ceramic Capacitor SparkFun-Capacitors CAPPTH 1
Voltage Supply Symbol SparkFun-Aesthetics VCC 1
Ground Symbol SparkFun-Aesthetics GND 2

 

All of these parts will go in the top-left of the schematic frame. Arranged like this:

Power circuitry placed

If you need to move parts around, use the MOVE tool –  (left toolbar or under the Edit menu). Left-click once on a part to pick it up (your mouse should be hovering over the part’s red “+” origin). Then left click again when it’s where it needs to be.

Step 4: Microprocessor and Supporting Circuitry

Next we’ll add the main component of the design – the ATmega328 microprocessor – as well as some components to support it. Here are the parts we’ll add:

Part DescriptionLibraryExact Part NameQuantity
ATmega328P (PTH) SparkFun-DigitalIC ATMEGA328P_PDIP 1
¼W Resistors SparkFun-Resistors RESISTORPTH-1/4W 4
5mm LEDs SparkFun-LED LED5MM 3
0.1µF Ceramic Capacitor SparkFun-Capacitors CAPPTH 1
Voltage Supply Symbol SparkFun-Aesthetics VCC 2
Ground Symbol SparkFun-Aesthetics GND 4

 

To rotate parts as your placing them, either select one of the four options on the rotate toolbar –  – or right click before placing the part. Place your microcontroller in the center of the frame, then add the other parts around it like so:

Microcontroller circuit added

Step 5: Adding the Connectors

Three connectors will finish off our design. One 8-pin connector to break out the analog pins, a 6-pin serial programming header, and a 2x3-pin ICSP programming header. Here are the three parts to add for this step:

Part DescriptionLibraryExact Part NameQuantity
8-Pin 0.1" Header SparkFun-Connectors M081X08 1
2x3 AVR Programming Header SparkFun-Connectors AVR_SPI_PRG_6PTH 1
6-Pin Serial Programming Header SparkFun-Connectors ARDUINO_SERIAL_PROGRAMPTH 1
Voltage Supply Symbol SparkFun-Aesthetics VCC 2
Ground Symbol SparkFun-Aesthetics GND 2

 

Finally! Here’s what your schematic should look like with every part added:

Schematic with all parts added

Wiring Up the Schematic

With all of the parts added to our schematic, it’s time to wire them together. There’s one major caveat here before we start: even though we’re wiring parts on the schematic, we not going to use the WIRE tool –  – to connect them together. Instead, we’ll use the NET tool –  (left toolbar, or under the Draw menu). The WIRE tool would be better-named as a line-drawing tool, NET does a better job of connecting components.

Use NET not WIRE

Using the NET Tool

To use the NET tool, hover over the very end of a pin (as close as possible, zoom in if you have to), and left-click once to start a wire. Now a green line should be following your mouse cursor around. To terminate the net, left-click on either another pin or a net.

Routing GIF

The hard part, sometimes, is identifying which part on a circuit symbol is actually a pin. Usually they’re recognizable by a thin, horizontal, red line off to the side of a part. Sometimes (not always) they’re labeled with a pin number. Make sure you click on the very end of the pin when you start or finish a net route.

Route the Power Input Circuit

Start back in the upper left, and route the power input circuit like so:

Power circuit wired up

Whenever a net splits in two directions a junction node is created. This signifies that all three intersecting nets are connected. If two nets cross, but there’s not a junction, those nets are not connected.

Route the ATmega328 Circuit

Next we’ll route the ATmega328 to its supporting circuitry. There’s LEDs, a connector, resistor, capacitor and VCC/GND symbols to route to:

Wiring the ATmega circuit

Don’t forget to add nets between the LEDs, resistors, and GND symbols!

Making Named, Labeled Net Stubs

The remaining nets we have to make are not going to be as easy to cleanly route. For example, we need to connect the TXO pin on JP2 to the ATmega’s RXD pin, all the way on the other side. You could do it, it would work, but it’d be really ugly. Instead, we’ll make net “stubs” and give them unique names to connect them.

We’ll start by adding short, one-sided nets to each of the six pins on the serial connector. Begin by starting a net at a pin, just as you’ve been doing. Terminate the net by left-clicking a few grid-lengths over to the right of the pin. Then, instead of routing to another pin, just hit ESC to finish the route. When you’re done, it should look like this:

Net stubs added to connector pins

Next, we’ll use the NAME tool –  (left toolbar, or under the Edit menu) – to name each of the six nets. With the NAME tool selected, clicking on a net should open a new dialog. Start by naming the net connected to the top, GND pin. Delete the auto-generated name (e.g. N$14), and replace it with “GND” (sans the quotation marks). This should result in a warning dialog, asking you if you want to connect this net to all of the other nets named “GND” (that would be every net connected to a GND symbol). Thanks for looking out for us EAGLE, but in this case Yes we do want to connect GND to GND.

After naming a net, you should use the LABEL tool –  – to add a text label. With the LABEL tool selected, left-click on the net you just named. This should spawn a piece of text that says “GND”, left-click again to place the label down right on top of your net.

Follow that same order of operations for the remaining five net stubs. In the end, they should look like this (note the net connected to the TXO pin is named “RX”, and a “TX” net connects to RXI – that’s on purpose):

Net stubs named and labeled

VCC should be the only other net that warns you that you’ll be connecting to other nets named “VCC” (anything connected to a VCC voltage node). For the other named nets, we’ll need to create this same stub somewhere else. Where exactly? Well, we need to add a “RX” and “TX” net on the ATmega328, and a “DTR” nearby as well:

Naming and labeling RX, TX, and DTR

Even though there’s no green net connecting these pins, every net with the same, exact name is actually connected.

We need to do a lot of the same to connect the 2x3 programming header to the ATmega328. First, wire up the connector like so (naming/labeling MOSI, MISO, SCK, and RESET):

ICSP connecter wired

Then, back to the ATmega328, add the same four named/labeled nets:

ATmega328 SPI pins named/labeled

Phew – you’re done. Get excited, it’s about time to lay out a PCB! When your schematic is done, it should look a little something like this:

Final schematic

Tips and Tricks

Names and Values

Every component on your schematic should have two editable text fields: a name and a value. The name is an identifier like R1R2LED3, etc. Every component on the schematic should have a unique name. You can use the NAME tool –  on any component to change the name.

A part’s value allows you to define unique characteristics of that part. For example, you can set a resistor’s resistance, or a capacitor’s capacitance. The importance of a part’s value depends on what type of component it is. For parts like resistors, capacitors, inductors, etc. the value is a critical piece of information when you’re generating a bill of materials or assembly sheet. To adjust a part’s value parameter, use the VALUE tool – .

Verifying Connections

The SHOW tool –  – is very useful for verifying that pins across your schematic are connected correctly. If you use SHOW on a net, every pin it’s connected to should light up. If you’re dubious of the fact that two like-named nets are connected, give the SHOW tool a try. SHOW-ing a net connected to GND, for example, should result in a lot of GND nets lighting up.

SHOWing a GND trace

As an alternative to show, you can temporarily MOVE a part a part to make sure nets are connected to it. Use MOVE to pick a part up, and the nets connected to it should bend and adjust to remain so. Just make sure you hit ESC to not move the part (or UNDO if you accidentally move it).

Moving a part to verify a connection

If all the nets connected to a part MOVE with it, all connections are good.

If a net isn’t moving along with the part, it’s not connected to the pin correctly. Double check to make sure you routed to the very end of the pin, and not a bit further:

Poorly routed net

If you have any nets incorrectly connected like above, DELETE –  – it, and try re-netting.

Group Moving/Deleting/Etc.

Any tool that you use on a single component, can also be used on a group of them. Grouping and performing an action on that group is a two-step process. First, use the group tool –  – to select the parts you want to modify. You can either hold down the left-mouse button and drag a box around them, or click multiple times to draw a polygon around a group. Once the group is made, every object in that group should glow.

After grouping, select the tool you want to use. The status box in the far bottom-left will have some helpful information pertaining to using the tool on a group:

Group move status box

In order to perform any action on a group, you have to select the tool, then hold down CTRL and right-click the group. After you CTRL+right-click, the tool will operate on the group just as it does a single component.

Copy/Paste

EAGLE’s Copy – – and Paste –  – tools don’t work exactly like other copy/paste tools you may have encountered before. Copy actually performs both a copy and paste when it’s used. As soon as you copy a part (or any object on the schematic – name, text, net, etc.) an exact copy will instantly spawn and follow your mouse awaiting placement. This is useful if you need to add multiples of the same part (like GND nodes or resistors).

Paste can only be used to paste a group that has previously been copied to your clipboard. To use paste you first have to create a group, then (with the copy tool selected) CTRL+right-click to copy it, but hit ESC instead of gluing it down. This’ll store the copied group into your operating system’s clipboard, and you can use paste to place it somewhere. This tool is especially useful if you need to copy parts of one schematic file into another.

Resources and Going Further

This tutorial is the first of a pair. The next tutorial, Using EAGLE: Board Layout, will use the schematic we designed here to lay out a “Bare Bones Arduino” PCB. If you’re headed over to that tutorial next, you can get a head start by clicking the Generate/Switch to Board icon –  – to create a board based on this schematic.


If you’d rather read about other EAGLE-related concepts, here are some tutorials you may want to check out:

  • How to Create SMD PCBs – This is a more advanced and fast-paced EAGLE tutorial. In this one, we focus on laying out a more complex, surface-mount (SMD) design.
  • How to Create SMD Footprints – If you want to create unique parts in a library, check out this tutorial.
  • Making Custom Footprints in EAGLE – Another footprint-making tutorial. This one details a unique process for making a custom 1:1 footprint.

If you’d like to share your PCB creations with the world, check out these tutorials:

How to Read a Schematic

Overview

Schematics are our map to designing, building, and troubleshooting circuits. Understanding how to read and follow schematics is an important skill for any electronics engineer.

This tutorial should turn you into a fully literate schematic reader! We’ll go over all of the fundamental schematic symbols:

Schematic component overview

Then we’ll talk about how those symbols are connected on schematics to create a model of a circuit. We’ll also go over a few tips and tricks to watch out for.

Suggested Reading

Schematic comprehension is a pretty basic electronics skill, but there are a few things you should know before you read this tutorial. Check out these tutorials, if they sound like gaps in your growing brain:

Schematic Symbols (Part 1)

Are you ready for a barrage of circuit components? Here are some of the standardized, basic schematic symbols for various components.

Resistors

The most fundamental of circuit components and symbols! Resistors on a schematic are usually represented by a few zig-zag lines, with two terminals extending outward. Schematics using international symbols may instead use a featureless rectangle, instead of the squiggles.

Resistor schematic symbols

Potentiometers and Variable Resistors

Variable resistors and potentiometers each augment the standard resistor symbol with an arrow. The variable resistor remains a two-terminal device, so the arrow is just laid diagonally across the middle. A potentiometer is a three-terminal device, so the arrow becomes the third terminal (the wiper).

Variable resistor symbols

Capacitors

There are two commonly used capacitor symbols. One symbol represents a polarized (usually electrolytic or tantalum) capacitor, and the other is for non-polarized caps. In each case there are two terminals, running perpendicularly into plates.

Capacitors symbols

The symbol with one curved plate indicates that the capacitor is polarized. The curved plate represents the cathode of the capacitor, which should be at a lower voltage than the positive, anode pin. A plus sign might also be added to the positive pin of the polarized capacitor symbol.

Inductors

Inductors are usually represented by either a series of curved bumps, or loopy coils. International symbols may just define an inductor as a filled-in rectangle.

Inductor symbols

Switches

Switches exist in many different forms. The most basic switch, a single-pole/single-throw (SPST), is two terminals with a half-connected line representing the actuator (the part that connects the terminals together).

Switch symbol

Switches with more than one throw, like the SPDT and SP3T below, add more landing spots for the the actuator.

SPDT and SP3T symbols

Switches with multiple poles, usually have multiple, alike switches with a dotted line intersecting the middle actuator.

DPDT symbol

Power Sources

Just as there are many options out there for powering your project, there are a wide variety of power source circuit symbols to help specify the power source.

DC or AC Voltage Sources

Most of the time when working with electronics, you’ll be using constant voltage sources. We can use either of these two symbols to define whether the source is supplying direct current (DC) or alternating current (AC):

Voltage source symbols

Batteries

Batteries, whether they’re those cylindrical, alkaline AA’s or rechargeable lithium-polymers, usually look like a pair of disproportionate, parallel lines:

Battery symbols

More pairs of lines usually indicates more series cells in the battery. Also, the longer line is usually used to represent the positive terminal, while the shorter line connects to the negative terminal.

Voltage Nodes

Sometimes – on really busy schematics especially – you can assign special symbols to node voltages. You can connect devices to these one-terminal symbols, and it’ll be tied directly to 5V, 3.3V, VCC, or GND (ground). Positive voltage nodes are usually indicated by an arrow pointing up, while ground nodes usually involve one to three flat lines (or sometimes a down-pointing arrow or triangle).

Voltage node symbols

Schematic Symbols (Part 2)

Diodes

Basic diodes are usually represented with a triangle pressed up against a line. Diodes are also polarized, so each of the two terminals require distinguishing identifiers. The positive, anode is the terminal running into the flat edge of the triangle. The negative, cathode extends out of the line in the symbol (think of it as a - sign).

Diode symbol

There are a all sorts of different types of diodes, each of which has a special riff on the standard diode symbol. Light-emitting diodes (LEDs) augment the diode symbol with a couple lines pointing away. Photodiodes, which generate energy from light (basically, tiny solar cells), flip the arrows around and point them toward the diode.

LED and Photodiode symbols

Other special types of diodes, like Schottky’s or zeners, have their own symbols, with slight variations on the bar part of the symbol.

Schottky and zener diode symbols

Transistors

Transistors, whether they’re BJTs or MOSFETs, can exist in two configurations: positively doped, or negatively doped. So for each of these types of transistor, there are at least two ways to draw it.

Bipolar Junction Transistors (BJTs)

BJTs are three-terminal devices; they have a collector (C), emitter (E), and a base (B). There are two types of BJTs – NPNs and PNPs – and each has its own unique symbol.

NPN and PNP BJT symbols

The collector (C) and emitter (E) pins are both in-line with each other, but the emitter should always have an arrow on it. If the arrow is pointing inward, it’s a PNP, and, if the arrow is pointing outward, it’s an NPN. A mnemonic for remembering which is which is “NPN: not pointing in.”

Metal Oxide Field-Effect Transistors (MOSFETs)

Like BJTs, MOSFETs have three terminals, but this time they’re named source (S), drain (D), and gate (G). And again, there are two different versions of the symbol, depending on whether you’ve got an n-channel or p-channel MOSFET. There are a number of commonly used symbols for each of the MOSFET types:

Variety of MOSFET symbols

The arrow in the middle of the symbol (called the bulk) defines whether the MOSFET is n-channel or p-channel. If the arrow is pointing in means it’s a n-channel MOSFET, and if it’s pointing out it’s a p-channel. Remember: “n is in” (kind of the opposite of the NPN mnemonic).

Digital Logic Gates

Our standard logic functions – AND, OR, NOT, and XOR – all have unique schematic symbols:

Standard logic functions

Adding a bubble to the output negates the function, creating NANDs, NORs, and XNORs:

Negated logic gates

They may have more than two inputs, but the shapes should remain the same (well, maybe a bit bigger), and there should still only be one output.

Integrated Circuits

Integrated circuits accomplish such unique tasks, and are so numerous, that they don’t really get a unique circuit symbol. Usually, an integrated circuit is represented by a rectangle, with pins extending out of the sides. Each pin should be labeled with both a number, and a function.

ATmega328, ATSHA204, and ATtiny45 IC symbols

Schematic symbols for an ATmega328 microcontroller (commonly found on Arduinos), an ATSHA204 encryption IC, and an ATtiny45 MCU. As you can see, these components greatly vary in size and pin-counts.

Because ICs have such a generic circuit symbol, the names, values and labels become very important. Each IC should have a value precisely identifying the name of the chip.

Unique ICs: Op Amps, Voltage Regulators

Some of the more common integrated circuits do get a unique circuit symbol. You’ll usually see operation amplifiers laid out like below, with 5 total terminals: a non-inverting input (+), inverting input (-), output, and two power inputs.

Op amp symbols

Often, there will be two op amps built into one IC package requiring only one pin for power and one for ground, which is why the one on the right only has three pins.

Simple voltage regulators are usually three-terminal components with input, output and ground (or adjust) pins. These usually take the shape of a rectangle with pins on the left (input), right (output) and bottom (ground/adjust).

Voltage regulator symbols

Miscellany

Crystals and Resonators

Crystals or resonators are usually a critical part of microcontroller circuits. They help provide a clock signal. Crystal symbols usually have two terminals, while resonators, which add two capacitors to the crystal, usually have three terminals.

Crystal and resonator symbols

Headers and Connectors

Whether it’s for providing power, or sending out information, connectors are a requirement on most circuits. These symbols vary depending on what the connector looks like, here’s a sampling:

Connector symbols

Motors, Transformers, Speakers, and Relays

We’ll lump these together, since they (mostly) all make use of coils in some way. Transformers (not the more-than-meets-the-eye kind) usually involve two coils, butted up against each other, with a couple lines separating them:

Transformer symbols

Relays usually pair a coil with a switch:

Relay symbol

Speakers and buzzers usually take a form similar to their real-life counterparts:

Speaker

And motors generally involve an encircled “M”, sometimes with a bit more embellishment around the terminals:

Motor

Fuses and PTCs

Fuses and PTCs – devices which are generally used to limit large inrushes of current – each have their own unique symbol:

Fuse and PTC symbol

The PTC symbol is actually the generic symbol for a thermistor, a temperature-dependent resistor (notice the international resistor symbol in there?).


No doubt, there are many circuit symbols left off this list, but those above should have you 90% literate in schematic reading. In general, symbols should share a fair amount in common with the real-life components they model. In addition to the symbol, each component on a schematic should have a unique name and value, which further helps to identify it.

Name Designators and Values

One of the biggest keys to being schematic-literate is being able to recognize which components are which. The component symbols tell half the story, but each symbol should be paired with both a name and value to complete it.

Names and Values

Values help define exactly what a component is. For schematic components like resistors, capacitors, and inductors the value tells us how many ohms, farads, or henries they have. For other components, like integrated circuits, the value may just be the name of the chip. Crystals might list their oscillating frequency as their value. Basically, the value of a schematic component calls out its most important characteristic.

Component names are usually a combination of one or two letters and a number. The letter part of the name identifies the type of component – R’s for resistors, C’s for capacitors, U’s for integrated circuits, etc. Each component name on a schematic should be unique; if you have multiple resistors in a circuit, for example, they should be named R1, R2, R3, etc. Component names help us reference specific points in schematics.

The prefixes of names are pretty well standardized. For some components, like resistors, the prefix is just the first letter of the component. Other name prefixes are not so literal; inductors, for example, are L’s (because current has already taken I [but it starts with a C…electronics is a silly place]). Here’s a quick table of common components and their name prefixes:

Name IdentifierComponent
R Resistors
C Capacitors
L Inductors
S Switches
D Diodes
Q Transistors
U Integrated Circuits
Y Crystals and Oscillators

Although theses are the “standardized” names for component symbols, they’re not universally followed. You might see integrated circuits prefixed with IC instead of U, for example, or crystals labeled as XTAL’s instead of Y’s. Use your best judgment in diagnosing which part is which. The symbol should usually convey enough information.

Reading Schematics

Understanding which components are which on a schematic is more than half the battle towards comprehending it. Now all that remains is identifying how all of the symbols are connected together.

Nets, Nodes and Labels

Schematic nets tell you how components are wired together in a circuit. Nets are represented as lines between component terminals. Sometimes (but not always) they’re a unique color, like the green lines in this schematic:

Example of nets on a schematic

Junctions and Nodes

Wires can connect two terminals together, or they can connect dozens. When a wire splits into two directions, it creates a junction. We represent junctions on schematics with nodes, little dots placed at the intersection of the wires.

A node

Nodes give us a way to say that “wires crossing this junction are connected”. The absences of a node at a junction means two separate wires are just passing by, not forming any sort of connection. (When designing schematics, it’s usually good practice to avoid these non-connected overlaps wherever possible, but sometimes it’s unavoidable).

Example of connected an disconnected nodes

Net Names

Sometimes, to make schematics more legible, we’ll give a net a name and label it, rather than routing a wire all over the schematic. Nets with the same name are assumed to be connected, even though there isn’t a visible wire connecting them. Names can either be written directly on top of the net, or they can be “tags”, hanging off the wire.

Linked name tags

Each net with the same name is connected, as in this schematic for an FT231X Breakout Board. Names and labels help keep schematics from getting too chaotic (imagine if all those nets were actually connected with wires).

Nets are usually given a name that specifically states the purpose of signals on that wire. For example, power nets might be labeled “VCC” or “5V”, while serial communication nets might be labeled “RX” or “TX”.

Schematic Reading Tips

Identify Blocks

Truly expansive schematics should be split into functional blocks. There might be a section for power input and voltage regulation, or a microcontroller section, or a section devoted to connectors. Try recognizing which sections are which, and following the flow of circuit from input to output. Really good schematic designers might even lay the circuit out like a book, inputs on the left side, outputs on the right.

Example of a sectioned schematic

If the drawer of a schematic is really nice (like the engineer who designed this schematic for the RedBoard), they may separate sections of a schematic into logical, labeled blocks.

Recognize Voltage Nodes

Voltage nodes are single-terminal schematic components, which we can connect component terminals to in order to assign them to a specific voltage level. These are a special application of net names, meaning all terminals connected to a like-named voltage node are connected together.

Annotated voltage node example

Like-named voltage nodes – like GND, 5V, and 3.3V – are all connected to their counterparts, even if there aren’t wires between them.

The ground voltage node is especially useful, because so many components need a connection to ground.

Reference Component Datasheets

If there’s something on a schematic that just doesn’t make sense, try finding a datasheet for the most important component. Usually the component doing the most work on a circuit is an integrated circuit, like a microcontroller or sensor. These are usually the largest component, oft-located at the center of the schematic.

Resources and Going Further

That’s all there is to schematic reading! Knowing component symbols, following nets, and identifying common labels. Understanding how a schematic works opens up the whole world of electronics to you! Check out some of these tutorial, to practice your new-found schematic knowledge:

  • Voltage Dividers - This is one of the most basic, fundamental circuits. Learn how to turn a big voltage into a smaller one, with just two resistors!
  • How to Use a Breadboard - Now that you know how to read schematics, why not make one! Breadboards are a great way to make temporary, functional, prototype circuits.
  • Working with Wire - Or, skip the breadboard and jump straight into wiring stuff up. Knowing how to cut, strip, and connect wire is an important electronics skill.
  • Series and Parallel Circuits - Building circuits in series or parallel requires a good understanding of schematics.
  • Sewing with Conductive Thread - If you don’t want to work with wire, how about building an e-textiles circuit with conductive thread? That’s the beauty of schematics, the same schematic circuit can be built in a number of different ways with a number of different mediums.