PRESA Raphaël
/
essai_DS1621
capteur DS1621
ds1621.cpp@0:78facd7c14b8, 2020-05-20 (annotated)
- Committer:
- rpresa
- Date:
- Wed May 20 12:03:32 2020 +0000
- Revision:
- 0:78facd7c14b8
essai DS1621
Who changed what in which revision?
User | Revision | Line number | New 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 | } |