Go Down

Topic: DS1631 (Read 1 time) previous topic - next topic

pseudoblogeus

Hello,

Just to propose a sketch to control the DS1631 Temperature Sensor.
Here it is. Hope that will help somebody in the future :

Code: [Select]

#include <Wire.h>

// PIN adresses are set to GND
#define DS1631_ADDR 0x90 >> 1

// SETUP
void setup(){
   
 // Setup Serial connection
 Serial.begin(9600);
 Serial.println("");
 Serial.println("-----------------------------------");
 Serial.println("DS1631 test: Temp. sensor");
 Serial.println("-----------------------------------");
 Serial.println("");
 
 Wire.begin();             // join I2C bus

 // Stop conversion to be able to modify "Access Config" Register
 Wire.beginTransmission(DS1631_ADDR);
 Wire.send((int)(0x22)); // Stop conversion
 Wire.endTransmission();  
   
 // Read "Access Config" regsiter
 Wire.beginTransmission(DS1631_ADDR);
 Wire.send((int)(0xAC)); // @AC : Acces Config
 Wire.endTransmission();
 Wire.requestFrom(DS1631_ADDR,1); //Reade 1 byte
 Wire.available();
 int AC = Wire.receive(); // receive a byte

 Serial.print("Acces Config (Before): "); Serial.print(AC);  Serial.println("");
   
 // WRITE into "Access Config" Register
 Wire.beginTransmission(DS1631_ADDR);
 Wire.send(0xAC); // @AC : Acces Config
 Wire.send(0x0C); // Continuous conversion & 12 bits resolution
 Wire.endTransmission();
   
 // READ "Access Config" register
 Wire.beginTransmission(DS1631_ADDR);
 Wire.send((int)(0xAC)); // @AC : Acces Config
 Wire.endTransmission();
 Wire.requestFrom(DS1631_ADDR,1);
 Wire.available();
 AC = Wire.receive();

 Serial.print("Acces Config (AFTER): "); Serial.print(AC);  Serial.println("");
 
 // START conversion to get T°
 Wire.beginTransmission(DS1631_ADDR);
 Wire.send((int)(0x51)); // Start Conversion
 Wire.endTransmission();
}

// Main Loop
void loop(){
 
 //READ T°
 Wire.beginTransmission(DS1631_ADDR);
 Wire.send((int)(0xAA)); // @AA : Temperature
 Wire.endTransmission();
 Wire.requestFrom(DS1631_ADDR,2); // READ 2 bytes
 Wire.available(); // 1st byte
 int Th = Wire.receive(); // receive a byte
 Wire.available(); // 2nd byte
 int Tl = Wire.receive(); // receive a byte


 // T° processing
 if(Th>=0x80) //if sign bit is set, then temp is negative
 Th = Th - 256;
 int T_dec=(10*(100*(Tl/16)))/16; // decimal part of the T°

 // Display T° on "Serial Monitor"
 Serial.print("Temperature : ");
 Serial.print(Th);   Serial.print(".");
 if (T_dec<10)   Serial.print("0");
 if (T_dec<100)   Serial.print("0");
 Serial.print(T_dec);   Serial.print(" degC / ");
 Serial.print("Th register: "); Serial.print(Th);  Serial.print(" / ");
 Serial.print("Tl register: "); Serial.print(Tl);  Serial.println("");
 
 // Wait 1s before restart
 delay(1000);
}



Have fun  ;)

itom

Thanks.
I made my first tests with ds1631 as a Object

Is it for somebody usable???

iTom

ds1631.cpp
Code: [Select]

/*
 Ds1631.cpp - Library for High-Precision Digital Thermometer and Thermostat
 Created by ITom Ibach
 Version 20090915
 http://datasheets.maxim-ic.com/en/ds/DS1631-DS1731.pdf
 
*/
#include <Wire.h>
#include <Ds1631.h>

// Initialize Class Variables //////////////////////////////////////////////////
 int _Addr;
 uint8_t Th;
 uint8_t Tl;

// Constructors ////////////////////////////////////////////////////////////////
Ds1631::Ds1631(int Addr){
 _Addr=Addr + 72;  // Ground Addr 72 for Ds1631  
}

// Public Methods //////////////////////////////////////////////////////////////
void Ds1631::stopConversion(){
 Wire.beginTransmission(_Addr);
 Wire.send(0x22); // Stop conversion
 Wire.endTransmission();
}

void Ds1631::startConversion(){
 Wire.beginTransmission(_Addr);
 Wire.send(0x51); // Start conversion
 Wire.endTransmission();
 
}

void Ds1631::writeConfig(uint8_t _data){
 stopConversion();
 Wire.beginTransmission(_Addr);
 Wire.send(0xAC);        // @AC : Acces Config
 Wire.send(_data);
 Wire.endTransmission();
 startConversion();
}

uint8_t Ds1631::readConfig(){
 uint8_t _data;
 Wire.beginTransmission(_Addr);
 Wire.send(0xAC);        // @AC : Acces Config
 Wire.endTransmission();
 Wire.requestFrom(_Addr, 1);
 if(Wire.available()) {
   _data = Wire.receive();
 }
 return _data;
}

void Ds1631::readT(){
 Wire.beginTransmission(_Addr);
 Wire.send(0xAA); // @AA : Temperature
 Wire.endTransmission();
 Wire.requestFrom(_Addr,2); // READ 2 bytes
 Wire.available(); // 1st byte
 Th = Wire.receive(); // receive a byte
 Wire.available(); // 2nd byte
 Tl = Wire.receive(); // receive a byte
}

float Ds1631::readTempF(){
 int T_dec;
 double T;
 readT();
 // T° processing
 Tl = Tl>>4;
 if(Th>=0x80){ //if sign bit is set, then temp is negative
   Th = Th - 256;
 }
 T = (float) Th + (float) Tl*0.0625;
 return T;
}

int32_t Ds1631::readTempD(){ // 1/16°C = 1 Bit 0.0625°C
 int T_dec;
 int32_t T;
 readT();
 
 T=((int32_t)Th << 8) + Tl ;
 // T° processing
 if(T >= 0x8000){   //if sign bit is set, then temp is negative
   T = T - 0xFFFF;
 }
 T = T >>4;
 return T;
}

bool Ds1631::conversionDone(){  // if Conversion Done = Boolean = True
 uint8_t _data = readConfig();
 if ((_data | 127)==255)
    return true;
 else
    return false;
}


ds1631.h
Code: [Select]
/*
 Ds1631.h - Lirbray for Ds1631 Expander
 Created by ITom Ibach
 Version 20090915
*/
#ifndef Ds1631_h
#define Ds1631_h

//#include <WProgram.h>
#include <inttypes.h>

class Ds1631
{
 public:
   Ds1631(int);
   void stopConversion();
   void startConversion();
   void writeConfig(uint8_t);
   uint8_t readConfig();
   float readTempF();  //Floatinpoint z.B. 24.125
   int32_t readTempD();  //Long * 1/16 = °C
   bool conversionDone();
 
 private:
   void readT();
   int _Addr;
   uint8_t Th;
   uint8_t Tl;
};

#endif


ds1631_Example_ease.pde
Code: [Select]

/*
 ds1631_Example_ease.pde - Easy Example for High-Precision Digital Thermometer
 Created by ITom Ibach
 Version 20090915
 http://datasheets.maxim-ic.com/en/ds/DS1631-DS1731.pdf
*/

#include <Wire.h>
#include <ds1631.h>

Ds1631 Temp1(0); //addr=0  = all PIN adresses are set to GND

// SETUP
void setup(){
 int AC;  
 // Setup Serial connection
 Serial.begin(19200);
 Serial.println("");
 Serial.println("-----------------------------------");
 Serial.println("DS1631 test: Temp. sensor");
 Serial.println("-----------------------------------");
 Serial.println("");
 
 Wire.begin();             // join I2C bus

 // WRITE into "Access Config" Register
 Temp1.writeConfig(0x0C);  // 0C=Continuous conversion & 12 bits resolution = +-0.0625°C
                           // 08=Continuous conversion & 11 bits resolution = +-0.125°C
                           // 04=Continuous conversion & 10 bits resolution = +-0.25°
                           // 00=Continuous conversion &  9 bits resolution = +-0.5°C
                                                       
 // READ "Access Config" register
 AC = Temp1.readConfig();
 Serial.print("Acces Config 1 (AFTER): "); Serial.print(AC,HEX);  Serial.println("");

}
 
// Main Loop
void loop(){

 // Display T° on "Serial Monitor"
 Serial.print("Temperature 1 : "); Serial.print(Temp1.readTempF()); Serial.println(" degC   ");
 delay(500);
 
}



ds1631_Example_LCD.pde
Code: [Select]

/*
 ds1631_Example_LCD.pde - Example for High-Precision Digital Thermometer with LCD
 The Idee was to hold the Celler as cool als posible
 Created by ITom Ibach
 Version 20090915
 http://datasheets.maxim-ic.com/en/ds/DS1631-DS1731.pdf
*/

// include the library code:
#include <LiquidCrystal.h>
#include <Wire.h>
#include <ds1631.h>

// these constants won't change.  But you can change the size of
// your LCD using them:
const int numRows = 2;
const int numCols = 16;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
Ds1631 Temp1(0); //addr=0
Ds1631 Temp2(1); //addr=1

void setup() {
 int AC;
 Serial.begin(19200);
 Serial.println("");
 Serial.println("-----------------------------------");
 Serial.println("DS1631 test: Temp. sensor");
 Serial.println("-----------------------------------");
 Serial.println("");
 
 Wire.begin();             // join I2C bus
 
 // set up the LCD's number of rows and columns:
 lcd.begin(numRows, numCols);

 // WRITE into "Access Config" Register
 Temp1.writeConfig(0x04);  // Continuous conversion & 10 bits resolution
 Temp2.writeConfig(0x04);  // Continuous conversion & 10 bits resolution
 
 // READ "Access Config" register
 AC = Temp1.readConfig();
 Serial.print("Acces Config 1 (AFTER): "); Serial.print(AC,HEX);  Serial.println(' ');
 AC = Temp2.readConfig();
 Serial.print("Acces Config 2 (AFTER): "); Serial.print(AC,HEX);  Serial.println(' ');

 // START conversion to get T°
 Temp1.startConversion();
 Temp2.startConversion();
}

void loop() {
  float TempInnen=Temp1.readTempF();
  float TempAussen=Temp2.readTempF();
  int hysterese=2;
  float diff=TempAussen-TempInnen;
  float SollWert=6;  // The best Temprature for the cellar

  boolean heizen;
  lcd.setCursor(0,0);
  lcd.print('A');lcd.print(':');
  lcd.print(TempAussen);
  lcd.print(' ');
  lcd.setCursor(9,0);
  lcd.print('D');lcd.print(':');
  lcd.print(diff); lcd.print(' ');
  //Serial.print("Temperature 1 : "); Serial.print(Temp1.readTempF()); Serial.println(" degC   ");
 
  lcd.setCursor(0,1);
  lcd.print('I'); lcd.print(':');
  lcd.print(TempInnen);
  lcd.print(' ');
  //Serial.print("Temperature 2 : ");  Serial.print(Temp2.readTempF()); Serial.println(" degC   ");
  lcd.setCursor(12,1);
  if (TempInnen <= SollWert){
    heizen=true;
    lcd.print('H'); lcd.print('=');
    if (diff >= hysterese) {
      lcd.print('1');
    }
    else {
      lcd.print('0');
    }      
  }
  else {
    heizen=false;
    lcd.print('K'); lcd.print('=');
    diff=0-diff;
    if (diff >= hysterese) {
      lcd.print('1');
    }
    else {
      lcd.print('0');
    }      
  }  
  delay(200);
}

Go Up