Go Down

Topic: DS1631 (Read 2248 times) 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy