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 support@ccsinfo.com

vl6180 library, single shot mode

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
PrinceNai



Joined: 31 Oct 2016
Posts: 471
Location: Montenegro

View user's profile Send private message

vl6180 library, single shot mode
PostPosted: Thu Jul 18, 2024 9:24 am     Reply with quote

Hi,

vl6180 library, single shot mode.

vl6180.h

Code:

#define VL6180_address 0x52                                   
unsigned int8 VL6180_distance;

// ****************** VL6180 FUNCTIONS ************************
// ************************************************************

// *********** READ ONE BYTE OF DATA FROM VL6180 **************
// reads 8 bits from register 'reg_addr' that has a 16 bit address
// Split 16-bit register address into two bytes and write
// the address + read one byte of data via I2C

char VL6180_ReadByte(unsigned int16 reg_addr)
{
   char data_read;
   int8 reg_address_MSB = make8(reg_addr, 1);                  // Make MSB of reg_addr
   int8 reg_address_LSB = make8(reg_addr, 0);                  // Make LSB of reg_addr. Could be done directly at i2c_write().
     
   I2C_Start();
   I2C_Write(VL6180_address);                                  // call VL6180
   I2C_Write(reg_address_MSB);                                 // send MSB of register address
   I2C_Write(reg_address_LSB);                                 // send LSB of register address
   I2C_Start();                                                // repeat start and turn the direction of the transfer
   I2C_Write(VL6180_address + 1);                              // send read address
   data_read = I2C_Read(0);                                    // read one byte of data, send NACK
   I2C_Stop();                                                 // stop I2C
   return data_read;                                           // and return data to the caller
}

// *********** WRITE ONE BYTE OF DATA TO VL6180 ***************
// Split 16-bit register address into two bytes and write
// the address + one byte of data via I2C

void VL6180_WriteByte(unsigned int16 reg_addr, char data) {

   int8 reg_address_MSB = make8(reg_addr,1);                   // MSB of register address
   int8 reg_address_LSB = make8(reg_addr,0);                   // LSB of register address. Could be done directly at i2c_write().     
   I2C_Start();
   I2C_Write(VL6180_address);                                  //
   I2C_Write(reg_address_MSB);                                 // write MSB of register address
   I2C_Write(reg_address_LSB);                                 // write LSB of register address
   I2C_Write(data);                                            // write data to the selected register
   I2C_Stop();
}


// ****************** INIT VL6180 *****************************
void Init_VL6180 (void){

   int8 reset;
   reset = VL6180_ReadByte(0x016);
   if (reset == 1){                                            // check to see if VL6180 has been initialised already
                                                               // if not, load
// sensor calibration values, should be loaded on any sensor reset or power-up
// Mandatory : private registers. Values are from the datasheet.
      VL6180_WriteByte(0x0207, 0x01);
      VL6180_WriteByte(0x0208, 0x01);
      VL6180_WriteByte(0x0096, 0x00);
      VL6180_WriteByte(0x0097, 0xfd);
      VL6180_WriteByte(0x00e3, 0x00);
      VL6180_WriteByte(0x00e4, 0x04);
      VL6180_WriteByte(0x00e5, 0x02);
      VL6180_WriteByte(0x00e6, 0x01);
      VL6180_WriteByte(0x00e7, 0x03);
      VL6180_WriteByte(0x00f5, 0x02);
      VL6180_WriteByte(0x00db, 0xce);
      VL6180_WriteByte(0x00dc, 0x03);
      VL6180_WriteByte(0x00dd, 0xf8);
      VL6180_WriteByte(0x009f, 0x00);
      VL6180_WriteByte(0x00a3, 0x3c);
      VL6180_WriteByte(0x00b7, 0x00);
      VL6180_WriteByte(0x00bb, 0x3c);
      VL6180_WriteByte(0x00b2, 0x09);
      VL6180_WriteByte(0x00ca, 0x09);
      VL6180_WriteByte(0x0198, 0x01);
      VL6180_WriteByte(0x01b0, 0x17);
      VL6180_WriteByte(0x01ad, 0x00);
      VL6180_WriteByte(0x00ff, 0x05);
      VL6180_WriteByte(0x0100, 0x05);
      VL6180_WriteByte(0x0199, 0x05);
      VL6180_WriteByte(0x01a6, 0x1b);
      VL6180_WriteByte(0x01ac, 0x3e);
      VL6180_WriteByte(0x01a7, 0x1f);
      VL6180_WriteByte(0x0030, 0x00);
       
// Recommended : Public registers - See data sheet for more detail
      VL6180_WriteByte(0x0011, 0x10);                          // Enables polling for 'New Sample ready' when measurement completes
      VL6180_WriteByte(0x010a, 0x30);                          // Set the averaging sample period (compromise between lower noise and increased execution time)
      VL6180_WriteByte(0x003f, 0x46);                          // Sets the light and dark gain (upper nibble). Dark gain should not be CHANGED.
      VL6180_WriteByte(0x0031, 0xFF);                          // sets the # of range measurements after which auto calibration of system is performed
      VL6180_WriteByte(0x0040, 0x63);                          // Set ALS integration time to 100ms
      VL6180_WriteByte(0x002e, 0x01);                          // perform a single temperature calibration of the ranging sensor
       
//Optional: Public registers - See data sheet for more detail
      VL6180_WriteByte(0x001b, 0x09);                          // Set default ranging inter-measurement period to 100ms
      VL6180_WriteByte(0x003e, 0x31);                          // Set default ALS inter-measurement period to 500ms
      VL6180_WriteByte(0x0014, 0x24);                          // Configures interrupt on 'New Sample Ready threshold event'
       
      VL6180_WriteByte(0x016, 0x00);                           // change fresh out of set status to 0
   }                                                             
}

///////////////////////////////////////////////////////////////
// Start a range measurement in single shot mode
///////////////////////////////////////////////////////////////
void VL6180_Start_Range() {
   VL6180_WriteByte(0x018,0x01);                               // do one measurement
}

///////////////////////////////////////////////////////////////
// poll for new RANGE sample to be ready
///////////////////////////////////////////////////////////////
void VL6180_Poll_Range() {
   int8 status;
   int8 range_status;
     
   status = VL6180_ReadByte(0x04f);                            // check the measurement status
   range_status = status & 0x07;

   while (range_status != 0x04) {                              // wait for new measurement ready status
      status = VL6180_ReadByte(0x04f);
      range_status = status & 0x07;
      delay_ms(1);                                             // (can be removed)
   }
}

///////////////////////////////////////////////////////////////
// Read range result (mm)
///////////////////////////////////////////////////////////////
char VL6180_Read_Range() {
   char range;
   range = VL6180_ReadByte(0x062);                             // read and return distance in mm
   return range;
}

///////////////////////////////////////////////////////////////
// clear VL6180 interrupts
///////////////////////////////////////////////////////////////
void VL6180_Clear_Interrupts() {
   VL6180_WriteByte(0x015, 0x07);                              // clear interrupts
}

////////////////// END VL6180 FUNCTIONS ///////////////////////


Example program:

Code:

// ************************************************************
// Sensor shows distances up to approx. 180mm, after that
// it returns 255 or Out of Range. Physical connections are
// only VCC, VDD, SCL, SDA. Shutdown pin is left floating
// (works on my module)
// ************************************************************
#include <18F46K22.h>
#device ADC=10

#FUSES NOWDT                                                   // No Watch Dog Timer
#FUSES DEBUG
#FUSES NOPUT                                                   // for compatibility with PICKIT3 debugging

#device ICD =TRUE
#use delay(internal=32000000)
#use rs232(baud = 19200, parity = N, UART1, bits = 8,stream = DEBUG, errors)
#use i2c(Master, Slow, sda = PIN_C4, scl = PIN_C3, force_hw, stream = I2C1)

// ********************* INCLUDES *****************************
#include <string.h>
#include "1306.h"                                              // The OLED driver 
#include "vl6180.h"                                            // vl1680 driver
// ************************************************************
                                                               
void main()
{   
   delay_ms(10);                                              // OLED takes time to wake up. Maybe not this much time, but...
                                                                                 
//now try to initialise OLED
   OLED_commands(init_sequence,sizeof(init_sequence));         // initialise OLED
   set = TRUE;                                                 // white on black text 
   size = NORMAL;                                              // 21 characters in a row, 8 rows, total 168 chars
//   size=LARGE;                                               // large font, switches between showing 21*8 & 10*4 characters
   OLED_CLS();                                                 // clear the physical screen, go top left
   printf(OLED_putc,"VL6180x\n\r");
   delay_ms(1000);
   OLED_CLS();                                                 // clear the physical screen, go top left
   
   Init_VL6180();                                              // load settings into VL6180X, must be done upon any reset 
     
   while(TRUE)
   {       
      VL6180_Start_Range();                                    // start a single range measurement
      VL6180_Poll_Range();                                     // poll the VL6180 till new range sample is ready
      VL6180_distance = VL6180_Read_Range();                   // read distance result in mm
      VL6180_Clear_Interrupts();                               // clear interrupts on VL6180
     
      OLED_gotoxy(0,0);                                        // go to appropriate position on OLED
     
      if(VL6180_distance < 255){                               // returned value of 255 means distance is out of range   
         fprintf(DEBUG, "%3u\r\n", VL6180_distance);           // send distance measurement to pc by serial         
         printf(OLED_putc,"%3u         \r\n", VL6180_distance);// display distance on OLED. Spaces are used to cover "Out of range" messages on OLED.
      }
      else{
         fprintf(DEBUG, "Out of range");                       // send out of range message to pc by serial 
         printf(OLED_putc, "Out of range");                    // and to OLED
      }
     
      delay_ms(100);
   }         // while(TRUE)
}            // main


If you don't have this OLED, simply remove all the parts of the code not needed.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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