Heightsensor VL6180

Firmware/software/electronics/mechanics
niklas
Beginner
Posts: 2
Joined: Fri Apr 10, 2015 9:48 am

Heightsensor VL6180

Post by niklas »

Hi,

I have a crazyflie 2.0 and want to get in to some modifications / hacking. I tested the time of flight sensor VL6180 https://www.sparkfun.com/products/12785
It gives really fast and accurate readings for distances under 20cm and it was a no brainer to get it working on my Arduino. it communicates over the I2C and the voltages looks like it should work on the crazyflie.

It would be cool to start to develop some kind of automated landing or just to start to play around.

Step one is to get all the readings form the sensor.
Before i get into this, any ideas / comment. best practice for debugging on the crazyflie?

cheers-
niklas
mwall002
Beginner
Posts: 20
Joined: Wed Jul 01, 2015 4:48 am

Re: Heightsensor VL6180

Post by mwall002 »

I also have a crazyflie 2.0 and want to integrate a VL6180 sensor for continuous height measurements to achieve a controlled hover about 4 inches off of the ground. I have attached the sensor application guide which explains how to perform a continuous range measurement and I think the routines that can handle this in the crazyflie firmware are i2cdev.c and i2croutines.c but I assume they need to be modified. Am I on the right track? I'm definitely not an experienced programmer.

Also, it appears you can directly connect the sensor as follows: VCC to VCC, GND to GND, SCL to PB6 and SDA to PB7

Any guidance or input would be greatly appreciated!
Attachments
VL6180_ApplicationNote.pdf
(689.62 KiB) Downloaded 248 times
marcus
Bitcraze
Posts: 659
Joined: Mon Jan 28, 2013 7:02 pm
Location: Sweden
Contact:

Re: Heightsensor VL6180

Post by marcus »

Looks like a nice sensor! I would recommend having a look at the MPU9250 driver. It's I2C and integrated in the regulation.
mwall002
Beginner
Posts: 20
Joined: Wed Jul 01, 2015 4:48 am

Re: Heightsensor VL6180

Post by mwall002 »

I have found the VL6180 code on Git Hub to be helpful but it is written in Arduino and I don't know yet what I need to change to make it work in C... :cry:

https://github.com/sparkfun/ToF_Range_F ... es/Arduino

I have attached a picture of my flie with the sensor installed :)
Attachments
crazyflie.jpg
tobias
Bitcraze
Posts: 2339
Joined: Mon Jan 28, 2013 7:17 pm
Location: Sweden

Re: Heightsensor VL6180

Post by tobias »

Your hardware wiring should be fine so it is now all about the firmware and that is where it might get a bit complected. I guess the easiest way would be to port the arduino driver to the Crazyflie platform. Use eeprom.c as a template/guide to put in the vl6180 driver code. Basically what you need to port is the code that uses arduino wire (i2c) driver, make it use i2cdev instead and make it c instead of c++.

e.g.

Code: Select all

void VL6180x::VL6180x_setRegister(uint16_t registerAddr, uint8_t data)
{
  Wire.beginTransmission( _i2caddress ); // Address set on class instantiation
  Wire.write((registerAddr >> 8) & 0xFF); //MSB of register address
  Wire.write(registerAddr & 0xFF); //LSB of register address
  Wire.write(data); // Data/setting to be sent to device.
  Wire.endTransmission(); //Send address and register address bytes
}
could be replaced with something like this:

Code: Select all

void VL6180x_setRegister(uint16_t registerAddr, uint8_t data)
{
  // Write a data byte to a 16bit internal register of the VL6180
  i2cdevWrite16(I2Cx, devAddr, registerAddr, 1, &data); //I2Cx and devAddr set during init. 
}
mwall002
Beginner
Posts: 20
Joined: Wed Jul 01, 2015 4:48 am

Re: Heightsensor VL6180

Post by mwall002 »

Thanks for the help Tobias! I will keep working on it and share the code once the sensor is reading properly.
mwall002
Beginner
Posts: 20
Joined: Wed Jul 01, 2015 4:48 am

Re: Heightsensor VL6180

Post by mwall002 »

I have an update on my progress and a few questions. I have ported the Arduino sensor code over to C and it compiles and flashes successfully to my crazyflie but the sensor isn't working yet.

The question I have is about i2cdev.h and i2croutines.h. Is it required that I use these drivers to make the sensor work? Right now the drivers for the sensor are separate but I could combine them into i2cdev.h and i2crouthines.h. If I do have to combine them, how would that work? More specifically, how can I convert something like this:

Code: Select all

uint8_t VL6180x_getRegister(uint16_t registerAddr)
{
  uint8_t data;

  write((registerAddr >> 8) & 0xFF);msb of register address
  write((registerAddr) & 0xFF);//LSB of register address
  read(_i2caddress, 1);
  data = read(); //Read Data from selected register
to this:

Code: Select all

/**
 * Read bytes from an I2C peripheral
 * @param I2Cx  Pointer to I2C peripheral to read from
 * @param devAddress  The device address to read from
 * @param memAddress  The internal address to read from, I2CDEV_NO_MEM_ADDR if none.
 * @param len  Number of bytes to read.
 * @param data  Pointer to a buffer to read the data to.
 *
 * @return TRUE if read was successful, otherwise FALSE.
 */
bool i2cdevRead(I2C_Dev *dev, uint8_t devAddress, uint8_t memAddress,
               uint16_t len, uint8_t *data);
Also, I have attempted to use the debug module code and debug_print functions to get some feedback from the senor to see if it is working and nothing shows up, so I must be doing something wrong there. The height parameter I created is working correctly and showing up but it is reading zero since the sensor isn't working.

Code: Select all

LOG_GROUP_START(height)
LOG_ADD(LOG_FLOAT, heightmm, VL6180X_RESULT_RANGE_VAL)
LOG_GROUP_STOP(height)
VL610X_RESULT_RANGE_VAL is located at 0x0062

I attached the code if that helps.
Attachments
SparkFun_VL6180X_Init.h
(13.33 KiB) Downloaded 216 times
SparkFun_VL6180X.h
(7.06 KiB) Downloaded 211 times
SparkFun_VL6180X.c
(3.7 KiB) Downloaded 214 times
tobias
Bitcraze
Posts: 2339
Joined: Mon Jan 28, 2013 7:17 pm
Location: Sweden

Re: Heightsensor VL6180

Post by tobias »

I've tried to help you a little bit on the way. I written the functions that you need but have not been able to test them (no HW).

Code: Select all

static uint8_t devAddr;
static I2C_Dev *I2Cx;
static bool isInit;
...

uint8_t VL6180xInit(I2C_Dev *i2cPort)
{
  uint8_t data; //for temp data storage

  if (isInit)
    return 0;

  I2Cx = i2cPort;
  devAddr = 0x29; // Check if it is the correct initial I2C address

  data = VL6180x_getRegister(VL6180X_SYSTEM_FRESH_OUT_OF_RESET);

  if(data != 1) return VL6180x_FAILURE_RESET;

  //Required by datasheet
  //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf
  VL6180x_setRegister(0x0207, 0x01);
  VL6180x_setRegister(0x0208, 0x01);
  VL6180x_setRegister(0x0096, 0x00);
  VL6180x_setRegister(0x0097, 0xfd);
  VL6180x_setRegister(0x00e3, 0x00);
  VL6180x_setRegister(0x00e4, 0x04);
  VL6180x_setRegister(0x00e5, 0x02);
  VL6180x_setRegister(0x00e6, 0x01);
  VL6180x_setRegister(0x00e7, 0x03);
  VL6180x_setRegister(0x00f5, 0x02);
  VL6180x_setRegister(0x00d9, 0x05);
  VL6180x_setRegister(0x00db, 0xce);
  VL6180x_setRegister(0x00dc, 0x03);
  VL6180x_setRegister(0x00dd, 0xf8);
  VL6180x_setRegister(0x009f, 0x00);
  VL6180x_setRegister(0x00a3, 0x3c);
  VL6180x_setRegister(0x00b7, 0x00);
  VL6180x_setRegister(0x00bb, 0x3c);
  VL6180x_setRegister(0x00b2, 0x09);
  VL6180x_setRegister(0x00ca, 0x09);
  VL6180x_setRegister(0x0198, 0x01);
  VL6180x_setRegister(0x01b0, 0x17);
  VL6180x_setRegister(0x01ad, 0x00);
  VL6180x_setRegister(0x00ff, 0x05);
  VL6180x_setRegister(0x0100, 0x05);
  VL6180x_setRegister(0x0199, 0x05);
  VL6180x_setRegister(0x01a6, 0x1b);
  VL6180x_setRegister(0x01ac, 0x3e);
  VL6180x_setRegister(0x01a7, 0x1f);
  VL6180x_setRegister(0x0030, 0x00);

  isInit = true;
  return 0;
}

uint8_t VL6180x_getRegister(uint16_t registerAddr)
{
  uint8_t data;
  // Read adata byte from a 16bit internal register of the VL6180
  i2cdevRead16(I2Cx, devAddr, registerAddr, 2, &data); //I2Cx and devAddr set during init.

  return data;
}

uint16_t VL6180x_getRegister16bit(uint16_t registerAddr)
{
  uint16_t data;
  // Read two data byte from a 16bit internal register of the VL6180
  i2cdevRead16(I2Cx, devAddr, registerAddr, 2, (uint8_t)&data); //I2Cx and devAddr set during init.

  return data;
}

void VL6180x_setRegister(uint16_t registerAddr, uint8_t data)
{
  // Write a data byte to a 16bit internal register of the VL6180
  i2cdevWrite16(I2Cx, devAddr, registerAddr, 1, &data); //I2Cx and devAddr set during init.
}

void VL6180x_setRegister16bit(uint16_t registerAddr, uint16_t data)
{
  // Write two data bytes to a 16bit internal register of the VL6180
  i2cdevWrite16(I2Cx, devAddr, registerAddr, 2, &data); //I2Cx and devAddr set during init.
}
I'm not sure the endianess will be correct for writing and reading 16bit data. It has to be checked. Also the VL6180 is connected to I2C1 so it should be initialized with VL6180xInit(I2C1_DEV)

As for logging the range, you can't read the I2C internal address directly. You need to save it in a local variable first.

Code: Select all

float vl6180xHeight;
...
void loop() 
{
...
vl6180xHeight = getDistance(); // I would name the function vl6180xGetDistance
...
}
LOG_GROUP_START(height)
LOG_ADD(LOG_FLOAT, heightmm, &vl6180xHeight)
LOG_GROUP_STOP(height)
Tell me how it turns out!
mwall002
Beginner
Posts: 20
Joined: Wed Jul 01, 2015 4:48 am

Re: Heightsensor VL6180

Post by mwall002 »

Awesome! Thanks again Tobias. I will definitely let you know how it goes :)
mwall002
Beginner
Posts: 20
Joined: Wed Jul 01, 2015 4:48 am

Re: Heightsensor VL6180

Post by mwall002 »

Hi Tobias,
I am having a problem. I have spent a lot of time working on my code and every time I flash it to the crazy flie nothing changes. So I wanted to check to see if it was actually updating the firmware and changed the name of the "height" parameter in the stabilizer.c file to "distance" and it didn't update... (stayed height) So then the crazy thing is after I commented the whole log height call out, the parameter disappeared as expected! Then I put the "distance" call out back in and the "height" comes back!

I have tried updating it through both the client and eclipse and the results are the same.
What am I doing wrong? #frustrated
Post Reply