Tested and working library for the DS1621 temperature sensor with I2C

Dependents:   condato_Coldchainlogger condato_Coldchainlogger 039847382-S3_DS1621_and_LCD_V1

Files at this revision

API Documentation at this revision

Comitter:
Bas
Date:
Fri Jul 06 20:51:31 2012 +0000
Commit message:
fixed compiler warning LastTemp

Changed in this revision

ds1621.cpp Show annotated file Show diff for this revision Revisions of this file
ds1621.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 20bfb7df0470 ds1621.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds1621.cpp	Fri Jul 06 20:51:31 2012 +0000
@@ -0,0 +1,142 @@
+#include "ds1621.h"
+
+DS1621::DS1621(I2C* _interface, unsigned char _address): i2c(_interface), address(_address) {
+    conversion_busy=false;
+    LastTemp=0.0;
+    StartConversion(false);
+
+    printf("Searching for I2C devices...\n");
+
+    int count = 0;
+    for (int address=4; address<256; address+=2) {
+        if (!i2c->write(address, NULL, 0)) { // 0 returned is ok
+            printf(" - I2C device found at address 0x%02X\r\n", address);
+            count++;
+        }
+    }
+    printf("%d devices found\r\n", count);
+}
+
+// Set configuration register
+void DS1621::SetConfig(unsigned char cfg) {
+    char data[2];
+    data[0]=ACCESS_CONFIG;
+    data[1]=cfg;
+    i2c->write(address,data,2);
+}
+
+// Read a DS1621 register
+unsigned char DS1621::ReadReg(unsigned char reg) {
+    char data[1];
+    data[0]=reg;
+    i2c->write(address,data,1,true);
+    i2c->read(address,data,1);
+    return (data[0]);
+}
+
+// Sets temperature limit
+// -- works only with ACCESS_TL and ACCESS_TH
+void DS1621::SetLimit(unsigned char reg, float temp) {
+    if (reg == ACCESS_TL || reg == ACCESS_TH) {
+        char data[3];
+        data[0]=reg;
+        if (temp <0.0) {
+            temp = ceil(temp * 2.0 - 0.5) / 2.0; //round to 1/2 degree
+            if (floor(temp) < temp ) { // check for extra half
+                data[1]=(~char(temp * -1.0)); //one's complement
+                data[2]=0x80; // -25.5 = -26 + 0.5
+            } else {
+                data[1]=(~char(temp * -1.0)) + 1; //two's complement
+                data[2]=0;   // -25 = -25
+            }
+        } else {
+            temp = floor(temp * 2.0 + 0.5) / 2.0; //round to 1/2 degree
+            data[1]=char(temp); //whole degrees
+            if (ceil(temp) > temp) { // check for extra half
+                data[2]=0x80;
+            } else {
+                data[2]=0x00;
+            }
+        }
+        i2c->write(address,data,3);
+        wait_ms(10);
+    }
+}
+
+// Start/Stop DS1621 temperature conversion
+void DS1621::StartConversion(bool start) {
+    char data[1];
+    if (start == true) {
+        data[0]=START_CONVERT_T;
+        i2c->write(address,data,1);
+    } else {
+        data[0]=STOP_CONVERT_T;
+        i2c->write(address,data,1);
+    }
+}
+
+// Reads temperature or threshold
+// -- works only with READ_TEMPERATURE, ACCESS_TL, and ACCESS_TH
+// -- DS1621 must be in continouis mode and started for the actual temperature
+bool DS1621::GetTemp(unsigned char reg, float *Temp) {
+    unsigned char data[2];
+    float Tc;
+
+    if (reg == READ_TEMPERATURE || reg == ACCESS_TL || reg == ACCESS_TH) {
+        ReadChipTemp(reg,data);
+
+        Tc=float(data[1]>>7) * 0.5;     // decimal part = +0.5 if bit7=1
+
+        if (data[0] >= 0x80) {          // negative? -> make two's complement
+            *Temp = float((char (~data[0])+1)*-1) + Tc;
+        } else {
+            *Temp = float(data[0])+ Tc;
+        }
+        return (true);
+    }
+    return (false);
+}
+
+// Read high resolution temperature
+// -- returns temperature in 1/100ths degrees
+// -- DS1620 must be in 1-shot mode
+bool DS1621::GetHResTemp(float *Temp) {
+
+    if (conversion_busy==false) {
+        SetConfig(ONESHOT);
+        StartConversion(true);               // initiate conversion
+        conversion_busy=true;
+        *Temp = LastTemp;
+        return (false);
+    }
+
+    if (!(ReadReg(ACCESS_CONFIG) & DONE)) {
+        *Temp = LastTemp;
+        return (false);
+    } else {
+        unsigned char data[2];
+        // get the results
+        ReadChipTemp(READ_TEMPERATURE,data);        // get whole degrees reading
+        float cRem = (float)ReadReg(READ_COUNTER); // get counts remaining
+        float cSlope = (float)ReadReg(READ_SLOPE);  // get counts per degree
+        if (data[0] >= 0x80) {          // negative? -> make two's complement
+            LastTemp = float((char (~data[0])+1)*-1);
+        } else {
+            LastTemp = float(data[0]);
+        }
+        LastTemp = LastTemp - 0.25 + (cSlope - cRem)/cSlope;
+        conversion_busy=false;
+        *Temp = LastTemp;
+        return (true);
+    }
+
+}
+
+void DS1621::ReadChipTemp(unsigned char reg, unsigned char *data) {
+    if (reg == READ_TEMPERATURE || reg == ACCESS_TL || reg == ACCESS_TH) {
+        char cmd[1];
+        cmd[0]=reg;
+        i2c->write(address,cmd,1,true);
+        i2c->read(address, (char *)data, 2);
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r 20bfb7df0470 ds1621.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds1621.h	Fri Jul 06 20:51:31 2012 +0000
@@ -0,0 +1,65 @@
+#ifndef __DS1621_H
+#define __DS1621_H
+
+#define VERSION 1.0
+
+#include <mbed.h>
+
+//Temperature conversion commands
+#define READ_TEMPERATURE    0xAA
+#define READ_COUNTER        0xA8
+#define READ_SLOPE          0xA9
+#define START_CONVERT_T     0xEE
+#define STOP_CONVERT_T      0x22
+
+//Thermostat commands
+#define ACCESS_TH           0xA1
+#define ACCESS_TL           0xA2
+#define ACCESS_CONFIG       0xAC
+
+//Config register
+#define DONE                0x80
+#define THF                 0x40
+#define TLF                 0x20
+#define NVB                 0x10
+#define POL                 0x02
+#define ONESHOT             0x01
+
+class DS1621 {
+public:
+    DS1621(I2C* interface, unsigned char address);
+
+    // Set configuration register
+    void SetConfig(unsigned char cfg);
+
+    // Read a DS1621 register
+    unsigned char ReadReg(unsigned char reg);
+
+    // Sets temperature limit
+    // -- works only with ACCESS_TL, and ACCESS_TH
+    void SetLimit(unsigned char reg, float temp);
+
+    // Start/Stop DS1621 temperature conversion
+    void StartConversion(bool start);
+
+    // Reads temperature or limit
+    // -- works only with READ_TEMPERATURE, ACCESS_TL, and ACCESS_TH
+    // -- for actual temperature, set ONESHOT mode off and start conversion
+    // -- returns true if reg valid
+    bool GetTemp(unsigned char reg, float *Temp);
+
+    // Read high resolution temperature
+    // -- returns temperature in 1/100ths degrees
+    // -- DS1621 is set in ONESHOT mode
+    // -- returns true if conversion has finished, new temperature is calculated
+    // -- returns false if conversion is busy, previous temperature is given
+    bool GetHResTemp(float *Temp);
+
+private:
+    I2C* i2c; // Communication interface
+    unsigned char address;
+    void ReadChipTemp(unsigned char cmd, unsigned char *data);
+    bool  conversion_busy;
+    float LastTemp;
+};
+#endif
\ No newline at end of file