[ Log In ]
Tumbnail: 62 oz-in NEMA 17 Stepping motors (also called stepper motor)

NEMA 17 Stepping Motor (62 oz-in 5mm single shaft)

$19.95
Qty:
Image of the Atmega324p

Atmega324P

$8.50
Qty:

10K timmer potentiometer

10K Trimmer Potentiometer (Through Hole)

$0.85
Qty:
16x2 LCD (Liquid Crystal Display)

16x2 LCD (Liquid Crystal Display)

$12.50
Qty:
White prototyping breadboard with 30 tie strips and two power rails on each side.

White Prototyping Breadboard (2x30 columns of tie strips and 2x2 rows of power strips)

$7.95
Qty:
Clear Semi Transparent Breadboard

Clear Prototyping Breadboard (2x30 columns of tie strips and 2x2 rows of power strips)

$8.50
Qty:
Red Through Hole LED (Light emitting diode)

Single Red Through Hole LED (Light Emitting Diode)

$0.34
Qty:
Green through hole LED (light emitting diode)

Single Green Through Hole LED (Light Emitting Diode)

$0.34
Qty:
Yellow through hole LED (light emitting diode)

Single Yellow Through Hole LED (Light Emitting Diode)

$0.34
Qty:
Skip Navigation Links

Microcontroller - A Beginners Guide - Creating a New Library Routine to Show Integer Numbers on the LCD

We know how to display an integer on the LCD, but there are many lines of code to do this. Let's make showing integers on the LCD screen, and where we want to show the integer a bit more easy. First, let's see what we need to do just to show an integer on the LCD and at a particualar location. Below is the code snippet to do this:

itoa(TenBitValue, adcResult, 10);
GotoMrLCDsLocation(1, 1);
Send_A_String(adcResult); Send_A_String(" ");

The itoa function takes three parameters: The integer variable, in this case, it is the TenBitValue variable that is storing the digital value from the analog reading, the adcResult is the string, or character array variable that will store the value of the digital reading in string form so it can be presented on the LCD, and finally, the 10 is base. The base is the number system. The standard digital number system is in base 10 and has the single digits of 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9. Base 2 would have only 2 single digit numbers: 0 and 1.

I can imagine showing numbers on the LCD all the time, so I definitely don't want to keep typing those four lines of code every time I need to have integers on the LCD, so it's time to add to the LCD library so we only need to write a single line of code to put integers on the LCD and include the position in that line of code as well. The parameters that will be passed in are x and y for the location, the integer variable, and the number of digits to make room in memory for the character array. The new function will look like the following:

Send_An_IntegerToMrLCD(x, y, TenBitValue, 4);

To make things for straightforward, another function will be added to the library to send a string to a particular location on the LCD since we may need this functionality as well. Then we can use this to make our integer function using that function. Here is the function to send a string of charagers to a specific location on the LCD:

void Send_A_StringToMrLCDWithLocation(uint8_t x, uint8_t y, char *StringOfCharacters)
{
GotoMrLCDsLocation(x, y);
Send_A_String(StringOfCharacters);
}

Now our send an integer function will be much easier to implement:

void Send_An_IntegerToMrLCD(uint8_t x, uint8_t y, int IntegerToDisplay, char NumberOfDigits)
{
char StringToDisplay[NumberOfDigits];
itoa(IntegerToDisplay, StringToDisplay, 10);
Send_A_StringToMrLCDWithLocation(x, y, StringToDisplay); Send_A_String(" ");
}

Here is the new and improved library file:

//These are the Includes
#include <avr/io.h>
#include <util/delay.h>
#include "Mr.LCD"

//These are the Routines
void Check_IF_MrLCD_isBusy()
{
DataDir_MrLCDsCrib = 0;
MrLCDsControl |= 1<<ReadWrite;
MrLCDsControl &= ~1<<BiPolarMood;

while (MrLCDsCrib >= 0x80)
{
Peek_A_Boo();
}

DataDir_MrLCDsCrib = 0xFF; //0xFF means 0b11111111
}

void Peek_A_Boo()
{
MrLCDsControl |= 1<<LightSwitch;
asm volatile ("nop");
asm volatile ("nop");
MrLCDsControl &= ~1<<LightSwitch;
}

void Send_A_Command(unsigned char command)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = command;
MrLCDsControl &= ~ ((1<<ReadWrite)|(1<<BiPolarMood));
Peek_A_Boo();
MrLCDsCrib = 0;
}

void Send_A_Character(unsigned char character)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = character;
MrLCDsControl &= ~ (1<<ReadWrite);
MrLCDsControl |= 1<<BiPolarMood;
Peek_A_Boo();
MrLCDsCrib = 0;
}

void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}

void GotoMrLCDsLocation(uint8_t x, uint8_t y)
{
Send_A_Command(0x80 + firstColumnPositionsForMrLCD[y-1] + (x-1));
}

void Send_A_StringToMrLCDWithLocation(uint8_t x, uint8_t y, char *StringOfCharacters)
{
GotoMrLCDsLocation(x, y);
Send_A_String(StringOfCharacters);
}

void Send_An_IntegerToMrLCD(uint8_t x, uint8_t y, int IntegerToDisplay, char NumberOfDigits)
{
char StringToDisplay[NumberOfDigits];
itoa(IntegerToDisplay, StringToDisplay, 10);
Send_A_StringToMrLCDWithLocation(x, y, StringToDisplay); Send_A_String(" ");
}

void InitializeMrLCD()
{
DataDir_MrLCDsControl |= 1<<LightSwitch | 1<<ReadWrite | 1<<BiPolarMood;
_delay_ms(15);

Send_A_Command(0x01); //Clear Screen 0x01 = 00000001
_delay_ms(2);
Send_A_Command(0x38);
_delay_us(50);
Send_A_Command(0b00001110);
_delay_us(50);
}

Here is how I use the new function within an interrupt service routine. For future reference, it is not the best programming practice to have too many instructions within an ISR (Interrupt Service Routine) because if it takes too long, other ISRs, or another conversion for this particualr ISR may not execute. It's best to handle the long instructions within the never ending loop. For instance, I could set a global flag variable to equal a 1 within the interrupt and inthe never ending loop, check this flag variable to see if it is a 1 and if so, it could execute the insgructions there instead of in the ISR.

ISR(ADC_vect)
{
uint8_t TheLow - ADCL;
uint16_t TenBitValue = ADCH<<2 | TheLow>>6;

Send_An_IntegerToMrLCD(x, y, TenBitValue, 4);

ADCSRA |= 1<<ADSC;
}