cancel
Showing results for 
Search instead for 
Did you mean: 

VL6180x at low SPI clock speeds.

TMout.1
Associate II

I am using a VL6180x with an Atmega8a in a lower-power application. The Atmega8a runs at a clock frequency of 1 MHz. After struggling for a few weeks to get the sensor working, I discovered an issue with the VL6180x. After writing 0x01 to register 0x038, to initiate a single-shot measurement, the value of register 0x04F remained 0 forever.

I then switched from the Atmega8a to an ESP32 and the problem was solved. I then discovered that the problem reappeared when I set the SPI clock speed on the ESP32 to less than 20kHz.

Is this a known issue with the VL6180x?

I then wrote the following inline assembler code that does bit-banging. The VL6180x now works fine with the Atmega8a.

void startSingleShot(){
   // SDA = PC4
   // SCL = PC5
   // Port C address = 0x15
   __asm__ __volatile__(
   // Set pin PC4 as output
    "SBI 0x14, 4                       \n\t"
    // Send start
    "CBI 0x15, 4                       \n\t" // Take SDA low to indicate start
    "CBI 0x15, 5                       \n\t" // Take SCL low
    // Send address
    "CBI 0x15, 4                       \n\t" // bit  7 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
    
    "SBI 0x15, 4                       \n\t" // bit 6 is high
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit 5 is low
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
    "SBI 0x15, 4                       \n\t" // bit 4 is high
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit 3 is low
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
 
    "CBI 0x15, 4                       \n\t" // bit 2 is low
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
    "SBI 0x15, 4                       \n\t" // bit 1 is high
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit 0 is low
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"
 
    // Set pin PC4 as input
    "CBI 0x14, 4                       \n\t"
 
    // Clock for acknowledge
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"   
 
    // Set pin PC4 as output
    "SBI 0x14, 4                       \n\t"
 
    // Send first index: 0x00
    "CBI 0x15, 4                       \n\t" // bit  7 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  6 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  5 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  4 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  3 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  2 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  1 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  0 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    // Set pin PC4 as input
    "CBI 0x14, 4                       \n\t"
 
    // Clock for acknowledge
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"   
 
    // Set pin PC4 as output
    "SBI 0x14, 4                       \n\t"
 
    // Send second index: 0x18
    "CBI 0x15, 4                       \n\t" // bit  7 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  6 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  5 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "SBI 0x15, 4                       \n\t" // bit  4 is high
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "SBI 0x15, 4                       \n\t" // bit  3 is high
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  2 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  1 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  0 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    // Set pin PC4 as input
    "CBI 0x14, 4                       \n\t"
 
    // Clock for acknowledge
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"   
 
    // Set pin PC4 as output
    "SBI 0x14, 4                       \n\t"
    
    // Set value to 0x01
 
    // Set pin PC4 as output
    "SBI 0x14, 4                       \n\t"
 
    // Send data: 0x01
    "CBI 0x15, 4                       \n\t" // bit  7 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  6 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  5 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  4 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  3 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  2 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "CBI 0x15, 4                       \n\t" // bit  1 is low
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    "SBI 0x15, 4                       \n\t" // bit  0 is high
    "SBI 0x15, 5                       \n\t" 
    "CBI 0x15, 5                       \n\t"
 
    // Set pin PC4 as input
    "CBI 0x14, 4                       \n\t"
 
    // Clock for acknowledge
    "SBI 0x15, 5                       \n\t"
    "CBI 0x15, 5                       \n\t"   
 
    // Set pin PC4 as output
    "SBI 0x14, 4                       \n\t"
 
    
    // Send stop
    "CBI 0x15, 4                       \n\t"  
    "SBI 0x15, 5                       \n\t"
    "SBI 0x15, 4                       \n\t"
 
    // Set pin PC4 as input
    "CBI 0x14, 4                       \n\t"
      
    );
  
 }

4 REPLIES 4
Anne BIGOT
ST Employee

Hello,

You are speaking about SPI protocol. The VL6180x is supporting I2C only in the range of 0 to 400kHz as explained in the datasheet. This explains why you could have issue at 1MHz.

Regarding the issue at low frequency, which capacitance did you put on SDA and SCL ? This has in impact on the functionality.

Did you also try with the Evaluation kit proposed by ST ?

Regards

Anne


Our community relies on fruitful exchanges and good quality content. You can thank and reward helpful and positive contributions by marking them as 'Accept as Solution'. When marking a solution, make sure it answers your original question or issue that you raised.

ST Employees that act as moderators have the right to accept the solution, judging by their expertise. This helps other community members identify useful discussions and refrain from raising the same question. If you notice any false behavior or abuse of the action, do not hesitate to 'Report Inappropriate Content'
TMout.1
Associate II

Thank you for your reply.

My apologies. I meant the SCL clock speed of the I2C interface. I didn't put any capacitance on the SDA and SCL lines and the rise and fall times are within the limits stipulated in the VL6180x data sheet. The clock speed of the microcontroller is 1 MHz. The SCL clock speed is much lower. The problem occurs when the SCL clock speed is below 20 kHz.

I didn't use the ST evaluation kit. My code works fine when I connect the VL6180x to and ESP32, but the problem reoccurs when the SCL clock speed is set below 20 kHz. The problem has been solved with the code I posted.

I just wanted to let you know that there is an potential issue with the VL6180x.

Another user reported that he was unable to get the VL6180x to work with an Atmega8A on the AdaFruit website.

John E KVAM
ST Employee

In the far reaches of my mind, I seem to remember that a user had this issue. (Maybe 6 years ago.) And I seem to remember that 20kHz was the lowest reliable I2C speed. I don't believe a solution was ever published - if it was ever found.

What I would like to know is what your code does that makes it work. Maybe there is a clue in that.

From my very quick look, I'm thinking you just did what the hardware would have done.

I'm pretty impressed that you would dig that deep.

Is <20kHz a must for your design?

  • john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

Thank you for confirming my findings.

My code just bit bangs the I2C pins at the highest possible speed. For some or other reason the native hardware I2C operates at a lower speed. I will do some measurements and write a more detailed reply.

The I2C clock speed is only an issue when writing to register 0x038.

My design runs off a small battery and I have to do everything I can to keep the power consumption as low as possible. Hence the low clock speed.

If there is a lower limit to the I2C clock speed, then ST should put it in the data sheet. It took a lot of time and experimentation to sort out this problem.