Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 14th September 2009, 01:47 AM   #31
Default

That chart doesn't look too good. If the voltage readings are correct for the blue chart it seems to be measuring the bottom of the vessel.

My 80cm Sharp sensor is currently soldered onto a robot and he might get a phobia if I go suspending him head first over a bucket of water...

I do have a few 30cm Sharp sensors spare, if fantabulous can't start to get some logical looking readings (and better labeled charts! ) I can fill a bucket with water and connect it up.
Mr RB is online now  
Old 14th September 2009, 10:02 AM   #32
Default

Quote:
Let's focus only on water for now -- wine is later
lol thats after I PASS....

Quote:
Do you have a cooking pot or aquarium
Pot Yes aquarium no.....My cat would eat the fish






Quote:
better labeled charts! )

Sorry i'll improve on that....too eager to post my data here





Ok im going to get my hands on that cardboard and pot when i get home.......and try again....(But tomorrow i have a practical on SQUIDS....and i get home at 16:30 from uni....uhmmmm i got to do my pre-prac lol or they will kick us out of the lab)....so do forgive me if i dont post any results today....
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.
fantabulous68 is offline  
Old 14th September 2009, 10:28 AM   #33
Default

Don't worry. Get what needs to be done, like studying for an exam, done first.

BTW, when is the IR/liquid-level project due? In one of your earliest posts, you indicated it was at least several weeks away.

John
jpanhalt is offline  
Old 14th September 2009, 12:57 PM   #34
Default

Quote:
have used 3 types of the Sharp GP2 sensors with no real stability problems but I had a good +5v supply and short wiring. Lots of people do report erratic readings, (probably noise?). Putting a 10uF cap right at the sensor power between +5v and ground is supposed to help, and also doing some low pass filtering of the analog voltage out would help especially if you have long wires between the sensor and the PIC.

the attached pic shows put a cap from the i/o line to ground.....


would it really make a difference in my readings that i placed the cap right at the sensor power between +5v and ground .....and not as shown in the pic???
Attached Thumbnails
infrared Liquid level detector-SharpGP2D12-irc.gif  
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.
fantabulous68 is offline  
Old 14th September 2009, 01:02 PM   #35
Default

Quote:
Originally Posted by fantabulous68 View Post
the attached pic shows put a cap from the i/o line to ground.....


would it really make a difference in my readings that i placed the cap right at the sensor power between +5v and ground .....and not as shown in the pic???
hi,
The caps on the wrong pins.!!
Should be +V and 0V common
__________________
Eric " Good enough is Perfect "
I will NOT answer PM's requesting technical help, please use the Forum
PIC tutorials: Nigel's www.winpicprog.co.uk/ Bill's: www.blueroomelectronics.com/
ericgibbs is offline  
Old 14th September 2009, 01:08 PM   #36
Default

Well...we have different phases....1, 2, 3(final)

first phse is done....
second phase is in october and so are exams...........

2nd phase is a full paper design.....
1. Report
2. Presentation
3. Breadboard version of the design must be working(OR will get zero for demonstration)



But Ill be over with exams in the 1st week then i can give all my attention to design
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.

Last edited by fantabulous68; 14th September 2009 at 01:16 PM.
fantabulous68 is offline  
Old 14th September 2009, 01:10 PM   #37
Default

Thanks Eric...lol( just checking)
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.
fantabulous68 is offline  
Old 16th September 2009, 06:34 PM   #38
Default

I tried programming the (pic16f690)GP2 sensor with MR RB code for the (pic18F) today and tried displaying just the distance to an object for now....


when i power up the LCD displays random numbers

now when i put a page & hold it steady....i get

EG.

010101010101010
010101010101010

i keep moving it away and...

020202020202020
020202020202020

030303030303030
030303030303030

till.....

090909090909090
090909090909090

THEN
000000000000000
000000000000000

and it repeats the sequence as i move away

010101010101010
010101010101010...............

and so on......

BTW


(it does not go to 111111111111111
111111111111111)

and 1212121212121212
1212121212121212 .....etc)


i just measured manually with a ruler to verify the values....its accurate

meaning....
the sensor has a min range of 10 cm......
so when the page is 10cm away it displays....

000000000000000
000000000000000

and if it 5cm away from the min range(ie. 15cm)

then it display:

050505050505050
050505050505050

and i measured this with a ruler and it gives 15cm

here is the code.....ONLY the Highlighted RED code is the parts dealing with ADC

Could some1 please tell me why its giving me such a long measured value??? Its the 1st time i tried using ADC



Code:
#include <pic.h>
#include "pic.h"
#include "delay.h"
#include "math.h" 
#include <stdio.h>
#include <stdlib.h>	//

void userMenu(char pos); //  
void FloatToStr(float , char[]); 
void DelayMs(unsigned char);
void lcd_cmd(unsigned char);
void lcd_data(unsigned char); 
void lcd_clear(void);
void lcd_puts(const char[]);
void lcd_goto_L1(void);
void lcd_goto_L2(void);
void lcd_cursor(unsigned char);
void lcd_init(void);
void init(void);
char WaitForInput(void);
unsigned char user_input(void);
void home_screen(void);
void EnterHeight(void);
void EnterScreen(void);
void ShowDigits(unsigned char val);
void calc_distance(void);
void main(void);


unsigned char cm2LCD;

unsigned char cmHigh, cmLow;

      

#define LCD_RS RC0		//LCD RS pin
#define LCD_EN RC1		//LCD EN pin
#define LCD_STROBE()	LCD_EN = 1; asm("nop"); asm("nop"); LCD_EN = 0

unsigned char cm10;		//
unsigned char cm;		//
unsigned int math;		// used for voltage calculations
unsigned char NumDec;
unsigned char NumSep[2];
   
unsigned char i,j,k;
//char temp[8];
//[/b]
unsigned char height=50;
unsigned char range;
unsigned char area;
unsigned char SensorPos=10;
//[/b] New Vars
char input_sw;

  
char mnuPOS;

unsigned char MyVal;
unsigned char MyValLCD[2];
unsigned char MyMaxVal;
unsigned char MyMinVal;
unsigned long bres;		// for bresenham 2-second timer system

unsigned char ;

#define HOME_SW RC2				//HOME switch	
#define INCREASE_SW RC3			//INCREASE switch
#define DECREASE_SW RC4			//DECREASE switch
#define ENTERSETTINGS_SW RA4	//ENTERSETTINGS switch



///////////////////////CONVERT FLOAT TO STRING///////////////////
// This function was taken from the CAVR library. It was modified slightly
// to suit our design.
void FloatToStr(float n, char str[])
{
float scale;
unsigned char d,f;
f=0;i=0;
if (n<0.0) {n=-n; str[f]='-'; f++;};
n=n+0.005;
scale=1.0;
while (n>=scale) {scale=scale*10.0; ++i;};
if (i==0) {str[f]='0'; f++;}
else
while (i--)
	  {
      scale=floor(0.5+scale/10.0);
      d=(unsigned char) (n/scale);
      str[f]=d+'0';
      n=n-scale*d;
	  f++;
      };

str[f]='.';
f++;
for (j=0;j<=1;j++) //2 decimal points
      {
      n=n*10.0;
      d=(unsigned char) n;
      str[f]=d+'0';
      n=n-d;
	  f++;
	  };
str[f]='\0';
}
///////////////////END CONVERT FLOAT TO STRING///////////////////

/////////////////////////////DELAY///////////////////////////////
void DelayMs(unsigned char cnt)
{
#if	XTAL_FREQ <= 2MHZ
	do {
		DelayUs(996);
	} while(--cnt);
#endif

#if    XTAL_FREQ > 2MHZ	
	unsigned char	p;
	do {
		p = 4;
		do { 
			DelayUs(250);
		} while(--p);  
	} while(--cnt);
#endif
}

void DelayS(unsigned char cnt)
{
	for (j=0; j<(cnt*10); j++)
		DelayMs(100);
}
///////////////////////////DELAY END/////////////////////////////

//////////////////////////////LCD SETUP//////////////////////////
/* send a command to the LCD */
void lcd_cmd(unsigned char c)
{
	DelayMs(2); //wait for LCD to be ready shorter delay 
	LCD_RS = 0;	 //write instruction
	PORTB = (c & 0xF0); //load upper nibble on LCD data lines
	LCD_STROBE(); //send instruction to LCD
	PORTB = ((c << 4) & 0xF0); //load upper nibble on LCD data lines
	LCD_STROBE(); //send instruction to LCD   	
}

/* send data to the LCD */
void lcd_data(unsigned char c)
{
	DelayMs(2); //wait for LCD to be ready shorter delay 
	PORTB = 0x00;
	LCD_RS = 1; //write data
    PORTB |= (c & 0xF0); //load upper nibble on LCD data lines     
	LCD_STROBE(); //send instruction to LCD
	PORTB &= 0x00; //load upper nibble on LCD data lines
	PORTB |= ( (c << 4) & 0xF0); 
	LCD_STROBE(); //send instruction to LCD
}

/*Clear the LCD*/
void lcd_clear(void)
{
	lcd_cmd(0x01); //command to clear LCD
}

/*write a string of chars to the LCD*/
void lcd_puts(const char s[])
{
	j = -1;
	while(s[++j]!=('\0')) // send characters until null character reached
		lcd_data(s[j]);
}

/*go to beginning of line 1*/
void lcd_goto_L1(void)
{
	lcd_cmd(0b10000000); // command to go to line 1
}

/*go to beginning of line 2*/
void lcd_goto_L2(void)
{
	lcd_cmd(0b11000000); // command to go to line 2
}

/*move cursor "x" positions to the right*/
void lcd_cursor(unsigned char x)
{
	lcd_cmd(((x)&0x7F)|0x80); 
}

/*initialise the LCD - put into 4 bit mode*/
void lcd_init(void)
{
	LCD_RS = 0;	
	LCD_EN = 0;
	DelayMs(20); //wait for LCD startup
	lcd_cmd(0x02);
 
	lcd_cmd(0x28);	// 4-bit mode
	lcd_cmd(0x08);	// display off
	lcd_cmd(0x01);	// clear display
	lcd_cmd(0x0C);	// disp. on, cursor off, cursor blink off
	lcd_cmd(0x06);	// entry mode
	lcd_cmd(0x80);  // initialise DDRAM address to zero
}
//////////////////////////LCD SETUP END//////////////////////////
    

void init(void)
{   
	
	// setup the PIC 16f690
	OSCCON = 0x72;      	// internal osc, 8MHz
	PORTA = 0;
	TRISA = 0b10010010; 	// RA7 high imp, RA3 is serial out, RA4 button input 


	
 	PORTB = 0;          	// PORTB not used
    WPUB = 1;				// PORTB pullups ON		
    RABPU = 0;


    /* Init ADC */
    ADCON0 = 0b10000101;	// bit 7 right justify,analogue channel select bits bits5-2  0001=AN1,ADC ON, RA1 is ADC input
	ADCON1 = 0b00100000;	//bits6-4  fosc/32
    ADON=1;	                // turn on the A2D conversion module

	
	ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
	ANSELH=0x00;

        T1CON = 0b00010001;     // TMR1 is ON, 1:2 prescale, =1MHz
	T2CON = 0b00000101;     // TMR2 is ON, 1:4 prescale, =1MHz



	MyVal = 0; //initializn these variables here
	MyMinVal = 0;
	MyMaxVal = 99;
  
	TRISB=0x00; 
	TRISC=0xFC;
    
	lcd_init(); //call LCD initialisation
}

char WaitForInput(void){
char done;
char temp;
done = 0;

while(!done){
    if(!ENTERSETTINGS_SW){
        temp = 1;
        done = 0xff;
    }

    if(!HOME_SW){
        temp = 2;
        done = 0xff;
    }

    if(!INCREASE_SW){
        temp = 3;
        done = 0xff;
    }

    if(!DECREASE_SW){
        temp = 4;
        done = 0xff;
    }
}//end of while
    DelayMs(150);    //debounce
    return temp;
}//
void userMenu(char pos){
	lcd_clear();
	lcd_goto_L1();

	switch(pos){
		case 0:
			lcd_puts("    HEIGHT    ");
			break;		
		case 1:
			lcd_puts("    RANGE     ");
			break;		
		case 2:
			lcd_puts(" SURFACE AREA ");
			break;		
	}

	lcd_goto_L2();
	lcd_puts("Press Up/Down"); //home screen message (line 2)
}
// New Menu System
void EnterHeight(void){
	lcd_clear();
	lcd_goto_L1();
	lcd_puts(" ENTER HEIGHT ");
	lcd_goto_L2();
	lcd_puts("Press Up/Down"); //home screen message (line 2)
}

void EnterScreen(void){
	lcd_clear();
	lcd_goto_L1();
	lcd_puts(" [cm] ");
}

void ShowDigits(unsigned char val){

    MyValLCD[0] = val /10;    //returns the quotient (if temp = 35 the result is 3)
    MyValLCD[1] = val % 10; 	//Returns remainder   (if temp = 35 the result is 5)

	MyValLCD[0] += 0x30;	//to ASCII
	MyValLCD[1] += 0x30;	//to ASCII

	EnterScreen();
	lcd_goto_L2();
	lcd_data(MyValLCD[0]);	//to LCD
	lcd_data(MyValLCD[1]);  //to LCD
}

  
void calc_distance(void)
{
	// from the transeiver datasheet the analog voltage is
	// the inverse of distance, so distance can be calculated
	// d = (1 / volts) then just scaled to suit the transeiver

	// load ADC value in 16bit math var
	math = ADRESH;
	math = (math * 256);
	math += ADRESL;

	// now invert it; (1 / volts) use (6050 / volts) for scaling
	math = (6050 / math);
	if(math >= 2) math -=2;		// fix linear error (-2)
	if(math > 99) math = 99;	// max limit at 99cm

	// convert from 0-99 to 2 decimal digits, 0-99cm
	cm10=0;
	while(math >= 10)
	{
		cm10++;
		math -= 10;
	}
	cm = math;
}
 //
unsigned char user_input(void)		//This will return what we want
{
	char done = 0;

	MyVal = 0;			//Start on 0
	while(done == 0){
   	  input_sw = WaitForInput();
		
      switch(input_sw){
		case 1:
			done = 0xff; 			//This tells us the user finished entering
			lcd_goto_L1();
			lcd_puts("     Done!      "); //home screen message (line 1)
			break;
      	case 3:
			if(MyVal < MyMaxVal)
      			MyVal++;
			EnterScreen();
			ShowDigits(MyVal);
			break;
      	case 4:
			if(MyVal > MyMinVal)
      			MyVal--;
			EnterScreen();
			ShowDigits(MyVal);
        	break;
		default: 
			break;
      }
	  
	}
	DelayS(1);
	return MyVal;
}

void home_screen(void){
	mnuPOS = 0;
	lcd_clear();
	lcd_goto_L1();
	lcd_puts("INFRARED LIQUID"); //home screen message (line 1)
	lcd_goto_L2();
	lcd_puts("LEVEL DETECTOR"); //home screen message (line 2)
  
	input_sw = 0;			//Reset the value

	while(input_sw != 1)  	//Wait until enter is pressed
		input_sw = WaitForInput();

	userMenu(0);
	DelayMs(2);				//shorter delay 
    height = user_input();	//The HEIGHT var will have the myVal

	userMenu(1);
	DelayMs(2);				//shorter delay 
    range = user_input();	//The HEIGHT var will have the myVal

	userMenu(2);
	DelayMs(2);				//shorter delay 
    area = user_input();	//The HEIGHT var will have the myVal
/*
"enter height"
call enter/settings (which is now user input function in new code)
height=MyVal

"enter range"
call user_input
range=MyVal

"enter surface area"
call user_input
area=MyVal
*/
}
  
//*********************************************************
/*  Junebug_Serial4.c    RomanBlack.com 19th July 2009.

    uses "zero error 1 second timer"
	system to generate a 2 second interval, then every
	2 seconds it reads an analog voltage from a
	Sharp GP2 distance sensor and converts it to decimal
	distance, then sends that data to a LCD

	Code for MikroC, config handled by MikroC compiler;
	_INTI02_OSC_1H
	_WDT_OFF_2H
	-MCLRE_ON_3H
	_LVP_OFF_4L
	_PWRT_ON_2L
*/
//*********************************************************

void main(void)
{  
    init();	// initialise I/O ports, LCD
    while(1){
 	//	home_screen();

 	// wait for 2 seconds, uses TMR1 free running at 1Mhz
   	while(!TMR1IF)  // wait for TMR1 overflow
	TMR1IF = 0; 	// clear overflow flag

	bres += 65536;			// add 65536uS to bres value
	if(bres >= 2000000)		// if reached 2 seconds!
	 {
    	bres -= 2000000;	// subtract 2 seconds, keep error
		  	
		// read the ADC voltage RA1 (Sharp GP2 sensor)
		GODONE=1;	// initiate conversion on the channel 0
		while(GODONE) continue;  // Wait convertion done
		calc_distance();		// convert ADC value to distance

//CM is higher than 09 so spilt the variable CM into 2 
cmHigh = ( ( cm >> 4 ) & 0x0F ) + 0x30;
cmLow = ( cm & 0x0F ) + 0x30;

lcd_data(cmHigh);
lcd_data(cmLow);



      				         
       }  
            
 
   } 
}
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.

Last edited by fantabulous68; 16th September 2009 at 06:36 PM.
fantabulous68 is offline  
Old 17th September 2009, 01:46 AM   #39
Default

Its not giving you a long value lol its looping. Try Clearing the LCD before the loop like:

Code:
void main(void)
{  
    init();	// initialise I/O ports, LCD
    while(1){
 	//	home_screen();

 	// wait for 2 seconds, uses TMR1 free running at 1Mhz
   	while(!TMR1IF)  // wait for TMR1 overflow
	TMR1IF = 0; 	// clear overflow flag

	bres += 65536;			// add 65536uS to bres value
	if(bres >= 2000000)		// if reached 2 seconds!
	 {
    	bres -= 2000000;	// subtract 2 seconds, keep error
		  	
		// read the ADC voltage RA1 (Sharp GP2 sensor)
		GODONE=1;	// initiate conversion on the channel 0
		while(GODONE) continue;  // Wait convertion done
		calc_distance();		// convert ADC value to distance

	//CM is higher than 09 so spilt the variable CM into 2 
		cmHigh = ( ( cm >> 4 ) & 0x0F ) + 0x30;
		cmLow = ( cm & 0x0F ) + 0x30;//
		lcd_clear();	//ADDED THIS
		lcd_data(cmHigh);
		lcd_data(cmLow);
    				         
     }  //END OF IF
   }//END OF WHILE(1) 
}//END OF MAIN
AtomSoft is offline  
Old 17th September 2009, 02:00 AM   #40
Default

Sorry i made a few mistakes in my PM code:

Code:
void main(void)
{  
  init();		//initialise I/O ports, LCD
  while(1){
    //home_screen();

    //wait for 2 seconds, uses TMR1 free running at 1Mhz
    while(!TMR1IF);             // wait for TMR1 overflow  forgot to place ; here
    TMR1IF = 0; 		// clear overflow flag

    bres += 65536;		// add 65536uS to bres value
    if(bres >= 2000000)		// if reached 2 seconds!
    {
      bres -= 2000000;		// subtract 2 seconds, keep error

    // read the ADC voltage RA1 (Sharp GP2 sensor)
      GODONE=1;		    // initiate conversion on the channel 0
      while(GODONE) continue; // Wait convertion done
      calc_distance();	    // convert ADC value to distance

    //CM is higher than 09 so spilt the variable CM into 2 //
      cmHigh = ( cm / 10 ) + '0'; // My Mistake this will get you true
      cmLow = ( cm % 10 ) + '0';  // values
      lcd_clear();                // ADDED THIS
      lcd_data(cmHigh);
      lcd_data(cmLow);
     }//END OF IF
   }//END OF WHILE(1)
}//END OF MAIN

Last edited by AtomSoft; 17th September 2009 at 02:09 AM.
AtomSoft is offline  
Old 17th September 2009, 03:17 AM   #41
Default

The calc_distance() routine you are using already decodes the measurement 00-99 into 2 values;
cm10 (this is the TENS digit)
cm (this is the UNITS digit)

Then later on in oyur code in the main loop you are doign this;
Code:
//CM is higher than 09 so spilt the variable CM into 2 
cmHigh = ( ( cm >> 4 ) & 0x0F ) + 0x30;
cmLow = ( cm & 0x0F ) + 0x30;
which is bad because it has already been done in the calc_distance() function.

All you need to do to display the distance in cm is this;
Code:
lcd_data(cm10 + '0');
lcd_data(cm + '0');
Which will display the 2 decimal digits (0-9) as 2 ascii digits ('0'-'9')
Mr RB is online now  
Old 17th September 2009, 09:13 AM   #42
Default

CoooooooooooooooooooooooooooooooooooooooooooL..... .......................



its working hehehehehehehe.......

Thanx Guys....

lol now I'll have something to demo to my lecturer tomorrow...
he wanted values on the LCD even if it was wrong lol (but he will be getting the right values)


for objects<8cm away....the sensor gives crazy readings...otherwise its pretty accurate.....

so the range is about [8-80]


Ok this feels good...-its far from over though
still got to integrate it with the other code to give the level of the liquid...
and then i got to TWEAK IT(or PIMP MY RIDE as you'll would say)
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.

Last edited by fantabulous68; 17th September 2009 at 09:15 AM.
fantabulous68 is offline  
Old 17th September 2009, 12:27 PM   #43
Default

Mr.RB good find. I even forgot about that calc routine. Even in red i didnt spot it
AtomSoft is offline  
Old 18th September 2009, 04:43 AM   #44
Default

Well I did have the unfair advantage of having seen it somewhere before...
Mr RB is online now  
Old 18th September 2009, 02:35 PM   #45
Default

i want to calculate the level of the liquid.................

*At the moment the sensor code gives the distance to the surface of the liquid.....

*the code allows the user to enter the "height" of container .....

So the liquid level=height of container-distance to surface of liquid

Now in the calc_distance function...the distance to the surface of the liquid is split into two digits..... which are displayed on a LCD.

ie. cm(units) & cm10(tens)


So do i need to send these 2 SPLIT digits from the calc_distance function to a NEW function that would combine them so that i can SUBTRACT it from the height of the container????


IS there a better solution?
__________________
Learn without thinking begets ignorance. Think without learning is dangerous.

Last edited by fantabulous68; 18th September 2009 at 02:41 PM.
fantabulous68 is offline  
Reply

Tags
detectorsharpgp2d12, infrared, level, liquid

Thread Tools
Display Modes


Similar
Title Starter Forum Replies Latest
Liquid level sensing Bizzarri Electronic Projects Design/Ideas/Reviews 17 11th September 2008 01:27 PM
Liquid Level Measurement/2 Joe McGivern General Electronics Chat 17 15th May 2007 09:12 AM
Liquid level measurement. Joe McGivern Chit-Chat 8 3rd May 2007 01:03 PM
Liquid Level detector and indicator Langat Electronic Projects Design/Ideas/Reviews 4 27th September 2006 03:13 PM
About and Liquid level display mishranirmal Electronic Projects Design/Ideas/Reviews 1 13th September 2003 03:48 AM



All times are GMT. The time now is 05:34 AM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker