Temperature LCD is not working with C language

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello guys, Right now I am learning C Language to use in AVR, I am realizing the code to sense temperature from Lm35 and show the temperature in a LCD, the code compile well, but when I send the code to proteus to simulate this, the display is not working, somebody can help me again please?, my microcontroller is Atmega2560. This is my code. 

 

#include <asf.h>
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>



#define DPORT_LCD PORTA
#define DDDR_LCD DDRA
#define CPORT_LCD PORTB
#define CDDR_LCD DDRB
#define RS_LCD 0
#define RW_LCD 1
#define E_LCD 2
void EscribirComando_LCD (unsigned char cmd);
void EscribirDato_LCD(unsigned char dat);
void print_LCD(char *string);
void Print_N(unsigned int a);

int16_t ValorTemperatura;
float Temperatura;
char array[] = {"Temperatura"};

void EscribirComando_LCD(unsigned char cmd)
{
	DPORT_LCD=cmd;
	_delay_us(40);
	CPORT_LCD &= ~(1<<RS_LCD);
	CPORT_LCD|=(0<<RW_LCD);
	CPORT_LCD|=(1<<E_LCD);
	_delay_ms(2);
	CPORT_LCD &=~(1<<E_LCD);
	_delay_ms(1);
}
void EscribirDato_LCD(unsigned char dat)
{
	DPORT_LCD=dat;
	_delay_us(40);
	CPORT_LCD &= ~(1<<RS_LCD);
	CPORT_LCD|=(0<<RW_LCD);
	CPORT_LCD|=(1<<E_LCD);
	_delay_us(2);
	CPORT_LCD &=~(1<<E_LCD);
	_delay_us(1);
}

void print_LCD(char *string)
{
	while(*string)
	{
		EscribirDato_LCD(*string++);
	}
}

void Print_N(unsigned int a)  //CONVERSIÓN A ASCII
{
	EscribirDato_LCD((a/10)+0x30);
	_delay_us(40);
	EscribirDato_LCD((a%10)+0x30);
}

			ISR(TIMER1_OVF_vect){
			asm("LDI R23, 0xC2");
			asm("STS 0x85, R23");
			asm("LDI R22, 0xF7");
			asm("STS 0x84, R23");
			ADCSRA|=(1<<ADSC);
			while(ADCSRA&(1<<ADSC))
			{
				ValorTemperatura=ADC;
			}
		}

	

int main (void)
{
	/* Insert system clock initialization code here (sysclk_init()). */
	board_init();

	/* Insert application code here, after the board has been initialized. */
		
		DDRA=0xff;
		DDRB=0xff;
		DDRF=0x00;
		ADMUX=0b01000000;
		ADCSRA=0b10000111;
		
		DIDR0|=(1<<ADC0D);
		asm("LDI R25, 0x05");
		asm("STS 0x81, R25");
		asm("LDI R24, 0x01");
		asm("STS 0x6F, R24");
		asm("SEI");
		asm("LDI R23, 0xC2");
		asm("STS 0x85, R23");
		asm("LDI R22, 0xF7");
		asm("STS 0x84, R23");
		EscribirComando_LCD(0x01);
		_delay_ms(2);
		EscribirComando_LCD(0x30);
		_delay_us(40);
		while (1)
		{
			EscribirComando_LCD(0x80 + 0);
			_delay_us(40);
			print_LCD(array);
			_delay_us(40);
			EscribirComando_LCD(0x80 + 0x0B);
			_delay_us(40);
			Print_N(ValorTemperatura);
			EscribirComando_LCD(0x01);
			_delay_us(82);
		}

}

 

 

Thanks. 

 

 

Last Edited: Thu. Oct 12, 2017 - 07:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Learn how to post code properly. Use the button marked <> just above the space where you write your post text (not actually typing < and > into the text). No-one will bother to read flush-left code with all indentation lost.

 

I spot this, though:

 

CPORT_LCD|=(0<<RS_LCD);

That won't work. Shifting a zero any number of positions will still be zero. Bit-OR'ing a zero will do nothing. If you want to clear a bit, use

 

CPORT_LCD &= ~(1<<RS_LCD);

If you want to know why then get your C textbook out, or go over to the Tutorials forum here and find a tutorial on "Bit manipulation". It will explain everything.

 

(Also, see how nice and easy to read that line off code got when using a few spaces. Itmakesjustasmuchsensetousespaceswhenwritingcodeasitdoeswhenwritinganyothertext!)

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

Learn how to post code properly. Use the button marked <> just above the space where you write your post text (not actually typing < and > into the text). No-one will bother to read flush-left code with all indentation lost.

 

I spot this, though:

 

CPORT_LCD|=(0<<RS_LCD);

That won't work. Shifting a zero any number of positions will still be zero. Bit-OR'ing a zero will do nothing. If you want to clear a bit, use

 

CPORT_LCD &= ~(1<<RS_LCD);

If you want to know why then get your C textbook out, or go over to the Tutorials forum here and find a tutorial on "Bit manipulation". It will explain everything.

 

(Also, see how nice and easy to read that line off code got when using a few spaces. Itmakesjustasmuchsensetousespaceswhenwritingcodeasitdoeswhenwritinganyothertext!)

 

I did not see the <> excuse me for that, I change this lines, but the simulation still not working:

 

void EscribirComando_LCD(unsigned char cmd)
{
	DPORT_LCD=cmd;
	_delay_us(40);
	//CPORT_LCD|=(0<<RS_LCD);
	CPORT_LCD &= ~(1<<RS_LCD);
	CPORT_LCD|=(0<<RW_LCD);
	CPORT_LCD|=(1<<E_LCD);
	_delay_ms(2);
	CPORT_LCD &=~(1<<E_LCD);
	_delay_ms(1);
}
void EscribirDato_LCD(unsigned char dat)
{
	DPORT_LCD=dat;
	_delay_us(40);
	//CPORT_LCD|=(1<<RS_LCD);
	CPORT_LCD &= ~(1<<RS_LCD);
	CPORT_LCD|=(0<<RW_LCD);
	CPORT_LCD|=(1<<E_LCD);
	_delay_us(2);
	CPORT_LCD &=~(1<<E_LCD);
	_delay_us(1);
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Having just been told that 0<<x does nothing, you change one instance and leave the rest! Go through your code and fix it!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

volterius wrote:
the display is not working

You need to be more specific than that. What did you expect would happen? What actually happened?

 

Three notes:

 

1. If you have a LCD display problem then remove any code that does not have anything to do with that problem. I.e. throw out the reading of the temperature sensor and start by just trying to display a single constanct character, or a short constant string.

 

2. Since this is Proteus, rather than running on real AVR hardware, the answers here at AVRfreaks might be limited.

 

3. Please go back and Edit your first post to display the complete code properly.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

volterius wrote:
the display is not working

You need to be more specific than that. What did you expect would happen? What actually happened?

 

Three notes:

 

1. If you have a LCD display problem then remove any code that does not have anything to do with that problem. I.e. throw out the reading of the temperature sensor and start by just trying to display a single constanct character, or a short constant string.

 

2. Since this is Proteus, rather than running on real AVR hardware, the answers here at AVRfreaks might be limited.

 

3. Please go back and Edit your first post to display the complete code properly.

 

I fixed my first post.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

volterius wrote:
 
I fixed my first post.

No. You still have zero shifting.
.
MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

That's OK, MG. He is responding to my asking about getting the code properly displayed/presented. If the zero-shifting mistakes are edited out then the thread becomes hard to understand.

 

IMO, edits of posts should only be done for correcting formatting and spelling and for adding material. Anything else just adds confusion.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Thu. Oct 12, 2017 - 07:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looking at the code in the original post:

 

1. I see no initialization of the LCD controller

 

2. Why is inline assembler used? What does it do? Why not do it in C? Could the code be commented in some way to explain what it does?

 

And, again:

What did you expect would happen? What actually happened?

 

 

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

Looking at the code in the original post:

 

1. I see no initialization of the LCD controller

 

2. Why is inline assembler used? What does it do? Why not do it in C? Could the code be commented in some way to explain what it does?

 

And, again:

What did you expect would happen? What actually happened?

 

 

 

One of the requeriment of my Professor is realize this project with a integration of C and ASM, on the desplay should show a message ("Temperatura= ##").

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

volterius wrote:
I send the code to proteus to simulate

One of the key reasons - if not the key reason - for using a simulator is that it allows you to step through the code and observe what's happening.

 

So have you done that?

 

This should quickly identify where things are going wrong - ie, where what actually happens is not what you wanted to happen ...

 

 

#WhySimulate

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

Looking at the code in the original post:

 

1. I see no initialization of the LCD controller

 

2. Why is inline assembler used? What does it do? Why not do it in C? Could the code be commented in some way to explain what it does?

 

And, again:

What did you expect would happen? What actually happened?

 

 

 

#include <asf.h>
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>



#define DPORT_LCD PORTA
#define DDDR_LCD DDRA
#define CPORT_LCD PORTB
#define CDDR_LCD DDRB
#define RS_LCD 0
#define RW_LCD 1
#define E_LCD 2
void EscribirComando_LCD (unsigned char cmd);
void EscribirDato_LCD(unsigned char dat);
void print_LCD(char *string);
void Print_N(unsigned int a);

int16_t ValorTemperatura;
float Temperatura;
char array[] = {"Temperatura"}; //The TemperatureTemperature variable will be the variable where the temperature is operated. 
								//The use of int16_t is because the value obtained at the output of the ADC was initially stored in this variable. 
								//Since this value is 10 bits, it is required that the variable where it is saved is 16 bits, because if a one-byte variable is used, 
								//2 bits are lost and, therefore, the variable to be displayed would not be correct.
								//The variable Temperature is used later and is the variable which will be sent to port A from time to time. 
								//The variable array contains the message Temperature =. 
								//The choice of char type is done according to the implementation of the printing subroutine on the LCD.

void EscribirComando_LCD(unsigned char cmd)	//The first thing that is done is the sending of the command through port A. 
											//Then a delay of 40us is generated, so that the command sent does not arrive so fast to the LCD.
											//The following lines allow you to set or clear the respective pin of port B. 
											//The next delay was selected in 2 milliseconds since for the operation of the LCD, 
											//the Enable pin must work while sending the data or command.
											//After 2 milliseconds the Enable pin is set to zero.
{
	DPORT_LCD=cmd;
	_delay_us(40);
	CPORT_LCD &= ~(1<<RS_LCD);
	CPORT_LCD|=(0<<RW_LCD);
	CPORT_LCD|=(1<<E_LCD);
	_delay_ms(2);
	CPORT_LCD &=~(1<<E_LCD);
	_delay_ms(1);
}
void EscribirDato_LCD(unsigned char dat)	//This subroutine performs the same procedure that the routine performs to write a command,
											//except that port A will send the data to be displayed on the LCD.
											//The subroutine is now displayed to print the message stored in the variable array.
{
	DPORT_LCD=dat;
	_delay_us(40);
	CPORT_LCD &= ~(1<<RS_LCD);
	CPORT_LCD|=(0<<RW_LCD);
	CPORT_LCD|=(1<<E_LCD);
	_delay_us(2);
	CPORT_LCD &=~(1<<E_LCD);
	_delay_us(1);
}

void print_LCD(char *string)			//In this subroutine, a string is used as the input parameter.
										//The subroutine you do is the impression of the message and for this we use the asterisk that precedes the string. 
										//This asterisk functions as a pointer, so upon entering the message, 
										//the pointer selects the first letter of the message and sends it to the subroutine to send data. 
										//Just finish sending the first letter, the pointer increases and now selects the second letter and resends it to the subroutine of sending data. 
										//This process is repeated until the last letter of the message was sent.
{
	while(*string)
	{
		EscribirDato_LCD(*string++);
	}
}

void Print_N(unsigned int a)	//CONVERSIÓN A ASCII
								//The main function of the subroutine is to convert the data I get from the ADC to ASCII values corresponding to the measured temperature. 
								//For this case, only the tens and the units are displayed, therefore, only two lines of operation are performed.
								//For tens, the value delivered by the ADC is divided by 10 and the result of the division is summed with 0x30 hexadecimal. 
								//It is added with this value since from this value, the numbers can be represented in ASCII.
								//For the units, the ADC value is made a module, to obtain residue and to this residue is added 0x30h hexadecimal to convert it to ASCII.
{
	EscribirDato_LCD((a/10)+0x30);
	_delay_us(40);
	EscribirDato_LCD((a%10)+0x30);
}

ISR(TIMER1_OVF_vect)					//The first thing to do in the interruption is the recharge of the initial value of the timer, in order to make sure that the timer counts correctly.
										//The ADSC bit of the ADCSRA register corresponding to bit 6 of the register is now set to high. 
										//This activates the conversion of the analog variable being measured.
										//The next cycle will be performed while the ADSC bit is active and in the cycle the capture of the value delivered by the ADC is done. 
										//Thus, the value of the ADC is saved in ValueTemperature and then use this variable in the printing of the numbers corresponding to the temperature.
			{
			asm("LDI R23, 0xC2");
			asm("STS 0x85, R23");
			asm("LDI R22, 0xF7");
			asm("STS 0x84, R23");
			ADCSRA|=(1<<ADSC);
			while(ADCSRA&(1<<ADSC))
			{
				ValorTemperatura=ADC;
			}
		}

	

int main (void)
{
	/* Insert system clock initialization code here (sysclk_init()). */
	board_init();

	/* Insert application code here, after the board has been initialized. */
		
		DDRA=0xff;
		DDRB=0xff;
		DDRF=0x00;
		ADMUX=0b01000000;	// For the ADMUX register only register bit 6 is placed high, since the power supply voltage of the microcontroller is used as the reference of the inverter. 
							// With this bit activated it is necessary to place an external capacitor which will be connected to the pin of the Arduino AREF board. 
							// The four least significant bits of the register together with the ADCSRB register allow the channel selection of the converter to be used.
		ADCSRA=0b10000111;	// prescaler, 128 
		
		DIDR0|=(1<<ADC0D);	// The DIDR0 register allows to disable the digital inputs to the converter and another advantage,
							// when using it is that it allows the decrease in power consumption. 
							// Finally, in the assembler language lines, the configuration and initial value of the timer are loaded.
		asm("LDI R25, 0x05");
		asm("STS 0x81, R25");
		asm("LDI R24, 0x01");
		asm("STS 0x6F, R24");
		asm("SEI");
		asm("LDI R23, 0xC2");
		asm("STS 0x85, R23");
		asm("LDI R22, 0xF7");
		asm("STS 0x84, R23");
		EscribirComando_LCD(0x01);
		_delay_ms(2);
		EscribirComando_LCD(0x30);
		_delay_us(40);
		while (1)						// What is wanted in the infinite cycle is that the variable is displayed on the LCD constantly. 
										// To do this, it is started by sending the 0x80 command, which places the cursor in the first position of the LCD in row 1. 
										// After the delay of 40 micro seconds, the character printing subroutine is called and sent as input parameter array array. 
										// In this way, the subroutine will take each array letter and send it over the data port, allowing the message to be displayed. 
										// Another 40 micro-second delay passes and the 0x0B command is sent. When sending this command, 
										// the cursor is positioned so that it is positioned near the end of the message.
										// A delay of 40 micro seconds is placed and the Print_N subroutine is called using the variable TemperatureTime 
										// as the input parameter. Finally, the command 0x01 is sent to clear the previous information LCD, so that the display is not altered.
		{
			EscribirComando_LCD(0x80 + 0);
			_delay_us(40);
			print_LCD(array);
			_delay_us(40);
			EscribirComando_LCD(0x80 + 0x0B);
			_delay_us(40);
			Print_N(ValorTemperatura);
			EscribirComando_LCD(0x01);
			_delay_us(82);
		}

}

I have posted comments to the code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You still haven't fixed the obvious problems in the code! Your comments regarding the assembler only tell us you load the timer, but with what??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Again, what have you learned by stepping through the code in your simulator?

 

That is the way to see where the actual behaviour diverges from your expected behaviour ...

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

volterius wrote:
One of the requeriment of my Professor is realize this project with a integration of C and ASM,
That does not excuse doing things like:

			asm("LDI R23, 0xC2");
			asm("STS 0x85, R23");
			asm("LDI R22, 0xF7");
			asm("STS 0x84, R23");
			ADCSRA|=(1<<ADSC);

How do you know that the compiler is not already relying on the value "(1 << ADSC)" already being in R22 or R23 as it hits that Asm?

 

Your use of asm seems arbitrary and meaningless. I am sure this is not what your tutor was expecting. I imagine (s)he thought you might take one part of this code that is maybe a candidate for speed or size optimisation and code that one part in Asm as a separate unit. Not just blitz the entire C with arbitrary use of asm(...)!

 

Hint: read about and understand what a clobber list is

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

+1

 

The must be more to the requirement of assembler integration than just "do whatever".

 

I still have not seen any actual description on what is the actual observed behavior of the system. Again: "not working" is not a precise description. Does it blow up? Are there small animations of Mario speeding across the display? Is it playing music instead of displaying things?

 

Here's the bottom advice, volterius: Imagine for just a moment that you're a reader of this thread. As such you know nothing about the problem that 'volterius' presents apart from what he has posted here. Nothing.

 

You have to realize that we don't do magic here. We are simply analyzing what we are actually told. Sometimes we can infer things not spelled out, but don't count on that. Be clear, precise, to-the-point and complete in your descriptions. You might as well learn this now, because if you're going to work with electronics or software then you will need to be very good at problem description. It'c absolutely central to our occupation.

 

So, again: What is actually happening when you run the code?

 


 

Next, as you've been told repeatedly - things like

	CPORT_LCD|=(0<<RW_LCD);

don't work. If you want to clear a bit, then that is not the way to do it. You need to fix all occurrences of this bad pattern. And if you don't understand this, the do go over to the tutorial I recommended and read it. Ask if you don't understand. Again, if you're going to be anywhere near programming microcontrollers in your professional life, then this is absolutely required knowledge. Learn it. Understand it.

 

I also fond the attitude to fix just one instance of this bad pattern sloppy, and having the attitude that we shall point out every individual error you have and tell you how to fix it. We won't. We want to explain what you do wrong, and then you think and fix all such mistakes. Any other approach and attitude than that will simply be a way of asking us to waste time on trivial stuff because you can't be bothered. You'll quickly find yourself alone if doing that.

 


 

I often tell newcomers here this: You are in a competition for attention. The better your questions are formed, the better attention you will get. The better you react to our responses the better continued attention will be. OTOH, ill-formed (e.g. unclear) questions will get less attention. Not following up and thinking about answer will result in the same.

 

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am somewhat familiar with the AVR timers but I haven't written any code for them in a while so at this point I don't remember the register names or what the individual bits do. 

This is the same situation that you could be in a few years down the road when you may want to reuse this code.

 

Your code should be commented to explain the significance (or non-significance) of your magic numbers.  For example:

							// Finally, in the assembler language lines, the configuration and initial value of the timer are loaded.
		asm("LDI R25, 0x05");
		asm("STS 0x81, R25");
		asm("LDI R24, 0x01");
		asm("STS 0x6F, R24");
		asm("SEI");
		asm("LDI R23, 0xC2");
		asm("STS 0x85, R23");
		asm("LDI R22, 0xF7");
		asm("STS 0x84, R23");

The name of the Timer mentioned in your sole comment would be helpful .

What is the significance of 0x05, 0x01, 0xC2, and 0xF7?

Assuming that 0x81, 0x6F, 0x85, and 0x84 are timer registers wouldn't their names be helpful? 

Is it important to preserve the contents of registers R25, R24, R23, and R22 or could you have re-used the same register?

Is it important to enable the interrupts at this specific point in the sequence?

 

Of course if your ultimate goal is to become indispensable to the company that hires you then obfuscation (look it up) might be the answer, but right now you have to impress your Professor.

 

Don

 

EDIT: Are you sure that you want to put 0xC2 into 0x84 in that last step?

Last Edited: Fri. Oct 13, 2017 - 02:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I have figured out what 'not working' probably means in this situation.  It means the display is blank.

 

You can pretty much guarantee a blank display by pulling pin 3 of the LCD up to Vcc.  Perhaps you should look into the recommended techniques for powering that pin.

 

Don

 

 

 

 

Last Edited: Fri. Oct 13, 2017 - 02:59 AM