PRESA Raphaël
/
essai_DS1621
capteur DS1621
Revision 0:78facd7c14b8, committed 2020-05-20
- Comitter:
- rpresa
- Date:
- Wed May 20 12:03:32 2020 +0000
- Commit message:
- essai DS1621
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Main.cpp Wed May 20 12:03:32 2020 +0000 @@ -0,0 +1,65 @@ +#include "ds1621.h" + + + +#define DS1621_ADDR 0x90 // I2c DS1621 address is 0x00 + +Serial pc(USBTX, USBRX); // port série USB +//pins are: TX RX + + +I2C i2c(p9, p10); // Declare I2C (pullup resistors 2.2k from p9 and p10 to +5v) +DS1621 ds(&i2c, DS1621_ADDR); // Declare ds1621 throught i2c interface + + + + +float Temperature = 24.0, + Temp_H=25.0, + Temp_L=23.0, + Temp_cons=35, + hysteresis=5.0, + periode=1.0; // acquisition toutes les secondes + +unsigned char trame[6]; +int cpt=0; // compteur trame +int flag=0; // detection de debut de trame +int etat_regulation=0; // =0 pas de regulation =1 regulation +int Sortie_reg=0; // etat sortie reg du DS1621 + + + +int main() { + i2c.frequency(5000); //5khz + pc.printf("-----------------------\n\rMain\n\r"); + char reg; + int result; + + + + ds.SetConfig(0x00); // POL=1, 1SHOT=0 + wait(1); + reg=ds.ReadReg(ACCESS_CONFIG); // lecture registre CONFIG pour controle + pc.printf("REG=%d\n\r",reg); + ds.SetLimit(ACCESS_TH,-20); // fixe TH: valeur basse pour avoir commande de sortie =0 + wait(1); + ds.SetLimit(ACCESS_TL, -21.0); // fixe TL: valeur basse pour avoir commande de sortie =0 + wait(1); + + ds.StartConversion(1); + wait(1); + + result=ds.GetTemp(ACCESS_TL,&Temp_L); + if(result==1) pc.printf("TL=%3.1f\n\r",Temp_L); + wait(1); + result= ds.GetTemp(ACCESS_TH,&Temp_H); + if(result==1) pc.printf("TH=%3.1f\n\r",Temp_H); + wait(1); + + while (1) { + result= ds.GetTemp(READ_TEMPERATURE,&Temperature); // acquisition Temp à 0.5 + //result= ds.GetHResTemp(&Temperature); // acquisition Temp à 0.1 °C + pc.printf("Temperature=%3.1f C\n\r",Temperature); + wait(1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ds1621.cpp Wed May 20 12:03:32 2020 +0000 @@ -0,0 +1,144 @@ +#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\r"); + + 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); + } + //printf("data[0]=%d\n\r",data[0]); + //printf("data[1]=%d\n\r",data[1]); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ds1621.h Wed May 20 12:03:32 2020 +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 + +//Bits of 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed May 20 12:03:32 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file