WiringPi/wiringPi/htu21d.c
Gordon Henderson b1dfc186ef A new version of wiringPi. Added in more stuff and fixed it up
for kernels 4.8 onwards.

Some very old stuff might break.

Additional fixes for the ISR code and some tweaks here and
there. I've removed the checks for some operations that might
fail when using the gpiomem interface - which is now the default
way of doing things - if your program segfaults, then you
may need to use sudo on it.
2016-12-12 14:19:55 +00:00

151 lines
3.4 KiB
C

/*
* htu21d.c:
* Extend wiringPi with the HTU21D I2C humidity and Temperature
* sensor. This is used in the Pi Weather station.
* Copyright (c) 2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include "wiringPi.h"
#include "wiringPiI2C.h"
#include "htu21d.h"
#define DEBUG
#undef FAKE_SENSOR
#define I2C_ADDRESS 0x40
int checksum (uint8_t data [4])
{
return TRUE ;
}
/*
* myAnalogRead:
*********************************************************************************
*/
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int chan = pin - node->pinBase ;
int fd = node->fd ;
uint8_t data [4] ;
uint32_t sTemp, sHumid ;
double fTemp, fHumid ;
int cTemp, cHumid ;
/**/ if (chan == 0) // Read Temperature
{
// Send read temperature command:
data [0] = 0xF3 ;
if (write (fd, data, 1) != 1)
return -9999 ;
// Wait then read the data
delay (50) ;
if (read (fd, data, 3) != 3)
return -9998 ;
if (!checksum (data))
return -9997 ;
// Do the calculation
sTemp = (data [0] << 8) | data [1] ;
fTemp = -48.85 + 175.72 * (double)sTemp / 63356.0 ;
cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ;
return cTemp ;
}
else if (chan == 1) // humidity
{
// Send read humidity command:
data [0] = 0xF5 ;
if (write (fd, data, 1) != 1)
return -9999 ;
// Wait then read the data
delay (50) ;
if (read (fd, data, 3) != 3)
return -9998 ;
if (!checksum (data))
return -9997 ;
sHumid = (data [0] << 8) | data [1] ;
fHumid = -6.0 + 125.0 * (double)sHumid / 65536.0 ;
cHumid = (int)rint (((100.0 * fHumid) + 0.5) / 10.0) ;
return cHumid ;
}
else
return -9999 ;
}
/*
* htu21dSetup:
* Create a new instance of a HTU21D I2C GPIO interface.
* This chip has a fixed I2C address, so we are not providing any
* allowance to change this.
*********************************************************************************
*/
int htu21dSetup (const int pinBase)
{
int fd ;
struct wiringPiNodeStruct *node ;
uint8_t data ;
int status ;
if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0)
return FALSE ;
node = wiringPiNewNode (pinBase, 2) ;
node->fd = fd ;
node->analogRead = myAnalogRead ;
// Send a reset code to it:
data = 0xFE ;
if (write (fd, &data, 1) != 1)
return FALSE ;
delay (15) ;
// Read the status register to check it's really there
status = wiringPiI2CReadReg8 (fd, 0xE7) ;
return (status == 0x02) ? TRUE : FALSE ;
}