PDA

View Full Version : 16F877A problem: "coupled" digital values



Lupo83
- 2nd December 2007, 16:21
Hi everybody :) here's my problem with PIC 16F877A on PICDEM Mechatronics board.

I get the 2 analog inputs produced by temperature sensor and light sensor, then I convert them into digital values and send them to a PC via RS-232 (serial port), and somehow I light some LEDs.
I actually use HyperTerminal to view the produced data.

I noticed that temp and light values are "coupled": if I cover the light sensor with a sheet, temp values go crazy... fluctuating from 26°C to -5°C (!!!)
So used a multimeter to measure the voltage levels on the output pins of the sensors, BEFORE being converted by the ADC of the PIC, and everything worked fine: no voltage coupling or wrong fluctuations.
So the fault is of the ADC (and mine, because I don't program it well :) ) What could it be?
Microcontroller's internal interferences?
What do you think?

My code:
[code]
// ANALOG SIGNALS ACQUISITION (TEMP, LIGHT)
// FROM PICdem Mechatronics board --- TARGET PIC = 16F877A

/******************************
* TEMP --> RA0 *
* LIGHT --> RA1 *
* RB0… RB7 --> LED1… LED8 *
* *
******************************/


#define XTAL_FREQ 20MHZ

#include <pic.h>
#include "delay.h"
#include "macro.h"
#include "ascii.h"
#include "uart.h"

// CONFIGURATION BITS
__CONFIG(HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & UNPROTECT);


main(void)
{
// VARIABLES DECLARATIONS, SERIAL INITIALIZATION
int temp, light, i;
unsigned char clock = 20;
unsigned long baudrate = 9600;
char c,tempstr[4], lightstr[4];

UartInit(clock, baudrate, UART_CFG_BITSTOP_1);


//PORTS AND REGISTERS INITIALIZATION
PORTA = 0b00000000;
PORTB = 0b00000000;

TRISA = 0b00000011; // Port A WITH INPUTS AN0, AN1 (temp, light)
TRISB = 0b00000000; // Port B AS OUTPUT

//ADC CONFIG
ADCON1 = 0b10000000; // RESULT IN LITTLE ENDIAN (ADFM BIT = 1)
// f_clock of ADC like in ADCON0
// AN0... AN7: all analog inputs



while(1)
{
ADCON0 = 0b01000001; //f_clock of ADC = 1/8 f_clock of the system
//Now I set AN0 (to reset to AN1!)
//ADC enabled

ADRESH = ADRESL = 0b00000000;

/*TEMP SIGNAL CONVERSION*/
ADGO = 1;
while(ADGO) // WAIT FOR ADC...
continue;

temp = ADRESL + (ADRESH<<8);
/****************************************/

ADRESH = ADRESL = 0b00000000;

/*LIGHT SIGNAL CONVERSION*/
ADCON0 = 0b01001001; //Switch input from AN0 to AN1

ADGO = 1;
while(ADGO)
continue;

light = ADRESL + (ADRESH<<8);
/****************************************/

// TEMP in RANGE -40 -- 125 ° C
// ==> 0.1 -- 1.75 V (v. datasheet sensor TC1047)
// ==> 21 -- 358 in 10 bit ADC values (Volt * 206)

// IRRADIANCE IN RANGE 0 -- 233 uW/cm^2
// ==> 0.005 -- 3.73 V (v. datasheet sensor TSL251RD)
// ==> 1 -- 768 in 10 bit ADC values (Volt * 206)


temp = (int)(temp*0.4896 - 50.282); // Map: 21 -- 358
// in -40 -- 125 °C

if (temp<21) //limiting absurd fluctuations...
temp=21;
if (temp>100)
temp=100;


light = (int)( 0.304*(light - 1) ); // Map: 1 -- 768
// in 0 -- 233 uW/cm^2

// LEDs
if (temp==26)
PORTB=0b00000001; // Light RB0
if (temp==27)
PORTB=0b00000010; // Light RB1
if (temp==28)
PORTB=0b00000100; // Light RB2
if (temp==29)
PORTB=0b00001000; // Light RB3
if (temp==30)
PORTB=0b00010000; // Light RB4
if (temp==31)
PORTB=0b00100000; // Light RB5
if (temp==32)
PORTB=0b01000000; // Light RB6
if (temp==33)
PORTB=0b10000000; // Light RB7

// VIEW DATA
for(i = 0; i < 14; i++)
DelayMs(100);

UartPutch('-');
UartPuts("Temperature level: ");
int2dec(temp,tempstr);
UartPuts(tempstr);
UartPuts(" C\r\n\n");

DelayMs(250);

UartPutch('-');
UartPuts("Light level: ");
int2dec(light,lightstr);
UartPuts(lightstr);
UartPuts(" uW/cm^2\r\n\n\n\n");
}

}

mackrackit
- 2nd December 2007, 17:55
Something looks veerry funny with your code.

Are you sure you are using PIC BASIC? That is the language we use here.

BobK
- 2nd December 2007, 17:57
Ah-hem, Lupo83,

You probably didn't notice it but we are a PicBasic, forum not a "C" forum.

BobK

Lupo83
- 2nd December 2007, 19:54
Yes guys, you are both perfectly right but I DID notice it :) I was just posting wherever there could be someone familiar with PICs and crosstalk troubles (electronical aspects do not depend on the language you use).
Besides, I was thinking that some basic expert could have also been involved in C matters.
I've already tried to write in C forums but nobody's been helpful yet, so it was despair that drove me here :D

Of course, I apologize if my post here was unappropriate: in that case, delete it and sorry again :)

ciao!

Darrel Taylor
- 2nd December 2007, 20:09
Hi Lupo,

Good answer. Not a problem.

I think you need some delay between selecting the A/D channel (with ADCON0) and starting the conversion (ADGO = 1;) for sample Aquisition time.

Starting it too soon won't allow the internal Sample and Hold capacitor to fully charge. Which leaves part of the charge from the last channel in it.

HTH,

Lupo83
- 2nd December 2007, 20:31
Ciao Darrel,

your answer is the most useful I've read so far, so I thank you very much for that!

I'll test your solution tomorrow morning, since the board/PIC I'm working on are not mine, but have to stay in a laboratory at my university.

Then, I'll let you know.

Best regards.

mackrackit
- 3rd December 2007, 00:20
Of course, I apologize if my post here was unappropriate:
I do not think your post was inappropriate, just thought you posted to the wrong forum.
There are a few here that use "C" and I understand needing help.

Tried PIC programming in "C" a few years ago and like you I could not find help. That was one of the reasons I ended up using PIC BASIC.

Good luck.

Lupo83
- 3rd December 2007, 11:16
Good morning everybody (here it's 11:40 AM).

Dear Darrel, your suggestion worked fine! You've been the only one to solve the problem, congrats!! I thank you very much for your competence. Hope to get as experienced as you, first or later :)

Dave
- 3rd December 2007, 12:02
Lupo83, If you would have read the data sheet for the PIC it would have told you that there is a minimum time required for the A/D caps to charge before taking a measurement. It's in the Data sheet......

Dave Purola,
N8NTA

mister_e
- 3rd December 2007, 16:09
PICMultiCalc (A/D calc) could also be useful, it use a generic maths formula. The whole idea started with this article....
http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.MinADtime

Some may recognize the author ?

Lupo83
- 3rd December 2007, 17:57
Ciao Dave,

sometimes one's attention misses some information when reading a 234 pages document, after being required to produce working code, starting from nothing, in 3 days and without a PIC programming background ;)
I found myself in a pressing situation and just needed to ask some help, since time was lacking :)
Thank you for the link, mister_e!

Bye,
L.

PS: Maybe the correct form for your sentence is "If you had read...."....?

Darrel Taylor
- 4th December 2007, 07:13
That's great Lupo,

It's tough being an outsider sometimes.
But I'm glad it worked out for you!

If you get a chance, come on in. The waters nice. (PBP)
and we have Lifeguards. ;)
<br>

T.Jackson
- 4th December 2007, 11:56
I do not think your post was inappropriate, just thought you posted to the wrong forum.
There are a few here that use "C" and I understand needing help.

Tried PIC programming in "C" a few years ago and like you I could not find help. That was one of the reasons I ended up using PIC BASIC.

Good luck.

C / Java is not as intimidating as it first looks - but you will find it difficult to learn from just reading a book. I learned more about Java from 100pgs of lecture material that was straight to the point than I did from reading portions of a 1,000pg book. The practical assignments helped as well. It's clearly a language that needs to be taught formally with a lot of resources for help.

mackrackit
- 4th December 2007, 12:07
C / Java is not as intimidating as it first looks.
About six months ago I purchased two Java books. I am starting to make a little progress. Now my biggest problem is finding time to work on it. The IDEs like NetBeans just made it more confusing. Every one seems to have a different method. Now I am using gedit and compiling from the command line.

T.Jackson
- 4th December 2007, 12:22
Personally, I just compile at console level. Typically I'll have two instances, 1 for compiling and the other for running / testing. As you may or may not be aware, java files need to be launched at console level unless you create a jar file with the inclusion of a manifest in order to be able to execute the program at OS level (double click to run) - which is your typical Windows-based executable. Sadly, this is as about as good as it gets for a standalone application with Java.

mackrackit
- 4th December 2007, 12:31
I got the manifest and jar things figured out. Those were some of the things the books did not cover well. Google to the rescue.

The thing I like about java and the reason I want to learn it is its cross platform capability.

T.Jackson
- 4th December 2007, 12:46
Java is king for that. No time lost learning Java, it uses the same syntax as C, it's object oriented, performance wise it's arguably almost par with C, will never be "as" quick because of the latency of the (VM) - Virtual Machine. I did a bit of a comparison test with Java & BASIC a few months ago - Java puts BASIC to shame (up to 20 times more efficient)