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");
}
}
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");
}
}