capteur DS1621

Dependencies:   mbed

Committer:
rpresa
Date:
Wed May 20 12:03:32 2020 +0000
Revision:
0:78facd7c14b8
essai DS1621

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rpresa 0:78facd7c14b8 1 #include "ds1621.h"
rpresa 0:78facd7c14b8 2
rpresa 0:78facd7c14b8 3 DS1621::DS1621(I2C* _interface, unsigned char _address): i2c(_interface), address(_address) {
rpresa 0:78facd7c14b8 4 conversion_busy=false;
rpresa 0:78facd7c14b8 5 LastTemp=0.0;
rpresa 0:78facd7c14b8 6 StartConversion(false);
rpresa 0:78facd7c14b8 7
rpresa 0:78facd7c14b8 8 printf("Searching for I2C devices...\n\r");
rpresa 0:78facd7c14b8 9
rpresa 0:78facd7c14b8 10 int count = 0;
rpresa 0:78facd7c14b8 11 for (int address=4; address<256; address+=2) {
rpresa 0:78facd7c14b8 12 if (!i2c->write(address, NULL, 0)) { // 0 returned is ok
rpresa 0:78facd7c14b8 13 printf(" - I2C device found at address 0x%02X\r\n", address);
rpresa 0:78facd7c14b8 14 count++;
rpresa 0:78facd7c14b8 15 }
rpresa 0:78facd7c14b8 16 }
rpresa 0:78facd7c14b8 17 printf("%d devices found\r\n", count);
rpresa 0:78facd7c14b8 18 }
rpresa 0:78facd7c14b8 19
rpresa 0:78facd7c14b8 20 // Set configuration register
rpresa 0:78facd7c14b8 21 void DS1621::SetConfig(unsigned char cfg) {
rpresa 0:78facd7c14b8 22 char data[2];
rpresa 0:78facd7c14b8 23 data[0]=ACCESS_CONFIG;
rpresa 0:78facd7c14b8 24 data[1]=cfg;
rpresa 0:78facd7c14b8 25 i2c->write(address,data,2);
rpresa 0:78facd7c14b8 26 }
rpresa 0:78facd7c14b8 27
rpresa 0:78facd7c14b8 28 // Read a DS1621 register
rpresa 0:78facd7c14b8 29 unsigned char DS1621::ReadReg(unsigned char reg) {
rpresa 0:78facd7c14b8 30 char data[1];
rpresa 0:78facd7c14b8 31 data[0]=reg;
rpresa 0:78facd7c14b8 32 i2c->write(address,data,1,true);
rpresa 0:78facd7c14b8 33 i2c->read(address,data,1);
rpresa 0:78facd7c14b8 34 return (data[0]);
rpresa 0:78facd7c14b8 35 }
rpresa 0:78facd7c14b8 36
rpresa 0:78facd7c14b8 37 // Sets temperature limit
rpresa 0:78facd7c14b8 38 // -- works only with ACCESS_TL and ACCESS_TH
rpresa 0:78facd7c14b8 39 void DS1621::SetLimit(unsigned char reg, float temp) {
rpresa 0:78facd7c14b8 40 if (reg == ACCESS_TL || reg == ACCESS_TH) {
rpresa 0:78facd7c14b8 41 char data[3];
rpresa 0:78facd7c14b8 42 data[0]=reg;
rpresa 0:78facd7c14b8 43 if (temp <0.0) {
rpresa 0:78facd7c14b8 44 temp = ceil(temp * 2.0 - 0.5) / 2.0; //round to 1/2 degree
rpresa 0:78facd7c14b8 45 if (floor(temp) < temp ) { // check for extra half
rpresa 0:78facd7c14b8 46 data[1]=(~char(temp * -1.0)); //one's complement
rpresa 0:78facd7c14b8 47 data[2]=0x80; // -25.5 = -26 + 0.5
rpresa 0:78facd7c14b8 48 } else {
rpresa 0:78facd7c14b8 49 data[1]=(~char(temp * -1.0)) + 1; //two's complement
rpresa 0:78facd7c14b8 50 data[2]=0; // -25 = -25
rpresa 0:78facd7c14b8 51 }
rpresa 0:78facd7c14b8 52 } else {
rpresa 0:78facd7c14b8 53 temp = floor(temp * 2.0 + 0.5) / 2.0; //round to 1/2 degree
rpresa 0:78facd7c14b8 54 data[1]=char(temp); //whole degrees
rpresa 0:78facd7c14b8 55 if (ceil(temp) > temp) { // check for extra half
rpresa 0:78facd7c14b8 56 data[2]=0x80;
rpresa 0:78facd7c14b8 57 } else {
rpresa 0:78facd7c14b8 58 data[2]=0x00;
rpresa 0:78facd7c14b8 59 }
rpresa 0:78facd7c14b8 60 }
rpresa 0:78facd7c14b8 61 i2c->write(address,data,3);
rpresa 0:78facd7c14b8 62 wait_ms(10);
rpresa 0:78facd7c14b8 63 }
rpresa 0:78facd7c14b8 64 }
rpresa 0:78facd7c14b8 65
rpresa 0:78facd7c14b8 66 // Start/Stop DS1621 temperature conversion
rpresa 0:78facd7c14b8 67 void DS1621::StartConversion(bool start) {
rpresa 0:78facd7c14b8 68 char data[1];
rpresa 0:78facd7c14b8 69 if (start == true) {
rpresa 0:78facd7c14b8 70 data[0]=START_CONVERT_T;
rpresa 0:78facd7c14b8 71 i2c->write(address,data,1);
rpresa 0:78facd7c14b8 72 } else {
rpresa 0:78facd7c14b8 73 data[0]=STOP_CONVERT_T;
rpresa 0:78facd7c14b8 74 i2c->write(address,data,1);
rpresa 0:78facd7c14b8 75 }
rpresa 0:78facd7c14b8 76 }
rpresa 0:78facd7c14b8 77
rpresa 0:78facd7c14b8 78 // Reads temperature or threshold
rpresa 0:78facd7c14b8 79 // -- works only with READ_TEMPERATURE, ACCESS_TL, and ACCESS_TH
rpresa 0:78facd7c14b8 80 // -- DS1621 must be in continouis mode and started for the actual temperature
rpresa 0:78facd7c14b8 81 bool DS1621::GetTemp(unsigned char reg, float *Temp) {
rpresa 0:78facd7c14b8 82 unsigned char data[2];
rpresa 0:78facd7c14b8 83 float Tc;
rpresa 0:78facd7c14b8 84
rpresa 0:78facd7c14b8 85 if (reg == READ_TEMPERATURE || reg == ACCESS_TL || reg == ACCESS_TH) {
rpresa 0:78facd7c14b8 86 ReadChipTemp(reg,data);
rpresa 0:78facd7c14b8 87
rpresa 0:78facd7c14b8 88 Tc=float(data[1]>>7) * 0.5; // decimal part = +0.5 if bit7=1
rpresa 0:78facd7c14b8 89
rpresa 0:78facd7c14b8 90 if (data[0] >= 0x80) { // negative? -> make two's complement
rpresa 0:78facd7c14b8 91 *Temp = float((char (~data[0])+1)*-1) + Tc;
rpresa 0:78facd7c14b8 92 } else {
rpresa 0:78facd7c14b8 93 *Temp = float(data[0])+ Tc;
rpresa 0:78facd7c14b8 94 }
rpresa 0:78facd7c14b8 95 return (true);
rpresa 0:78facd7c14b8 96 }
rpresa 0:78facd7c14b8 97 return (false);
rpresa 0:78facd7c14b8 98 }
rpresa 0:78facd7c14b8 99
rpresa 0:78facd7c14b8 100 // Read high resolution temperature
rpresa 0:78facd7c14b8 101 // -- returns temperature in 1/100ths degrees
rpresa 0:78facd7c14b8 102 // -- DS1620 must be in 1-shot mode
rpresa 0:78facd7c14b8 103 bool DS1621::GetHResTemp(float *Temp) {
rpresa 0:78facd7c14b8 104
rpresa 0:78facd7c14b8 105 if (conversion_busy==false) {
rpresa 0:78facd7c14b8 106 SetConfig(ONESHOT);
rpresa 0:78facd7c14b8 107 StartConversion(true); // initiate conversion
rpresa 0:78facd7c14b8 108 conversion_busy=true;
rpresa 0:78facd7c14b8 109 *Temp = LastTemp;
rpresa 0:78facd7c14b8 110 return (false);
rpresa 0:78facd7c14b8 111 }
rpresa 0:78facd7c14b8 112
rpresa 0:78facd7c14b8 113 if (!(ReadReg(ACCESS_CONFIG) & DONE)) {
rpresa 0:78facd7c14b8 114 *Temp = LastTemp;
rpresa 0:78facd7c14b8 115 return (false);
rpresa 0:78facd7c14b8 116 } else {
rpresa 0:78facd7c14b8 117 unsigned char data[2];
rpresa 0:78facd7c14b8 118 // get the results
rpresa 0:78facd7c14b8 119 ReadChipTemp(READ_TEMPERATURE,data); // get whole degrees reading
rpresa 0:78facd7c14b8 120 float cRem = (float)ReadReg(READ_COUNTER); // get counts remaining
rpresa 0:78facd7c14b8 121 float cSlope = (float)ReadReg(READ_SLOPE); // get counts per degree
rpresa 0:78facd7c14b8 122 if (data[0] >= 0x80) { // negative? -> make two's complement
rpresa 0:78facd7c14b8 123 LastTemp = float((char (~data[0])+1)*-1);
rpresa 0:78facd7c14b8 124 } else {
rpresa 0:78facd7c14b8 125 LastTemp = float(data[0]);
rpresa 0:78facd7c14b8 126 }
rpresa 0:78facd7c14b8 127 LastTemp = LastTemp - 0.25 + (cSlope - cRem)/cSlope;
rpresa 0:78facd7c14b8 128 conversion_busy=false;
rpresa 0:78facd7c14b8 129 *Temp = LastTemp;
rpresa 0:78facd7c14b8 130 return (true);
rpresa 0:78facd7c14b8 131 }
rpresa 0:78facd7c14b8 132
rpresa 0:78facd7c14b8 133 }
rpresa 0:78facd7c14b8 134
rpresa 0:78facd7c14b8 135 void DS1621::ReadChipTemp(unsigned char reg, unsigned char *data) {
rpresa 0:78facd7c14b8 136 if (reg == READ_TEMPERATURE || reg == ACCESS_TL || reg == ACCESS_TH) {
rpresa 0:78facd7c14b8 137 char cmd[1];
rpresa 0:78facd7c14b8 138 cmd[0]=reg;
rpresa 0:78facd7c14b8 139 i2c->write(address,cmd,1,true);
rpresa 0:78facd7c14b8 140 i2c->read(address, (char *)data, 2);
rpresa 0:78facd7c14b8 141 }
rpresa 0:78facd7c14b8 142 //printf("data[0]=%d\n\r",data[0]);
rpresa 0:78facd7c14b8 143 //printf("data[1]=%d\n\r",data[1]);
rpresa 0:78facd7c14b8 144 }