th02: fix non-working driver

There were a few issues with this driver, corrected in this update.

1) i2c transactions were not working - I replaced the i2c
implementation with the MRAA i2c class implementation.

2) status check was inverted - fixed.

3) fixed up #defines in header file to avoid naming collisions (ADDR,
etc).

4) Added capability to supply bus and i2c address to ctor, setting
defaults of 0, and TH02_ADDR respectively.

NOTE: For proper operation on Edison using the arduino breakout
board, the voltage needs to be set to 3.3V rather than 5v.  On G2, 5v
works fine.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
Jon Trulson 2015-05-26 13:59:30 -06:00 committed by Mihai Tudor Panu
parent d36499eac8
commit b633ecf97f
3 changed files with 49 additions and 105 deletions

View File

@ -50,7 +50,7 @@ main(int argc, char **argv)
while (!doWork) { while (!doWork) {
temperature = sensor->getTemperature (); temperature = sensor->getTemperature ();
// humidity = sensor->getHumidity (); humidity = sensor->getHumidity ();
std::cout << "Temperature = " << temperature << ", Humidity = " << humidity << std::endl; std::cout << "Temperature = " << temperature << ", Humidity = " << humidity << std::endl;
usleep (500000); usleep (500000);
} }

View File

@ -1,5 +1,6 @@
/* /*
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com> * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
* Contributions: Jon Trulson <jtlulson@ics.com>
* Copyright (c) 2014 Intel Corporation. * Copyright (c) 2014 Intel Corporation.
* *
* Credits to Seeed Studeo. * Credits to Seeed Studeo.
@ -30,6 +31,7 @@
#include "th02.h" #include "th02.h"
using namespace std;
using namespace upm; using namespace upm;
struct TH02Exception : public std::exception { struct TH02Exception : public std::exception {
@ -39,122 +41,68 @@ struct TH02Exception : public std::exception {
const char* what() const throw () { return message.c_str(); } const char* what() const throw () { return message.c_str(); }
}; };
TH02::TH02 () { TH02::TH02 (int bus, uint8_t addr) : m_i2c(bus) {
m_addr = addr;
m_name = "TH02"; m_name = "TH02";
m_i2Ctx = mraa_i2c_init(0);
mraa_result_t ret = mraa_i2c_address(m_i2Ctx, ADDR); mraa_result_t ret = m_i2c.address(m_addr);
if (ret != MRAA_SUCCESS) { if (ret != MRAA_SUCCESS) {
throw TH02Exception ("Couldn't initilize I2C."); throw TH02Exception ("Couldn't initilize I2C.");
} }
} }
TH02::~TH02 () { TH02::~TH02 () {
mraa_i2c_stop(m_i2Ctx);
} }
float float
TH02::getTemperature () { TH02::getTemperature () {
uint8_t buffer[3];
uint16_t temperature = 0; uint16_t temperature = 0;
/* Start a new temperature conversion */ /* Start a new temperature conversion */
i2cWriteReg (REG_CONFIG, CMD_MEASURE_TEMP); if (m_i2c.writeReg(TH02_REG_CONFIG, TH02_CMD_MEASURE_TEMP)) {
cerr << __FUNCTION__ << "@" << __LINE__
<< ": writeReg failed" << endl;
return 0.0;
}
/* Wait until conversion is done */ /* Wait until conversion is done */
while (getStatus() == false); while (getStatus() == false);
if (i2cReadReg_N (REG_DATA_H, 3, buffer) > 2) { temperature = m_i2c.readReg(TH02_REG_DATA_H) << 8;
temperature = (buffer[1] << 8) | buffer[2]; temperature |= m_i2c.readReg(TH02_REG_DATA_L);
temperature >>= 2; temperature >>= 2;
return (temperature / 32.0) - 50.0; return ((float(temperature) / 32.0) - 50.0);
}
return 0.0;
} }
float float
TH02::getHumidity () { TH02::getHumidity () {
uint8_t buffer[3];
uint16_t humidity = 0; uint16_t humidity = 0;
/* Start a new humility conversion */ /* Start a new humidity conversion */
i2cWriteReg (REG_CONFIG, CMD_MEASURE_HUMI); if (m_i2c.writeReg(TH02_REG_CONFIG, TH02_CMD_MEASURE_HUMI)) {
cerr << __FUNCTION__ << "@" << __LINE__
<< ": writeReg failed" << endl;
return 0.0;
}
/* Wait until conversion is done */ /* Wait until conversion is done */
while (getStatus() == false); while (getStatus() == false);
if (i2cReadReg_N (REG_DATA_H, 3, buffer) > 2) { humidity = m_i2c.readReg(TH02_REG_DATA_H) << 8;
humidity = (buffer[1] << 8) | buffer[2]; humidity |= m_i2c.readReg(TH02_REG_DATA_L);
humidity >>= 4; humidity >>= 4;
return (humidity / 16.0) - 24.0; return ((float(humidity) / 16.0) - 24.0);
}
return 0.0;
} }
bool bool
TH02::getStatus () { TH02::getStatus () {
uint8_t buffer[1]; uint8_t status = m_i2c.readReg(TH02_REG_STATUS);
if (i2cReadReg_N (REG_STATUS, 1, buffer) > 0) { if (status & TH02_STATUS_RDY_MASK)
if (buffer[0] & STATUS_RDY_MASK) { return false; // NOT ready
return true; // ready else
} return true; // ready
}
return false;
} }
/*
* **************
* private area
* **************
*/
uint16_t
TH02::i2cReadReg_N (int reg, unsigned int len, uint8_t * buffer) {
int readByte = 0;
if (m_i2Ctx == NULL) {
throw TH02Exception ("Couldn't find initilized I2C.");
}
mraa_i2c_address(m_i2Ctx, ADDR);
mraa_i2c_write_byte(m_i2Ctx, reg);
mraa_i2c_address(m_i2Ctx, ADDR);
readByte = mraa_i2c_read(m_i2Ctx, buffer, len);
return readByte;
}
mraa_result_t
TH02::i2cWriteReg_N (uint8_t reg, unsigned int len, uint8_t * buffer) {
mraa_result_t error = MRAA_SUCCESS;
if (m_i2Ctx == NULL) {
throw TH02Exception ("Couldn't find initilized I2C.");
}
error = mraa_i2c_address (m_i2Ctx, ADDR);
error = mraa_i2c_write_byte (m_i2Ctx, reg);
error = mraa_i2c_write (m_i2Ctx, buffer, len);
return error;
}
mraa_result_t
TH02::i2cWriteReg (uint8_t reg, uint8_t data) {
mraa_result_t error = MRAA_SUCCESS;
if (m_i2Ctx == NULL) {
throw TH02Exception ("Couldn't find initilized I2C.");
}
error = mraa_i2c_address (m_i2Ctx, ADDR);
error = mraa_i2c_write_byte (m_i2Ctx, reg);
error = mraa_i2c_write_byte (m_i2Ctx, data);
return error;
}

View File

@ -1,5 +1,6 @@
/* /*
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com> * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
* Contributions: Jon Trulson <jtlulson@ics.com>
* Copyright (c) 2014 Intel Corporation. * Copyright (c) 2014 Intel Corporation.
* *
* Credits to Seeed Studeo. * Credits to Seeed Studeo.
@ -26,26 +27,20 @@
#pragma once #pragma once
#include <string> #include <string>
#include <mraa/i2c.h> #include <mraa/i2c.hpp>
#define ADDR 0x40 // device address #define TH02_ADDR 0x40 // device address
#define REG_STATUS 0x00 #define TH02_REG_STATUS 0x00
#define REG_DATA_H 0x01 #define TH02_REG_DATA_H 0x01
#define REG_DATA_L 0x02 #define TH02_REG_DATA_L 0x02
#define REG_CONFIG 0x03 #define TH02_REG_CONFIG 0x03
#define REG_ID 0x11 #define TH02_REG_ID 0x11
#define STATUS_RDY_MASK 0x01 #define TH02_STATUS_RDY_MASK 0x01
#define CMD_MEASURE_HUMI 0x01 #define TH02_CMD_MEASURE_HUMI 0x01
#define CMD_MEASURE_TEMP 0x11 #define TH02_CMD_MEASURE_TEMP 0x11
#define TH02_WR_REG_MODE 0xC0
#define TH02_RD_REG_MODE 0x80
#define HIGH 1
#define LOW 0
namespace upm { namespace upm {
@ -68,7 +63,10 @@ namespace upm {
* *
* @brief C++ API for th02 temperature & humidity sensor library * @brief C++ API for th02 temperature & humidity sensor library
* *
* This file defines the TH02 C++ interface for libth02 * This file defines the TH02 C++ interface for libth02
*
* NOTE: For use on the Edison with the arduino breakout board, the
* Edison must be set to 3v rather than 5v.
* *
* @image html th02.jpg * @image html th02.jpg
* @snippet th02.cxx Interesting * @snippet th02.cxx Interesting
@ -78,7 +76,7 @@ class TH02 {
/** /**
* Instanciates a TH02 object * Instanciates a TH02 object
*/ */
TH02 (); TH02 (int bus=0, uint8_t addr=TH02_ADDR);
/** /**
* TH02 object destructor, basicaly it close i2c connection. * TH02 object destructor, basicaly it close i2c connection.
@ -107,13 +105,11 @@ class TH02 {
{ {
return m_name; return m_name;
} }
private: private:
std::string m_name; std::string m_name;
mraa_i2c_context m_i2Ctx; mraa::I2c m_i2c;
uint8_t m_addr;
uint16_t i2cReadReg_N (int reg, unsigned int len, uint8_t * buffer);
mraa_result_t i2cWriteReg_N (uint8_t reg, unsigned int len, uint8_t * buffer);
mraa_result_t i2cWriteReg (uint8_t reg, uint8_t data);
}; };
} }