[ Log In ]

The LCD is an output device that can display actual alphanumeric characters.

Each of the pins on the LCD have their own functions.

#1 pin: VSS - Ground
#2 pin: VDD - 5v Supply
#3 pin: V0 - contract Adjustment
#4 pin: RS - Register Select Signal
#5 pin: RW - Read/Write
#6 pin: Enable
#7, #8, #9, #10 pins: Low Data Lines
#11, #12, #13, #14 pin: High Data Lines
#15 pin: Anode or + LED backlight
#16 pin: Cathode or - LED backlight

When using all 8 data lines for the LCD, you will need a full port and three more pins on the mictocontroller. Careful consideration should be made when selecting this port.

In this case, the data lines are connected to all the pins of PORTB.

The data pins of the LCD is labeled D0, D1, D2, D3, D4, D5, D6 and D7, and these are connected to PORTB pin 0 to pin 7 respectively. (i.e. D0 to pin 0, D1 to pin 1 and so on). The remaining control pins RS, RW and enable are connected to three pins of PORTD.

To communication to the LCD we need to make sure that the LCD is not busy. When the LCD is ready, the Enable must be triggered and the read/write should be off and the RS should be on if a character is sent, or off if a command is sent.

The sending of the data must be on the data bus for at least 500 ns. nop is used to create this waiting time.

The enable must be off to inform the LCD that the data is sent.

The AVR microcontroller is programmed to show simple characters on the LCD (Liquid Crystal Display). The pin functions are defined so the microcontroller can easily access these pins with an understandable name. Four functions are created to make it easy to write typical methods that the LCD can understand. These functions are Peek_A_Boo (Gets the LCD to see the data), Send_A_ Command, Send_A_Character, and Check_IF_MrLCD_IsBusy.

With these definitions and functions, the main function can then be written easily accessing these functions when needed to send a command and to send a character.

The #define statement is a macro. The #define statement can be use to substitute a name for a number. It can also be used to change the name of another definition.

Example: #define MrLCDsCrib PORTB

This makes MrLCDsCrib defined as PORTB, so MrLCDsCrib can be used wherever PORTB is used.

The #define also makes it convenient to change values whenever the need arises. Say, for instance, MrLCDsCrib was plugged into PORTA instead. Then only one statement would need to be changed rather than having to go throughout the program changing all of the PORTBs to PORTAs.

The #define can also be used to name numbers:

I generally only use #define statement for things that may change.

Every time you need to reference pin 5, LCDEnable can be used for this purpose.

This is an example of sending a command to clear the screen of the LCD and sending a character to the LCD.

Initialization for the LCD to enable the LCD, put it in write mode, and the Register Select set high. A delay of 15 ms is needed to wait for the LCD wakes up.

To send a command to the LCD, the data port connected to the LCD must have the data on that bus and the data will remain on that bus while the next commands are invoked:

- The control port of the LCD should a the R/W line low to write.
- The register select (RS) of the LCD needs to be set low for command mode.
- The enable needs to be set high and wait and then set low. During this time, the LCD gets the information from the port of the command and port of the data lines.

Now the command can be zeroed.

To send a character to the LCD, the data port connected to the LCD must have the data on that bus and the data will remain on that bus while the next commands are invoked:

- The control port of the LCD should a the R/W line low to write.
- The register select (RS) of the LCD needs to be set high for character mode.
- The enable needs to be set high and wait and then set low. During this time, the LCD gets the information from the port of the command and port of the data lines.

Now the character can be zeroed.

The data direction for the data port must be input since we will be getting information from the LCD. All of the PORTB lines will be set low for this to happen.

The enable must be set high and wait for a little while using the asm volatile ("nop"); command a couple of times.

The R/W line is set high to have the LCD in read mode so we can receive data from the LCD.

The RS line is set low to be in command mode.

Turn the enable on and off and grabbing the data until the data gives us the not busy signal of < 0x80

When all of the reading from the LCD is completed, the port is set back to output so the rest of the program can be in output mode for sending commands and sending characters.

A command to clear the screen is 0x01 and is used first. A time delay is needed since the clear screen command takes a bit of time.

The next command is to set the LCD into 8-bit mode using 0x38. This command takes 39 microseconds, so 50 microseconds is used to be safe.

The next command set is done in one statement using a binary notation: the x denotes the location that a '1' would be.
0b0000x000 = to enable this command function
0b00001x00 = to make the display on
0b000010x0 = to turn the cursor on
0b0000100x = to make the cursor blink

The final command is 0b00001110 to turn the display and cursor on, but not blink the cursor.

Another delay of 39 us is needed so 50 us is used.

The sending a character function is used hereafter to send characters.

A set of characters were sent to the LCD from the first LCD program.

The enhancement that is made to the program is to send a string of characters to the LCD in one function rather than sending one character at a time.

The prototype and function is added called void Send_A_String(unsigned char *stringOfCharacters)

A loop is needed to traverse the characters in the memory locations starting at the pointer.

To loop through a set of characters using a pointer:

To be able to send a number as a string to the LCD that comes from a variable, a function must be used to convert the number to a string. Two functions are available for this: itoa and dtostrf. Itoa is for integer conversion to string. Dtostrf is for converting double precision numbers to string.

The functions syntax:
itoa(value, character array, base);
dtostrf(value, width, precision, character array);

- value is the variable that contains the number
- character array is the output string
- base - binary - 2, decimal - 10, hexadecimal - 16
- width - the length of the final string including the sign. (i.e. -123.45 would be 7)
- Precision if the number of digits after the decimal.

a 20x4 LCD is described. the command 0b10000000 to the LCD allows you to set the curcor at a specific location. The trailing 0000000 is the position on the display. There are 128 possible locations, but for the 20x4, there are 80 possible locations.

1st line: 0 - 19
2nd line: 64 - 83
3rd line: 20 - 39
4th line: 84 - 103

Notice that the first line and the 3rd line continue like its on one line and the 4th line continues from the 2nd line. This is like it was meant to be a 2 line LCD with very long lines which is how the LCD processor treats all LCDs.

In the LCD program, a new function is created called GotoLocation(x, y).

A moving 'x' is displayed along all possible LCD cursor locations and the actual location of the 'x' is displayed on the bottom right of the LCD to inform what are the possible locations on the current LCD. Many LCDs have different row ans column specifications. This program allow the user to determine the constraints of their LCD so the LCD can be used within these cursor location constraints.

A for loop is used to cycle the 'x' in all of the cursor locations. An x is placed on the current location, a delay is used to give the user time to see the x and the location number. The cursor goes back to that location and displays a space to remove the 'x' so the next 'x' can be displayed and it appears to be moving.

A moving 'x' is displayed along all possible LCD cursor locations and the actual location of the 'x' is displayed on the bottom right of the LCD to inform what are the possible locations on the current LCD. Many LCDs have different row ans column specifications. This program allow the user to determine the constraints of their LCD so the LCD can be used within these cursor location constraints.

A for loop is used to cycle the 'x' in all of the cursor locations. An x is placed on the current location, a delay is used to give the user time to see the x and the location number. The cursor goes back to that location and displays a space to remove the 'x' so the next 'x' can be displayed and it appears to be moving.

A for loop is constructed to move an x in every LCD position.

A prototype and function is created to put the cursor on the LCD to any location on the display.

The result of the 'x' character cycling through all of the cursor locations using x and y coordinates rather than the 128 positions.

Modifying the program so that the xa nd y location values are shown on the LCD screen while the 'x' chasing character runs through all of the LCD cursor locations.

Modifying the program so that the xa nd y location values are shown on the LCD screen while the 'x' chasing character runs through all of the LCD cursor locations.

The commands that are required to be able to use the LCD are put into an initialization function. Commands that are required for the LCD use is:

- Setting the correct data direction for the LCD pins
- Clearing the Screen if the LCD: 0x01 with a delay afterwards
- Command to turn the LCD on and set the cursor attributes.

The commands that are required to be able to use the LCD are put into an initialization function. Commands that are required for the LCD use is:

- Setting the correct data direction for the LCD pins
- Clearing the Screen if the LCD: 0x01 with a delay afterwards
- Command to turn the LCD on and set the cursor attributes.

Using the commands and sending characters to the LCD to put a number on the screen at a specified location takes a few lines of code, where this is not necessary. The code can be put into a function since it will be used quite often.

A potentiometer is connected to the ADC using voltage divider connection to vary the voltage to the ADC pin. The output of the voltage to digital number is displayed on the LCD.

The LCD is showing the 10-bit result from the ADC, getting the 10-bit conversion from the ADCH and ADCL registers and using the Left Adjusted ADLAR = 1.

When doing conversions with the ADC (Analog to Digital Conversion), the result may have a variance from conversion to conversion. This gives you a method to calculate this deflection over time and some possible techniques to minimize this deflection, such as using capacitors or using the ADC sleep mode.
Using the LCD, the ADC values are shown for testing the ADC conversion and collecting the deflection over many samples.

To be able to measure the previous result to the current result, the previous result must be stored. Once the current result is captured, another variable is incremented by the absolute value of the difference of the result and the previous result.

First a few global variables are needed to store the previous result, total deflection over time, and the sample count (they start static volatile because the compiler would optimize them out if these keywords were not there):

This is a boilerplate code to initialize the ADC for interrupts and including the LCD library so the result can be displayed.

Adding a label to the LCD is simply sending a string of data to the LCD. The Send_A_StringToMrLCDWithLocation(x, y, string) is the function that we will use that is part of the MrLCD.h file.

The constant vacuum source is a system that maintains a vacuum within a tank. The vacuum is created by a motor and pump (vacuum pump) that is connected to the tank. The vacuum pump is actuated by a microcontroller and relay that uses a pressure sensor to sense the amount of vacuum in the tank. When the tank looses vacuum of 15 inches of Hg (Mercury) or more, then the motor will turn on and will climb to 25 or so inches of Hg.

The value of the low andn high thresholds for inches of Hg that is desired inthe tank and the amount of vacuum in the tank is shown on an LCD. Two potentiometers are used to adjust the low and high vacuum thresholds.

An interface (breakout) was created to make the connection from the LCD to the microcontroller easier. The DIY interface contains a trimmer potentiometer to adjust the contrast of the LCD. The interface has ribbon cable soldered and connected to the data lines of the LCD. The power, RS, R/W and Enable share another cable assembly that go to another part of the microcontroller.

This reduces the amount of space that the LCD uses on the breadboard.

In this case, the LCD data lines are connected to the PORT B of the AVR microcontroller. The E (enable), RW (Read Write) and RS (Register Select) are all plugged into PORT D. The power is plugged into the power rail.

The LCD library and initialization is established. The interrupts for the ADC is started and a string is sent to the LCD. This is to get ready for the pressure sensor program. A string is sent to the LCD to create a label called Pressure.

to get the 10-bit number from the ADC conversion, the ADCL (ADC Low Data Byte) is read first (must be read first) and stored into another variable. The remaining data is located in the ADCH (ADC High Data Byte) and is moved 8 positions to the left so there is room for the ADCL variable byte. That result is stored in another variable and is sent to the LCD.

When the pressure sensor is tested to see the raw ADC 10-bit data on the LCD, the actual data did not appear. In the program, the bitwise operation for shifting and setting the ADEN (ADC Enable) to 1 was not correct. The shift operator uses two less than symbols and the program only had one less than symbol. It was a runtime error rather than an error at compile time is because the singe less than symbol is a valid symbol and valid in the context.

The LCD shows the results of a raw output from the ADC reading the pressure sensor. A simple test of the pressure sensor was made successfully.

The result of converting the ADC to a useful value of inches of Hg is displayed on the LCD.

The formula that converts the ADC value to inches of Hg (using the slope intercept formula):

inches of HG = -0.0377(ADC_Value) + 35.5134

The trimmer potentiometers are used to adjust the high and low thresholds for the pressure sensor circuit. The adjustment needs to read between 0 and 33 rather than the ADC result of 0 and 1023, so the slope intercept formula is a good formula to use in this case.

The code in the ADC channels are updated to reflect the slope intercept formula so the trimmer potentiometers show a range or 0 - 33 rather than the raw ADC result of 0 - 1023.

The code in the ADC channels are updated to reflect the slope intercept formula so the trimmer potentiometers show a range or 0 - 33 rather than the raw ADC result of 0 - 1023.