In part two of the tachometer/speedometer project, we'll add a keypad and LCD for easier user interaction.

In this project, we're making our own tachometer using a C8051 microcontroller development kit, an optoelectronic sensor, a variable-speed DC motor, a 5-inch diameter transparent disc, and the Simplicity Studio IDE. 

This article is part two of a two-part series. Please read part one before continuing:

While part one measured both the angular and linear velocities of a spinning disc and sent the measured data to a terminal window via the UART, part 2 displays the same measured data on an eight-segment LCD screen. And, because not all the measured data can be displayed simultaneously on the LCD screen, a keypad will be used for selecting which data is to be displayed.


LCD Display

As mentioned in part one of this project, the C8051F930DK development kit is utilized. However, for this second part I've added an LCD development board—the manufacturer's part number for the complete development kit, including the microcontroller and the LCD dev board, is CP2400DK.


Figure 1. Silicon Labs CP2400DK development kit (C8051 microcontroller and LCD display). Image courtesy of Digi-Key.


The manufacturer part number of the LCD device itself (Figure 2) is VIM-878-DP-RC-S-LV. And, while this device is advertised as being a 14-segment display, which is accurate, when including the decimal point and the apostrophe, the device becomes a 16-segment LCD display. Furthermore, since this display has eight digits the device has a total of 128 segments. The 128-segment LCD driver, that Silicon Labs has mated with this LCD display, is the CP2400 (Figure 3).


Figure 2. LCD screen with 16 segments for each of the eight digits (total of 128 segments). Image courtesy of Digi-Key.


Figure 3. 128-segment LCD driver. Images courtesy of Silicon Labs (pages 1 and 22).



The keypad (Figure 4) I chose for this project, simply because of its low cost, is made by Adafruit Industries (product ID 419). This keypad type is known as a 3×4 matrix keypad because of its three connecting columns and four connecting rows, for a total of seven connections (see Figure 5).


Figure 4. Keypad. Image courtesy of Digi-Key.


Figure 5. Keypad pinout.


Parts list:

Item # Description/Source Cost (each) Other Information
1  C2400DK development kit $148.75  User guide
 Quick-start guide
 C8051F930 datasheet
 Note: schematics are on pages 25-31 of the User
2  Breadboard $8.98  or equivalent
3  Jumper wire kit $5.28  or equivalent
4  Clear acrylic plexiglass disc $7.99  or equivalent
5  Optical sensor $3.62  or equivalent
6  DC motor $6.55  The motor used in the project was re-purposed from
 a printer teardown. However, this motor looks to be
 an equivalent motor.
7  Keypad 419 $3.95  Datasheet
8  Resistor: 100-ohms $0.10  or equivalent
9  Resistor: 3.3k-ohms $0.10  or equivalent
10  Resistor: 20k-ohms (qty: 4) $0.10  or equivalent


Making the Connections/Schematics

Part one of this project uses the microcontroller's port 1 pin 2 (P1.2) as the input from the optical switch (more specifically, from the collector of the switch’s phototransistor). However, since part 2 uses P1.2 for the SPI interface, the microcontroller has been reconfigured such that the optical switch is now connected to port 1 pin 4 (P1.4).

And speaking of the SPI interface, Figure 6 below shows how it's configured via Simplicity Studio's hardware configuration GUI.


Figure 6. SPI interface configuration.


Choosing Resistor Values

While the selection process for choosing values for R1 and R2 is discussed in part one, resistors R3 through R6 are all new to the project. All four resistors have the same value (although this is not necessary) and serve the same function: they are all pull-down resistors. A wide range of resistor values are possible here, though very low resistance results in higher current consumption and very high resistance results in lower noise immunity. I decided to use four 20kΩ resistors; this value is fairly high for a pull-down resistor, which makes it more appropriate for applications where reduced power consumption is a priority.


Keypad Connection

Because only four types of measured data will be displayed on the LCD screen (REV/S, RPM, FT/S, and MPH), I chose to make the keypad connections in a manner that would simplify the firmware: I use buttons "1", "4", "7", and "*"; this requires the use of only one column and four rows. If I had used buttons "1" through "4", for example, I'd have to use two columns and two rows for determining which button was depressed, and this would require additional firmware.


Figure 7. Connection diagram. Click to enlarge.


Configuring the Microcontroller Development Kit

As stated in the previous article, before powering up the microcontroller development kit, be sure to configure it as follows:


  • J11: VBAT to WALL_PWR
  • J12:
    • VDD to VIO
    • P0.5 to TXD
  • J17: VBAT_PIN to VBAT



  • SW4: set to "2 CELL"
  • Power switch (SW5) to "OFF" position



  • Connect the ribbon cable debug adapter to J9
  • Connect the USB debug adapter to your PC
  • Connect the USB serial-port cable between P3 and your PC
  • Connect the supplied AC/DC power adapter to P2


The Firmware

When writing the firmware, I heavily leveraged Silicon Lab's example LCD project (CP240x_LCD_Example) which made my firmware writing task much easier, especially since the example project included all the necessary LCD library files. In general, I always attempt to use other people's firmware, at least as a springboard, when the firmware task at hand is complex.

Besides configuring the SPI interface and reassigning the microcontroller's port (from P1.2 to P1.4) for the optical switch connection, all the firmware creation that remained was determining which keypad button was depressed and then displaying the desired measured data. And due to the fashion in which I connected the keypad, this firmware task was fairly straightforward. By default (i.e., at power on), revolutions per second is displayed.

Because the LCD screen is limited to 8 digits, when displaying the measured data I rounded the value to the nearest integer.


LCD firmware snippet:


                    if (Keypad_Number_1 == 1)
	sprintf(display_string, "%0.0f rev/s  ", (float) FrequencyAverage);

if (Keypad_Number_4 == 1)
	sprintf(display_string, "%0.0f RPM  ", (float) FrequencyAverage*60);

if (Keypad_Number_7 == 1)
	sprintf(display_string, "%0.0f ft/s  ", (float) FeetPerSecond);

if (Keypad_Number_star == 1)
	sprintf(display_string, "%0.0f MPH  ", (float) MPH);


Keypad firmware snippet:


// Keypad Routine
// ----------------------------------------------------------------------------
if(Row_1 == 1)		// P2.0
	Keypad_Number_1 = 1;
	Keypad_Number_4 = 0;
	Keypad_Number_7 = 0;
	Keypad_Number_star = 0;

else if(Row_2 == 1)	// P2.1
	Keypad_Number_1 = 0;
	Keypad_Number_4 = 1;
	Keypad_Number_7 = 0;
	Keypad_Number_star = 0;

else if(Row_3 == 1)	// P2.2
	Keypad_Number_1 = 0;
	Keypad_Number_4 = 0;
	Keypad_Number_7 = 1;
	Keypad_Number_star = 0;

else if(Row_4 == 1)	// P2.3
	Keypad_Number_1 = 0;
	Keypad_Number_4 = 0;
	Keypad_Number_7 = 0;
	Keypad_Number_star = 1;

  Download Code  

Building and Loading the Code ... and Testing the System

After downloading, building, and loading the code, make sure your terminal window is configured as follows:

  • baud rate set to 230400
  • Data: 8-bits
  • Parity: none
  • Stop: 1-bit


You're now ready to test the system! Power up the microcontroller development board, slowly ramp up the voltage to the DC motor, and monitor the terminal window. The measured data on the terminal window will match that displayed on the LCD screen. Don't forget to press the following buttons for the associated measured data:

  • "1" = REV/S
  • "4" = RPM
  • "7" = FT/S
  • "*" = MPH


Next Steps

Since this project utilizes development boards, the next step would be to integrate all the parts and pieces onto a single customized PCB, sans the spinning disc, DC motor, and optical switch. Also, for an actual application I would consider using a multi-line LCD screen for allowing all the measured data to be displayed simultaneously and thus eliminate the keypad. Or, I would keep the existing LCD, eliminate the keypad, and settle on a single data stream, probably FT/S or RPM. But of course, this data stream decision would be dependent on the end application.

Happy building!!