View previous topic :: View next topic |
Author |
Message |
andrew007
Joined: 27 Feb 2023 Posts: 8
|
SHT40-AD1B temperature and Humidity sensor issue |
Posted: Tue Feb 28, 2023 4:53 am |
|
|
hi,
Passing from HTS221 to SHT40 seems there is a problem in reading the sensor.
I've used the standard C reference instructions i2c_transfer_in e i2c_transfer_out but the sensor don't answer. I've used PIC18LF47K40.
Code: |
#include <18LF47K40.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#use delay(internal=8MHz)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,Force_Sw)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#define Centigrade
#define SHT40_OK 0
#define SHT40_ERROR 1
#define SHT40_BASE_ADDR 0x44
#define CRC8_POLYNOMIAL 0x31
#define CRC8_INIT 0xFF
#define CRC8_LEN 1
#define CRC_ERROR 1
#define NO_ERROR 0
#define T_CRC 2
#define H_CRC 3
#define HIGH_PREC_HIGH_REPEAT 0xFD
#define delay_HH 10
#define MED_PREC_MED_REPEAT 0xF6
#define delay_MM 5
#define LOW_PREC_LOW_REPEAT 0xE0
#define delay_LL 2
#define READ_SERIAL_NUM 0x89
#define SOFT_RESET 0x94
#define HEATER_200mW_1SEC 0x39
#define HEATER_200mW_0P1SEC 0x32
#define HEATER_110mW_1SEC 0x2F
#define HEATER_110mW_0P1SEC 0x24
#define HEATER_20mW_1SEC 0x1E
#define HEATER_20mW_0P1SEC 0x15
#define delay_LP 1100
#define delay_SP 100
void main()
{
unsigned int8 data[6];
int1 ack;
i2c_init(TRUE);
printf("Hello world!"); // UART write
delay_ms(1000);
ack = i2c_transfer_out(0x44,0xFD,1);
if(ack==0)
printf("\r\nData transferred successfully");
else
printf("\r\nData transferred unsuccessfully");
delay_ms(10);
ack=i2c_transfer_in(0x44,data,6);
if(ack==0)
printf("Data read successfully");
else
printf("data not read");
printf("%d\n\r",data[0]);
printf("%d\n\r",data[1]);
printf("%d\n\r",data[2]);
printf("%d\n\r",data[3]);
printf("%d\n\r",data[4]);
printf("%d\n\r",data[5]);
while(TRUE)
{
//TODO: User Code
}
}
|
Thanks to all, please the datasheet of the SHT40 is very poor for information, not tell us much over the registers. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 01, 2023 1:59 am |
|
|
Your code has several mistakes. You need to do it like this:
Code: |
#define SHT40_BASE_ADDR 0x88
#define SHT4X_CMD_MEASURE_HPM 0xFD
//================================
void main(void)
{
unsigned int8 wData[1] = SHT4X_CMD_MEASURE_HPM;
unsigned int8 rData[6] = {0};
ack = i2c_transfer_out(SHT40_BASE_ADDR, wData, 1);
.
.
.
ack=i2c_transfer_in(SHT40_BASE_ADDR, rData, 6);
.
.
.
while(TRUE)
{
//TODO: User Code
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Mar 01, 2023 7:49 am |
|
|
low level hardware comments...
'SHT40'....is a 3 volt device. I see 'LF',so the PIC IS a 3 volt ?
Assuming it's on a 'module', can you confirm, using the I2C scanner program in the code library, that you CAN communicate to it ?
When using any I2C device it's always a good idea to run I2Cscanner ! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Mar 02, 2023 1:59 am |
|
|
Agree wholeheartedly with Jay on testing with the I2C_scanner.
However the big 'critical' one has already been pointed out by PCM. The
device has a 7bit I2C address of 0x44, so for a PIC 8bit I2C address,
needs to be talked to on 0x88. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Thu Mar 02, 2023 6:38 am |
|
|
and....
running I2CSCANNER will SHOW you the address of the device when it finds it.
7 bit addressing has always struck me as odd (no pun), as you must either read or write to the device using 8 bits of one byte and there's no other way to access the device.
one of life's mysteries |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Mar 02, 2023 6:50 am |
|
|
Quote: | 7 bit addressing has always struck me as odd (no pun ) |
Maybe none was intended, but it is in fact a very good one |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Mar 06, 2023 7:11 am |
|
|
I think what was peculiar, was the decision when designing I2C, to put the
R/W bit at the bottom of the address field. It could have been put at the
top just as easily, and if so the addresses wouldn't have the issue of having
to be doubled when used in the byte... |
|
|
andrew007
Joined: 27 Feb 2023 Posts: 8
|
|
Posted: Tue Mar 07, 2023 8:13 am |
|
|
temtronic wrote: | low level hardware comments...
'SHT40'....is a 3 volt device. I see 'LF',so the PIC IS a 3 volt ?
Assuming it's on a 'module', can you confirm, using the I2C scanner program in the code library, that you CAN communicate to it ?
When using any I2C device it's always a good idea to run I2Cscanner ! |
Many thanks, yes is a 3.3V device. Thanks for the suggestion. I use i2c_scanner an example that searched here adapted and he found all adress at the moment not only one |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Mar 07, 2023 8:22 am |
|
|
hmm... 'found all addresses' sounds like no I2C pullup resistors, or the wrong value.
With a 3 volt PIC, the pullups should probably be 3K3 or 2K7, though that depends on speed of the interface, distance between them and 'wiring'. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Tue Mar 07, 2023 8:32 am |
|
|
One other critical thing. He needs to turn off slew rate control on the
I2C pins. By default this will be on. Needs:
set_slow_slew_C(FALSE);
To disable this on this port. |
|
|
andrew007
Joined: 27 Feb 2023 Posts: 8
|
|
Posted: Tue Mar 07, 2023 8:36 am |
|
|
PCM programmer wrote: | Your code has several mistakes. You need to do it like this:
Code: |
#define SHT40_BASE_ADDR 0x88
#define SHT4X_CMD_MEASURE_HPM 0xFD
//================================
void main(void)
{
unsigned int8 wData[1] = SHT4X_CMD_MEASURE_HPM;
unsigned int8 rData[6] = {0};
ack = i2c_transfer_out(SHT40_BASE_ADDR, wData, 1);
.
.
.
ack=i2c_transfer_in(SHT40_BASE_ADDR, rData, 6);
.
.
.
while(TRUE)
{
//TODO: User Code
}
}
|
|
Many thanks for your correction, for the sensor we have, according to datasheet of SHT40-AD1B address 0x44 and the i2c communication that start with S+i2c_address(7bit)+Write_bit after ack +8bit_command+ack+Stop .... and thus the question is if i need to write something similar
i2c_init();
i2c_start();
i2c_write(SHT40_BASE_ADDR);
i2c_write(0);
i2c_write(wData);
i2c_stop();
delay_ms(10);
i2c_start();
i2c_write(SHT40_BASE_ADDR); ///044*2 because the 0 of the write (8bit total)
i2c_write(1);
rData[0]= i2c_read();
rData[1]=i2c_read();
rData[2]=i2c_read();
rData[3]=i2c_read();
rData[4]=i2c_read();
rData[5]=i2c_read();
i2c_stop();
thanks to all for the support |
|
|
andrew007
Joined: 27 Feb 2023 Posts: 8
|
|
Posted: Tue Mar 07, 2023 8:41 am |
|
|
Ttelmah wrote: | Agree wholeheartedly with Jay on testing with the I2C_scanner.
However the big 'critical' one has already been pointed out by PCM. The
device has a 7bit I2C address of 0x44, so for a PIC 8bit I2C address,
needs to be talked to on 0x88. |
Thanks a lot, corrected! |
|
|
andrew007
Joined: 27 Feb 2023 Posts: 8
|
|
Posted: Tue Mar 07, 2023 8:42 am |
|
|
temtronic wrote: | and....
running I2CSCANNER will SHOW you the address of the device when it finds it.
7 bit addressing has always struck me as odd (no pun), as you must either read or write to the device using 8 bits of one byte and there's no other way to access the device.
one of life's mysteries |
is a truly mistery... |
|
|
andrew007
Joined: 27 Feb 2023 Posts: 8
|
|
Posted: Tue Mar 07, 2023 8:43 am |
|
|
temtronic wrote: | hmm... 'found all addresses' sounds like no I2C pullup resistors, or the wrong value.
With a 3 volt PIC, the pullups should probably be 3K3 or 2K7, though that depends on speed of the interface, distance between them and 'wiring'. |
Yes thanks the resistors for SCL and SDA are both 3,3k and there is also the 100nF capcitor between Vcc =3,3V and gnd |
|
|
andrew007
Joined: 27 Feb 2023 Posts: 8
|
|
Posted: Tue Mar 07, 2023 8:59 am |
|
|
Ttelmah wrote: | One other critical thing. He needs to turn off slew rate control on the
I2C pins. By default this will be on. Needs:
set_slow_slew_C(FALSE);
To disable this on this port. |
Thanks a lot, disabled! |
|
|
|