Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

urgent help in Code!!!!

Status
Not open for further replies.
engkhlaif said:
ok i will try
i want to ask also is that right to write ADCON1=14 as i just need A0 to be analog input as i think if i write ADCON1=0 i set all of them analog and i just want to use A0 !!!!!]

ADCON1 = 0x0E will make only RA0 analog, try to avoid decimal when setting SFRs. Use binary or hex.
ADCON1 also sets the conversion speed and left or right justification. Make sure it matches your project.
 
Last edited:
blueroomelectronics said:
ADCON1 = 0x0E will make only RA0 analog, try to avoid decimal when setting SFRs. Use binary or hex.
ADCON1 also sets the conversion speed and left or right justification. Make sure it matches your project.
what do u mean by SFR !!!
any way also iam just want to set pin A0 analog input and is that right to assign just pin A0 analog and what about the else pins of PORTA!!!
 
engkhlaif said:
what do u mean by SFR !!!
SFR = Special Function Register

Like TRISA, TRISB, PORTA, PORTB. All those kind of registers are SFRs.

also iam just want to set pin A0 analog input and is that right to assign just pin A0 analog and what about the else pins of PORTA!!!
You can set just one pin analog and the rest digital if you want. No problem.

The reason Bill was suggesting hex or binary for setting SFRs is because it's just plain easier and more clear, and therefore less prone to errors.

For setting/clearing individual bits, 14 decimal gives me not much clue as to which bits I'm changing unless I figure it out on paper.

0x0e hex I can immediately tell the top nibble is all 0's and the bottom nibble has the top 3 bits set and bit-0 clear.

Even better is 0b00001110 binary. You can tell at a glance which bits are set.
 
Last edited:
futz said:
SFR = Special Function Register

Like TRISA, TRISB, PORTA, PORTB. All those kind of registers are SFRs.


You can set just one pin analog and the rest digital if you want. No problem.

The reason Bill was suggesting hex or binary for setting SFRs is because it's just plain easier and more clear, and therefore less prone to errors.

For setting/clearing individual bits, 14 decimal gives me not much clue as to which bits I'm changing unless I figure it out on paper.

0x0e hex I can immediately tell the top nibble is all 0's and the bottom nibble has the top 3 bits set and bit-0 clear.

Even better is 0b00001110 binary. You can tell at a glance which bits are set.
thanx for that commecnts
but what i want to say is that if u see my code when i compile it using the MBLAP and download the HEX file i get the reading whith out using any power to the PIC so why is that and what is that reading!!!!!!!!!!
 
engkhlaif said:
but what i want to say is that if u see my code when i compile it using the MBLAP and download the HEX file i get the reading whith out using any power to the PIC so why is that and what is that reading!!!!!!!!!!
Huh? English is not your first language, is it? :) Do you mean that your target circuit is being powered by the programmer, and you didn't expect that? Many (most?) PIC programmers I've used are able to power target boards/circuits.
 
futz said:
Huh? English is not your first language, is it? :) Do you mean that your target circuit is being powered by the programmer, and you didn't expect that? Many (most?) PIC programmers I've used are able to power target boards/circuits.
first yes it is not my main language!!:D
seconde what i want to say is that befor i connect my the power to the sensor ( give the sensor 5 volt) i see and output on the lcd "A2D=10670 vlots"
i dont know why is that number appear to me and how it find it and display it on the LCD
the LCD is connected to another power supply and the sensor has its own supply
so what is the reason
the is my code again
Code:
#include <pic.h>
#include "lcd.h"
#include "delay.h"
#include<stdio.h>

// Setup the configuration word for use with ICD2
__CONFIG(DEBUGEN & WDTDIS & LVPDIS);


void init_a2d(void)
{
	ADCON0=0;	// select Fosc/2
	ADCON1=0;	// select left justify result. A/D port configuration 0
	ADON=1;		// turn on the A2D conversion module
}
unsigned char read_a2d(unsigned char channel)
{
	channel&=0x07;	// truncate channel to 3 bits
	ADCON0&=0xC5;	// clear current channel select
	ADCON0|=(channel<<3);	// apply the new channel select
	ADGO=1;	// initiate conversion on the selected channel
	while(ADGO)continue;
	return(ADRESH);	// return 8 MSB of the result
}



void main(void)
{
   unsigned char outString[20];
   float voltage;
   unsigned char x;
    init_a2d();	// initialise the A2D module
	GIE=0;

TRISE = 0;
TRISD = 0;
TRISB = 0;
TRISA  = 0x01;;
ADCON1 = 14;
RE2 = 0;
DelayMs(500);
lcd_init();

while(1) {
      lcd_clear();
      lcd_goto(0);
      lcd_puts("Damn!");
      x=read_a2d(0);      
      // lcd_goto(40);
      voltage=(x/255.0)*(5.0);   
     sprintf(outString,"A2D = %d volts",voltage);    
      lcd_puts(outString);
 
engkhlaif said:
what i want to say is that befor i connect my the power to the sensor ( give the sensor 5 volt) i see and output on the lcd "A2D=10670 vlots"
i dont know why is that number appear to me and how it find it and display it on the LCD
When there is nothing connected to the AD pin mine displays 70. When the GP2D12 is connected I get anywhere from around 10 or 11 up to 125 or so, depending on target distance from the sensor. These are all decimal numbers. I'm not converting and displaying voltage - I'm just converting the value from ADRESH to ASCII and putting it on the LCD.

Like I and Nigel have been saying to you for days, test it with hard coded numbers and make sure it works properly. You should ensure that the display correctly displays the number it's going to get from the sensor later. Then connect the sensor.

the LCD is connected to another power supply and the sensor has its own supply so what is the reason
Hmm... One thing you should be very sure you do is to connect the grounds of both power supplies together. If you don't, this thing will never work.
 
futz said:
When there is nothing connected to the AD pin mine displays 70. When the GP2D12 is connected I get anywhere from around 10 or 11 up to 125 or so, depending on target distance from the sensor. These are all decimal numbers. I'm not converting and displaying voltage - I'm just converting the value from ADRESH to ASCII and putting it on the LCD.

Hmm... One thing you should be very sure you do is to connect the grounds of both power supplies together. If you don't, this thing will never work.

you mean that i have to get the value that is stored in the ADRESH and then convert it into ASCII and then dispkay it into LCD!!!
what is this value refers to !!!:confused:
note: iam a student and i need this help in my graduation project !!!:)
 
engkhlaif said:
you mean that i have to get the value that is stored in the ADRESH and then convert it into ASCII and then dispkay it into LCD!!!
what is this value refers to !!!:confused:
Well... ya! Didn't you know that? I'd have thought that much would be obvious. :D :D You're using (I guess) library functions to convert though, like this:
Code:
    sprintf(outString,"A2D = %d volts",voltage);    
      lcd_puts(outString);
I wrote my own.

Anyway, you have to give that piece of code some test numbers. Never mind ADRESH for now - it only returns a value from 0 to 255 (and from that sensor more like 10 to 125). Plug some numbers like that into the code and see what the LCD displays. If it's totally wrong you'll need to fix the problem. THEN plug in the sensor and change the code to read it instead of your test values.
 
Last edited:
OK, we're getting somewhere. I took a piece of your code and put it in mine to test. Instead of using my own hex to ascii converter I used sprintf as you did, like this:
Code:
	while(1)
	{
		a = read_a2d();
		lcd_line1();
		sprintf(number,"A2D = %d volts",a);
//		lcd_16number(a);
		lcd_string(number);
		delay();
	}
and it works just fine. It's not converting to voltage first of course. That's the next part of the test...
 
Now I'm running into the problem that you're likely having. Using the following test
Code:
char number[] = "                ";
	float temp;
		temp=179.34;
		sprintf(number,"%f volts",temp);
just doesn't work. It should. But it doesn't. Still trying things...
 
futz said:
OK, we're getting somewhere. I took a piece of your code and put it in mine to test. Instead of using my own hex to ascii converter I used sprintf as you did, like this:
Code:
	while(1)
	{
		a = read_a2d();
		lcd_line1();
		sprintf(number,"A2D = %d volts",a);
//		lcd_16number(a);
		lcd_string(number);
		delay();
	}
and it works just fine. It's not converting to voltage first of course. That's the next part of the test...

dear, firts of all what do u mean it works fine !!!! what is the reslut you get!! as i think it will display the message A2D= 17797 volts!! is not that !!!
 
engkhlaif said:
dear, firts of all what do u mean it works fine !!!! what is the reslut you get!! as i think it will display the message A2D= 17797 volts!! is not that !!!
No no! Look again. I have it displaying the contents of ADRESH directly, as decimal, with no calculation for voltage and no floats involved. That part works perfect.

The problem comes when I do the voltage calculation and try to sprintf the resulting float. It breaks completely on my compiler. Just displays an f.

After much digging around I'm finding that most microcontroller compilers disable floats in printf and sprintf to control code size. There are command-line options to enable that part of the library, but I haven't been able to find the option for the compiler I'm using yet.
 
futz said:
After much digging around I'm finding that most microcontroller compilers disable floats in printf and sprintf to control code size. There are command-line options to enable that part of the library, but I haven't been able to find the option for the compiler I'm using yet.
I found the command-line option for PICC Lite and added it. Now, much to my disgust, I find that they don't give those libs away with the demo version. So I can't printf/sprintf floats at all.

EDIT: I guess there would be no point in supplying those libs, as the code would always go over the max demo program and RAM size anyway if you used them.

It's likely that you're having a similar problem.
 
Last edited:
Here's a question/answer that describes precisely the problem I'm having with PICC Lite. The solution may be in the answer there. I'll try it.

EDIT: **broken link removed**

EDIT: No go so far. Time for dinner.

Hahahaha! :D
The sprintf function is evil on the PIC, unless you have oodles and oodles of code space to burn.

Your best bet is usually to multiply the float by a suitable scaling factor and convert to an integer. For example, if you have a four digit display that's supposed to show 0.000 to 9.999, multiply your float by 2000, convert to an integer, add 1, and divide by two (this is more efficient than adding 0.5 before converting to an integer and multiplying by 1000).
 
Last edited:
I just had a play with the HiTech C compiler and tried this,
Code:
    Voltage=137;            //2.68V
    Voltage*=5;
    Fract=(int)(((Voltage*100)/255)%100);
    sprintf(number,"A2D = %d.%d volts",Voltage/255,Fract);
I got 2.11 in the buffer!!

I then tried,
Code:
    Voltage=137;            //2.68V
    Voltage*=5;             //=685
    Fract=Voltage*100;      //=2964
    Fract/=255;
    Fract=Fract%100;
    sprintf(number,"A2D = %d.%d volts",Voltage/255,Fract);
The values are what was obtained by single stepping in the simulator. How on earth is 685*100 equal to 2964?

Mike.
 
Ahaa!!! Microchip has an App Note on this - AN670. Port that to C and we may have something useful. :D

EDIT: For a "very bad, bad" :p "urgent" post, this one has turned out to be quite interesting.
 
Last edited:
Here is a rather ugly solution,
Code:
int Voltage;
long Fract;
char Fract1,Fract2;
char number[] = "                ";
    Voltage=104;            //2.05
    Voltage*=5;
    Fract=((((long)Voltage*100)/255)%100);
    Fract1=(Fract/10)%10;
    Fract2=(Fract)%10;
    Voltage/=255;
    sprintf(number,"A2D = %d.%d%d volts",Voltage,Fract1,Fract2);

The two char vars are because I don't know how to get Picc to print leading zeroes.

Mike.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top