|
|
View previous topic :: View next topic |
Author |
Message |
bmete
Joined: 13 Jul 2023 Posts: 37
|
|
Posted: Sat May 04, 2024 9:23 am |
|
|
Hello everyone,
Thank you all for your help, I finally reached the solution. This forum is truly special.
I think the problem was in the chip or pcb. Maybe the probes of the scope were corrupting the signals. I am not sure. I continued testing with the PIC18F2520 and different PCB then finally managed to communicate properly with the sensor.
Below, I am sharing a simplified version of the code that can access a total of 32 VL6180 sensors connected to 4 TCA9548s and requests distance and signal return rate information from them. Maybe it'll be useful to someone.
Code: |
#include <18F2520.h>
#device ADC=10
#FUSES NOWDT
#use delay(internal=32MHz)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#define TCA9548_ADDRESS1 0xE0 //70 default
#define TCA9548_ADDRESS2 0xE2 //71 default
#define TCA9548_ADDRESS3 0xE4 //72 default
#define TCA9548_ADDRESS4 0xE6 //73 default
#define VL6180X_ADDRESS 0x52 // 29 default
#define VL6180X_IDENTIFICATION_MODEL_ID 0x0000
#define VL6180X_IDENTIFICATION_MODEL_REV_MAJOR 0x0001
#define VL6180X_IDENTIFICATION_MODEL_REV_MINOR 0x0002
#define VL6180X_IDENTIFICATION_MODULE_REV_MAJOR 0x0003
#define VL6180X_IDENTIFICATION_MODULE_REV_MINOR 0x0004
#define VL6180X_IDENTIFICATION_DATE 0x0006 // 16bit value
#define VL6180X_IDENTIFICATION_TIME 0x0008 // 16bit value
#define VL6180X_SYSTEM_MODE_GPIO0 0x0010
#define VL6180X_SYSTEM_MODE_GPIO1 0x0011
#define VL6180X_SYSTEM_HISTORY_CTRL 0x0012
#define VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO 0x0014
#define VL6180X_SYSTEM_INTERRUPT_CLEAR 0x0015
#define VL6180X_SYSTEM_FRESH_OUT_OF_RESET 0x0016
#define VL6180X_SYSTEM_GROUPED_PARAMETER_HOLD 0x0017
#define VL6180X_SYSRANGE_START 0x0018
#define VL6180X_SYSRANGE_THRESH_HIGH 0x0019
#define VL6180X_SYSRANGE_THRESH_LOW 0x001A
#define VL6180X_SYSRANGE_INTERMEASUREMENT_PERIOD 0x001B
#define VL6180X_SYSRANGE_MAX_CONVERGENCE_TIME 0x001C
#define VL6180X_SYSRANGE_CROSSTALK_COMPENSATION_RATE 0x001E
#define VL6180X_SYSRANGE_CROSSTALK_VALID_HEIGHT 0x0021
#define VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE 0x0022
#define VL6180X_SYSRANGE_PART_TO_PART_RANGE_OFFSET 0x0024
#define VL6180X_SYSRANGE_RANGE_IGNORE_VALID_HEIGHT 0x0025
#define VL6180X_SYSRANGE_RANGE_IGNORE_THRESHOLD 0x0026
#define VL6180X_SYSRANGE_MAX_AMBIENT_LEVEL_MULT 0x002C
#define VL6180X_SYSRANGE_RANGE_CHECK_ENABLES 0x002D
#define VL6180X_SYSRANGE_VHV_RECALIBRATE 0x002E
#define VL6180X_SYSRANGE_VHV_REPEAT_RATE 0x0031
#define VL6180X_SYSALS_START 0x0038
#define VL6180X_SYSALS_THRESH_HIGH 0x003A
#define VL6180X_SYSALS_THRESH_LOW 0x003C
#define VL6180X_SYSALS_INTERMEASUREMENT_PERIOD 0x003E
#define VL6180X_SYSALS_ANALOGUE_GAIN 0x003F
#define VL6180X_SYSALS_INTEGRATION_PERIOD 0x0040
#define VL6180X_RESULT_RANGE_STATUS 0x004D
#define VL6180X_RESULT_ALS_STATUS 0x004E
#define VL6180X_RESULT_INTERRUPT_STATUS_GPIO 0x004F
#define VL6180X_RESULT_ALS_VAL 0x0050
#define VL6180X_RESULT_HISTORY_BUFFER 0x0052
#define VL6180X_RESULT_RANGE_VAL 0x0062
#define VL6180X_RESULT_RANGE_RAW 0x0064
#define VL6180X_RESULT_RANGE_RETURN_RATE 0x0066
#define VL6180X_RESULT_RANGE_REFERENCE_RATE 0x0068
#define VL6180X_RESULT_RANGE_RETURN_SIGNAL_COUNT 0x006C
#define VL6180X_RESULT_RANGE_REFERENCE_SIGNAL_COUNT 0x0070
#define VL6180X_RESULT_RANGE_RETURN_AMB_COUNT 0x0074
#define VL6180X_RESULT_RANGE_REFERENCE_AMB_COUNT 0x0078
#define VL6180X_RESULT_RANGE_RETURN_CONV_TIME 0x007C
#define VL6180X_RESULT_RANGE_REFERENCE_CONV_TIME 0x0080
#define VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD 0x010A
#define VL6180X_FIRMWARE_BOOTUP 0x0119
#define VL6180X_FIRMWARE_RESULT_SCALER 0x0120
#define VL6180X_I2C_SLAVE_DEVICE_ADDRESS 0x0212
#define VL6180X_INTERLEAVED_MODE_ENABLE 0x02A3
void enable_bus(int8 mux_address, int8 n)
{
int8 bus = 0;
bit_set(bus,n);
i2c_start();
i2c_write(mux_address);
i2c_write(bus);
i2c_stop();
}
void VL6180x_getRegister(unsigned int16 registerAddr)
{
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((registerAddr >> 8) & 0xFF);
i2c_write(registerAddr & 0xFF);
i2c_stop();
}
void VL6180x_setRegister(unsigned int16 registerAddr, unsigned int8 data2)
{
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((registerAddr >> 8) & 0xFF);
i2c_write(registerAddr & 0xFF);
i2c_write(data2);
i2c_stop();
}
void VL6180x_setRegister16bit(unsigned int16 registerAddr, unsigned int16 data)
{
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((registerAddr >> 8) & 0xFF);
i2c_write(registerAddr & 0xFF);
unsigned int8 temp;
temp = (data >> 8) & 0xff;
i2c_write(temp);
temp = data & 0xff;
i2c_write(temp);
i2c_stop();
}
void VL6180x_init()
{
//VL6180x_getRegister(VL6180X_SYSTEM_FRESH_OUT_OF_RESET);
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);
}
void VL6180xDefautSettings()
{
//VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO, (4 << 3) | (4)); // Set GPIO1 high when sample complete
VL6180x_setRegister(VL6180X_SYSTEM_MODE_GPIO1, 0x10); // Set GPIO1 high when sample complete
VL6180x_setRegister(VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30); // Set Avg sample period
VL6180x_setRegister(VL6180X_SYSALS_ANALOGUE_GAIN, 0x46); // Set the ALS gain
VL6180x_setRegister(VL6180X_SYSRANGE_VHV_REPEAT_RATE, 0xFF); // Set auto calibration period (Max = 255)/(OFF = 0)
VL6180x_setRegister(VL6180X_SYSALS_INTEGRATION_PERIOD, 0x63); // Set ALS integration time to 100ms
VL6180x_setRegister(VL6180X_SYSRANGE_VHV_RECALIBRATE, 0x01); // perform a single temperature calibration
// Optional settings from datasheet
// http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf
VL6180x_setRegister(VL6180X_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x09); // Set default ranging inter-measurement period to 100ms
VL6180x_setRegister(VL6180X_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A); // Set default ALS inter-measurement period to 100ms
VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO, 0x24); // Configures interrupt on 'New Sample Ready threshold event'
// Additional settings defaults from community
VL6180x_setRegister(VL6180X_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32);
VL6180x_setRegister(VL6180X_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01);
VL6180x_setRegister16bit(VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x7B);
VL6180x_setRegister16bit(VL6180X_SYSALS_INTEGRATION_PERIOD, 0x64);
VL6180x_setRegister(VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30);
VL6180x_setRegister(VL6180X_SYSALS_ANALOGUE_GAIN, 0x40);
VL6180x_setRegister(VL6180X_FIRMWARE_RESULT_SCALER, 0x01);
}
void getSensorData()
{
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((0x0018 >> 8) & 0xFF);
i2c_write(0x0018 & 0xFF);
i2c_write(0x01);
i2c_stop();
delay_ms(10);
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((0x0015 >> 8) & 0xFF);
i2c_write(0x0015 & 0xFF);
i2c_write(0x07);
i2c_stop();
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((0x0062 >> 8) & 0xFF);
i2c_write(0x0062 & 0xFF);
i2c_start();
i2c_write(VL6180X_ADDRESS+1);
sensor_data1 = i2c_read(0);
i2c_stop();
i2c_start();
i2c_write(VL6180X_ADDRESS);
i2c_write((0x0066 >> 8) & 0xFF);
i2c_write(0x0066 & 0xFF);
i2c_start();
i2c_write(VL6180X_ADDRESS+1);
sensor_data2 = i2c_read(0);
i2c_stop();
}
void main()
{
enable_interrupts(GLOBAL);
VL6180x_init();
VL6180xDefautSettings();
while(TRUE)
{
for (int mux = 0xE0; mux <= 0xE6; mux += 2) // for four TCA9548
{
for(int busNum = 0; busNum < 8; busNum++) // 8 channels
{
enable_bus(mux, busNum);
getSensorData();
int8 distance = sensor_data1;
int8 returnRate = sensor_data2;
//printf("Return Rate: %X --- Distance: %X \r\n", returnRate, distance);
//delay_ms(200);
}
}
}
} |
Last edited by bmete on Sat May 04, 2024 6:37 pm; edited 1 time in total |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sat May 04, 2024 12:57 pm |
|
|
Great, it's nice you've found the solution.
And yes, this forum is special. With a right question that shows one made at least a minimal effort to find a solution at home, someone will 100% try to help. Within a day, most likely. For us in Europe even sooner, experience shows :-) |
|
|
|
|
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
|