VL6180X 0x018 Register

Hey, JonathanKosh.

I have a startup issue with my vl6180x. whenever i try to read 0x018 register shows 0(HEX) value.Even if i’m writing 1(HEX) to 0x018. Then also it shows 0, am i missing some steps in initialization…

Thanks
Rahul

Hello, Rahul.

I moved this post to a new topic since it does not appear to be related to the original post. It sounds like you are trying to set the SYSRANGE__START register. According to the VL6180X datasheet, that bit can be auto-cleared, so it should not be too surprising if it does not hold the value you set for it. If you tell me more about how you want the sensor to behave for your application, post your code, and tell me how the system is behaving, I might be able to help you find and solve a problem.

-Nathan

i am trying to run vl6180x explorer shield with arduino uno without using wire library
this is the code…

#define scl 19   // I2C bus
#define sda 18   //
#define gpio0 13
#define gpio1 12


int ack_flag;
unsigned char ack;

void setup() {
  Serial.begin(9600);
  pinMode(sda, OUTPUT);
  pinMode(scl, OUTPUT);
  pinMode(gpio0, OUTPUT);
  pinMode(gpio1, INPUT);
}
///////////////////////////////////////////////////////////////////
// I2C Software Implementation
///////////////////////////////////////////////////////////////////
void i2c_start(void)
{
  digitalWrite(sda, HIGH);             // i2c start bit sequence
  digitalWrite(scl, HIGH);
  delayMicroseconds(100); 
  digitalWrite(sda, LOW);
  delayMicroseconds(100); 
  digitalWrite(scl, LOW);
  delayMicroseconds(1000); 
}

void i2c_stop(void)
{
  digitalWrite(sda, LOW);             // i2c stop bit sequence
  delayMicroseconds(100);  //
  digitalWrite(scl, HIGH);
  delayMicroseconds(100);  //
  digitalWrite(sda, HIGH);
  delayMicroseconds(1000); //
}


unsigned char i2c_rx(unsigned char ack)
{
  //  digitalWrite(sda, HIGH);//*
  pinMode(sda, INPUT_PULLUP);//*
  char x, d = 0;

  delayMicroseconds(100);
  for (x = 0; x < 8; x++)
  {
    d <<= 1;
    //pinMode(sda, INPUT_PULLUP);
    digitalWrite(scl, HIGH);
    delayMicroseconds(100);

    if (digitalRead(sda)) {
      d |= 0x01;
    }
    else {
      d |= 0x00;
    }
    //d <<= 1;
    delayMicroseconds(100);
    digitalWrite(scl, LOW);
    delayMicroseconds(100);
  }

  if (ack) digitalWrite(sda, LOW);
  else digitalWrite(sda, HIGH);
  delayMicroseconds(10);
  digitalWrite(scl, HIGH);
  delayMicroseconds(100);             // send (N)ACK bit
  digitalWrite(scl, LOW);
  delayMicroseconds(100);
  digitalWrite(sda, HIGH);
  delayMicroseconds(100);
  pinMode(sda, OUTPUT);
  return d;
}

int i2c_tx(uint16_t d)
{
  //    Serial.print("d = ");
  //    Serial.println(d, HEX);
  //    delay(2000);
  uint16_t x;
  pinMode(sda, OUTPUT);
  // digitalWrite(sda, LOW);
  for (x = 0; x < 8; x++) {
    if (d & 0x80) digitalWrite(sda, HIGH);
    else digitalWrite(sda, LOW);
    delayMicroseconds(100);
    digitalWrite(scl, HIGH);
    delayMicroseconds(100);

    digitalWrite(scl, LOW);
    d <<= 1;
    delayMicroseconds(100);
  }

  pinMode(sda, INPUT_PULLUP);
  //digitalWrite(sda, HIGH);
  digitalWrite(scl, HIGH);
  delayMicroseconds(100);
  ack = digitalRead(sda);          // possible ACK bit

  delayMicroseconds(100);
  if (digitalRead(sda))
  {
    ack_flag = 0;
    Serial.println ('N');
  }

  if (!(digitalRead(sda)))
  {
    ack_flag = 1;
    Serial.println ('Y');
  }
  digitalWrite(scl, LOW);
  pinMode(sda, OUTPUT);
  digitalWrite(sda, LOW);
  return ack;
}
///////////////////////////////////////////////////////////////////
// WriteByte Function
///////////////////////////////////////////////////////////////////
void WriteByte(uint16_t reg, uint16_t data) {
  char data_write[2];
  data_write[0] = (reg >> 8) & 0xFF;; // MSB of register address
  data_write[1] = reg & 0xFF; // LSB of register address
  ack_flag = 1;
  i2c_start();
  i2c_tx (0x52);
  delay(100);
  i2c_tx (data_write[0]);
  delay(100);
  i2c_tx (data_write[1]);
  delay(100);
  i2c_tx (data);
  delay(100);
  i2c_stop();
  if (ack_flag == 1)
  {
    Serial.println ("WB ACK = YES");
    Serial.print ("Reg_WB = ");
    Serial.println (reg, HEX);
    Serial.print ("Data_WB = ");
    Serial.println (data, HEX);
  }

  if (ack_flag == 0)
  {
    Serial.print("WB ACK = NO");
    Serial.print ("Reg_WB = ");
    Serial.println (reg, HEX);
  }
}
///////////////////////////////////////////////////////////////////
// ReadByte Function
///////////////////////////////////////////////////////////////////
char ReadByte(int reg) {
  char data_write[2];
  char data_read[1];
  uint16_t data_low;
  uint16_t data_high;
  data_write[0] = (reg >> 8) & 0xFF; // MSB of register address
  data_write[1] = reg & 0xFF; // LSB of register address
  ack_flag = 1;
  i2c_start();
  i2c_tx (0x52);
  delay(100);
  i2c_tx (data_write[0]);
  delay(100);
  i2c_tx (data_write[1]);
  i2c_stop();
  delay(100);
  if (ack_flag == 1)
  {
    Serial.println ("RBT ACK = YES");
  }
  delay(100);
  i2c_start();
  i2c_tx (0x53);
  delay(100);
  data_read[0] = i2c_rx (1);
  // data_high = i2c_rx (1);
  //  data_low = i2c_rx (0);
  // uint16_t data = (data_high << 8) | data_low & 0xFF;
  delay(100);
  i2c_stop();
  //  return data;
  return data_read[0];
  Serial.print ("Reg_RB = ");
  Serial.println (reg, HEX);
  //  Serial.print ("Data_RB = ");
  //  Serial.println (data, HEX);
  Serial.print ("data_read[0]_RB = ");
  Serial.println (data_read[0], HEX);
}

int VL6180X_Init()
{
  ///////////////////////////////////////////////////////////////////
  // load settings
  ///////////////////////////////////////////////////////////////////
  // Mandatory : private registers
  WriteByte(0x0207, 0x01);

  WriteByte(0x0208, 0x01);

  WriteByte(0x0096, 0x00);

  WriteByte(0x0097, 0xfd);

  WriteByte(0x00e3, 0x00);

  WriteByte(0x00e4, 0x04);

  WriteByte(0x00e5, 0x02);

  WriteByte(0x00e6, 0x01);

  WriteByte(0x00e7, 0x03);

  WriteByte(0x00f5, 0x02);

  WriteByte(0x00d9, 0x05);

  WriteByte(0x00db, 0xce);

  WriteByte(0x00dc, 0x03);

  WriteByte(0x00dd, 0xf8);

  WriteByte(0x009f, 0x00);

  WriteByte(0x00a3, 0x3c);

  WriteByte(0x00b7, 0x00);

  WriteByte(0x00bb, 0x3c);

  WriteByte(0x00b2, 0x09);

  WriteByte(0x00ca, 0x09);

  WriteByte(0x0198, 0x01);

  WriteByte(0x01b0, 0x17);

  WriteByte(0x01ad, 0x00);

  WriteByte(0x00ff, 0x05);

  WriteByte(0x0100, 0x05);

  WriteByte(0x0199, 0x05);

  WriteByte(0x01a6, 0x1b);

  WriteByte(0x01ac, 0x3e);

  WriteByte(0x01a7, 0x1f);

  WriteByte(0x0030, 0x00);

  WriteByte(0x016, 0x00); //change fresh out of set status to 0

  ///////////////////////////////////////////////////////////////////
  // Added latest settings here
  ///////////////////////////////////////////////////////////////////

  // Recommended : Public registers - See data sheet for more detail
  WriteByte(0x0011, 0x10);// Enables polling for ‘New Sample ready’ when measurement completes

  WriteByte(0x010a, 0x30);// Set the averaging sample period (compromise between lower noise and increased execution time)

  WriteByte(0x003f, 0x46);// Sets the light and dark gain (upper nibble). Dark gain should not be changed.

  WriteByte(0x0031, 0xFF);// sets the # of range measurements after which auto calibration of system is performed

  //  WriteByte(0x0040, 0x63);//xxxxxxxdata_1 Set ALS integration time to 100ms

  WriteByte(0x002e, 0x01); //xxxxxxxdata_0 perform a single temperature calibration of the ranging sensor

  WriteByte(0x001b, 0x09); //Set default ranging inter-measurement period to 100ms

  WriteByte(0x003e, 0x31); // Set default ALS inter-measurement period to 500ms
  reg_data(0x003e);
  WriteByte(0x0014, 0x24); // Configures interrupt on ‘New Sample Ready threshold event’

  return 0;
}
//////////////////////////////////////////////////////////////////
// Start a range measurement in single shot mode
///////////////////////////////////////////////////////////////////
int VL6180X_Start_Range() {
  WriteByte(0x018, 0x01);
  char SYSRange_start = ReadByte(0x018);
  delay (1000);
  Serial.print("SYSRange_start = ");
  Serial.println(SYSRange_start, HEX);
  if (SYSRange_start == 0)
  {
    Serial.println("Start Range Measurement");
    delay (1000);
  }
  else if (SYSRange_start == 2)
  {
    Serial.println("Start Range Measurement");
    delay (1000);
  }
  else {
    Serial.println("Device is Not Ready For Measurement");
    delay (1000);
  }
  return 0;
}
///////////////////////////////////////////////////////////////////
// poll for new sample ready
///////////////////////////////////////////////////////////////////
int VL6180X_Poll_Range() {
  char status;
  char range_status;
  // check the status
  status = ReadByte(0x04f);

  range_status = status & 0x07; // wait for new measurement ready status

  while (range_status != 0x04) {
    status = ReadByte(0x04f);
    Serial.print("status = ");
    Serial.println(status, HEX);
    Serial.println("waiting");
    range_status = status & 0x07;
    Serial.print("range_status = ");
    Serial.println(range_status, HEX);
    delay(1000);
  }
  return 0;
}
///////////////////////////////////////////////////////////////////
// Read range result (mm)
///////////////////////////////////////////////////////////////////
int VL6180X_Read_Range() {
  int range;
  range = ReadByte(0x062);
  Serial.print("Range = ");
  Serial.println(range, HEX);
  return range;
}

///////////////////////////////////////////////////////////////////
// clear interrupts
///////////////////////////////////////////////////////////////////
int VL6180X_Clear_Interrupts() {
  WriteByte(0x015, 0x07);
  return 0;
}
///////////////////////////////////////////////////////////////////
// Main
///////////////////////////////////////////////////////////////////
void loop() {
  digitalWrite(gpio0, LOW);
  delay (1);

start:  digitalWrite(gpio0, HIGH);
  //    delayMicroseconds(10);
  //    digitalWrite(gpio1, HIGH);
  delay (10);
  WriteByte(0x016, 0x01);
  delay (10);
  char reset;
  reset = ReadByte(0x016);
  Serial.print("Reset = ");
  Serial.println(reset, HEX);
  if (reset == 1) {
    Serial.println("Device is Ready");
    delay (1000);
    //    WriteByte(0x0016, 0x00);
  }
  else {
    Serial.println("Device is Busy");
    digitalWrite(gpio0, LOW);
    delay (1);
    goto start;
  }
  
  VL6180X_Init();     // load settings onto VL6180X
  delayMicroseconds(100);

  int range;

  while (1) {
    VL6180X_Start_Range();  // start single range measurement
    delayMicroseconds(100);

    VL6180X_Poll_Range();  // poll the VL6180X till new sample ready
    delayMicroseconds(100);

    range = VL6180X_Read_Range();  // read range result
    delayMicroseconds(100);

    VL6180X_Clear_Interrupts(); // clear the interrupt on VL6180X
    delayMicroseconds(100);
  }
}

Thanks
-Rahul

You might use a logic analyzer to verify your I2C communications are working as you intend. It looks like you are attempting to set all the same registers as our library and our library works, so it is not clear what the difference is.

-Nathan