wiringPi/wiringPi/htu21d.c

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 ;
}