LCDs, Sensors, and Actuators

1. Be able to use LCD as the display device
2. Be able to use temperature, humidity, untrasonic, and remote sensors
3. Be able to use motors as actuators

1. The LCD (Liquid Crystal Display)

A liquid-crystal display (LCD) is a flat-panel display or other electronically modulated optical device that uses the light-modulating properties of liquid crystals. Liquid crystals do not emit light directly, instead using a backlight or reflector to produce images in color or monochrome.

A Casio Alarm Chrono digital watch with LCD.

To understand how LCD works by searching and reading articles online may be overwhelming. However, I found a fatastic video from SparkFun that explains how this works using a very simple and professional way (use a earphone if you are watching it in public):

In this section, you will learn how to wire up and use an alphanumeric LCD display. The display has an LED backlight and can display two rows with up to 16 characters on each row. You can see the rectangles for each character on the display and the pixels tht make up each character.

The LCD we'll use for this experiment is LCD1602: (datasheet)
Pin names and functions:
VSS: A pin connects to groud.
VDD: A pin connects to +5V power supply on board.
VO: A pin adjusts the contrast of LCD1602.
RS: A register select pin controls where in the LCD's memory is being written. You can select either the data register, which holds what being displayed, or an instruction registerr, which is where the LCD's controller looks for instructions on what to do next.
R/W: A Read/Write pin selects the reading mode or the writting mode.
E: An enabling pin when being applied with low-level energy then triggers relevant instructions.
D0-D7: Pins write and read data.
A and K: Pins control the LED backlight.

Follow the connections in the figure below to wire up your boards:

Before you start typing your code into the Arduino IDE, download and add the 'zip' library to your IDE.

Open the Arduino IDE, go to Sketch - Include Library - Add Zip Library - Find the location of the '' library, then add it to the IDE.

Then you are ready to go:

Use the following example code to get your first 'Hellow World!' on your LCD:

In which,
lcd.print(millis() / 1000) does integer division. Counts by one for every 1000 miliseconds
lcd.setCursor(0,1) defines the starting position (column 0 & row 1) to display the data . Both column and row numbers start at 0 rather than 1.

You should see this on your side:

Please note that it does not have to be '85' on the second line. Mine was just counted to 85. It will start from 0 and count up.

Task 1: Display the 'Hello World!' starting from the second rectangle on the same line.
Task 2: Count to 5 and then reset to 0, then start over:

Some hints for Task 2:

Task 3: Given that the command 'lcd.clear()' will clear out everything on the LCD. Modify the code to implement the scrolling text as presented in the video below:

The 'Liquid Crystal' library loaded to the Arduino IDE in the beginning has made this entire programming process much less stressful so the developer can focus on the software and the control strategy other than focusing on the hardware. Back to 10 years ago when I was in college, there were not too much resource like this for developers. It was more challenging for beginners to have fun with these MCUs.

2. Sensors
2.1 Temperature and Humidity Sensors
2.1.1 Use a Thermistor to mesure the temperature
A thermistor is a thermal resistor - a resistor changes its resistance with temperature. Technically, all resistors are thermistors - their resistance changes slightly with temperature - but the change is usually very small and difficult to measure. Thermistors are made so that the resistance changes drastically with temperature so that it can be 100 ohms or more of change per degree.

There are two kinds of thermistors, NTC (negative temperature coefficient) and PTC (positive temperature coefficient). In general you will see NTC sensors used for temperature measurement (we'll used NTC in this experiment). PTC's are often used as resettable fuses - an increase in temperature increases the resistance which means as more current passes through them, they heat up and 'choke back' the current, quite handy for protecting circuits!

Since the thermistor is a variable resistor, we’ll need to measure the resistance before we can calculate the temperature. However, the Arduino can’t measure resistance directly, it can only measure voltage. The Arduino will measure the voltage at a point between the thermistor and a known resistor. This is known as a voltage divider. The equation for a voltage divider is:

This equation can be rearranged and simplified to solve for R2, the resistance of the thermistor:

Finally, the Steinhart-Hart equation is used to convert the resistance of the thermistor to a temperature reading.

The Thermistor looks like this:

Add the Thermistor and a 10K resistor to the existing circuit:

The Steinhart–Hart equation: (Just for your reference, you do not need to remember this equation)

The Steinhart–Hart equation is a model of the resistance of a semiconductor at different temperatures. The equation is

T is the temperature (in kelvins),
R is the resistance at T (in ohms),
A, B, and C are the Steinhart–Hart coefficients, which vary depending on the type and model of thermistor and the temperature range of interest. (The most general form of the applied equation contains a (lnR)^2 term, but this is frequently neglected because it is typically much smaller than the other coefficients, and is therefore not shown above.)

Use the following example code to convert resistance changes to tempterature changes.

The result looks like the following:

Task 4: Repeat the work above, show room temperature on the LCD. Use your finger to warm it up see if it changes.

2.1.2 Use DHT11 to measure temperature and humidity

DHT11 temperature and humidity sensor is good enough for most projects that need to keep track of humidity and temperature readings. Load the library to your Arduino IDE. The '' library.

The sensor's pins:

There is a newer version (DHT12, white, which is not being used in this tutorial).

Humidity sensing component is used, of course to measure humidity, which has two electrodes with moisture holding substrate (usually a salt or conductive plastic polymer) sandwiched between them. The ions are released by the substrate as water vapor is absorbed by it, which in turn increases the conductivity between the electrodes. The change in resistance between the two electrodes is proportional to the relative humidity. Higher relative humidity decreases the resistance between the electrodes, while lower relative humidity increases the resistance between the electrodes.

The DHT sensor has been mounted to a PCB in your Arduino Kit so plesae directly use that one for your experiment.

DHT11 digital temperature and humidity sensor is a composite sensor which contains a calibrated digital signal output of the temperature and humidity. The sensor includes a resistive sense of wet components and a NTC temperature measurement devices, and connects with a high-performance 8-bit microcontroller.

Please add the following connections to your existing connections in the LCD sections.

It looks as follows on the board:

The example code:

The results on my side:

To understand how the '' function works, run the following example:

Code and results:

Task 5: Modify the code to display in the form below. Simply blow at the sensor to change the temperature and the humidity to test it. Show a demonstration video in your report.

2.1.3 Use an integrated circuit temperature sensor

In this section, we will use an electronic integrated circuit temperature sensor. The Vendor is Analog Devices. There are only three pins out of the sensor. VDD, VSS, and analog output. The analog output voltage change carries the information of the temperature change in the environment. A snapshot from the datasheet of the sensor:

The datasheet of the sensor can be found at here.

Be careful about the polarity of the pins of the temperature sensor!! The VS+ pin must be connected to +5 V, the GND pin must be connected to GND, the Vout pin is connected to A0. Inversely connect the VS and the GND will burn the sensor and generate lots of heat, which will burn your finger if you touch it!!!!

The safe way to connect the circuit: Do not power up your board (hook it to the USB port) before you have the circuit connected and double checked!! Let your neighbors to check your connection for you before you power up your circuit.

The connections between the sensor and the board: (This looks different from yours because this one does not have the LCD connections).

A snapshot from the datasheet:

The code to read the analog voltage at A0 and convert it into temperature:

Task 6: Repeat the work above to display temperature data from TMP36.

2.2 The IR Receiver Module (The '' library, you can find this library in the folder you downloaded in the beginning of this tutorial)

Using an IR Remote is a great way to have wireless control of your device.

IR detectors are little microchips with a photocell that are tuned to 'listen' to infrared light. Every TV and DVD player has one of these in the front to receive the IR signal from the remote. Inside the remote control is a matching IR LED, which emits IR pulses to tell the TV to turn, off or change channels. IR light is not visible to the human eyes.

IR detectors are specifically filtered for IR light, they are not good at detecting visible light. IR detectors have a demodulator inside looks for mudulated IR at 38 KHz, which means the detector is 'picky' at the frequency of the incident light.

Keep your previous LCD connections and add the following connections to the board:

 On the LCD, the first line is the code received, the second line is the number on the remote being pressed.

You may have a different remote controller. The one I used in the figure above has pretty bad quality (the receiver is fine). Every time the same key was pressed but different signals will be sent to the receiver. However, the one you are going to use is good enough for your experiments. You need to modify the code provided to you to match the new remote given to you.

Task 7: Modify the example code to match your new remote controller. (The example code). You do not have the datasheet for the new remote controller available. The way to decode it is to just press every button on the new remote controller and look at the response on the LCD. Just map the code for the key to the actual function assigned/printed on the key on the remote controller.

My demonstration video:

You must be wondering in the example code, the 'results.value' are Hex numbers but if I print it to the LCD, it shows a decimal number. They are actually equal. Open the calculator in Windows and use the 'Programmer' option to convert the Hexadecimal number to the corresponding decimal number, you will find they are the same number:

Barebone ATmega328p and a digital/portable temperature meter
3.1 The barebone ATmega328p

The purpose of this section is to build a portable temperature meter on a bread board. The Arduino board series are for educational purposes. There are many ports and features are redundant for a real commercial product.

To build a portable temperature meter, we only need the functioning microcontroller chip but not other redundant parts on the original Arduino board.

The minimum circuit to power up and 'oscillate up' the 328p chip is as follows:
Some critical connections for programming the 328 chip off the Arduino board: (if you only need to use the programmed chip, you can build a reset circuit on the breadboard).
1. The Reset pin of the chip needs to be connected to the Reset header on the UNO board.
2. Both VACC/VCC and GNDs should be connected to power and ground respectively.

Add the 'Reset' function to the chip:

Take out the original 328p chip on your Arduino board. Find the TX and the RX pins on your 328p chip:

Pinout of the ATMega328p can be found in this link.

Find the TX and the RX headers on the Arduino board:

This time, should you make the TX-RX, RX-TX connections or TX-TX, RX-RX connections?? Use your judgement and make the connections.

The minimal circuit to make it programmable on a breadboard can be found in this drawing.

Use a very basic LED blinking program to test your barebone 328p MCU. My demo video:

Task 8: Repeat the work in the demo video above, show your result in a VIDEO for the report.

3.2 Interrupts

If you have done the 4-digit seven-segment display (SSD) program in the last tutorial, you will know that the SSD unit needs a dedicated loop to scan the four digits. The delay inbetween every activation of every digit cannot be too long or too short. Normally 5-10 ms is the good range.
In that case, any other programs (temperature testing and number conversion) will take significant amount of time compare to the delays inbetween the digit activations and further affect the display quality.

Here we will introduce the 'Interrupt' function at the first time. The 'Interrupts' used in this section is being triggered by a timer on the chip. When the timer is up, the original loop will be interrupted and the MCU will execute the special program called 'interrupt service routine' (ISR). The ISR is prorammable, you can define whatever you'd like the MCU to do during this interrupts.

In 'void setup()', you need to add the following registers to turn on the interrupt function.

Open the datasheet of the MCU, on Page 140, the function of every bit in the register 'TCCR1A' is explained:

The following screenshot shows the control bits in TCCR1B.

The WGM12 bit in the TCCR1B register is to set the CTC mode of operation. CTC means 'Clear Timmer on Compare Match'.

In which the CS12 CS11 CS10 bits controls the prescaler: (The prescaler factor, N, is 1024 in this example)

The OCR1A=62500 will allow the LED to blink every 4 seconds. From the datasheet:

Therefore, 1/T = 16M/(2x1024x62501)=0.125 Hz, so T=8s, which is period, and the ISR is being triggered whenever it is toggled, so ISR is triggered every 4s.

The following screenshot shows the control bits in TCNT1. (Timer/Counter1)

The following screenshot shows the OCR1A Register (Output Compare Register 1A).

Now the last line in the setup() function:

OCIE1A means:

You can definitely choose different prescalers for any specific application.

Then outside of the 'loop()' and the 'setup()' function, add an extra function called:

This is the Interrupt Service Routine. Put whatever you'd like the MCU to run during the interrupt inside this function. In this specific application, I believe you just want the MCU to update the temperature on the seven-segment display.

Task 9:
Use the barebone ATMega 328p to build a portable digital temperature meter. Use an Interrupt Service Routine to update the temperature display. The temperature/humidity sensor is the DHT11, the display unit is the 4-digit 7-segment display.
Record a video for the report.


1. Complete
Task 1-8 (10 points for each)
Task 9 (20 points)