CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem with the light sensor ISL29010 and PIC18F4550

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
frankcr



Joined: 29 Apr 2010
Posts: 11

View user's profile Send private message MSN Messenger

Problem with the light sensor ISL29010 and PIC18F4550
PostPosted: Mon Oct 11, 2010 12:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 11, 2010 1:03 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Mon Oct 11, 2010 2:03 pm     Reply with quote

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: 19496

View user's profile Send private message

PostPosted: Tue Oct 12, 2010 2:06 am     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Wed Oct 13, 2010 4:49 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 13, 2010 5:34 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Thu Oct 14, 2010 11:55 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 14, 2010 12:23 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Thu Oct 14, 2010 12:38 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 14, 2010 1:56 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Thu Oct 14, 2010 2:23 pm     Reply with quote

I don´t have a 48 MHz external oscillator chip. I have only the internal oscillator
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 14, 2010 2:47 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Thu Oct 14, 2010 3:02 pm     Reply with quote

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????
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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