View previous topic :: View next topic |
Author |
Message |
Jody
Joined: 08 Sep 2006 Posts: 182
|
i2c problem, changed |
Posted: Tue Mar 31, 2020 3:10 pm |
|
|
Hello,
I am a little confuse (and in lock down)..
But what I have:
Compiler 5.080
PIC: 18F87J50
I am trying to test a i2c device but the i2c port is not responding..
Have connected a oscilliscoop connected and SDA , SCL are not giving any sign of live.. What have I done to make the i2c not responding at all.????
This is what I have done:
Code: |
#include <main_PIC18F87J50.h>
#include <CCS811.c>
int init_CCS811_ok = 1;
void main()
{
while(1)
{
// check of the CCS811 is present
init_CCS811_ok = CCS811_Check_Present();
}
} |
the include:
Code: |
#include <18F87J50.h>
#device ADC=10
#define CCS811_ENABLE PIN_D0
#FUSES NOWDT //No Watch Dog Timer
#use delay(oscillator=20000000)
#use i2c(Master,Slow,sda=PIN_D5,scl=PIN_D6,stream=CCS811_STREAM)
|
and the CCS811 code (so far)
Code: |
#define CCS811_CHIP_ID 0x81
#define STATUS_REG 0x00
#define MEAS_MODE_REG 0x01
#define ALG_RESULT_DATA 0x02
#define ENV_DATA 0x05
#define THRESHOLDS 0x10
#define BASELINE 0x11
#define HW_ID_REG 0x20
#define ERROR_ID_REG 0xE0
#define APP_START_REG 0xF4
#define SW_RESET 0xFF
#define CCS_811_ADDRESS 0x5B // CCS811 ADDR pin is logic zero otherwise address would be 0x5B
#define GPIO_WAKE 0x5
#define DRIVE_MODE_IDLE 0x0
#define DRIVE_MODE_1SEC 0x10
#define DRIVE_MODE_10SEC 0x20
#define DRIVE_MODE_60SEC 0x30
#define INTERRUPT_DRIVEN 0x8
#define THRESHOLDS_ENABLED 0x4
// reads 8 bits from register 'reg_addr'
int8 CCS811_Read8(int8 reg_addr)
{
int8 ret;
output_low(CCS811_ENABLE);
delay_us(50);
I2C_Start(CCS811_STREAM);
I2C_Write(CCS811_STREAM, CCS_811_ADDRESS);
I2C_Write(CCS811_STREAM, reg_addr);
ret = I2C_Read(CCS811_STREAM, 0);
I2C_Stop(CCS811_STREAM);
output_high(CCS811_ENABLE);
return ret;
}
//CCS811 read the cip ID register must be CCS811_CHIP_ID = 0x81
int1 CCS811_Check_Present()
{
if(CCS811_Read8(HW_ID_REG) != CCS811_CHIP_ID)
return 0;
} |
Last edited by Jody on Wed Apr 01, 2020 2:48 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Tue Mar 31, 2020 11:53 pm |
|
|
This:
Code: |
int1 CCS811_Check_Present()
{
if(CCS811_Read8(HW_ID_REG) != CCS811_CHIP_ID)
return 0;
}
|
Does not return anything, if CCS811_Red8(HW_ID_REG) == CCS811_CHIP_ID
This is an undefined value.
In C, this is implicitly 'legal', but automatically 'undefined'...
The latest compilers will warn if a routine does not always
return a value.
It sounds as if it has started actually sending data after a restart. However
this should be corrected. |
|
![](templates/subSilver/images/spacer.gif) |
Jody
Joined: 08 Sep 2006 Posts: 182
|
|
Posted: Wed Apr 01, 2020 2:35 am |
|
|
Thanks,
I will fix this...
But now I have your attention.....
Could you read with me where I made a boo boo...
I have:
sensor: CCS811
[url]
https://ams.com/documents/20143/36005/CCS811_AN000369_2-00.pdf/fb08da36-5b40-732b-39b0-62d2d9db5a3c
[/url]
at page 16 it's similair with what I am sending..
in the *.h file:
#use i2c(Master,Slow,sda=PIN_D5,scl=PIN_D6,force_HW,stream=CCS811_STREAM)
Code: |
//***** reg_addr = 0x20 ****//
//***** CCS_811_aADDRESS = 0x5A ****//
// reads 8 bits from register 'reg_addr'
int8 CCS811_Read8(int8 reg_addr)
{
int8 ret;
output_low(CCS811_ENABLE);
delay_us(50);
I2C_Start(CCS811_STREAM,0);
I2C_Write(CCS811_STREAM, CCS_811_ADDRESS);
I2C_Write(CCS811_STREAM, reg_addr);
ret = I2C_Read(CCS811_STREAM);
I2C_Stop(CCS811_STREAM);
output_high(CCS811_ENABLE);
delay_us(50);
return ret;
}
|
I am always getting 0xFF as a output...
Logic anaylyzer is showing the correct data sends to the sensor ( I hope).
Screenshot from mine analyzer:
https://www.dropbox.com/s/6ad14nxkfqb16sa/screenshot.png?raw=1
best regards,
Jody |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Wed Apr 01, 2020 2:59 am |
|
|
Before doing anything else, go to the code library, get the I2C bus scanner
program from there, modify this to match your I2C settings, and run this.
This will tell you if the device is actually being seen on the I2C bus.
There is no point in wondering about the code, till you have proved that
the connections are correct and the device is being seen. |
|
![](templates/subSilver/images/spacer.gif) |
Jody
Joined: 08 Sep 2006 Posts: 182
|
|
Posted: Wed Apr 01, 2020 3:05 am |
|
|
Oke thanks for the advice!!
I will start this!! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Wed Apr 01, 2020 3:06 am |
|
|
You device address is wrong. The device is on address 0xB4.
You are misunderstanding how a '7bit address' needs to be used. On a
PIC, the address byte is an 8bit value, comprising the 7bit device address
followed by the flag bit for R/W.
On I2C, when you want to read, you have to issue a 'restart'.
Code: |
#define CCS_811_aADDRESS 0xB4
output_low(CCS811_ENABLE);
delay_us(50);
I2C_Start(CCS811_STREAM,0);
I2C_Write(CCS811_STREAM, CCS_811_ADDRESS);
I2C_Write(CCS811_STREAM, reg_addr);
I2C_WRITE(CCS811_STREAM, CCS_811_ADDRESS+1); //bus read
ret = I2C_Read(CCS811_STREAM);
I2C_Stop(CCS811_STREAM);
output_high(CCS811_ENABLE);
|
The restart command reverses the bus direction so you can read.
Look at Figure 6 in the data sheet where it shows this happening. |
|
![](templates/subSilver/images/spacer.gif) |
Jody
Joined: 08 Sep 2006 Posts: 182
|
|
Posted: Wed Apr 01, 2020 3:25 am |
|
|
It found one I2C device.
at address 0xB4....
still no response.... |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 01, 2020 3:43 am |
|
|
Look at this i2c diagram on page 14 of the CCS811 data sheet:
Quote: |
Figure 10: I²C Register Read
Select and read register
value, as single
transaction |
The following code duplicates the i2c diagram.
Code: | i2c_start();
i2c_write(CCS_811_ADDRESS); // Write address
i2c_write(reg_addr);
i2c_start(); <== *** restart ***
i2c_write(CCS_811_ADDRESS+1); // Read address
ret = i2c_read(0); // NAK
i2c_stop();
|
Also, when you put in this very long stream name in every single i2c line
it obscures the actual necessary operations. It makes it harder to read.
At least initially, leave off the stream name until you get the code right. |
|
![](templates/subSilver/images/spacer.gif) |
Jody
Joined: 08 Sep 2006 Posts: 182
|
|
Posted: Wed Apr 01, 2020 3:50 am |
|
|
Thanks for all your assistance but It is still not working.
The signals look the same as in the datasheet
I mentioned (page 16) but I get 0xFF instead of 0x81.
So it is alive but not responding like it should.
Any idea's ?
Function I use is:
Code: | // reads 8 bits from register 'reg_addr'
int8 CCS811_Read8(int8 reg_addr)
{
int8 ret;
output_low(CCS811_ENABLE);
delay_us(50);
i2c_start();
i2c_write(0xB4); // Write address
i2c_write(reg_addr);
i2c_start(); // <== *** restart ***
i2c_write(0xB5); // Read address
ret = i2c_read(0); // NAK
i2c_stop();
delay_us(50);
return ret;
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Jody
Joined: 08 Sep 2006 Posts: 182
|
|
Posted: Wed Apr 01, 2020 3:52 am |
|
|
Found it!!!!!!!
Not pulling the ENABLE low but pulling it UP....
Still this is not what I read in the datasheet!!!!
Thanks you both!!!!! for all the tips!!
and the i2C_scanner is a keeper!!!!! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Wed Apr 01, 2020 1:03 pm |
|
|
Slightly puzzled, since the data sheet for the chip doesn't show an 'enable'.
Which pin are you actually using?. |
|
![](templates/subSilver/images/spacer.gif) |
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Wed Apr 01, 2020 8:09 pm |
|
|
Hi All,
My guess would be the ‘nWake’ pin, which is pin 7. This pin needs to be asserted low by the host for the device to work.
John _________________ John
If it's worth doing, it's worth doing in real hardware! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Wed Apr 01, 2020 11:54 pm |
|
|
Agreed. That is the only pin that possibly makes sense. However he
is saying that it is working with this taken high?.
It would need to be taken high at the start of the main code, so that it
can then be dropped for the I2C transactions.
If it is working with this taken high, then we would need details of the board
he is using?. Possibly he has one that has a buffer on this connection. |
|
![](templates/subSilver/images/spacer.gif) |
Jody
Joined: 08 Sep 2006 Posts: 182
|
|
Posted: Thu Apr 02, 2020 3:48 am |
|
|
Ok I have an update...
The hardware engineer who makes this board I am working with (me),
has placed a buffer at some outputs....inverted buffers and guess what....
This is the output to drive the nWake input... :oops:
This with my mistake using the wrong address.... makes that is leaves me dazed and confused...
So at this moment I can communicate with the device and make it work so that I get the data I need...
Sorry for all my stupid mistakes... working from home makes me sloppy.
And thank for all the useful advice !!!
Best regards,
Jody |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Thu Apr 02, 2020 6:56 am |
|
|
At least that makes sense!...
Anyone here who hasn't had a 'opps' moment like this, won't understand,
but 95+% of people will understand totally. ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|