Things used in this project

Hardware components:
Compare particleelectron
Particle Electron
×1
313j9z2e56l
Pocket Solder- 60/40 Rosin Core 0.031" diameter
×1

Schematics

sch file
tempshield_upaqwp8vxC.sch
pcb file
tempshield_WBOkIBjsQ7.brd

Code

Adafruit_TMP007.hC/C++
#include "application.h"
#include "Particle.h"
#include "math.h"

// uncomment for debugging!
//#define TMP007_DEBUG 1

#define TMP007_VOBJ       0x00
#define TMP007_TDIE       0x01
#define TMP007_CONFIG     0x02
#define TMP007_TOBJ       0x03
#define TMP007_STATUS     0x04
#define TMP007_STATMASK   0x05

#define TMP007_CFG_RESET    0x8000
#define TMP007_CFG_MODEON   0x1000
#define TMP007_CFG_1SAMPLE  0x0000
#define TMP007_CFG_2SAMPLE  0x0200
#define TMP007_CFG_4SAMPLE  0x0400
#define TMP007_CFG_8SAMPLE  0x0600
#define TMP007_CFG_16SAMPLE 0x0800
#define TMP007_CFG_ALERTEN  0x0100
#define TMP007_CFG_ALERTF   0x0080
#define TMP007_CFG_TRANSC   0x0040

#define TMP007_STAT_ALERTEN 0x8000
#define TMP007_STAT_CRTEN   0x4000

#define TMP007_I2CADDR 0x40
#define TMP007_DEVID 0x1F



class Adafruit_TMP007  {
 public:
  Adafruit_TMP007(uint8_t addr = TMP007_I2CADDR);
  boolean begin(uint8_t samplerate = TMP007_CFG_16SAMPLE);  // by default go highres

  int16_t readRawDieTemperature(void);
  int16_t readRawVoltage(void);
  double readObjTempC(void);
  double readDieTempC(void);

 private:
  uint8_t _addr;
  uint16_t read16(uint8_t addr);
  void write16(uint8_t addr, uint16_t data);
};
Adafruit_TMP007.cppC/C++
/*************************************************** 
  This is a library for the TMP007 Temp Sensor
  Designed specifically to work with the Adafruit TMP007 Breakout 
  ----> https://www.adafruit.com/products/2023
  These displays use I2C to communicate, 2 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!
  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "Adafruit_TMP007.h"

#define ARDUINO  200

//#define TESTDIE 0x0C78
//#define TESTVOLT 0xFEED

Adafruit_TMP007::Adafruit_TMP007(uint8_t i2caddr) {
  _addr = i2caddr;
}


boolean Adafruit_TMP007::begin(uint8_t samplerate) {
  Wire1.begin();

  write16(TMP007_CONFIG, TMP007_CFG_MODEON | TMP007_CFG_ALERTEN | 
	  TMP007_CFG_TRANSC | samplerate);
  write16(TMP007_STATMASK, TMP007_STAT_ALERTEN |TMP007_STAT_CRTEN);
  // enable conversion ready alert

  uint16_t did;
  did = read16(TMP007_DEVID);
#ifdef TMP007_DEBUG
  Serial.print("did = 0x"); Serial.println(did, HEX);
#endif
  if (did != 0x78) return false;
  return true;
}

//////////////////////////////////////////////////////

double Adafruit_TMP007::readDieTempC(void) {
   double Tdie = readRawDieTemperature();
   Tdie *= 0.03125; // convert to celsius
#ifdef TMP007_DEBUG
   Serial.print("Tdie = "); Serial.print(Tdie); Serial.println(" C");
#endif
   return Tdie;
}

double Adafruit_TMP007::readObjTempC(void) {
  int16_t raw = read16(TMP007_TOBJ);
  // invalid
  if (raw & 0x1) return NAN;
  raw >>=2;

  double Tobj = raw;
  Tobj *= 0.03125; // convert to celsius
#ifdef TMP007_DEBUG
   Serial.print("Tobj = "); Serial.print(Tobj); Serial.println(" C");
#endif
   return Tobj;
}



int16_t Adafruit_TMP007::readRawDieTemperature(void) {
  int16_t raw = read16(TMP007_TDIE);

#if TMP007_DEBUG == 1

#ifdef TESTDIE
  raw = TESTDIE;
#endif

  Serial.print("Raw Tambient: 0x"); Serial.print (raw, HEX);
  

  float v = raw/4;
  v *= 0.03125;
  Serial.print(" ("); Serial.print(v); Serial.println(" *C)");
#endif
  raw >>= 2;
  return raw;
}

int16_t Adafruit_TMP007::readRawVoltage(void) {
  int16_t raw;

  raw = read16(TMP007_VOBJ);

#if TMP007_DEBUG == 1

#ifdef TESTVOLT
  raw = TESTVOLT;
#endif

  Serial.print("Raw voltage: 0x"); Serial.print (raw, HEX);
  float v = raw;
  v *= 156.25;
  v /= 1000;
  Serial.print(" ("); Serial.print(v); Serial.println(" uV)");
#endif
  return raw; 
}


/*********************************************************************/

uint16_t Adafruit_TMP007::read16(uint8_t a) {
  uint16_t ret;

  Wire1.beginTransmission(_addr); // start transmission to device 
#if (ARDUINO >= 100)
  Wire1.write(a); // sends register address to read from
#else
  Wire1.send(a); // sends register address to read from
#endif
  Wire1.endTransmission(); // end transmission
  
  Wire1.beginTransmission(_addr); // start transmission to device 
  Wire1.requestFrom(_addr, (uint8_t)2);// send data n-bytes read
#if (ARDUINO >= 100)
  ret = Wire1.read(); // receive DATA
  ret <<= 8;
  ret |= Wire1.read(); // receive DATA
#else
  ret = Wire1.receive(); // receive DATA
  ret <<= 8;
  ret |= Wire1.receive(); // receive DATA
#endif
  Wire1.endTransmission(); // end transmission

  return ret;
}

void Adafruit_TMP007::write16(uint8_t a, uint16_t d) {
  Wire1.beginTransmission(_addr); // start transmission to device 
#if (ARDUINO >= 100)
  Wire1.write(a); // sends register address to read from
  Wire1.write(d>>8);  // write data
  Wire1.write(d);  // write data
#else
  Wire1.send(a); // sends register address to read from
  Wire1.send(d>>8);  // write data
  Wire1.send(d);  // write data
#endif
  Wire1.endTransmission(); // end transmission
}
Adafruit_SHT30.hC/C++
#include "application.h"
#include "Particle.h"
#include "math.h"


//by compare with a more standard temperature/humidity sensor, got the belwo calibration value
#define CALIB_TEMP  4       
#define CALIB_HUM   10



#define SHT31_DEFAULT_ADDR         0x44
#define SHT31_MEAS_HIGHREP_STRETCH 0x2C06
#define SHT31_MEAS_MEDREP_STRETCH  0x2C0D
#define SHT31_MEAS_LOWREP_STRETCH  0x2C10
#define SHT31_MEAS_HIGHREP         0x2400
#define SHT31_MEAS_MEDREP          0x240B
#define SHT31_MEAS_LOWREP          0x2416
#define SHT31_READSTATUS           0xF32D
#define SHT31_CLEARSTATUS          0x3041
#define SHT31_SOFTRESET            0x30A2
#define SHT31_HEATEREN             0x306D
#define SHT31_HEATERDIS            0x3066

class Adafruit_SHT31 {
 public:
  Adafruit_SHT31();
  boolean begin(uint8_t i2caddr = SHT31_DEFAULT_ADDR);
  float readTemperature(void);
  float readHumidity(void);
  uint16_t readStatus(void);
  void reset(void);
  void heater(boolean);
  uint8_t crc8(const uint8_t *data, int len);

 private:
  boolean readTempHum(void);
  void writeCommand(uint16_t cmd);

  uint8_t _i2caddr;
  boolean readData(void);
  float humidity, temp;
};

class SHT30{
public:
    bool setAddress(int a0);
    bool update();
    double temperature;
    double humidity;
    
private:
    int address = 0x44;
    int buffer[6] = {0,0,0,0,0,0};
};
Adafruit_SHT30.cppC/C++
#include "Adafruit_SHT30.h"
#define ARDUINO  200

Adafruit_SHT31::Adafruit_SHT31() {
}


boolean Adafruit_SHT31::begin(uint8_t i2caddr) {
  Wire1.begin();
  _i2caddr = i2caddr;
  reset();
  //return (readStatus() == 0x40);
  return true;
}

uint16_t Adafruit_SHT31::readStatus(void) {
  writeCommand(SHT31_READSTATUS);
  Wire1.requestFrom(_i2caddr, (uint8_t)3);
  uint16_t stat = Wire1.read();
  stat <<= 8;
  stat |= Wire1.read();
  //Serial.println(stat, HEX);
  return stat;
}

void Adafruit_SHT31::reset(void) {
  writeCommand(SHT31_SOFTRESET);
  delay(10);
}

void Adafruit_SHT31::heater(boolean h) {
  if (h)
    writeCommand(SHT31_HEATEREN);
  else
    writeCommand(SHT31_HEATERDIS);
}


float Adafruit_SHT31::readTemperature(void) {
  if (! readTempHum()) return NAN;

  return temp;
}
  

float Adafruit_SHT31::readHumidity(void) {
  if (! readTempHum()) return NAN;

  return humidity;
}


boolean Adafruit_SHT31::readTempHum(void) {
  uint8_t readbuffer[6];

  writeCommand(SHT31_MEAS_HIGHREP);
  
  delay(500);
  Wire1.requestFrom(_i2caddr, (uint8_t)6);
  if (Wire1.available() != 6) 
    return false;
  for (uint8_t i=0; i<6; i++) {
    readbuffer[i] = Wire1.read();
  //  Serial.print("0x"); Serial.println(readbuffer[i], HEX);
  }
  uint16_t ST, SRH;
  ST = readbuffer[0];
  ST <<= 8;
  ST |= readbuffer[1];

  if (readbuffer[2] != crc8(readbuffer, 2)) return false;

  SRH = readbuffer[3];
  SRH <<= 8;
  SRH |= readbuffer[4];

  if (readbuffer[5] != crc8(readbuffer+3, 2)) return false;

 // Serial.print("ST = "); Serial.println(ST);
  double stemp = ST;
  stemp *= 175;
  stemp /= 0xffff;
  stemp = -45 + stemp;
  temp = stemp-CALIB_TEMP;
  
//  Serial.print("SRH = "); Serial.println(SRH);
  double shum = SRH;
  shum *= 100;
  shum /= 0xFFFF;
  
  humidity = shum+CALIB_HUM;
  
  return true;
}

void Adafruit_SHT31::writeCommand(uint16_t cmd) {
  Wire1.beginTransmission(_i2caddr);
  Wire1.write(cmd >> 8);
  Wire1.write(cmd & 0xFF);
  Wire1.endTransmission();  
}

uint8_t Adafruit_SHT31::crc8(const uint8_t *data, int len)
{


  const uint8_t POLYNOMIAL(0x31);
  uint8_t crc(0xFF);
  
  for ( int j = len; j; --j ) {
      crc ^= *data++;

      for ( int i = 8; i; --i ) {
	crc = ( crc & 0x80 )
	  ? (crc << 1) ^ POLYNOMIAL
	  : (crc << 1);
      }
  }
  return crc;
}
main.inoC/C++
// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_SHT30.h"

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_TMP007.h"

//for the display theory, please refer to 
//http://www.atmel.com/images/doc8103.pdf



#define PORT_COM1 C0
#define PORT_COM2 C1
#define PORT_COM3 C2
#define PORT_COM4 C3

#define COM1    1
#define COM2    2
#define COM3    3
#define COM4    4

#define SEG_A D0
#define SEG_B D1
#define SEG_F D2
#define SEG_G D3
#define SEG_C D4
#define SEG_E D5
#define SEG_D D6
#define SEG_P D7


//this is used for polority flip 
#define POSITIVE 1
#define NEGATIVE 0

#define TEMP 1
#define HUMIDITY    2
#define UNIT_C  0xa7    //the temperature unit of 'C'       0xa6|0x01
//#define MARK_C  0x01    //the temperature mark of `round circule`
#define UNIT_H  0x7D    //the humidity unit of 'H'      0X7C|0X01
#define MARK_DOT    0x01
#define MARK_DOT_NONE   0x00


//0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
uint8_t displayTable[10]={0xee,0x48,0xd6,0xda,0x78,0xba,0xbe,0xc8,0xfe,0xfa};



SYSTEM_MODE(MANUAL);

Adafruit_SHT31 sht31;

float t,h;
unsigned long interval = 0;

//init the GPIO for LCD display
void lcdDisplayInit(void)
{
    pinMode(C0,OUTPUT);
    pinMode(C1,INPUT);
    pinMode(C2,INPUT);
    pinMode(C3,INPUT);
    pinMode(D0,OUTPUT);
    pinMode(D1,OUTPUT);
    pinMode(D2,OUTPUT);
    pinMode(D3,OUTPUT);
    pinMode(D4,OUTPUT);
    pinMode(D5,OUTPUT);
    pinMode(D6,OUTPUT);
    pinMode(D7,OUTPUT);  
}

void loadDisplayTable(uint8_t data)
{
    
    digitalWrite(SEG_A,((data>>7)&0x01));
    digitalWrite(SEG_B,((data>>6)&0x01));    
    digitalWrite(SEG_F,((data>>5)&0x01));
    digitalWrite(SEG_G,((data>>4)&0x01));  
    digitalWrite(SEG_C,((data>>3)&0x01));
    digitalWrite(SEG_E,((data>>2)&0x01));  
    digitalWrite(SEG_D,((data>>1)&0x01));
    digitalWrite(SEG_P,((data>>0)&0x01));   
}


//displayData had beem enlarged by 10
void lcdDisplay(uint16_t displayData,uint8_t unit)
{
    static uint8_t comCounter = 1;
    static uint8_t lastDisplayData=0;
    static uint8_t firstBit=0,secondBit=0,thirdBit=0;
    static uint8_t dotDisplay = MARK_DOT;       //display the dot when in default mode
    static uint8_t comPolarity = NEGATIVE;  //the default voltage on COM port is 0v

    uint8_t tempValue = 0;
    
    if(lastDisplayData!=displayData)    //update bits only input value had changed
    {
        lastDisplayData = displayData;
        if(displayData<=999)        
        {
            firstBit = displayData/100;               
            secondBit = displayData%100/10;
            thirdBit = displayData%10; 
            dotDisplay = MARK_DOT;        //need to display dot when the value is smaller than 100degree,like 23.2 or 02.3
        }
        else       
        {
            firstBit = displayData/1000;               
            secondBit = displayData%1000/100;
            thirdBit = displayData%100/10;  //omit the last fourth bit   
            dotDisplay = MARK_DOT_NONE;    //only display integer when the value is bigger than 99.9degree   
        }
    }
    switch(comCounter)
    {
        case COM1:
            pinMode(PORT_COM2,INPUT);
            pinMode(PORT_COM3,INPUT);
            pinMode(PORT_COM4,INPUT);
            if(comPolarity==POSITIVE)
                tempValue = ~displayTable[firstBit];    
            else
                tempValue = displayTable[firstBit];    
                
            loadDisplayTable(tempValue);
            pinMode(PORT_COM1,OUTPUT);
            digitalWrite(PORT_COM1,comPolarity);
            break;
        case COM2:
            pinMode(PORT_COM1,INPUT);
            pinMode(PORT_COM3,INPUT);
            pinMode(PORT_COM4,INPUT);
            if(comPolarity==POSITIVE)
                tempValue = ~(displayTable[secondBit]|dotDisplay); 
            else
                tempValue = displayTable[secondBit]|dotDisplay;    
            loadDisplayTable(tempValue);
            pinMode(PORT_COM2,OUTPUT);
            digitalWrite(PORT_COM2,comPolarity);
            break;
        case COM3:
            pinMode(PORT_COM1,INPUT);
            pinMode(PORT_COM2,INPUT);
            pinMode(PORT_COM4,INPUT);
            if(comPolarity==POSITIVE)
                tempValue = ~displayTable[thirdBit];   
            else
                tempValue = displayTable[thirdBit];    
                
            loadDisplayTable(tempValue); 
            pinMode(PORT_COM3,OUTPUT);
            digitalWrite(PORT_COM3,comPolarity);
            break;
        case COM4:
            pinMode(PORT_COM1,INPUT);
            pinMode(PORT_COM2,INPUT);
            pinMode(PORT_COM3,INPUT);
            if(unit==TEMP)
                tempValue = UNIT_C; // UNIT_C|MARK_C;
            else
                tempValue = UNIT_H;
            if(comPolarity==POSITIVE)
                tempValue = ~tempValue;  //displayTable[firstBit]    
            loadDisplayTable(tempValue);
            pinMode(PORT_COM4,OUTPUT);
            digitalWrite(PORT_COM4,comPolarity);
            break;
        default:
            break;
    }
    /*
    comCounter++;
    if(comCounter==5)
    {
        comCounter = 1;
        comPolarity=(comPolarity==1)? 0:1;
    }
    */
    //which means one seg had finished the AC from 0-1
    if(comPolarity==1)  //0-->1--0-->1
    {
        comCounter++;
        if(comCounter==5)
        {
            comCounter=0;
            comPolarity=1;  //start from negative after execut the below program 
        }
    }
    comPolarity = (comPolarity==1)?0:1;
}



//display the seg every 2ms, which is around 60HZ
Timer timer(2,updateDisplay);
void setup(void)
{
    lcdDisplayInit();
    Serial.begin(9600);
    if (! sht31.begin(0x44)) {  
    Serial.println("Couldn't find SHT30");
    }
    timer.start();
}


void updateDisplay()
{
    lcdDisplay((uint16_t)t,TEMP);  
}


void loop(void)
{
    
    if((millis()-interval)>=1000)
    {
        interval = millis();
        t = sht31.readTemperature();
        t*=10;
        h = sht31.readHumidity();
        h*=10;
    }
    
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Two Person Weasley Clock with Particle Photon and IFTTT
Easy
  • 669
  • 8

Full instructions

Taking inspiration from the Harry Potter character's Weasley clock, this one uses Particle and IFTTT to tell you where two people are.

Security+ 2.0 MyQ Garage Door Opener
Easy
  • 759
  • 3

Full instructions

Interface newer garage door openers with more than a relay.

IoT Alcohol Tester
Easy
  • 1,890
  • 16

Full instructions

This project explains how to build a device for estimating blood alcohol content from a breath sample.

Measuring temperature and humidity with Particle Photon
Easy
  • 520
  • 3

Full instructions

Measure temperature and humidity with Particle Photon and Adafruit Si7021 using the Adafruit Si7021 library for I2C based communication.

Study Buddy
Easy
  • 2,388
  • 140

Full instructions

Know when an assignment is coming up!

Study Buddy

Team Alexa and Shannon

Automatic garage door opener using geolocation on Android.
Easy
  • 611
  • 2

Full instructions

Control and monitor your garage door remotely and open it automatically when approaching your house using geolocation.

Add projectSign up / Login
Respect project