LCD getting messy as soon as sensor is connected to the analog pin

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

Hello all,

 

I have wrote a code for sensor reading and displaying it on LCD for atmega328p. The soil I am using is soil moisture sensor. The problem I am facing is when I turn on the power the LCD is displaying random value as I have not connected sensor yet but as soon as I connect sensor to the A0 pin of the atmega328p the LCD starts to display black boxes in first line.

 

In order to test whether the ADC is working properly or not I connected A0 of the controller to the ground and the LCD showed 100% as I coded and 00% when I connected A0 to Vcc.

 

What can be the problem?

 

#include <avr/io.h>
#include <util/delay.h>

#define LCD_PRT PORTB
#define LCD_DDR DDRB
#define LCD_PIN PINB
#define LCD_RS 4
#define LCD_EN 5
#define LED PORTD
#define ADC PORTC
#define ACTU1 6
#define ACTU2 7

unsigned int adc;
unsigned char on_time;

//delay functions
void delay_us();
void delay_ms();

//lcd functions 
void lcd_Command(unsigned char );
void lcd_Data(unsigned char );
void lcd_inti();
void lcd_gotoxy(unsigned char , unsigned char );
void lcd_print(char *);
unsigned int lcd_interger(unsigned int);

//adc functions
void adc_inti();
void adc_run();

//i/o initialization
void io_init();

//actuator
void actu(unsigned int);

int main(void)
{	
	io_init();
	lcd_inti();
	lcd_gotoxy(1,1);
	lcd_print("Probe 1");
	lcd_gotoxy(1,2);
	lcd_print("Moisture");
	adc_inti();
	lcd_gotoxy(13,2);
	lcd_Data('%');
	LED =0x00;
	while(1)
	{
		adc_run();
		on_time=lcd_interger(adc);
		_delay_ms(10);
	}
}

void delay_us()
{
	_delay_us(100);
}
void delay_ms()
{
	_delay_ms(2);
}

void lcd_Command(unsigned char cmnd)
{
	LCD_PRT = (LCD_PRT & 0xf0) | ((cmnd>>4) & 0x0F);
	LCD_PRT &= ~(1<<LCD_RS);
	LCD_PRT |= (1<<LCD_EN);
	delay_us();
	LCD_PRT &= ~(1<<LCD_EN);
	
	LCD_PRT = (LCD_PRT & 0xf0) | (cmnd & 0x0f);
	LCD_PRT |= (1<<LCD_EN);
	delay_us();
	LCD_PRT &= ~(1<<LCD_EN);
}
void lcd_Data(unsigned char data)
{
	LCD_PRT = (LCD_PRT & 0xf0) | ((data>>4) & 0x0f);
	LCD_PRT |= (1<<LCD_RS);
	LCD_PRT |= (1<<LCD_EN);
	delay_us();
	LCD_PRT &= ~(1<<LCD_EN);
	
	LCD_PRT = (LCD_PRT & 0xf0) | (data & 0x0f);
	LCD_PRT |= (1<<LCD_EN);
	delay_us();
	LCD_PRT &= ~(1<<LCD_EN);
}
void lcd_inti()
{
	LCD_DDR = 0xff;
	LCD_PRT &= ~(1<<LCD_EN);
	delay_ms;
	lcd_Command(0x33);
	delay_us();
	lcd_Command(0x32);
	delay_us();
	lcd_Command(0x28);
	delay_us();
	lcd_Command(0x0e);
	delay_us();
	lcd_Command(0x01);
	delay_ms();
	lcd_Command(0x06);
	delay_us();
}
void lcd_gotoxy(unsigned char x, unsigned char y)
{
unsigned char firstCharAdr[] = {0x80, 0xc0,0x94, 0xd4};
lcd_Command(firstCharAdr[y-1]+x-1);
delay_us();
}
void lcd_print(char *str)
{
	unsigned char i=0;
	while(str[i]!=0)
	{
		lcd_Data(str[i]);
		i++;
	}
}
unsigned int lcd_interger(unsigned int x)
{
	unsigned int shifter,temp,temp1;
	float prcntg;
	shifter = temp = x;
	temp = (temp>>8) & 0x00ff;
	temp = (shifter<<8 & 0xff00) | temp;
	prcntg = temp;
	prcntg = prcntg/255;
	prcntg = prcntg*25;
	temp = 100-prcntg;
	shifter = temp;
	temp1=temp;
	for(int i=2;i>=0;i--)
	{
		lcd_gotoxy(10+i,2);
		temp = shifter%10;
		shifter = shifter/10;
		lcd_Data('0'+temp);
	}
	//actu(temp);
	return(temp1);
}

void adc_inti()
{
	ADCSRA = 0x87;
	ADMUX = 0x00;
}
void adc_run()
{
	ADCSRA |= (1<<ADSC);
	while((ADCSRA&(1<<ADIF))==0);
	adc = ADCL;
	adc = adc<<8;
	adc = (adc)|(ADCH);
}


void io_init()
{
	LED = 0xff;
	ADC = 0x00;
}

void actu(unsigned int level)
{
		if (level<=30)
		{
			PORTD=0xff;
		}
		else
		{
			PORTD=0x00;
		}

}

And I connected Aref and Avcc directly to the Vcc terminal.

 

The circuit as below and their is no problem in simulation, I'm getting trouble only on hardware.

 

This topic has a solution.
Last Edited: Mon. Jun 12, 2017 - 04:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do not connect Aref to Vcc. There should be a register controlled switch to do that internally. The only thing you should connect to Aref is (1) an external reference or (2) a capacitor.

 

I do not see any bypass caps on your schematic. There should be at least on on Vcc and even better, one on AVcc.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim this seems to be another thread of simulator real life except that it doesn't simulate real life.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

What power supply is being used? My guess is an earth loop is created via the power supply via the via back throughbthe sensor to earth (as in REAL earth)

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

John said it right, Proteus didn't noticed that I didn't set the DDR for input/output and by mistake I used PORT registers for that purpose.