Asynchronous serial communication, which you can see in action in the Serial Output lab, is a common way for two computers to communicate. Both computers must have their own clock, and keep time independently of each other. This works well for personal computers, mobile devices, and microcontrollers because they all have their own clock crystal that acts as the processor’s heartbeat. However, there are simpler integrated circuits that have only one function, such as to read a sensor or to control a digital potentiometer or an oscillator to drive a PWM circuit. These ICs have no clock crystal of their own. They consist of a few memory registers and the minimal circuitry needed to connect these memory registers to the circuit that they control. To communicate with these ICs, you need to use synchronous serial communication.
Synchronous serial communication protocols feature a controller device which sends a clock pulse to one or more peripheral devices. The devices exchange a bit of data every time the clock changes. There are two common forms of synchronous serial, Inter-Integrated Circuit, or I2C (sometimes also called Two-Wire Interface, or TWI), and Serial Peripheral Interface, or SPI.
Synchronous serial devices communicate by shifting bits of data along their communication lines, like a bucket brigade. Data moved down the line one bit every time the clock pulses. All the devices in a synchronous serial chain share the same data and clock lines. Peripheral devices are directed by the controller device when to listen to the bits coming down the line, and when to ignore them. However, the two most common synchronous serial protocols, SPI and I2C, use different methods for directing the peripheral devices.
SPI devices are connected by four wires, as shown in Figure 1:
a Serial Data In (SDI), on which the controller sends data to the peripheral devices.
a Serial Data Out (SDO), on which the peripheral devices send data to the controller.
a Clock (SCLK) connection, on which the controller sends a regular clock signal to the peripheral devices.
one or more Chip Select (CS) connections, which the controller uses to signal the peripheral devices when to listen to incoming data and when to ignore it.
A Note on Pin Naming
The electronics industry has used the terms “master/slave” to refer to controller devices and peripheral devices for decades without regard for the historical context of, and offense caused by, those terms. As a result, you will see the terms MOSI/MISO/SS in data sheets to refer to the pins of an SPI device. While a modern standard naming scheme has not yet emerged to replace these, the Open Source Hardware Association has a proposal on the table. Make Magazine proposes retaining the acronym while renaming the terms. The SDO, SDI and CS terms are currently used by a handful of companies within the industry, but have some ambiguity when used in practice. Hence, the PICO/POCI proposal. The debate is not resolved, and you will likely see some variations on the terms. The SDO, SDI, and SCK terms are the most widely accepted terms that do not carry historical baggage.
The SDI, SDO, and SCLK connections are shared between all the devices connected to the controller. This configuration is called a bus. Each peripheral has its own dedicated Chip Select connection to the controller, however.
Figure 1. A typical SPI bus configuration. The Controller’s output (SDO) is the peripherals’ input (SDI) and vice versa. Each peripheral gets its own Chip Select line. All other lines are shared.
When the controller device wants to communicate with one of the peripherals, it sets that device’s Chip Select pin low. The peripheral will then listen for new bits of data on the microcontroller’s Serial Data Out (SDO) line every time the clock changes from low to high (called the rising edge of the clock). If it is instructed to send any data back, it will send data back to the controller when the clock signal changes from high to low (called the falling edge of the clock). When a peripheral device’s Chip Select pin is high, it will not respond to any commands sent on the data line.
The data exchange between SPI devices is usually shown like this (Figure 2):
Figure 2. Timing diagram for SPI serial communication
The Arduino’s SPI pins are determined by the processor. You can find the pins for the various models on the SPI library reference page. For the Arduino Uno, the pin numbers are pin 11 for SDO, pin 12 for SDI, and pin 13 for Clock (SCK). Pin 10 is the default Chip Select pin (SS), but you can use other pins for Chip Select as needed. The Arduino SPI library allows you to control the SPI bus. Most SPI devices that are compatible with Arduino come with their own libraries, however, which wrap the SPI library in commands specific to the device in question.
For example, the Analog DevicesADXL345 accelerometer can communicate via SPI. Its protocol works as follows: first the controller sets the ADXL345’s Chip Select (CS) pin low, then sends a command to the ADXL345 on the SDI line to enter measurement mode. The ADXL345 then continually samples the accelerometer and stores the latest readings in three memory registers. When the controller wants to know those values, it sets the Chip Select (CS) pin low and sends a request to read those memory registers. The ADXL345 responds by sending back the contents of the memory registers on the SDO line. When all the data has been received, the controller sets the Chip Select pin high again.
The advantage of SPI is that the data transactions are simple: all you need to do is to send the data to the device you’re communicating with. The disadvantage is that the number of wires needed to connect goes up by one for every peripheral device you add to the bus.
Figure 3. Data capture from a microcontroller communicating with an Analog Devices digital Potentiometer over SPI. The potentiometer sends no data, but the controller sends two bytes over the SDO line.
Inter-Integrated Circuit (I2C) or Two-Wire Interface (TWI)
I2C is another popular synchronous serial protocol. It also uses a bus configuration like SPI, but there are only two connections between the controller device and the peripheral devices as shown in Figure 4:
a Serial Clock (SCL) connection, on which the controller sends the clock signal, just as in SPI
a Serial Data (SDA) connection, on which the controller and peripherals exchange data in both directions.
Figure 4. Diagram of I2C synchronous serial communication.
Each I2C peripheral device has a unique address on the bus. When the controller wants to communicate with a particular peripheral, it sends that peripheral’s address down the SDA connection, transferring each bit on the rising edge of the clock. An extra bit indicates whether the controller wants to write or read to the peripheral that it’s addressing. The appropriate peripheral then goes into listening mode, and the controller sends a command to the peripheral. Then the controller switches its connection to the SDA line from output to input. The peripheral then replies with the appropriate data, sending each bit on the falling edge of the clock. The controller switches its connection on the SDA line back to output once it’s received all of the data.
The I2C data capture in Figure 5 is typical (click to enlarge it). This is from a Texas InstrumentsTMP007 temperature sensor. The peripheral’s address is 0x40. First the controller sends a byte with 0x40 + 0 in the final bit, indicating that it plans to write a command to the peripheral. All of this data is sent valid on the rising edge of the clock. Then the controller sends a command, 0x03, which means “tell me your object’s temperature” to this particular IC. Then the controller sends a byte with the peripheral’s address again, 0x40 +1 in the final bit, indicating that it wants to read from the peripheral. The peripheral responds with two bytes, 0x0B and 0xC0. The controller then puts those two bytes together to get the object’s temperature (see the TMP007 datasheet if you want to know more)
Figure 5. Data capture from a microcontroller communicating with an TMP007 temperature sensor using I2C communication. he advantage of I2C is that you really only need two wires to connect all the I2C devices you want to your controller. The disadvantage is that you have to send an address before you send any command.
The Arduino’s I2C pins are determined by the processor. You can find the pins for the various models on the Wire library reference page. The Arduino Wire library allows you to control the I2C bus. For the Arduino Uno, the pin numbers are analog pin 4 for SDA and analog pin 5 for SCL. On the Uno rev.3 layout, SDA and SCL are also broken out on the digital side of the board, next to the ground pin. Most I2C devices that are compatible with Arduino come with their own libraries which wrap the Wire library in commands specific to the device in question. For example, Adafruit‘s library for the TMP007 relies on the Wire library to transmit and receive data.
I2C Control of Multiple Microcontrollers
You can also use I2C as a way to control many microcontrollers from one central controller. For example, if you needed to operate a large number of servomotors, you could put five or six each on a single Arduino, then chain several Arduinos together in an I2C chain and program them all to respond as peripherals. Then you would program a central microcontroller as the controller, and have it send commands to the peripheral devices when it’s time to move each device’s servos. You can see an example of how to do this in this example from the Arduino site.
What are Qwiic/Stemma/Grove/Gravity?
In addition to the standard I2C connections, Sparkfun and Adafruit use a connector called Qwiic which connects the I2C, power, and interrupt connectors all in one cable, eliminating the need for soldering. It’s a Sparkfun brand name. However, you’ll need a Qwiic adapter shield to use it. Adafruit have a similar brand called Stemma, Seedstudio uses Grove, and DFRobot uses Gravity. They all support I2C, and they all have custom solderless connectors, though they are not all compatible with each other. The most compatible way is to stick with the I2C header pins.
Conclusion
SPI and I2C are useful protocols because they allow you to interface with a wide variety of sensor and actuator ICs without having to use many of your microcontroller’s IO pins. Because they are both bus protocols, you can chain many devices on the same bus, and call on them only when needed from your microcontroller. For more on their usage, see the Lab: SPI Communication With A Digital Potentiometer and the Lab: I2C Communication With An Infrared Temperature Sensor.
A list of components available for checkout from the ITP equipment room. Unlike the components in the shop, these are not expendable, and should be returned. But if you wanthttps://itp.nyu.edu/physcomp/itp/checkout-components-at-itp/ to get a feel for how they’ll work in your project before you buy one of your own, then check them out from the equipment room.
Texas Instruments’ Bluetooth LE sensorTags contain a number of useful sensors in a self-contained, compact package: accelerometer, gyrometer, magnetometer, temperature sensors, all in a Bluetooth LE-enabled package.
Sensors convert various forms of physical energy into electrical energy, allowing microcontrollers to read changes in the physical world.
The simplest sensors read changes in mechanical energy, usually by moving electrical contacts. For example the pushbutton or switch (related video) converts mechanical energy (e.g, your finger’s press) into electrical energy by closing a connection between two metal contacts. The potentiometer (related video) shown in Figure 1 and Figure 2 is another sensor that reads mechanical energy changes: a metal contact called a wiper slides along a resistor, effectively short circuiting the resistor (related video) into two halves and creating a voltage divider circuit.
Figure 1. A potentiometer broken open, showing the carbon substrate and wiper.
Figure 2. Inside a potentiometer, the wiper, attached to the center contact, slides along the carbon resistor, forming effectively two resistors in series.
Although switches and pushbuttons typically only read an on state or an off state, most other sensors can read a wide range of possible states. In other words, they’re analog sensors, because they read a variable change. Whenever you use a new sensor, the first thing you need to understand is what the range is that it can read and deliver. When you’re using your sensor in an application, you need to know the range of possible values your application requires. Do you just need high, medium, and low (3 possible values), or a range from 0 to 10? Do you need a 100-point range? The range that you need depends on what your user can perceive. For example, if you’re making a lighting dimmer, and your user can only perceive about a dozen different light levels, then you don’t need to give her a sensor that can give her a 1000-point range of control.
Many sensors work by converting the energy they read into a changing electrical resistance by using a variably resistive material at their heart. Examples of resistive sensors are shown in Figure 3. For example, force sensors and stretch sensors are made of a partially conductive rubber. When the rubber is stretched or compressed, the resistance change. Photoresistors or light dependent resistors change their resistance when exposed to a change in light energy. In order to read changes in resistance, you typically place these sensors in a voltage divider circuit , which converts the resistance change into a changing voltage.
Light is used in many sensors in a variety of ways. Light-emitting diodes, light-dependent resistors, and phototransistors can be combined to sense dust, measure distance, or determine reflected color. Light is also used in some ranging sensors to determine distance from a sensor to a target.
Many sensors measure movement or distance indirectly, by sending out a pulse of light or sound and reading the reflected signal when it bounces off a target as illustrated in Figure 5. These are called ranging sensors (Figure 4) because they read a range of distance.
Figure 5. Ranging sensors work by bouncing energy off the target and reading the reflection.
Still other sensors work by converting the energy they read into a change in capacitance. For example, accelerometers and other miniaturized electromechanical (MEMS) sensors typically have a tiny moving conductive mass at their core, suspended on tiny springs and surrounded on both sides by electrical contacts. Because the conductive mass is parallel to the outer contacts, a capacitance builds up between the contact. When the mass is moved, the capacitance changes between the two sides, effectively creating two variable capacitors as illustrated in Figure 6. That variable capacitor is then placed in a resistor-capacitor circuit to convert the change in capacitance into a changing voltage.
Figure 6. MEMS sensors often form a variable capacitor by moving a capacitive plate in between two other capacitive surfaces.
Other than switches and variable resistors, most sensors you buy are integrated circuits that include the resistance-to-voltage or capacitance-to-voltage circuit and provide you with an analog voltage output. Some will even include an analog-to-digital converter and provide you with a serial data interface, either I2C, SPI, or asynchronous serial, so that you can connect the sensor to the serial ports of your microcontroller. Still others will provide a changing pulse output, or pulse width modulation (PWM) output, where the width of the pulse represents the sensor value.
Figure 7. A collection of sensors with digital interfaces. Clockwise, from top: AS7341 spectrometer; LIS3DH accelerometer; VL53L0X Time-of-flight distance sensor; Max3010x particle detector. These sensors are on small breakout boards which can connect to a solderless breadboard. They all connect to a microcontroller using SPI or I2C.
When you shop for sensors, you need to look at the data sheet to learn how they operate. The data sheet will usually include the following essential facts:
a text description of the sensor and its operation;
a pin diagram to tell you what pins perform what functions;
a table of electrical characteristics that tells you what the supply voltage is, what the operating current is, and what the output is, along with other electrical and physical properties;
a graph or conversion formula that relates the input energy to the output energy;
a mechanical description of the sensor itself.
Some datasheets will include other information as well, such as application circuits, reliability data, and so forth.
You should follow the datasheet’s guideline for sensor operation. Don’t exceed the maximum or minimum operating voltage, and make sure to supply adequate current to operate the sensor. Avoid supplying too much current, because the excess current will get turned into heat, which often changes the sensor’s operating characteristics. Make sure you understand the sensor’s interface. Be clear on whether it’s an analog electrical property like resistance, capacitance or voltage, or a digital serial data interface. Look for typical application circuits and microcontroller code samples online if you can find them.
Once you understand how a sensor works and what its output will be, you should connect it to your microcontroller and write a simple program to read the output. Don’t jump right into writing a complex program. Write the smallest program necessary to read the sensor’s changing values and output them for debugging purposes. Then put the sensor in the physical context in which you plan to use it and read the output values in action. The range that a sensor can read will change depending on the specific conditions or actions that you plan to read. So make sure the physical setting of the sensor is as close to reality as possible in order to test it. Once you know the range of values that it’s going to output in those conditions, then you can write a function to convert the sensor’s raw output range into a range you can use. Depending on the context, you probably won’t get the full output range that the sensor is capable of delivering. So your conversion function should be based on the range you’re actually seeing, not the total range.
You probably don’t need to convert the sensor’s readings into its output voltage or its physical property. For example, if you’re using a force sensing resistor, you probably don’t need to know how many Newtons of force are being exerted on the sensor, or what the output voltage is. Instead, you probably just need to know whether someone is pressing gently, firmly, or really firmly against the sensor. Perhaps you just need a range from 0 to 10. When you write your conversion function, consider what the relevant result is for you, and write a function that delivers that result.
In this lab, you’ll learn how to connect a variable resistor to a microcontroller and read it as an analog input. You’ll be able to read changing conditions from the physical world and convert them to changing variables in a program.
Introduction
In this lab, you’ll learn how to connect a variable resistor to a microcontroller and read it as an analog input. You’ll be able to read changing conditions from the physical world and convert them to changing variables in a program.
Many of the most useful sensors you might connect to a microcontroller are analog input sensors. They deliver a variable voltage, which you read on the analog input pins using the analogRead() command.
To get the most out of this lab, you should be familiar with the following concepts and you should install the Arduino IDE on your computer. You can check how to do so in the links below:
Flexible jumper wires. These wires are quick for breadboard prototyping, but can get messy when you have lots of them on a board.
A solderless breadboard with two rows of holes along each side. The . board is turned sideways so that the side rows are on top and bottom in this view. There are no components mounted on the board.
Photo of an 8 ohm speaker
LEDs. The long leg goes to voltage and the short leg goes to ground
220-ohm resistors. These ones are 4-band resistors
10-kilohm resistors. These ones are 5-band resistors
Pushbuttons
Potentiometer
Force Sensing Resistor (FSR)
Thermistor
Phototransistors. The short leg goes to voltage, and the long leg goes to the input pin of a microcontroller.
Figure 1-12. The parts you’ll need for this exercise. Click on any image for a larger view.
Figures 1-12 show the parts you’ll need for this exercise. Click on any image for a larger view.
Set Up the Breadboard
Connect power and ground on the breadboard to power and ground from the microcontroller. On the Arduino module, use the 5V or 3.3V (depending on your model) and any of the ground connections. Figures 13 and 14 show how to do this for an Arduino Uno and an Arduino Nano 33 IoT.
As shown in Figure 13, the Uno’s 5V output hole is connected to the red column of holes on the far left side of the breadboard. The Uno’s ground hole is connected to the blue column on the left of the board. The red and blue columns on the left of the breadboard are connected to the red and blue columns on the right side of the breadboard with red and black wires, respectively. These columns on the side of a breadboard are commonly called the buses. The red line is the voltage bus, and the black or blue line is the ground bus.
Figure 13. An Arduino Uno on the left connected to a solderless breadboard, right.
Figure 14. Breadboard view of an Arduino Nano mounted on a breadboard
In Figure 14, the Nano is mounted at the top of the breadboard, straddling the center divide, with its USB connector facing up. The top pins of the Nano are in row 1 of the breadboard.
The Nano, like all Dual-Inline Package (DIP) modules, has its physical pins numbered in a U shape, from top left to bottom left, to bottom right to top right. The Nano’s 3.3V pin (physical pin 2) is connected to the left side red column of the breadboard. The Nano’s GND pin (physical pin 14) is connected to the left side black column. These columns on the side of a breadboard are commonly called the buses. The red line is the voltage bus, and the black or blue line is the ground bus. The blue columns (ground buses) are connected together at the bottom of the breadboard with a black wire. The red columns (voltage buses) are connected together at the bottom of the breadboard with a red wire.
Add a Potentiometer and LED
Connect the wiper of a potentiometer to analog in pin 0 of the module and its outer connections to voltage and ground. Connect a 220-ohm resistor to digital pin 9. You can replace the LED with a speaker if you prefer audible output. Connect the anode of an LED to the other side of the resistor, and the cathode to ground as shown below. See Figure 15 and Figure 16 to learn how to do this with an Arduino Uno. Figure 17 shows a breadboard view of an Arduino Nano for the same circuit.
Figure 15. Schematic view of a potentiometer connected to analog in 0 of an Arduino and an LED connected to digital pin 9. Connect the voltage lead of the potentiometer to 5V for Uno, 3.3V for Nano 33 IoT.
Figure 16. Breadboard view of a potentiometer connected to analog in 0 of an Arduino and an LED connected to digital pin 9.
Figure 17. Breadboard view of Arduino Nano with an analog input and LED output.
Figure 17 shows the breadboard view of an Arduino Nano connected to a potentiometer and an LED. The +3.3 volts and ground pins of the Arduino are connected by red and black wires, respectively, to the left side rows of the breadboard. +3.3 volts is connected to the left outer side row (the voltage bus) and ground is connected to the left inner side row (the ground bus). The side rows on the left are connected to the side rows on the right using red and black wires, respectively, creating a voltage bus and a ground bus on both sides of the board. The potentiometer is mounted in the left center section of the solderless breadboard. Its outside pins are connected to the voltage and ground buses, respectively There is a wire connecting to analog in 0 of the nano (physical pin 4) to the the center pin of the potentiometer. An LED is mounted in the right center section of the board, with a 220-ohm resistor attached to its anode (long leg). The other end of the resistor connects to the Nano’s digital pin 9 (physical pin 27). The cathode of the LED (short leg) connects to ground. If you’re using a speaker instead of the LED, connect it to the same connections as the LED.
Program the Module
Now that you have the board wired correctly, program your Arduino as follows:
First, establish some global variables: one to hold the value returned by the potentiometer, and another to hold the brightness value. Make a global constant to give the LED’s pin number a name.
1
2
3
constintledPin =9; // pin that the LED is attached to
intanalogValue =0; // value read from the pot
intbrightness =0; // PWM pin that the LED is on.
In the setup() method, initialize serial communications at 9600 bits per second, and set the LED’s pin to be an output.
1
2
3
4
5
// initialize serial communications at 9600 bps:
Serial.begin(9600);
// declare the led pin as an output:
pinMode(ledPin, OUTPUT);
}
In the main loop, read the analog value using analogRead() and put the result into the variable that holds the analog value. Then divide the analog value by 4 to get it into a range from 0 to 255. Then use the analogWrite() command to face the LED. Then print out the brightness value. An alternate loop function for the speaker follows right after the first one.
1
2
3
4
5
6
voidloop() {
analogValue =analogRead(A0); // read the pot value
brightness =analogValue /4; //divide by 4 to fit in a byte
analogWrite(ledPin, brightness); // PWM the LED with the brightness value
Serial.println(brightness); // print the brightness value back to the serial monitor
}
If you’re replacing the LED with a speaker, here’s an alternate loop function that will play a changing tone on the speaker:
1
2
3
4
5
6
voidloop() {
analogValue =analogRead(A0); // read the pot value
frequency =(analogValue /4) *10; // divide by 4 to fit in a byte, multiply by 10 for a good tonal range
tone(pinNumber, frequency); // make a changing tone on the speaker
Serial.println(brightness); // print the brightness value back to the serial monitor
}
When you run this code, the LED should dim up and down as you turn the pot, and the brightness value should show up in the serial monitor.
Other variable resistors
You can use many different types of variable resistors for analog input. For example, the pink monkey in the photo below has his arms wired with flex sensors. These sensors change their resistance as they are flexed. When the monkey’s arms move up and down, the values of the flex sensors change the brightness of two LEDs. The same values could be used to control servo motors, change the frequency on a speaker, or move servo motors.
Figure 18. A stuffed pink monkey with flex sensors attached
Note on Soldering Sensor Leads
Flex sensors and force-sensing resistors melt easily, so unless you are very quick with a soldering iron, it’s risky to solder directly to their leads. See Figure 19-21 to learn about three better solutions:
Figure 19. Wire-wrapped connections of a force-sensing resistor
Figure 20. Screw terminal connection for force sensing resistor
Figure 21. Force sensing resistor connected to breakaway socket headers
If you’d like to read a changing light level, you can use a phototransistor for the job. Phototransistors are not variable resistors like photoresistors (which are shown in this video), but they perform similarly are made from less toxic materials. They are actually transistors in which the light falling on the sensor acts as the transistor’s base. Like photoresistors, they are sensitive to changes in light, and they work well in the same voltage divider circuit. Figure 22 shows how to connect a phototransistor and a 10-kilohm resistor as an analog input:
Figure 22. Breadboard view of an Arduino Nano connected to a phototransistor as an analog input. The long leg of the phototransistor connects to voltage, and the long leg connects to the input pin. The 10-kilohm fixed resistor then connects from the input pin to ground.
Different phototransistors will have different sensitivities to light. For example, this model from Everlight, which has a clear top, is most sensitive to 390 – 700 nm light range, with a peak at 630nm (orange-red). This model from Excelitas has a colored top to block IR light, and has a range from 450 -700nm, with a peak at 585nm (yellow). For the frequencies of the visible light spectrum, see this chart from Wikipedia.
Figure 23 and 24 shows an example circuit much like the pink monkey circuit (Figure 18) above, but with force-sensing resistors instead of flex sensors.
On the breadboard, two force-sensing resistors are mounted in rows 16 and 17 and 24 and 25, respectively, in the left center section of the board. Two red wires connects rows 16 and 24 in the left center section to the voltage bus on the left side. Two 10-kilohm resistors (orange, black, brown, and gold bands) connect rows 17 and 25 to the ground bus on the left hand side. Two blue wires connect from rows 17 and 25 to analog in pins 0 and 1 of the Arduino, respectively. Two 220-ohm resistors straddle the center divide of the breadboard, connecting to row 7 on both sides and 11 on both sides, respectively. In the left center section of the breadboard, two blue wires connect rows 7 and 11 to pins D10 and D9 of the Arduino, respectively. In the right center section, the anodes of two LEDs are connected to rows 7 and 11, respectively. The cathodes of the LED are in rows 6 and 10, respectively. Two black wire connects row 6 and 10 to the ground bus on the right side of the board.
Figure 23. Schematic view of two force-sensing resistors and two LEDs attached to an Arduino.
Figure 24. Breadboard view of two force-sensing resistors and two LEDs attached to an Arduino.
The circuit above works for any variable resistor. You could replace the force-sensing resistors with flex sensors to use the monkey toy above with this circuit. Two resistors placed in series like this are called a voltage divider. There are two voltage dividers in the circuit shown, one on analog in 0 and one on analog in 1. The fixed resistor in each circuit should have the same order of magnitude as the variable resistor’s range. For example, if you’re using a flex sensor with a range of 50 – 100 kilohms, you might use a 47-kilohm or a 100-kilohm fixed resistor. If you’re using a force sensing resistor that goes from infinity ohms to 10 ohms, but most of its range is between 10 kilohms and 10 ohms, you might use a 10-kilohm fixed resistor.
The code above assumed you were using a potentiometer, which always gives the full range of analog input, which is 0 to 1023. Dividing by 4 gives you a range of 0 to 255, which is the full output range of the analogWrite() command. The voltage divider circuit, on the other hand, can’t give you the full range. The fixed resistor in the circuit limits the range. You’ll need to modify the code or the resistor if you want a different range.
To find out your range, open the serial monitor and watch the printout as you press the FSR or flex the flex sensor. Note the maximum value and the minimum value. Then you can map the range that the sensor actually gives as input to the range that the LED needs as output.
For example, if your photocell gives a range from 400 to 900, you’d do this:
1
2
3
// map the sensor value from the input range (400 - 900, for example) to the output range (0-255):
You know that the maximum input range of any analog input is from 0 to 5 volts. So if you wanted to know the voltage on an analog input pin at any point, you could do some math to extrapolate it in your loop() like so:
1
2
3
4
5
6
7
8
9
10
voidloop() {
// read the sensor on analog pin 0:
intsensorValue =analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
floatvoltage =sensorValue *(5.0/1023.0);
// for 0-3.3V use the line below:
// voltage = sensorValue * (3.3 / 1023.0);
// print out the value you read:
Serial.println(voltage);
}
Now write a sketch to control the red LED with the first sensor (we’ll call it the right hand sensor) and the green LED with the second sensor (we’ll call it the left hand sensor). First, make two constants for the LED pin numbers, and two variables for the left and right sensor values.
1
2
3
4
constintredLED =10; // pin that the red LED is on
constintgreenLED =11; // pin that the green LED is on
intrightSensorValue =0; // value read from the right analog sensor
intleftSensorValue =0; // value read from the left analog sensor
In the setup(), initialize serial communication at 9600 bits per second, and make the LED pins outputs.
1
2
3
4
5
6
7
voidsetup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
// declare the led pins as outputs:
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
}
Start the main loop by reading the right sensor using analogRead(). Map it to a range from 0 to 255. Then use analogWrite() to set the brightness of the LED from the mapped value. Print the sensor value out as well.
1
2
3
4
5
6
7
8
voidloop() {
rightSensorValue =analogRead(A0); // read the pot value
// map the sensor value from the input range (400 - 900, for example)
// to the output range (0-255). Change the values 400 and 900 below
analogWrite(greenLED, brightness); // set the LED brightness with the result
Serial.println(leftSensorValue); // print the sensor value back to the serial monitor
}
Mapping works for audible tones as well. Human hearing is in a range from 20Hz to 20 kHz, with 100 – 10000 Hz being a reasonable middle ground so if your input is in a range from 0 to 255, you can quickly get audible tones by mapping like so:
int pitch = map(input, 0, 255, 100, 10000);
When you run this, you should see the LEDs changing in brightness, or hear the speaker changing in pitch, as you press the sensors. This is the central function of analog sensors on a microcontroller: to allow for a variable range of input to control a variable range out output. Whether your sensor is read through an analog sensor like this, or through synchronous serial interfaces as you’ll see in the SPI and I2C labs, you always need to find out how the range of action from the user relates to the range of values that the sensor produces. Once you’re comfortable with this concept, get to know how to read the change in a sensor’s readings as well.
This is an introduction to basic analog input on a microcontroller. In order to get the most out of it, you should know something about the following concepts. You can check how to do so in the links below:
While a digital input to a microcontroller can tell you about discrete changes in the physical world, such as whether the cat is on the mat, or the cat is off the mat, there are times when this is not enough. Sometimes you want to know how fat the cat on the mat is. In order to know this, you’d need to be able to measure the force the cat exerts on the mat as a variable quantity. When you want to measure variably changing conditions like this, you need analog inputs. An analog input to a microcontroller is an input that can read a variable voltage, typically from 0 volts to the maximum voltage that powers the microcontroller itself.
Many transducers are available to convert various changing conditions to changing electrical quantities. There are photocells that convert the amount of light falling on them to a varying resistance; flex sensors that change resistance as they are bent; Force-sensitive resistors (FSRs) that change resistance based on a changing force applied to the surface of the sensor; thermistors that change resistance in response to changing heat; and many more.
In order to read these changing resistances, you put them in a circuit and pass a current through them, so that you can see the changing voltage that results. There are a few variations on this circuit. The simplest is called a voltage divider. Because the two resistors are in series voltage at the input to the microcontroller is proportional to the ratio of the resistors. If they are equal, then the input voltage is half the total voltage. So in the circuit in Figure 1, if the variable resistor changes (for example, if it’s a flex sensor being bent), then the voltage at the input changes. The fixed resistor’s value is generally chosen to complement the variable resistor’s range. For example, if you have a variable resistor that’s 10-20 kilohms, you might choose a 10 kilohm fixed resistor.
Figure 1. voltage divider with a variable resistor and a fixed resistor
In Figure 2, you use a potentiometer, which is a variable resistor with three connections. The center of the potentiometer, called the wiper, is connected to the microcontroller. The other two sides are attached to power and ground. The wiper can move from one end of the resistor to the other. In effect, it divides the resistor into two resistors and measures the resistance at the point where they meet, just like a voltage divider.
Since a microcontroller’s inputs can read only two values (typically 0 volts or the controller’s supply voltage), an analog input pin needs an extra component to read this changing, or analog voltage, and convert it to a digital form. An analog-to-digital converter (ADC) is a device that does this. It reads a changing input voltage and converts it to a binary value, which a microcontroller can then store in memory.Many microcontrollers have ADCs built in to them. Arduino boards have an ADC attached to the analog input pins.
The ADC in the Arduino can read the input voltage at a resolution of 10 bits. That’s a range of 1024 points. If the input voltage range (for example, on the Uno) is 0 to 5 volts, that means that the smallest change it can read is 5/1024, or 0.0048 Volts. For a 3.3V board like the Nano 33 IoT, it’s 0.0029 volts. When you take a reading with the ADC using the analogRead() command, the microcontroller stores the result in memory. It takes an int type variable to store this, because a byte is not big enough to store the 10 bits of an ADC reading. A byte can hold only 8 bits, or a range from 0 to 255.
The command in Arduino is the analogRead() command, and it looks like this:
1
sensorReading =analogRead(pin);
Pin is the analog input pin you are using;
sensorReading is an integer variable containing the result from the ADC.
The number produced in sensorReading is will be between 0 and 1023. Its maximum may be less, depending on the circuit you use. A potentiometer will give the full range, but a voltage divider for a variable resistor like a force sensing resistor or flex sensor, where one of the resistors is fixed, will not.
The analog inputs on an Arduino (and in fact, on most microcontrollers), are all connected to the same ADC circuit, so when the microcontroller has to switch the ADC’s input from one pin to another when you try to read two pins one after another. If you read them too fast, you can get unstable readings. You can also get more reliable readings by introducing a small delay after you take an analog reading. This allows the ADC time to stabilize before you take your next reading.
Here’s an example of how to read three analog inputs with minimal delay and maximum stability:
1
2
3
4
5
6
sensorOne =analogRead(A0);
delay(1);
sensorTwo =analogRead(A1);
delay(1);
sensorOne =analogRead(A2);
delay(1);
Analog and digital inputs are the two simplest ways that a microcontroller reads changing sensor voltage inputs. Once you’ve understood these two, you’re ready to use a variety of sensors.
A schematic diagram is a representation of an electrical circuit, showing the electrical relationships using abstract graphic symbols rather than realistic pictures of components.
There are some components that schematics commonly include: voltage, ground, resistors, diodes, light emitting diodes (LED), switches, relays, capacitors.
A transistor includes three connections: a base, a collector and a emitter. It can work as an amplifier and a switch.
In schematics, to show a junction point, draw a dot at crossing.
In this lab you will learn about some of the components you’ll use frequently when making electronic circuits.
Introduction
In this lab you will learn about some of the components you’ll use frequently when making electronic circuits. For more on any given component, please check out its datasheet. There are no specific activities in this lab other than to examine the components and to familiarize yourself with them.
A datasheet or spec sheet is a document (printed or .pdf) that describes the technical characteristics of a sensor, electronic component, product, material or other. It includes details on how to use the component in a circuit and other useful design info on how to integrate it into a system together with specifications on performance and other characteristics that are important to know.
Different electronic circuits operate at different voltages. For example, the Arduino Uno operates at 5 volts, while the Arduino Nano 33 IoT and BLE, and the MKR series, operate at 3.3 volts. A voltage regulator takes a range of DC voltage as input and convert it to a constant voltage. For example, this regulator shown in Figure 1, a 7805 regulator, takes a range of 9 – 15 volts DC input and converts it to a constant 5-volt output. Using this regulator, you could power a 5-volt motor or a string of addressable LEDs from a 12-volt power source.
Note the label on the regulator that reads “7805”. This is the part number. Other parts have the same physical form factor, however. The form factor, called the package, is not dependent on what the actual part is. This is a TO-220 package. Many different parts use this same package, for example, and not all of them are voltage regulators. Also, sometimes the same part will come in different packages, so you can use it in different size devices.
The 7800 series regulators come in many different voltages. 7805 is a 5-volt regulator. 7809 is a 9-volt regulator. 7812 is a 12-volt regulator. All the regulators of this family have the same pin connections. In the image above, the left leg is connected to the input voltage. The middle leg is connected to ground. The right leg is the output voltage.
3.3V regulators are also common. Note that not all regulators which share the same package have the same pin configuration. For example, the LD1117V33, a 3.3V regulator shown in Figure 2, comes in the same physical package as a 7805, but its pins are in a different order. The LD1117V33’s pins, from left to right, are ground, output voltage, input voltage.
LED
Figure 3. LEDs. Shown here are four LEDs. The one on the right is an RGB LED. You can tell this because it has four legs, while the others have only two legs.
LEDs, or Light Emitting Diodes (see Figure 3), are diodes that emit light when given the correct voltage and current. Like all diodes, they are polarized, meaning that they only operate when oriented correctly in the circuit. The anode of the LED connects to voltage, and the cathode connects to ground. The anode in the LEDs in this photo is the longer leg on each LED. LEDs come in many different packages. The packages above have built-in lenses.
These LEDs are the cheapest you can buy, and they’re not very bright. You can get super-bright LEDs as well, which are much brighter. If you’re working on applications that need very small light sources, you can also get LEDs in a surface mount package.
LEDs can only handle a limited amount of current and voltage. The details should be covered in each LED’s datasheet. Here is the datasheet of a typical white LED. You’ll see that the forward current is 30 mA max, and the forward voltage is between 2.9 and 3.6V. That means if you give it 30mA at 3.6V, you should get maximum brightness out of it. If you don’t have the datasheet for your LED, here’s a link to a handy LED current calculator. Try putting in the supply voltage (3.3V or 5V), the voltage drop across the LED (the forward voltage), and the current (30 mA) and see what value of resistance you get. For most common LEDs running at 3.3 or 5 volts, a resistor about 220 will limit the current safely while still providing enough to light the LED.
Solderless breadboards are reusable prototyping tools for electronics that allow you to build and experiment with circuits simply by plugging components in and out of its rows and columns. They come in different shape and sizes. Figure 4 shows a typical short solderless breadboard. It has two rows of holes on either side of the board, usually used as voltage and ground buses. The board is turned in this photo so that the bus rows are on top and bottom. In the center of the board, there are thirty rows of holes. There is a divider down the center of the board that breaks up the rows of holes into separate rows. There are five holes per row on the center left and on the center right of each row.
Resistors
Figure 5. Resistors. Shown here are 220-ohm resistors. You can tell this because they have two red and one brown band, followed by a gold band.
Resistors resist the flow of electrical current. When placed in series, they reduce the voltage, and limit the current. The bands on a resistor indicate the resistor’s value. Here’s a handy resistor color code calculator. Resistors come in 4-band, 5-band, and 6-band models. In a 4-band resistor, the bands represent the first digit, second digit, multiplier, and tolerance. The resistors shown in Figure 5 are 4-band resistors marked red, red, brown, and gold, for 2, 2, times 101, 5%. In other words, these are 220 ohm resistors, +/-5%. The resistor color code calculator explains the bands for 5-and 6-band resistors as well.
Potentiometers
Figure 6. Potentiometer. The one shown here has three legs spaced 0.1 inches apart and can be therefore mounted on a solderless breadboard.
Potentiometers are variable resistors. The two outside terminals act as a fixed resistor. A movable contact called the wiper moves across the resistor, producing a variable resistance between the center terminal and either of the two sides. The potentiometer in Figure 6 has pins so you can mount it on a breadboard.
Trimmer potentiometers like those shown in Figure 7 are designed to be mounted on a circuit board, and are difficult to turn, so you can use them to adjust a circuit. They’re very small. They’re handy to use as physical variables, to tune your project.
Force Sensing Resistors
Force sensing resistors are sensors that change their resistance in response to force. They’re usually used to make analog alternatives alternatives to buttons. They’re made of a substrate of resistive rubber between two layers of conductive ink on a plastic film. They come in a variety of form factors. Figure 8 shows a pair of force sensors about 2.5cm across, sized for finger presses. There are a few companies who make them, including Interlink, Ohmite, and Tekscan.
Figure 8. Force sensing resistors
Flex Sensors (Flex Resistors)
Flex sensors are similar to force sensing resistors in construction, but they change their resistance as they bend. They are typically about the length of a finger, and they work well for measuring the bend of a finger. Spectrasymbol make these.
Figure 9. Flex sensor
Force Sensing Potentiometers
Force Sensing Potentiometers, sometimes called SoftPots, are also similar to force sensing resistors. The difference is that a force sensing resistor gives one value wherever you press on it, while a force sensing potentiometer acts like a normal potentiometer: the value changes depending on where along its length you press. They come in linear and round form factors. Ohmite, Interlink, and Spectrasymbol make FSPs.
Light-dependent resistors, or photocells, are variable resistors whose resistance changes with the intensity of the light falling on the resistor. Photocells, as seen in Figure 11, are made with cadmium sulfide, which is a toxic chemical. Increasingly, they are being replaced in hobbyist kits by phototransistors, which are somewhat less toxic (see below).
Thermistors
Figure 12. Themistor, or temperature-sensitive resistor
Thermistors, seen in Figure 12, are variable resistors whose resistance changes as the temperature changes. You measure the resistance between the two legs of the thermistor and expose the top to a varying temperature in order to vary the resistance between the two legs.
Switches
Figure 13. Pushbuttons, also called momentary switches
Switches are one form of digital input. There are many kinds of switches. The two most useful categories are momentary switches, which remain closed only when you press them, and toggle switches, which stay in place after you switch them.
Pushbuttons are a common type of momentary switch. The pushbuttons in the photo in Figure 13 above are designed to be mounted on a circuit board. They are very small, less than 1 centimeter on a side. They have four pins. When the button is facing you, top two are connected to each other, and the bottom two are connected to each other. Pushing the button connects the top pins to the bottom pins.
Toggle switches (Figure 14) stay in one position when you flip them. Wall light switches are common examples of toggle switches. Unlike a momentary switch, a toggle switch can be used to turn a device on or off, because they stay in one state when you remove your hand. The toggle switches below each have three connectors, also called pins or legs. They’re usually labeled C for common, NO for Normally Open, and NC for Normally Closed. When you switch the switch, it will open the connection between the common pin and the normally closed pin, and close the connection between the common pin and the normally open pin. Switch it the other way, and you will reverse the connection.
Figure 14. Toggle switches
Rotary Encoder
Figure 15. Rotary encoder
A rotary encoder is a sensor that usually looks a bit like a potentiometer. It has a central shaft that you can turn with your fingers, or with an axle. It produces a pair of electrical pulses as you turn the shaft of the encoder, one slightly before or after the other, depending on the direction you are turning the shaft. Unlike a potentiometer, they can turn endlessly. They are used both as tangible controls, when you want a knob that turns endlessly, and as rotary sensors for motors and axles. The encoder in Figure 15 has three pins. The center is connected to ground, and the two side pins produce the pulses. The Encoder library for Arduino is useful for reading these.
Capacitors store electrical energy while there’s energy coming in, and release it when the incoming energy stops. They have a variety of uses. One common use is to smooth out the dips and spikes in an electrical supply. This use is called decoupling.
Ceramic capacitors are unpolarized. They generally have very small capacitance values. They’re useful decoupling caps in a low-current circuit. You often see them used to decouple the power going into a microcontroller or other integrated circuit.
The number on a ceramic cap gives you its value and order of magnitude. For example, 104 on the capactors in Figure 16 indicates a 0.1 microfarad (uF) cap. 103 indicates a 0.01 microfarad cap.
Figure 17. Electrolytic capacitor
Electrolytic capacitors (Figure 17) can generally store more charge than ceramic caps, and are longer lasting. They’re usually polarized, meaning that they have a positive leg and a negative leg. This is because current flows more efficiently through them one way than the other.
Figure 18. Electrolytic capacitor, showing the minus sign on the negative side.
An electrolytic cap will have a + or – on one side, as shown in Figure 18.
Diodes
Figure 19. Diodes. Shown here are 1N400x power diodes. The body of the component is black, and the end is silver. The silver end indicates the cathode end of the diode.
Diodes permit voltage to flow in one direction and block it in the other direction. LEDs are a type of diode, as are the 1N4001 diodes shown in Figure 19. They’re useful for stopping voltage from going somewhere you don’t want it to go. The 1N4001 diodes are power diodes, capable of carrying a higher amount of current than other diodes.
Figure 20. Zener Diodes
Zener diodes (Figure 20) have a breakdown voltage past which they allow current to flow in both directions. They’re used to chop off excess voltage from a part of a circuit. They are usually smaller than power diodes.
Transistors act as electronic switches. When you put a small voltage across the base and emitter, the transistor allows a larger current and voltage to flow from the collector to the emitter. The transistor shown above in Figure 21, a TIP120, is a type of transistor known as a Darlington transistor. It is usually used to control high-current loads like motors. Note that it uses the same physical form factor, or package, as the voltage regulator above (the TO-220 package).
The TIP120 shown here is jus one option for controlling high current loads. Metal Oxide Semiconductor Field Effect Transistors, or MOSFETS, are also good for controlling motors, lights, and other high current loads. These two models also come in the same physical package as the TIP120. The IRF510 and IRF520 MOSFETs have the same pin configuration as the TIP120, and perform similarly with a 5V gate voltage. The FQP30N06L MOSFET has the same pin configuration, and operates on as low as 1.0V, and works well for 3.3V applications. MOSFETs can generally handle more amperage and voltage, but are more sensitive to static electricity damage.
Figure 15. Phototransistors. The short leg goes to voltage, and the long leg goes to the input pin of a microcontroller.
Phototransistors are transistors, but instead of being controlled by electricity, they are controlled by light. The base of a phototransistor is photosensitive. They often look like LEDs. The ones in Figure 15, Everlight model ALS-PT243-3C/L177, have flat tops to differentiate them from LEDs. The short leg of a phototransistor is the emitter, and the long leg is the collector. The lens is the base. To use them in an analog input circuit. emitter goes to voltage and the collector goes to your input pin. A 10-kilohm pulldown resistor connects the input pin to ground, just as it would if you were using a photocell..
Power Jacks
Figure 22. A DC Power Jack
DC Power jacks are used to connect your breadboard to a DC power supply that you can plug into a wall. They’re less common in microcontroller circuits now that USB power connectors and USB wall plugs are common, but they are still very handy when you have only a DC power supply to work with. The one in Figure 22 has screw terminals on the back to which you can connect wires to connect to your breadboard. It is a 2.1mm inside diameter, 5.5mm outside diameter jack, which is a very common size.
Battery Holders
Figure 23. AA battery holder
Figure 24. 9V battery snap with DC power plug on it.
Battery connectors like the ones shown in Figures 23 and 24 are good for connecting batteries to your project. The one in Figure 20 can hold 4 AA batteries, and has a 9V battery snap on the outside. The one in Figure 21 has a DC power jack on one end, and a 9V battery snap on the other end.
A servo motor is a motor paired with an encoder (e.g. a potentiometer) to provide position/speed readings and control messages in a feedback loop. This loop is used to precisely control of the servo’s degree of rotation. RC servomotors like the one shown in Figure 25 can only turn 180 degrees. They are often used for the rudder control on remote control planes and cars. The plastic bits shown in the photo are called horns, and they attach to the shaft to let you attach the motor to the mechanism that you want to control.
DC motors, as seen in Figure 26, utilize induction (an electromagnetic field generated by current flowing through a wire coil) to rotate a central shaft. You can reverse the direction that the shaft rotates by reversing the leads powering it.
Motor Driver
Figure 27. Motor Driver (H-bridge), model TB6612FNG
A motor driver, sometimes called an H bridge, is an electronic circuit that enables a voltage to be applied across a load in either direction. They are often used to control the direction of DC motors. The motor driver in Figure 27 is a Toshiba model TB6612FNG. It is a good option for both 5V (from an Arduino Uno) and 3.3V (from a Nano 33 IoT) control of DC motors and stepper motors.
Electromechanical Relay
Figure 28. Electromechanical relays: top and left views as well as inside.
Like transistors, relays are electronic switches. Electromechanical relays contain a small coil that, when energized, creates a magnetic field that moves a small metal armature to open or close an electrical contact. Relays can handle higher current than transistors and can be used for AC or DC loads. However, because they rely on a physical mechanism, they are slower and more prone to wearing out. If you want to control a relay with the Arduino, you will need to use a transistor as an intermediary because most relays draw more current than the Arduino’s output pins can supply.
Screw terminals, as seen in Figure 29, are electrical connectors that hold wires in place with a clamping screw. They allow for a more secure connection than female headers and more flexibility than soldering a wire in place. There is one screw, socket, and pin per connection.
Sensor Modules
Increasingly, sensors are no longer just simple components that output a changing resistance or capacitance. Sensor modules are application-specific integrated circuits (ASICs) which read a particular physical property and give you a measurement via a synchronous serial communications channel like I2C.
Figure 30 shows four different I2C sensors: a ten-channel spectrometer, at the top, which measures the intensity of light in ten different frequencies; An accelerometer, on the right (read below for more); a time-of-flight distance ranging sensor, that measures distance using an infrared low-power laser, on the bottom; and a light sensor that functions as both a particle sensor and a pulse oximeter, on the left, by measuring the change in color of your blood through the skin of your finger.
These are only a few of the many sensor modules available that can be connected to a microcontroller via I2C. You’ll see color and gesture sensors, temperature and humidity sensors, and many more. They are often available as breadboard-friendly breakout board modules, like the ones shown here, that are typically a circuit board that’s a few centimeters square, with holes on one side spaced 0.1″ apart so you can attach pins to plug it into a breadboard.
Figure 30. Various I2C sensors
Accelerometer
Figure 31. Accelerometer, LIS3DH
Accelerometers are sensors which measure a changing acceleration (Figure 31). They are typically part of sensors called Inertial Measurement Units, or IMUs. They are useful for measuring the tilt of a body, or for measuring the force of an impact. They come in both digital and analog forms. A typical accelerometer measures acceleration along three axes, all perpendicular to each other. Accelerometers are increasingly built into microcontroller modules and other electronic devices. There is accelerometer and a gyrometer built into the Nano 33 IoT.
Infrared Distance Ranger
Sharp makes a line of infrared distance ranging sensors that measure distance in about a 1-meter range using infrared light. The one shown in Figure 32 has an analog voltage output.
Figure 32. IR distance ranger
Ultrasonic Distance Ranger
Ultrasonic distance rangers measure distance by emitting pulsed ultrasonic waves and listening for the echo from a distant object. These are sometimes used in cars to aid in detecting the distance of objects behind the rear bumper. The one shown in Figure 33 outputs a digital pulse whose pulse width varies with the distance from the target object.
Figure 33. An Ultrasonic sensor, model HC-SR04. The sensor has two cylindrical transducers, and four pins at the bottom of the board, labeled from left to right: Vcc, Trig., Echo, Ground.
Temperature and Humidity Sensors
There are dozens of temperature and humidity sensors on the market, with many different interfaces. The one shown in Figure 34, the DHT22, is very popular because it’s simple to use, reliable with a long track record, and inexpensive. It uses a one-wire interface.
Figure 34. a DHT-22 temperature and humidity sensor
Speaker
Figure 35. Photo of an 8 ohm speaker
A speaker is a paper or plastic cone mounted to a coil of wire. The coil is mounted next to a magnet. When a current is passed through the wire, it induces a magnetic field, which attracts or repulses the magnet. This makes the cone vibrate, and produce sound. The speaker shown in Figure 35 is an 8-ohm speaker.