Humidity and temperature sensor Sensirion SHT71 |
SHT71 wiring
Thanks to Douglas Gilbert here is a fixed and improved version of the source code in C language that reads the humidity and temperature measurements and show it on the console:
// Example of user space C program to read a humidity and temperature
// sensor Sensirion SHT71 (http://www.acmesystems.it/?id=89)
// Version improved by by Douglas Gilbert
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __CRIS__
#include "linux/gpio_syscalls.h"
#endif
// -----------------------------------------------------------------------
// SHT71 sensor define
// -----------------------------------------------------------------------
#define CLOCK_BIT 25 // IO line on port G (was OG25)
#define DATA_BIT 24 // IO line on port G
#define CLOCK_MSK (1 << CLOCK_BIT)
#define DATA_MSK (1 << DATA_BIT)
#ifdef __CRIS__
// Macro to set the data line direction
#define DATA_LINE_IN gpiosetdir(PORTG,DIRIN,DATA_MSK)
#define DATA_LINE_OUT gpiosetdir(PORTG,DIROUT,DATA_MSK)
#define DATA_LINE_LOW gpiosetdir(PORTG,DIROUT,DATA_MSK);gpioclearbits(PORTG,DATA_MSK)
#define DATA_LINE_HIGH gpiosetdir(PORTG,DIRIN,DATA_MSK)
#define DATA_LINE_READ gpiogetbits(PORTG,DATA_MSK)?(1):(0)
#define CLOCK_LINE_LOW gpioclearbits(PORTG,CLOCK_MSK)
#define CLOCK_LINE_HIGH gpiosetbits(PORTG,CLOCK_MSK)
#endif
#define CMD_READ_TEMP 0x03
#define CMD_READ_HUM 0x05
static int verbose = 0;
static const char * version_str = "1.02 20090128";
static void
usage(void)
{
fprintf(stderr, "Usage: "
"sht_test [-h] [-r] [-v] [-V]\n"
" where:\n"
" -h print usage message\n"
" -r send reset to SHT before fetching info\n"
" -v increase verbosity (more written to log)\n"
" -V print version string then exit\n\n"
"Test Sensirion SHT-71, CLK=(I)OG%d DATA=IOG%d\n", CLOCK_BIT,
DATA_BIT);
}
#ifdef __CRIS__
// -----------------------------------------------------------------------
// Send the start sequence
// -----------------------------------------------------------------------
static void
SendStart(void)
{
DATA_LINE_OUT;
CLOCK_LINE_HIGH;
usleep(1000);
DATA_LINE_IN;
DATA_LINE_LOW;
CLOCK_LINE_LOW;
CLOCK_LINE_HIGH;
usleep(1000);
DATA_LINE_HIGH;
CLOCK_LINE_LOW;
DATA_LINE_IN;
}
// -----------------------------------------------------------------------
// Sensor reset
// -----------------------------------------------------------------------
static void
SendReset (void)
{
int k;
for (k = 0; k < 12; k++) {
CLOCK_LINE_HIGH;
usleep(1000);
CLOCK_LINE_LOW;
}
}
// -----------------------------------------------------------------------
// Send a byte to the sensor
// -----------------------------------------------------------------------
static int
SendByte(unsigned char byte)
{
unsigned char tempbyte;
int k;
DATA_LINE_OUT;
tempbyte = byte;
for (k = 0x80; k > 0; k /= 2) {
if (tempbyte & k)
DATA_LINE_HIGH;
else
DATA_LINE_LOW;
CLOCK_LINE_HIGH;
usleep(1000);
CLOCK_LINE_LOW;
}
DATA_LINE_IN;
CLOCK_LINE_HIGH;
CLOCK_LINE_LOW;
return 1;
}
// -----------------------------------------------------------------------
// Read a byte from the sensor
// withack
// 1 = send the ACK
// 0 = don't send the ACK
// -----------------------------------------------------------------------
static unsigned char
ReadByte(int withack)
{
unsigned char tempbyte;
int k;
tempbyte = 0;
DATA_LINE_IN;
for (k = 0x80; k > 0; k /= 2) {
CLOCK_LINE_HIGH;
if (DATA_LINE_READ)
tempbyte |= k;
CLOCK_LINE_LOW;
}
if (withack) {
// Acknowledge del byte
DATA_LINE_OUT;
DATA_LINE_LOW;
CLOCK_LINE_HIGH;
CLOCK_LINE_LOW;
DATA_LINE_IN;
} else {
// Senza acknowledge
DATA_LINE_OUT;
DATA_LINE_HIGH;
CLOCK_LINE_HIGH;
CLOCK_LINE_LOW;
DATA_LINE_IN;
}
return tempbyte;
}
// ----------------------
// Read the temperature
// ----------------------
static int
ReadTemperature(void)
{
unsigned char Lsb, Msb, Chk;
SendStart();
if (! SendByte(CMD_READ_TEMP))
return 0;
while (DATA_LINE_READ)
;
Msb = ReadByte(1);
if (verbose > 1)
fprintf(stderr, "ReadTemperature: Msb=%d\n", Msb);
Lsb = ReadByte(1);
if (verbose > 1)
fprintf(stderr, "ReadTemperature: Lsb=%d\n", Lsb);
Chk = ReadByte(0);
if (verbose > 1)
fprintf(stderr, "ReadTemperature: Chk=%d\n", Chk);
if (1 == verbose)
fprintf(stderr, "ReadTemperature: Msb=%d Lsb=%d Chk=%d\n", Msb, Lsb,
Chk);
return (Msb << 8) + Lsb;
}
// ------------------
// Read the humidity
// ------------------
static int
ReadHumidity(void)
{
unsigned char Lsb, Msb, Chk;
SendStart();
if (! SendByte(CMD_READ_HUM))
return 0;
while (DATA_LINE_READ)
;
Msb = ReadByte(1);
if (verbose > 1)
fprintf(stderr, "ReadHumidity: Msb=%d\n", Msb);
Lsb = ReadByte(1);
if (verbose > 1)
fprintf(stderr, "ReadHumidity: Lsb=%d\n", Lsb);
Chk = ReadByte(0);
if (verbose > 1)
fprintf(stderr, "ReadHumidity: Chk=%d\n", Chk);
if (1 == verbose)
fprintf(stderr, "ReadHumidity: Msb=%d Lsb=%d Chk=%d\n", Msb, Lsb,
Chk);
return (Msb << 8) + Lsb ;
}
#else
static int
ReadHumidity(void)
{
return 0;
}
static int
ReadTemperature(void)
{
return 0;
}
static void
SendReset(void)
{
}
#endif
// ----------
// main code
// ----------
int
main(int argc, char ** argv)
{
int opt, soh, sot;
int do_reset = 0;
float rel_humidity, temperature_c;
while ((opt = getopt(argc, argv, "hrvV")) != -1) {
switch (opt) {
case 'h':
usage();
exit(EXIT_SUCCESS);
case 'r':
++do_reset;
break;
case 'v':
++verbose;
break;
case 'V':
printf("%s\n", version_str);
exit(EXIT_SUCCESS);
default: /* '?' */
usage();
exit(EXIT_FAILURE);
}
}
if (optind < argc) {
if (optind < argc) {
for (; optind < argc; ++optind)
fprintf(stderr, "Unexpected extra argument: %s\n",
argv[optind]);
usage();
exit(EXIT_FAILURE);
}
}
if (verbose)
fprintf(stderr, "%s: Clock line (I)OG%d, Data line IOG%d\n",
__FILE__ ,CLOCK_BIT, DATA_BIT);
if (do_reset > 0)
SendReset();
// assume 12 bit (rather than 8 bit) accuracy
soh = ReadHumidity();
sot = ReadTemperature();
if (verbose)
fprintf(stderr, "soh=%d [0x%x] sot=%d [0x%x]\n", soh, soh, sot, sot);
#if 1
// new formula from SHT7x version 4.1 datasheet
rel_humidity = -2.0468 + (0.0367 * soh) + (-1.5955E-6 * soh * soh);
#else
// older formula
rel_humidity = -4 + (0.0405 * soh) + -2.8E-6;
#endif
if (rel_humidity > 99.9)
rel_humidity = 100.0;
else if (rel_humidity < 0.1)
rel_humidity = 0.0;
temperature_c = -39.66 + (0.01 * sot);
printf ("Rel. Humidity: %.2f %%\n", rel_humidity);
printf ("Temperature : %.2f C\n", temperature_c);
return 0;
}
Its possible to compile it directly on-line with the Webcompiler.
# ./sht71 Humidity : 60.15 % Temperature: 22.70 C #
The FOXZB board has a placement for the Sensirion SHT71 or SHT75 sensor has shown in the following pictures ():
Placement for the SHT7x sensor on the FOXZB add-on board