# Reading data from device in programming

#### Parth786

Joined Jun 19, 2017
642
I am struggling with some basics. I think I am missing some basics. I think this is my third attempt to decrease the complexity of program on same topics.
Code:
#include<REGX51.h>
#define LED_ON     (1)
#define LED_OFF    (0)
#define SW1_ON     (1)
#define SW1_OFF    (0)
#define SW2_ON     (1)
#define SW2_OFF    (0)
/*set bit P1^7 to LED*/
sbit LED = P1^7;
/*set bit P2^0 to Switch*/
sbit  SW1 = P0^0;
sbit  SW2 = P2^0;
void main ()
{
LED = LED_OFF;
while (1)
{
if (SW1 == 1 )
{
LED = LED_ON;
}

else
{
LED = LED_OFF;
}
}
I wrote this program to understand interfacing of LED and Switches. Now I am just trying to replace LED with LCD. so there are only switch and LCD connected to 8051. In program , if switch is High than LED should be ON and If switch is Low the LED should be OFF

I want to write c program for following conditions?
condition1 : if there is only one switch- read the condition of Switch if its ON than Display "1" on screen else don't display anything
Condition 2 : if there are two switches - read the condition of switches if SW1 on then Display "1" on screen and if if SW2 on then Display "2" on screen else don't display anything

generally I understand basics such as string, array, while loop, for loop, if else condition and I think I have to use these in program. I don't understand whats my fault why I am not making program. why I am not updating from LED to LCD so please help me on right direction

Last edited:

#### WBahn

Joined Mar 31, 2012
26,398
First things first. Write a program that does nothing more than display a "1" on the screen.

Then change it so that it alternates between a "1" and a "2", changing once a second.

Then start worrying about tying what is displayed to reading switch inputs.

#### Parth786

Joined Jun 19, 2017
642
First things first. Write a program that does nothing more than display a "1" on the screen.
.
Ok here is program that display only "1"
Code:
#include<reg51.h>
#define port P1           /* Data pins connected to port P1 */
sbit RS = P2^0;           /* RS pin connected to pin 0 of port P2 */
sbit RW = P2^1;           /* RW pin connected to pin 1 of port P2 */
sbit EN = P2^2;           /* EN pin connected to pin 2 of port P2 */
void Delay(unsigned int wait)
{
unsigned i,j ;
for(i=0;i<wait;i++)
for(j=0;j<1200;j++);
}
/* Function to send command instruction to LCD */
void LCD_Command(unsigned char cmd)
{
port = cmd;
RS=0;
RW=0;
EN=1;
Delay(2);
EN=0;
}
/*Function to send display dato LCD */
void LCD_Data(unsigned char Data)
{
port = Data;
RS=1;
RW=0;
EN=1;
Delay(2);
EN=0;
}
/* function for delay */
/* Function to prepare the LCD */
void LCD_init()
{
LCD_Command(0x38);
Delay(20);
LCD_Command(0x0f);
Delay(20);
LCD_Command(0x01);
Delay(20);
LCD_Command(0x81);
Delay(20);
}
void main()
{
unsigned char string[15]="1";
char *buffer = string;
LCD_init();
while(*buffer)
{
LCD_Data(*buffer++);
Delay(60);
}
}

#### WBahn

Joined Mar 31, 2012
26,398
If that works, then see if you can get it to replace the "1" with a "2" (as opposed to displaying the "2" after the "1").

#### Parth786

Joined Jun 19, 2017
642
If that works, then see if you can get it to replace the "1" with a "2" (as opposed to displaying the "2" after the "1").
I have tested code, my first program display "1" and below program display first "1" and than "2"
Code:
#include<reg51.h>
#define port P1           /* Data pins connected to port P1 */
sbit RS = P2^0;           /* RS pin connected to pin 0 of port P2 */
sbit RW = P2^1;           /* RW pin connected to pin 1 of port P2 */
sbit EN = P2^2;           /* EN pin connected to pin 2 of port P2 */

void Delay(unsigned int wait);
void LCD_Command(unsigned char cmd);
void LCD_Data(unsigned char Data);
void LCD_init();

void LCD_init()
{
LCD_Command(0x38);
Delay(20);
LCD_Command(0x0e);
Delay(20);
LCD_Command(0x06);
Delay(20);
LCD_Command(0x01);
Delay(20);
}

void LCD_Command(unsigned char cmd)
{
port = cmd;
RS=0;
RW=0;
EN=1;
Delay(2);
EN=0;
}
void LCD_Data(unsigned char Data)
{
port = Data;
RS=1;
RW=0;
EN=1;
Delay(2);
EN=0;
}

void LCD_String(unsigned char *str)  //Function to send string to LCD
{
int i=0;
while(str[i]!='\0')
{
LCD_Data(str[i]);
i++;
Delay(10);
}
return;
}
void Delay(unsigned int wait)
{
unsigned i,j ;
for(i=0;i<wait;i++)
for(j=0;j<1200;j++);
}
void main()
{
unsigned char str1[] ="1";
unsigned char str2[] ="2";
lcd_init();
while(1) {
LCD_Command(0x82);
LCD_String(str1);
Delay(500);
LCD_Command(0x01);
LCD_String(str2);
Delay(500);
LCD_Command(0x01);
Delay(10);

}
}

#### WBahn

Joined Mar 31, 2012
26,398
You realize that it's impossible for use to give you much feedback since we have no idea what is required to run your LCD module.

You can go a long way toward rectifying this by documenting your code. That will not only help others make heads or tails of what you are doing and help catch mistakes you might make, but will be a huge help to YOU as well.

You also still need to work on properly formatting/indenting your code to make the written structure match the logical structure.

#### Parth786

Joined Jun 19, 2017
642
You realize that it's impossible for use to give you much feedback since we have no idea what is required to run your LCD module.
.
Sorry. I forget to mention controller compiler and LCD. I am using 8051 controller, Keil and 16*2 LCD module
You can go a long way toward rectifying this by documenting your code. That will not only help others make heads or tails of what you are doing and help catch mistakes you might make, but will be a huge help to YOU as well.

You also still need to work on properly formatting/indenting your code to make the written structure match the logical structure.
I use keil compiler. while making some changes in previous program I could not arrange my code properly and I posted that code directly to forum. I will keep in my mind next time posting code. another disadvantage is keil don't have automatic indenting option.

does it look like good
Code:
    #include<reg51.h>
#define port P1           /* Data pins connected to port P1 */
sbit RS = P2^0;           /* RS pin connected to pin 0 of port P2 */
sbit RW = P2^1;           /* RW pin connected to pin 1 of port P2 */
sbit EN = P2^2;           /* EN pin connected to pin 2 of port P2 */

void Delay(unsigned int wait);
void LCD_Command(unsigned char cmd);
void LCD_Data(unsigned char Data);
void LCD_init();

void LCD_init()
{
LCD_Command(0x38);
Delay(20);
LCD_Command(0x0e);
Delay(20);
LCD_Command(0x06);
Delay(20);
LCD_Command(0x01);
Delay(20);
}

void LCD_Command(unsigned char cmd)
{
port = cmd;
RS=0;
RW=0;
EN=1;
Delay(2);
EN=0;
}
void LCD_Data(unsigned char Data)
{
port = Data;
RS=1;
RW=0;
EN=1;
Delay(2);
EN=0;
}

void LCD_String(unsigned char *str)  //Function to send string to LCD
{
int i=0;
while(str[i]!='\0')
{
LCD_Data(str[i]);
i++;
Delay(10);
}
return;
}
void Delay(unsigned int wait)
{
unsigned i,j ;
for(i=0;i<wait;i++)
for(j=0;j<1200;j++);
}
void main()
{
unsigned char str1[] ="1";
unsigned char str2[] ="2";
lcd_init();
while(1) {
LCD_Command(0x82);
LCD_String(str1);
Delay(500);
LCD_Command(0x01);
LCD_String(str2);
Delay(500);
LCD_Command(0x01);
Delay(10);

}
}

Last edited:

#### WBahn

Joined Mar 31, 2012
26,398
One of the bad things about the forum software is that indenting is not preserved when you paste text and multiple spaces are reduced to a single space. It really sucks. It means that you have to go through your code after it is pasted and indent things manually. As long as you keep your code snippets reasonably short, it's not too burdensome, but it is a pain.

It looks better, but still needs work.

As an example of what I'm talking about, consider the following function

Code:
   void Delay(unsigned int wait)
{
unsigned i,j ;
for(i=0;i<wait;i++)
for(j=0;j<1200;j++);
}
Your two loops are at the same level of indentation, implying that they are executed one after the other. But in fact, the second loop is nested within the first. Your indenting should reflect this

Code:
   void Delay(unsigned int wait)
{
unsigned i, j;
for(i = 0; i < wait; i++)
for(j = 0; j < 1200; j++);
}
It's good to tell us what LCD module you are using, but don't expect people that you are asking for free help from to go out and learn how to program that module. If it gets down to the nitty-gritty then some people will probably be willing to go take a look, but probably only if they think it is worth their time because it is evident that you have spent the time to make their life as easy as possible.

So make a reasonable effort to document your code.

For instance, you have

LCD_Command(0x82);

in a few places.

Why? What does this do? Does it clear the display? If so, then say so.

LCD_Command(0x82); // Clear display

Better yet, make your code self-documenting

#define LCD_CLEAR_DISPLAY (0x82)
...
LCD_Command(LCD_CLEAR_DISPLAY);

#### Parth786

Joined Jun 19, 2017
642
So make a reasonable effort to document your code.
Better yet, make your code self-documenting
...
I will remember your suggestion. I will follow your advice as I can , I will try to overcome my mistakes. I know my programming skill is not very good. I am just started to get interest in programming. I think it take time to make good in programming. I am just practicing with some real ideas that come in mind. and I tried to write program for that I don't want to do any mistake but it happen. I will try to post clean code. I always try to give my best. sometime I understand and sometime I don't understand easily.

It's good to tell us what LCD module you are using, but don't expect people that you are asking for free help from to go out and learn how to program that module. If it gets down to the nitty-gritty then some people will probably be willing to go take a look, but probably only if they think it is worth their time because it is evident that you have spent the time to make their life as easy as possible.
If you see my old threads, there is program for LCD, where I learned programming of LCD module. I understand working of each module. I don't want that someone do my work. .

#### WBahn

Joined Mar 31, 2012
26,398
You learn by doing and making mistakes and being shown ways to improve. So don't sweat it.

I'm not trying to say that you are trying to have others do your work for you -- unlike many folks here, you are clearly making the effort. What I am saying is that in order to look over your code and be of much help, we need to be able to determine what the code is doing, at least at an abstract level. If the code indicated that a command initialized the LCD module and another clears the display, then we can make reasonable recommendations about which commands need to be within what loops or what selection blocks. That's the level of documentation that you need to achieve if you want people to offer input at that level.

You should be able to identify the part of your current LCD code that makes a "1" appear on the screen and the part that makes a "2" appear on the screen. Then put that code in the appropriate place instead of your LED commands. Of course, don't forget to do the initialization, too.

#### Parth786

Joined Jun 19, 2017
642
You should be able to identify the part of your current LCD code that makes a "1" appear on the screen and the part that makes a "2" appear on the screen. Then put that code in the appropriate place instead of your LED commands. Of course, don't forget to do the initialization, too.
I am confused on switches. I don't know what I have to use switches or push buttons I have read that keypad made of several push buttons. so what I use switches or Push buttons

Yes means = "1"
No means = "2"

Last edited:

#### Parth786

Joined Jun 19, 2017
642
I checked below program but its not working I don't know weather my code is wrong or there is any problem in hardware design.
C:
    #include<reg51.h>

/* Data pins connected to port P1 of 8051 */
#define  Data_Port_Pins                            (P1)

#define  Switch1_ON                                 (1)      /* switch 1 ON */
#define  Switch1_OFF                                (0)      /* switch 1 OFF */
#define  Switch2_ON                                 (1)      /* switch 2 ON */
#define  Switch2_OFF                                (0)       /* switch 2 OFF */

#define  LCD_Set_Display                           (0x38)    /* Set display to be 2 lines 16 characters */
#define  LCD_Increment_cursor                      (0x06)    /* Increment cursor */
#define  LCD_Clear_display_screen                  (0x01)    /* Clear display */

sbit    Register_Select_Pin   = P2^0;           /* Register Pin of LCD connected to Pin 0 of Port P2 */
sbit    Read_Write_Pin        = P2^1;           /* Read/Write Pin of LCD connected to Pin 1 of Port P2 */
sbit    Enable_Pin            = P2^2;           /* EN pin connected to pin 2 of port P2 */

sbit    Switch1               = P3^0;           /* switch 1 connected to port pin P3.0 */
sbit    Switch2               = P3^3;           /* switch 2 connected to port pin P3.3 */

/* Function for creating delay in milliseconds */
void Delay(unsigned int wait)
{
unsigned i, j;
for(i = 0; i < wait; i++)
for(j = 0; j < 1200; j++);
}

/* Function to send command instruction to LCD */
void LCD_Command (unsigned char cmd)
{
Data_Port_Pins = cmd;
Register_Select_Pin =0;
Enable_Pin =1;
Delay (2);
Enable_Pin =0;
}

/* Function to send display data to LCD */
void LCD_Data (unsigned char Data)
{
Data_Port_Pins = Data;
Register_Select_Pin=1;
Enable_Pin =1;
Delay(2);
Enable_Pin =0;
}

/* Function to prepare the LCD  and get it ready */
void LCD_Initialization()
{
LCD_Command (LCD_Set_Display );
LCD_Command (LCD_Increment_cursor );
LCD_Command (LCD_Clear_display_screen);
}

/* Function to send string to LCD */
void LCD_String (unsigned char *string)
{
int i=0;
while(string[i]!='\0')
{
LCD_Data(string[i]);
i++;
Delay(10);
}
return;
}

void main()
{
unsigned char string1[] ="1";
unsigned char string2[] ="2";
LCD_Initialization();
{
while(1)
{
if (Switch1 == Switch1_ON)
{
LCD_String(string1);
Delay(200);
LCD_Command(LCD_Clear_display_screen);
}

else if ( Switch2 == Switch2_ON )
{
LCD_String(string2);
Delay(200);
LCD_Command(LCD_Clear_display_screen);
Delay(10);
}
else
{
LCD_Command(LCD_Clear_display_screen);
}
}
}
}

Last edited by a moderator:

#### JohnInTX

Joined Jun 26, 2012
4,503
Your LCD initialization is faulty. Not sure why you changed it from post #5.

As @WBahn said, get the LCD working so that it reliably displays something at power up. Then proceed to sampling the switches and updating the display.

Page 45 describes how to initialize the LCD for an 8 bit interface.

Last edited:

#### Parth786

Joined Jun 19, 2017
642
I have cleaned some issues. This program display "1" when I press switch 1 and display "2" when I press switch 2
C:
#include<reg51.h>
/* Data pins connected to port P1 of 8051 */
#define  Data_Port_Pins        (P1)

sbit    Register_Select_Pin   = P2^0;           /* Register Pin of LCD connected to Pin 0 of Port P2 */
sbit    Read_Write_Pin        = P2^1;           /* Read/Write Pin of LCD connected to Pin 1 of Port P2 */
sbit    Enable_Pin            = P2^2;           /* EN pin connected to pin 2 of port P2 */
sbit    Switch1               = P3^0;           /* switch 1 connected to port pin P3.0 */
sbit    Switch2               = P3^3;           /* switch 2 connected to port pin P3.3 */

/* Function for creating delay in milliseconds */
void Delay(unsigned int wait)
{
unsigned i, j;
for(i = 0; i < wait; i++)
for(j = 0; j < 1200; j++);
}

/* Function to send command instruction to LCD */
void LCD_Command (unsigned char cmd)
{
Data_Port_Pins = cmd;
Register_Select_Pin =0;
Enable_Pin =1;
Delay (2);
Enable_Pin =0;
}

/* Function to send display data to LCD */
void LCD_Data (unsigned char Data)
{
Data_Port_Pins = Data;
Register_Select_Pin=1;
Enable_Pin =1;
Delay(2);
Enable_Pin =0;
}

/* Function to prepare the LCD  and get it ready */
void LCD_Initialization()
{
LCD_Command(0x38);
Delay(20);
LCD_Command(0x0e);
Delay(20);
LCD_Command(0x06);
Delay(20);
LCD_Command(0x01);
Delay(20);
}

/* Function to send string to LCD */
void LCD_String (unsigned char *string)
{
int i=0;
while(string[i]!='\0')
{
LCD_Data(string[i]);
i++;
Delay(10);
}
return;
}

void main()
{
unsigned char string1[] ="1";
unsigned char string2[] ="2";

LCD_Initialization();

while(1)
{
if (Switch1 == 1)
{
LCD_Command(0x82);
LCD_String(string1);
Delay(500);
LCD_Command(0x01);
}
else if (Switch2 == 1)
{
LCD_Command(0x82);
LCD_String(string2);
Delay(500);
LCD_Command(0x01);
Delay(10);
}
else
{
LCD_Command(0x01);
}
}
}
if you think all is right than I am planning to add extra switch is (+) operator. so I have three buttons
switch1 =1
switch2= 2
switch3=+
Now I want to do that If I press switch addition should be done. How to do that ?
Note: I have tested this program with another design where I am using switches with pull down resistors

Mod edit: added code=C tag for better formatting

Last edited by a moderator:

#### JohnInTX

Joined Jun 26, 2012
4,503
Addition of what? 1 and 2 or varying combinations of them?

If you are trying to make a simple calculator, think about how you would do it on paper. Pressing the '+' key says 'add' but add what? You need to store the previous key values, yes? then add them and presumably display the sum.

Hint: this isn't the way to make a calculator, but you are making progress with the display.

#### Parth786

Joined Jun 19, 2017
642
Hint: this isn't the way to make a calculator, but you are making progress with the display.
I know but I have lot things in mind to do with this small example and when I get basic idea definitely I will write code for keypad interfacing. but I think I don't have enough skill to write code for keypad interfacing. that's the reason I want to understand basic with simple buttons using (+) operator
Addition of what? 1 and 2 or varying combinations of them?.
so there are some issues for me
1. I want to do addition of varying combination of them ?
Example 1+2 =3, 2+1=3, 12+1=13, 1+12=13, 21+2=23, 21+1=22..... and so on
If you are trying to make a simple calculator, think about how you would do it on paper. Pressing the '+' key says 'add' but add what? You need to store the previous key values, yes? then add them and presumably display the sum.
enter numbers than press addition button than enter numbers and I am thinking why not use (=) this button to display result
simple idea
example: 1+2 =3, 2+1=3, 12+1=13, 1+12=13, 21+2=23, 21+1=22 ... and so on
I want to write program to short out these issues. how to resolve every issues one by one what I have to attempt first than next.. next...?

#### JohnInTX

Joined Jun 26, 2012
4,503
Whew.. OK. You are taking a big jump.
Consider the parts of your example:
1+2 =3, 2+1=3, 12+1=13, 1+12=13, 21+2=23, 21+1=22
In each addition you have to
1) get the first argument, maybe multiple digits
2) get the operator '+'
3) get the second argument
4) get another operator '=' then perform the operation

Problems to solve:
You said you were going to add one key ('+') but your description adds TWO ('+' and '=').
Your arguments can be more than one digit so you have to be able to accept consecutive digits and form a number from them i.e. '2' is 2 but '2' then '1' evaluates to 2*10 +1. Argument entry terminates with an operator. If the operator is '+' you have to store the argument you just got then read in the next one. When you get to '=', you add the stored arguments then display the result. You should, yes, flow this out to see how you will do it.
What you are using is 'infix' notation. Note that the article says that infix is more difficult to use than prefix or postfix notation. These are relatively advanced topics. If you just want to bang out something that adds two numbers you can brute force it by accepting argument 1, the operator, argument 2 then '='. If you want a more general purpose calculator then you are in for some serious programming. I don't want to pop your balloon here but that is probably beyond your capabilities at this point. It would be better to concentrate on simpler topics for now, keyboard scanning for all digits would be a start.

General info:
https://en.wikipedia.org/wiki/Calculator_input_methods

#### Parth786

Joined Jun 19, 2017
642
It would be better to concentrate on simpler topics for now, keyboard scanning for all digits would be a start.
you know very well what is batter for me , ok I am focusing on keyboard scanning.

C:
keypad_read ()
/* scan keypress on first Row 7 8 9 */
RowA = 0;
RowB = 1;
RowC = 1;
RowD = 1;

if (Column1 == 0)     /* key "7" is pressed */
if (Column2 == 0)     /* key "8" is pressed */
if (Column3 == 0)     /* key "9" is pressed */
if (Column4 == 0)     /* key "/" is pressed */

/* scan keypress on second Row 4 5 6 x */
RowA = 1;
RowB = 0;
RowC = 1;
RowD = 1;

if (Column1 == 0)     /* key "4" is pressed */
if (Column2 == 0)     /* key "5" is pressed */
if (Column3 == 0)     /* key "6" is pressed */
if (Column4 == 0)     /* key "x" is pressed */

/*scan keypress on third Row 1 2 3 -  */
RowA = 1;
RowB = 1;
RowC = 0;
RowD = 1;

if (Column1 == 0)     /* key "1" is pressed */
if (Column2 == 0)     /* key "2" is pressed */
if (Column3 == 0)     /* key "3" is pressed */
if (Column4 == 0)     /* key "-" is pressed */

// scan keypress on fourth Row C 0 = + */
RowA = 1;
RowB = 1;
RowC = 1;
RowD = 0;

if (Column1 == 0)     /* key "C"  is  pressed */
if (Column2 == 0)     /* key "0" is   pressed */
if (Column3 == 0)     /* key "+" is pressed */
if (Column4 == 0)     /* key "=" is pressed * /
I’m assigning high to all column and Then i am assigning first row to zero and keeps remaining row as high. to check which key is pressed. Then i am assigning second row to zero , than third and fourth row to zero to check which key is pressed

Last edited:

#### JohnInTX

Joined Jun 26, 2012
4,503
Before you get into all of that, is your LCD working? Can you display characters and strings where you want them i.e. locate the cursor and write characters on both lines?

I ask because you went from a simple switch detect to several LCD versions and now to a keyboard scanner but the LCD code is gone.

It looks to me like you are jumping around without a plan. What is the plan? Despite your nice statement, I don't know what is better for you, only you know that. You asked about adding two numbers but your example of adding multiple digit numbers increased the complexity. In response, I suggested that you were moving into more complex coding and that was something to think about before proceeding. My suggestion that you need a keyboard scanner was something to think about as you kept adding things (the second operator).

As we have been telling you, you can't proceed without a plan. If you want to make a calculator, think about the main components and what they do:

Data entry (keypad, discrete switches, terminal, etc). The function for any of these is the same:
Manage hardware issues (debouncing etc).
Process keystrokes.
Convert keystrokes to a usable representation i.e. text to binary number

Data display (LCD, multiplexed LED, terminal, etc). The function for any of these is also the same:
Take a binary number and display it in readable format.

Data manipulation:
Get binary numbers from input and store for processing
Get operators
Process stored inputs using operators
Display result

That's a lot to do but note that the big task is split into smaller tasks - get keyboard input, display things. Note that the each big part is split into smaller parts. With a good design, you split things up then code and test each one separately. Once its working, move on to the next thing. That's why I asked about the LCD. If it's not working, get it working then leave it in your code and use it. Then on to the next step. and the next. When you are out of steps, you are done.

But even if you don't want the whole calculator, displays and keypads are common modules for many projects and its worth knowing how to do them.

That's the only way I know how to do it.

Last edited:

#### MrChips

Joined Oct 2, 2009
23,958
Before you get too far ahead of yourself, you should be aware of how calculators work.

Suppose you wanted to enter a 10-digit number. How would you store that information?
How would you do arithmetic operations on 10-digit numbers?

Calculators work with 4-bit processors. Digits are stored in binary-coded decimal (BCD).

You need to have a plan before you start coding.

You appear to be ignoring advice given before.
Draw a flow chart before you start coding. Design comes before coding. The flow chart must work on paper. The code must match the flow chart otherwise there is no point in drawing a flow chart.