LCDs and Buttons

Individual Assignment

Objectives

To develop and demonstrate individual proficiency in:

  1. Reading multiple buttons with a microcontroller and controlling an output

  2. Displaying text on a character LCD screen

  3. Updating a character LCD screen based on input from multiple buttons

This is an individual homework assignment. While you may talk with others about how to complete the assignment, you must individually design, write, and implement all code and circuitry by yourself. All cases of academic dishonesty (including sharing your or using others’ code, circuits, or breadboards) will be reported to the Dean’s office.

Resources

Prior to Demonstration of Proficiency

Complete all of the steps below prior to the demonstration of proficiency.

1.0 Breadboard Preparations

In this assignment, you may use either the PIC18F47Q10 Curiosity Nano or the PIC18F47Q10 DIP IC connected to your breadboard.

The components necessary for this assignment will take up most of the space on your breadboard. To minimize time spent rewiring, it is recommended that you lay out the large components prior to wiring to ensure sufficient space.

Components

Part
PIC18F47Q10 Curiosity Nano (or DIP IC)
16x2 LCD screen (You will need to solder on a 16-pin male to male header in order to connect it to the breadboard.)
75Ω resistor.
One breadboard-compatible 10kOhm potentiometer
Two breadboard-compatible SPST buttons
LED and an appropriate current-limiting resistor (or the onboard LED)

Arrange all of the above components on your breadboard so that you will be able to connect wires to each of them.

Hint: Place the Curiosity Nano board as far to one edge of the breadboard as possible such that the micro USB port is accessible from the edge of the board, and place the LCD screen adjacent to the opposite of the board. This will leave you with space for the potentiometer, buttons, and LED.

2.0 Reading Multiple Buttons and Controlling an LED

  1. Study the following critical information and concepts:
Critical Information and Concepts Importance
a. How each of the 4 pins of the button in your kit are wired. Needed to correctly wire the button into your circuit. Use your DMM set to continuity mode and test all combinations of the pins being connected with the button pressed and not pressed.
b. What a pullup resistor is, why it is necessary, and how you can enable an onboard pullup in the PIC. Needed to understand how to properly wire the switch so that it is always providing a value to the PIC. First, read section 12.6.9 of Scherz & Monk.
c. In the Microchip MPLab Code Configurator User’s Guide, determine what WPU and OD stand for. WPU is explained better on this page that discusses setting up GPIO. Look up the explanation for OD by searching for “ODC Registers” on this page to understand its use for a different PIC family. Determine the correct GPIO settings for I/O pins, as well as the best way to use these options in conjunction with a pushbutton switch.
  1. Wire the two buttons on your breadboard to two different I/O pins. Avoid Port D pins (these will be used for the LCD later). Wire the other side of each button to ground. With this configuration the I/O pin will be grounded when the button is pressed, and floating (no specific voltage) when the button is not pressed. This will cause problems with reading the button when it is not pressed, but this issue can be fixed in software later.

  2. Wire the external LED and appropriate current-limiting resistor to another I/O pin. Avoid Port D pins.

  3. Launch MPLAB® X and create a new project for your PIC IC.

  4. Open Microchip Code Configurator and apply the following settings:

    Please use MCC Classic. We can support it better, it has more advanced configuration options, but is also still relatively easy to use.

    1. System

      1. System Clock: Configure your system clock to use the HFINTOSC at 4MHz

      2. Clock divider: select a clock divider of 4.

      3. Disable watchdog timer (unused)

      4. Disable low-freq programming

    2. In the Pin Manager, make sure that the Package matches the package of the PIC you are using. Then, in the Pin Manager configure GPIO pins for the two buttons.

    3. In the Pin Module, configure the PICs internal pull-up resistors to both button pins. This will ensure that the pins’ inputs are not floating when the buttons are not pressed (grounded).

    4. Add a PWM with 50% duty cycle and associated Timer. Configure the timer in a similar way to how you did in HW2. Then, in the Pin Manager connect the output of the PWM to the LED pin.

    5. Add a UART component as you did in HW1 for debugging purposes (optional)

  5. Write code to do the following:

    1. Initialize the PWM duty cycle to 50% of its maximum value.

      (See pwmX.h for the API function to do this)

    2. Read the current value of each button.

      (See pin_manager.h for the API function to do this)

    3. If the left button is pressed, decrease the current duty cycle by 25% of the total PWM resolution

    4. If the right button is pressed, increase the duty cycle of the PWM by 25% of the total PWM resolution

    5. If no button is pressed, do not change the duty cycle.

    6. Wait for 200 ms before repeating steps c - f.

      Note: This delay reduces the likelihood of a single button press causing a fast change in the duty cycle. A better way to do this is by processing button presses using interrupts, which you will do later in the semester in another homework assignment.

  6. Compile and download your code to the microcontroller. The code should visibly change the duty cycle of the blinking LED up or down depending on which button is pushed.

If this step doesn’t work, debug by first checking all connections against the data sheet, looking for error messages in the IDE, and searching for the error messages on Google. Next, try adding a UART component and printing the value of the duty cycle variable to see if it changes. If you’re still stuck, see the teaching team for help.

3.0 Displaying information on a character LCD screen

  1. Study the following critical information and concepts:
Critical Information and Concepts Importance
a. How dot-matrix LCDs work and are controlled. Needed to understand the hardware and software necessary to get the LCD communicating with your microcontroller. First, read section 12.10.2 of Scherz & Monk starting from the subsection on “Intelligent” Dot-Matrix LCD Modules. This section describes a module that is very similar to the one you will be using.
b. What the purpose of each pin on your LCD module is, and which pins should be connected to a microcontroller if the LCD is in 4-bit mode. Needed to understand the specific connections of the LCD module in your EGR 304 kit, which is a 16x2 character LCD (model number 1602A). Study the entire 1602A datasheet to understand the hardware and software interfaces. Note that the controller chip on this LCD uses the same protocol as the common Hitachi HD44780-based LCDs. Also note that this datasheet (as well as those for most other similar LCDs) are not very good, with inconsistent and unclear information.
c. How the LCD code library works, and what API (application programming interface) functions it provides. Needed in order to program your LCD to display text. The functions are specific to this library, so you will need to study the .h and .c files as well as the README* *file for pic-lcd-library-master.
d. In this tutorial on sprintf(), determine what library(or libraries) you need to include You will need to format a string.
  1. Wire the LCD as follows:
LCD Pin PIC18F47Q10 Pin Comments
VSS TBD Follow the connection diagram on page 4 in the 1602A datasheet. Use your 3.3V supply for power to your LCD.
VDD TBD
V0 TBD
RS Any unused pin in Port D except RD0-3 It is more organized if the control pins are on the same port as the data pins.
RW Ground You will configure the LCD driver library to control the LCD in 4-bit mode, and this pin is not used in 4-bit mode.
E Any unused pin in Port D except RD0-3 It is more organized if the control pins are on the same port as the data pins.
D0 Ground You will configure the LCD driver library to control the LCD in 4-bit mode, so these pins should not be connected (see section 12.10.2 of Scherz & Monk).
D1 Ground
D2 Ground
D3 Ground
D4 RD0 The LCD driver library you will be using requires that the four pins start at the lowest nibble (4 bits) of a PIC port.
D5 RD1
D6 RD2
D7 RD3
A 3.3V through 75Ω resistor This is the power pin for the backlight. Connect it to 3.3V through a 75Ω current-limiting resistor. Note that we are using a +3.3V power supply instead of +5V per the Absolute Maximum table in the datasheet.
K Ground This is the ground pin for the backlight.
  1. Launch MPLAB® X and load your project from part 2.0 of this assignment. In MPLAB® X, right-click on the project name and select “Copy” from the contextual menu to make a copy that will include both the button and the LCD. Then, right-click on the new project and select “Set as main project” from the contextual menu.

    1. In Windows, copy the .h and .c files from the pic-lcd-library-master.zip file to the same folder as your MPLAB® X project files for this assignment (at the same folder level as main.c).

    2. LAB® X, right-click on the Header Files and Source Files folders and select “Add Existing Item…” to add the .h and .c files from the PIC LCD Library to their respective folders in your project.

    3. Modify the project hardware to add output pins that match those you selected and connected above. Make sure that none of the pins are set as analog. It is helpful to rename the pins in the Pin Module according to their purpose in the project.

      Note: If you added a UART to Port D you will have to remove it so that it doesn’t conflict with the LCD.

  2. Modify your existing code in main.c to add the following features:

The next step involves referencing and modifying some example code given by the original developer of the library. You will need to read, modify, and fix this code in order to get it working and customize it according to the specific pins you are using.

Context: Finding code online is often fraught with problems. This can include incomplete documentation, outright errors, and code that is not written specifically for your device.

a. Include the LCD.h header file so that you can use the LCD library functions in main.c.

b. Configure and initialize the LCD screen according to the example in the README* *file for pic-lcd-library-master. Pay special attention to ensure you are specifying the correct pins for “register select” and “reset” pins

c. Based on the README* *file example code and the functions in LCD.h, add code to display your name and anything else you would like to write on the LCD.

  1. Compile and download your code to the microcontroller. The code should display the text you specified on the LCD screen. If it doesn’t work, here are some debugging steps:

    1. ike much code downloaded from the Internet, there are errors in the README* *file example code. Refer to the error messages from the compiler when debugging as well as the function definitions in LCD.h.

    2. e potentiometer is to adjust the contrast of the screen. If you don’t see any text, try adjusting the potentiometer.

    3. If you still don’t see anything on the screen, double-check your wiring.

    4. If your wiring is correct, double-check that the code (particularly the LCD initialization function) matches your wiring configuration.

    5. If your code is correct, try unplugging and re-plugging the USB cable into the Curiosity Nano. This causes the chip and the LCD screen to reset.

    6. If you’re still stuck, see the teaching team for help.

4.0 Displaying the current duty cycle on the LCD screen

  1. Study the following critical information and concepts:
Critical Information and Concepts Importance
a. How to convert a 16-bit unsigned integer into a character string Needed in order to print the duty cycle variable to the LCD screen as an integer. Study the functions in the stdio.h library to find one that is appropriate for this purpose.
  1. Launch MPLAB® X and load your project from part 3.0 of this assignment. In MPLAB® X, right-click on the project name and select “Copy” from the contextual menu to make a copy that will include both the button and the LCD. Then, right-click on the new project and select “Set as main project” from the contextual menu.

  2. Modify your existing code in main.c to add the following features:

    1. Include the library for sprintf()

    2. Configure and initialize the LCD screen.

    3. On the first line of the LCD screen, display text with your initials and “Duty Cycle”.

    4. On the second line of the LCD screen, display the current value of the duty cycle register as an integer.

    5. Read the current value of each button.

    6. If the left button is pressed, decrease the current duty cycle by 25% of the total PWM resolution and update the duty cycle number on the LCD screen

    7. If the right button is pressed, increase the duty cycle of the PWM by 25% of the total PWM resolution and update the duty cycle number on the LCD screen

    8. If no button is pressed, do not change the duty cycle or what is displayed on the LCD screen.

    1.Wait for 200 ms before repeating steps 3 - h.

  3. Compile and download your code to the microcontroller. The code should display your custom text label on the first line and the current integer value of the duty cycle variable on the second line. When you press the up button, the duty cycle value should increase on the LCD screen and the duty cycle of the LED flashing should increase by 25%. When you press the down button, the duty cycle value should decrease on the LCD screen and the duty cycle of the LED flashing should decrease by 25%.


Next

Check out the Timers and Interrupts Tutorial that follows this!