View previous topic :: View next topic |
Author |
Message |
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu May 02, 2024 10:01 am |
|
|
Quote: |
i2c_write((0x0062 >> 8 ) & 0xFF);
//This will always write 0, since 0x0062 (and the other values you use
//have 00 as their top byte. Something not right here......
|
Mr.T,
there are some registers (I have 5 in the datasheet), that don't have 0 as a top byte address. Why ST chose to use 16bit addressing is beyond me. But it is a very good idea to use make8. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Thu May 02, 2024 3:33 pm |
|
|
re: Why ST chose to use 16bit addressing is beyond me.
easy, allows for 1,000s of devices !
Several Philips (and others) have 2 or more devices with the SAME 8 bit address, made it 'interesting' in the early dayze......
Even the lowly PC has 16 bit wide 'I/O ports', so 65,535 possible devices could be 'on the bus'. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu May 02, 2024 4:21 pm |
|
|
I meant internal register addresses. 65+ thousand seems a bit much for a sensor :-) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Thu May 02, 2024 7:43 pm |
|
|
OK, internally , they have some 'microcontroller', perhaps it's 16 bit wide architecture ? Wider is better, allows for data to move faster in single operations?? |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Fri May 03, 2024 12:57 am |
|
|
They must have a reason, of course. As for the read function, maybe this will work:
Code: |
char ReadByte(unsigned int16 reg_addr)
{
char data_read;
int8 MSB;
int8 LSB;
MSB = make8(reg_addr, 1); // Gets MSB of reg_addr
LSB = make8(reg_addr, 0); // Gets LSB of reg_addr
I2C_Start();
I2C_Write(VL6180_address); //
I2C_Write(MSB); // write MSB of address
I2C_Write(LSB); // write LSB of address
I2C_Start(); // repeat start and turn the direction of transfer
I2C_Write(VL6180_address + 1); // read
data_read = I2C_Read(0); // get data
I2C_Stop();
return data_read; // and return it to the caller
}
|
Please note that I'm mixing cases. Makes it easier for me to read, but might cause problems if case sensitivity is turned on.
Last edited by PrinceNai on Fri May 03, 2024 4:38 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri May 03, 2024 1:38 am |
|
|
Looks sensible. However, the last I2C_read in a transaction, should always
use I2C_read(0) to send the NACK. Some devices "don't care", but on a lot
of devices, not doing this can screw up subsequent operations.....
Caveat. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Fri May 03, 2024 4:38 am |
|
|
From the datasheet:
Quote: |
A message can only be terminated by the bus master, either by issuing a stop condition or
by a negative acknowledge (that is, not pulling the SDA line low) after reading a complete
byte during a read operation
|
I corrected the code above. Thanks. |
|
|
bmete
Joined: 13 Jul 2023 Posts: 37
|
|
Posted: Fri May 03, 2024 5:04 am |
|
|
Hello Prince,
I tried it the way you said and it behaves the same as the code I last shared. When I examine it with Scope, the sensor sends the response correctly, but there is still a problem in the "read" part. For some reason the data coming to the chip is always 0x00. While making a comparison and printing the data I read from the serial port, it is always 0x00. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Fri May 03, 2024 9:31 am |
|
|
for test purposes, I'd try to access the 'identification-model-id' register and confirm it IS what the datasheet says it's supposed to be.
you should see 0xB4.
if you do then proceed.. otherwise, code/compile/test until you do see 0xB4. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri May 03, 2024 9:52 am |
|
|
Are you sure you have A0,A1,& A2 low on the chip?.
Do a test with a modified version if PCM_Programmers I2C bus scanner
program. Program the multiplexer, and verify the chip is being seen at
your specified address.
This is very much a 'must do', when working with I2C. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Fri May 03, 2024 12:52 pm |
|
|
hmm, I was under the impression he wasn't using the I2C mux, keeping it simple until the sensor code actually works THEN and in the I2C MUX.
Agree the I2C Scanner is always a must run 1st to actually see the address of the I2C device is true. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sat May 04, 2024 1:17 am |
|
|
Quote: |
I was finally able to read the distance data from the sensor with the scope.
But I cannot read these values on the processor. It is always return zero.
|
Are you using mux? If so, where are you spying with the scope? Directly on the sensor or on the Pic? Can you confirm that the data that comes from the sensor appears on the other side of the mux, meaning on SDA of the PIC?
The question is this. The clock from the master obviously goes through the mux, if the sensor outputs data you see on the scope. Does that data reach PIC? I'd definitely try without the mux, to be able to isolate which part makes the problem. Software or mux. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sat May 04, 2024 1:25 am |
|
|
This is the minimal code to read ID from the sensor:
Code: |
#include <18F452.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#use delay(crystal=20000000)
#use i2c(Master, Slow, sda=PIN_C4, scl=PIN_C3, force_hw)
///////////////////////////////////////////////////////////////
// ******************** DEFINITIONS****************************
#define VL6180_address 0x52 // 0x29 is default
char IDENTIFICATION__MODEL_ID;
// ******************* FUNCTIONS ******************************
// *********** READ ONE BYTE OF DATA FROM VL6180 **************
// reads 8 bits from register 'reg_addr' that has a 16 bit address
// Split 16-bit register address into two bytes and write
// the address + read one byte of data via I2C
char ReadByte(unsigned int16 reg_addr)
{
char data_read;
int8 MSB;
int8 LSB;
MSB = make8(reg_addr, 1); // Create high byte of reg_addr
LSB = make8(reg_addr, 0); // Create low byte of reg_addr
I2C_Start();
I2C_Write(VL6180_address);
I2C_Write(MSB); // write high byte of register address
I2C_Write(LSB); // writelow byte of register address
I2C_Start(); // repeat start and turn the direction of transfer
I2C_Write(VL6180_address + 1); // write read address
data_read = I2C_Read(0); // read data from the desired register , send NACK at the end of transfer
I2C_Stop();
return data_read; // and return it to the caller
}
///////////////////////////////////////////////////////////////
void main()
{
delay_ms(100); // just in case sensor needs some time to come online
IDENTIFICATION__MODEL_ID = ReadByte(0); // read sensor model from register 0x0000. Result must be 0xB4
// display IDENTIFICATION__MODEL_ID that you just read here!!!
while(1);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Sat May 04, 2024 2:22 am |
|
|
Yes, I think he is using a mux, that is why I said a 'modified version' of
the scanning program. He needs to program the mux as he has it setup,
and then run the scanner through the mux, to see if the chip is being
seen correctly via the mux.
Suspicion is that there is something wrong perhaps with levels or timing
when the mux is enabled. Obvious things are that the pull-ups both sides
of the mux need to be adequate, and the levels these go to, need to
match the chip, and the PIC. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Sat May 04, 2024 5:28 am |
|
|
Might be time to post the complete test program !
Fresh eyes from around the World may see something you've missed. |
|
|
|