Heightsensor VL6180
Heightsensor VL6180
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
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
Re: Heightsensor VL6180
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!
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 250 times
Re: Heightsensor VL6180
Looks like a nice sensor! I would recommend having a look at the MPU9250 driver. It's I2C and integrated in the regulation.
Re: Heightsensor VL6180
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...
https://github.com/sparkfun/ToF_Range_F ... es/Arduino
I have attached a picture of my flie with the sensor installed
https://github.com/sparkfun/ToF_Range_F ... es/Arduino
I have attached a picture of my flie with the sensor installed
Re: Heightsensor VL6180
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.
could be replaced with something like this:
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
}
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.
}
Re: Heightsensor VL6180
Thanks for the help Tobias! I will keep working on it and share the code once the sensor is reading properly.
Re: Heightsensor VL6180
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:
to this:
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.
VL610X_RESULT_RANGE_VAL is located at 0x0062
I attached the code if that helps.
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
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);
Code: Select all
LOG_GROUP_START(height)
LOG_ADD(LOG_FLOAT, heightmm, VL6180X_RESULT_RANGE_VAL)
LOG_GROUP_STOP(height)
I attached the code if that helps.
- Attachments
-
- SparkFun_VL6180X_Init.h
- (13.33 KiB) Downloaded 218 times
-
- SparkFun_VL6180X.h
- (7.06 KiB) Downloaded 213 times
-
- SparkFun_VL6180X.c
- (3.7 KiB) Downloaded 217 times
Re: Heightsensor VL6180
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).
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.
Tell me how it turns out!
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.
}
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)
Re: Heightsensor VL6180
Awesome! Thanks again Tobias. I will definitely let you know how it goes
Re: Heightsensor VL6180
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
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