|
|
View previous topic :: View next topic |
Author |
Message |
frankcr
Joined: 29 Apr 2010 Posts: 11
|
Problem with the light sensor ISL29010 and PIC18F4550 |
Posted: Mon Oct 11, 2010 12:07 pm |
|
|
Hi all,
I am tried to use the sensor ISL29010 with a PIC 18F4550, but the problem is the value is always 0 lux. I had read the datasheet but I don't understand why it don't work. I want to use the internal timing mode with A0 = 0 (GND). This is my code, I did two options, but none works.....
The first one
Code: |
void luz_write (){
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x00); //Indica que empiece en registro COMMAND 0
i2c_write(0x8B);
// i2c_write(0x08);
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x01); //Indica que empiece en registro COMMAND 1
i2c_write(0x08);
i2c_stop();
}
//******************************************************************************
//******************************************************************************
void luz_read (){
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x04); //Indica que empiece en registro COMMAND 1
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x89); //Direcciona ISL29023
luz_l = i2c_read(); //Indica que empiece en registro COMMAND 1
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x05); //Indica que empiece en registro COMMAND 1
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x89); //Direcciona ISL29023
luz_h = i2c_read(0);
i2c_stop(); //
}
|
The second one
Code: |
void luz_write (){
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x40); //Indica que empiece en registro COMMAND 0
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x00); //Indica que empiece en registro COMMAND 0
i2c_write(0x8B);
i2c_write(0x08);
i2c_stop();
}
//******************************************************************************
//******************************************************************************
void luz_read (){
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x04); //Indica que empiece en registro COMMAND 1
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x89); //Direcciona ISL29023
luz_l = i2c_read(); //Indica que empiece en registro COMMAND 1
luz_h = i2c_read(0);
i2c_stop(); //
}
|
Also I don´t undertand when I have to use the register clar_int (page 5)..... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 11, 2010 1:03 pm |
|
|
Quote: | void luz_read (){
i2c_start(); //Inicia I2C
i2c_write(0x88); //Direcciona ISL29023
i2c_write(0x04); //Indica que empiece en registro COMMAND 1
i2c_stop(); //
i2c_start(); //Inicia I2C
i2c_write(0x89); //Direcciona ISL29023
luz_l = i2c_read(); //Indica que empiece en registro COMMAND 1
i2c_stop(); // |
The line shown in bold above should have a 0 parameter, like this:
Quote: | luz_l = i2c_read(0);
|
Also, do you have 4.7K pull-up resistors on the SDA and SCL lines ?
You need them.
If it still doesn't work after you have added the pull-up resistors,
then run this program. It will tell you if the ISL29010 chip exists
on the i2c bus.
http://www.ccsinfo.com/forum/viewtopic.php?t=42368&start=4 |
|
|
frankcr
Joined: 29 Apr 2010 Posts: 11
|
|
Posted: Mon Oct 11, 2010 2:03 pm |
|
|
Thanks for your response, I have 10K resistors as ISL29010 data sheet. Also I have a DS1307 and a EEPROM connected to the I2C . This sensor is the only thing I need to present my graduation project, so I need your help. I have a doubt with the registration clar_int called, I do not know if I have to use. I will try your solution .................... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19561
|
|
Posted: Tue Oct 12, 2010 2:06 am |
|
|
10K, is 'high'.
The resistance value needed, depends on the clock rate being used, and the capacitance on the lines. With four devices on the lines, and presumably also some significant wire lengths to connect these, you will have significant capacitance.
Assuming the system is running at 5v, for 'standard' 100KHz I2C signaling, 10K, allows a maximum of 170pF total bus capacitance. If however you are running at 400KHz, then this falls to only just over 50pF. The minimum resistor value, allowed, will be below 2K, with even the 'wimpiest' I2C driver. Typical values used, are 2K2, to 4K7. 10K, is 'pushing the envelope', for anything more complex than a pair of IC's, with short tracks, which is probably what is being shown in the data sheet you are looking at...
Best Wishes |
|
|
frankcr
Joined: 29 Apr 2010 Posts: 11
|
|
Posted: Wed Oct 13, 2010 4:49 pm |
|
|
Hi all, I run the program in this link http://www.ccsinfo.com/forum/viewtopic.php?t=42368&start=4, who was provided by PCM Programmer. I have 10 K resistors, I get the ack, but It don´t work when I have to read the lux, this is my code:
Code: |
//******************************************************************************
void get_ack_status() {
int8 status;
i2c_start();
status = i2c_write(0x88); // Status = 0 if got an ACK
i2c_stop();
if(status == 0){
delay_ms(100);
fprintf(BT,"\n\rSensor de luz encontrado ");
}
else {
delay_ms(100);
fprintf(BT,"\n\rSensor de luz no encontrado ");
}
}
//******************************************************************************
void luz_write (){
i2c_start(); //
i2c_write(0x88); // WRITE
i2c_write(0x00); // REGISTER
i2c_write(0x8B); // COMMAND
i2c_stop(); //
delay_ms(100);
i2c_start(); //
i2c_write(0x88); // WRITE
i2c_write(0x01); // REGISTER
i2c_write(0x08); // CONTROL
i2c_stop(); //
}
//******************************************************************************
//******************************************************************************
void luz_read (){
i2c_start(); //SEARCH
i2c_write(0x88); //ISL29010
i2c_write(0x04); //REGISTER LSB DATA
i2c_stop(); //
i2c_start(); //
i2c_write(0x89); // READ
luz_l = i2c_read(0);// LSB DATA
i2c_stop(); //
delay_ms (100);
i2c_start(); //SEARCH
i2c_write(0x88); //ISL29010
i2c_write(0x05); //REGISTER MSB DATA
i2c_stop(); //
i2c_start(); //
i2c_write(0x89); //READ
luz_h = i2c_read(0);//MSB DATA
i2c_stop(); //
}
//******************************************************************************
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 13, 2010 5:34 pm |
|
|
Do you have the 100K resistor connected between the Rext pin on the
ISL29010 and ground ? You need it. |
|
|
frankcr
Joined: 29 Apr 2010 Posts: 11
|
|
Posted: Thu Oct 14, 2010 11:55 am |
|
|
Yes I have the 100k resistor...... What is better internal timing mode or external timing mode?
Other question: I have to call the method luz_write every time I need measure the light or only one call? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 14, 2010 12:23 pm |
|
|
I don't know. All I can do is read the data sheet. I have never used
this device.
I notice that your luz_read() routine is not returning a 16-bit value.
You're putting the results into two 8-bit global values. Show the code
where you display these values, and the code where you combine them
into a 16-bit value. Also post the code where you call these routines.
Post the #fuses, #use delay(), #use i2c(), main(), etc. (a test program). |
|
|
frankcr
Joined: 29 Apr 2010 Posts: 11
|
|
Posted: Thu Oct 14, 2010 12:38 pm |
|
|
OK my code is very large, because I have a bluetooth comunnication and I have others sensors, but I am tried to post the most important
Code: |
#include <18F4550.h>
#device adc=10
#include <stdlib.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV4 //System Clock by 4
#FUSES USBDIV //USB clock source comes from PLL divide by 2
#FUSES VREGEN //USB voltage regulator enabled
#FUSES ICPRT //ICPRT enabled
#use delay(clock=8000000)
#define EEPROM_SDA PIN_B0
#define EEPROM_SCL PIN_B1
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=BT)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8,stream=VD2)
#use i2c(Master,Fast=100000,sda=PIN_B0,scl=PIN_B1)
unsigned int16 temp=0;
unsigned int16 humed=0;
unsigned int16 co2=0;
unsigned int16 luz1=0;
unsigned int luz=0;
unsigned int16 temp2=0;
unsigned int16 humed2=0;
unsigned int16 co22=0;
unsigned int16 luz2=0;
unsigned int auxl=0;
unsigned int auxh=0;
unsigned int auxl2=0;
unsigned int auxh2=0;
unsigned int luz_l=0;
unsigned int luz_h=0;
void medicion_2(){
Obtener_Hora(); //Obtiene datos de DS1307 (hora correcta)
delay_ms(10);
ADC(); //Tomo valor del canal del adc respectivo
delay_ms(1);
luz_read ();
delay_ms(10);
Matematica(); //Calculos de los valores del adc
delay_ms(1);
esc_eeprom(); //Escriben datos en EEPROM
delay_ms(10);
}
void ADC(){ //Toma valores del ADC
//*************************** SENSOR DE TEMPERATURA *****************************
set_adc_channel(0); //temp
delay_us(50);
for (i=1;i<=10;++i){
adctin=read_adc();
delay_ms(500);
promediotin = adctin + promediotin;
}
//*************************** SENSOR DE HUMEDAD *****************************
set_adc_channel(1); //HUMEDAD
delay_us(50);
for (j=1;j<=10;++j){
adctout=read_adc();
delay_ms(500);
promediotout = adctout + promediotout;
}
//*************************** SENSOR DE CO2 **********************************
set_adc_channel(2); //CO2
delay_us(100);
adchin=read_adc();
//*************************** SENSOR DE LUZ **********************************
} //
//******************************************************************************
//******************************************************************************
void Matematica(){
promediotin = promediotin / 10;
temperaturain = (((promediotin *(0.09010964))+ 1.85-0.927));
promediotout = promediotout / 10;
temperaturaout = (((promediotout / 1024 * 5)*0.908559 - 0.826) / 0.0315);
if(temperaturaout < 99.99){temperaturaout = temperaturaout;}
else temperaturaout = 99.99;
humedadin = adchin*0.051807*100;
if(humedadin > 400){humedadin = humedadin;}
else humedadin = 400;
luz=MAKE16(luz_h,luz_l);
// lux = (128000 * 0,999)*luz / (65536);
lux = luz;
}//
void get_ack_status() {
int8 status;
i2c_start();
status = i2c_write(0x88); // Status = 0 if got an ACK
i2c_stop();
if(status == 0){
delay_ms(100);
fprintf(BT,"\n\rSensor de luz encontrado ");
}
else {
delay_ms(100);
fprintf(BT,"\n\rSensor de luz no encontrado ");
}
}
//******************************************************************************
void luz_write (){
i2c_start(); //
i2c_write(0x88); // WRITE
i2c_write(0x00); // REGISTER
i2c_write(0x8B); // COMMAND
i2c_stop(); //
delay_ms(100);
i2c_start(); //
i2c_write(0x88); // WRITE
i2c_write(0x01); // REGISTER
i2c_write(0x08); // CONTROL
i2c_stop(); //
}
//******************************************************************************
//******************************************************************************
void luz_read (){
i2c_start(); //SEARCH
i2c_write(0x88); //ISL29010
i2c_write(0x04); //REGISTER LSB DATA
i2c_stop(); //
i2c_start(); //
i2c_write(0x89); // READ
luz_l = i2c_read(0);// LSB DATA
i2c_stop(); //
delay_ms (100);
i2c_start(); //SEARCH
i2c_write(0x88); //ISL29010
i2c_write(0x05); //REGISTER MSB DATA
i2c_stop(); //
i2c_start(); //
i2c_write(0x89); //READ
luz_h = i2c_read(0);//MSB DATA
i2c_stop(); //
}
//******************************************************************************
//******************************************************************************
void main()
{
// ******** Configuraciones de ADC, INT, WDT, TMRS *****************************
setup_psp(PSP_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_PLL_OFF);
setup_adc_ports(AN0_TO_AN3|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_timer3(2450);
enable_interrupts(GLOBAL);
disable_interrupts(INT_EXT2); // Habilita interrupcion externa en RB0 (rcv=PIN_B2)
ext_int_edge(2,H_TO_L); // Habilita interrupcion por flanco H_to_L
enable_interrupts(INT_RDA);
//******************************************************************************
//***********************INICIO VRIVE ******************************************
OUTPUT_HIGH(PIN_C2);
OUTPUT_HIGH(PIN_D0);
OUTPUT_HIGH(PIN_D1);
delay_ms(2000);
inic_host();//Inicializa el Host VDRIVE2
init_eeprom(); //Inicializa memoria externa eeprom
Establecer_Hora();
//******************************************************************************
estado=0;
while(TRUE) {
switch (estado)
{
case 0:{
// Here I read the time´s values who are send for bluetooth
OUTPUT_LOW(PIN_C2);
OUTPUT_LOW(PIN_D0);
OUTPUT_LOW(PIN_D1);
delay_ms(2000);
break;
}
case 1:{
Establecer_Hora(); //Toma los valores preestablecidos en la
delay_ms(1); //configuración del reloj
OUTPUT_HIGH(PIN_C2);
OUTPUT_LOW(PIN_D0);
OUTPUT_LOW(PIN_D1);
delay_ms(3000);
estado=2;
break;
}
case 2:{
OUTPUT_LOW(PIN_C2);
OUTPUT_HIGH(PIN_D0);
OUTPUT_LOW(PIN_D1);
OUTPUT_HIGH(PIN_A4);
delay_ms(500); //estaba en 1000
OUTPUT_LOW(PIN_A4);
delay_ms(1000); //estaba en 4000
delay_ms(1000);
get_ack_status();
luz_write ();
delay_ms(100);
Toma_medicion();
if (copy_usb==1){
estado=3;
copy_usb=0;
}
else{
estado=0;
}
delay_ms(2000);
break;
}
case 3:{ // SE INTRODUCE USB
OUTPUT_HIGH(PIN_C2);
OUTPUT_HIGH(PIN_D0);
OUTPUT_LOW(PIN_D1);
disable_interrupts(INT_RDA);
delay_ms(3000);
estado=4;
break;
}
case 4:{
OUTPUT_LOW(PIN_C2);
OUTPUT_LOW(PIN_D0);
OUTPUT_HIGH(PIN_D1);
enable_interrupts(INT_EXT2);
delay_ms(5000);
estado=5;
break;
}
case 5:{
OUTPUT_HIGH(PIN_C2);
OUTPUT_LOW(PIN_D0);
OUTPUT_HIGH(PIN_D1);
while(!buscar_dispositivo_2());
delay_ms(3000);
estado=6;
break;
}
case 6:{
OUTPUT_LOW(PIN_C2);
OUTPUT_HIGH(PIN_D0);
OUTPUT_HIGH(PIN_D1);
write_vdrive();
delay_ms(2000);
estado=7;
break;
}
case 7:{
OUTPUT_HIGH(PIN_C2);
OUTPUT_HIGH(PIN_D0);
OUTPUT_HIGH(PIN_D1);
retire_dispositivo_2();
delay_ms(2000);
enable_interrupts(INT_RDA);
estado=2;
break;
}
case 8:{
OUTPUT_LOW(PIN_C2);
OUTPUT_LOW(PIN_D0);
OUTPUT_LOW(PIN_D1);
estado=8;
break;
}
}//SWITCH PRINCIPAL
}
}
//******************************************************************************
//******************************************************************************
void Toma_medicion(){
int minutes_2=0;
salir=0;
int time_2 =0;
time_2 = time +1;
delay_ms(999);
fprintf(BT,"\n\r*************************************************************************\n\r");
delay_ms(999);
fprintf(BT,"\n\rMuestreando las condiciones ambientales");
delay_ms(999);
fprintf(BT,"\n\rPara detener el proceso de medicion oprima q\n\r");
delay_ms(999);
fprintf(BT,"\n\r*************************************************************************\n\r");
delay_ms(999);
while(rcvchar!=0x71){
ciclo:
if(rcvchar==0x71){goto fin2;}
else if ((input(PIN_D2)))
{
OUTPUT_HIGH(PIN_D3);
delay_ms(3000);
copy_usb=1;
estado=3;
goto fin2;
}
else {
Obtener_Hora(); //Para poder llevar el tiempo de inicio
while(seconds != 0x30){goto ciclo;} //ciclo de un minuto
minutes_2 = minutes_2 + 1; //incremento variable que lleva los minutos
if(minutes_2 >= time){
minutes_2=0;
k++;
OUTPUT_HIGH(PIN_C1);
medicion_2(); //llama al metodo que toma las mediciones de los sensores
OUTPUT_LOW(PIN_C1);
goto fin;
}else{
delay_ms(8000);
goto ciclo;
}
fin: delay_us(1);
}
}
fin2: delay_ms(999);
fprintf(BT,"\n\r*************************************************************************\n\r");
delay_ms(999);
fprintf(BT,"\n\rProceso de medicion detenido\n\r");
delay_ms(999);
fprintf(BT,"\n\r*************************************************************************\n\r");
OUTPUT_LOW(PIN_D3);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 14, 2010 1:56 pm |
|
|
This code doesn't compile so it's not that useful to me.
Quote: | #FUSES PLL12 //Divide By 12(48MHz oscillator input) |
Do you really have a 48 MHz external oscillator chip, which drives
the 18F4550 ? Or do you have a crystal ? If it's a crystal, what's the
frequency ? |
|
|
frankcr
Joined: 29 Apr 2010 Posts: 11
|
|
Posted: Thu Oct 14, 2010 2:23 pm |
|
|
I don´t have a 48 MHz external oscillator chip. I have only the internal oscillator |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 14, 2010 2:47 pm |
|
|
Quote: | #FUSES XT
I have only the internal oscillator.
|
This is not the correct fuse for the internal oscillator. This is for an
external crystal of 4 MHz.
Are you testing this in Proteus ? I'm starting to think this is not a
real board. |
|
|
frankcr
Joined: 29 Apr 2010 Posts: 11
|
|
Posted: Thu Oct 14, 2010 3:02 pm |
|
|
What??? I have connected a "controller serial-usb", a bluetooth, a ds1307, a eeprom, a co2 sensor, a temperature sensor, a humidity sensor, some buttons and LEDS and all is working...........
OK, I did a test with the light sensor: read the command register, read the control register, read the LSB sensor register, read the MSB sensor register and this is the result: (Left I write, right I read)
COMMAND 0X8B - 0X8B
CONTROL 0X08 - 0X28
LSB SENSOR - - 0X00
MSB SENSOR - - 0X00
I don´t understand why the control register have a 0x28, it should be 0x08???? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|