Problem with DS1620

I am trying to interface DS1620 with Arduino ( Diecimela).

Arduino <--------------->DS1620
digital Pin5------------- pin 1 ( Dq pin )
digital Pin6------------- pin 2 ( clk pin )
digital Pin7------------- pin 3 ( rst pin )

I modified the shiftIn and shiftOut in order to do LSBFIRST as well as the clock pin setting 'falling edge'

The code kept reading value 0 celcius.

Anybody has any clue with the problem of my code ?

I suspect it has to do with my clock setting because I do not have an understanding of this setting.

Thanks for any advice or correction.

samira

int ledPin = 13 ;

int dqPin  = 5 ; 
int clkPin = 6 ; 
int rstPin = 7 ; 

byte data ; 
int i ; 

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output

  pinMode(clkPin, OUTPUT);
  pinMode(rstPin, OUTPUT);
  
  Serial.begin ( 9600 ) ; 

// write to config register 
  pinMode ( dqPin, OUTPUT) ; // set it as output 
  // request write config registger
  // send write config command ( ox0C )
  myShiftOut ( dqPin, clkPin,  0x0C );

//send command cpu & continuous ( 0x02)
  myShiftOut( dqPin, clkPin, 0x02 ) ;

// send command "start convert"  0xee
  myShiftOut ( dqPin, clkPin, 0xEE ) ;
}

void loop() 
{
int myTemp ;

// request read temp  (0xAA)
    myShiftOut ( dqPin, clkPin, 0xAA);

// set dq pin to input for reading 
    pinMode ( dqPin, INPUT) ;
        
    myTemp = shiftIn( dqPin, clkPin);
   
    Serial.print ("temp = ") ;
    Serial.print ( myTemp, DEC ) ;
    Serial.println ( " Celcius");
    delay (1000);
  }

byte shiftIn(int myDataPin, int myClockPin ) { 
  int i;
  int temp = 0;
  int data ;
    
  pinMode(myDataPin, INPUT);
  pinMode ( myClockPin, OUTPUT) ;

  data = 0 ; 
  digitalWrite ( rstPin, HIGH ) ;
  digitalWrite ( myClockPin, HIGH);
  for (i=0; i<= 7; i++)
  {

    digitalWrite(myClockPin, HIGH );
    temp = digitalRead(myDataPin);
    delayMicroseconds(50);

    if (temp) {
      data  = data | (1 << i);
    }
    digitalWrite(myClockPin, LOW );
  }
  digitalWrite ( rstPin, LOW );
  return data  / 2;
 
}

void myShiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out LSB first, 
  //on the falling edge of the clock,
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);
  
  digitalWrite ( rstPin, HIGH) ;
  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite ( myClockPin, 1) ;
  
  for (i= 0 ; i <= 7 ; i++ )  {
    digitalWrite(myClockPin, 0);

    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {      
      pinState= 0;
    }

// Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
// register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
// zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 1);
  digitalWrite ( rstPin, LOW ) ; 
}

I've been using the DS1620 for a long time and I can tell you -- based on the last two days -- it's not easy to use with the Arduino. The program below works, but is not as elegant as it could be; my fault for being new to (and not liking) C for embedded control. I can tell you that the DS1621 (the I2C counterpart) is easier to use with the Arduino, and I wrote a full blown program that you can find in another thread.

// DS1620 demo
// -- by Jon McPhalen (www.jonmcphalen.com)
// -- 26 DEC 2007

// DS1620 to Arduino Connections

#define DQ 2
#define CLK 3
#define RST 4

// DS1620 Commands

#define RD_TEMP 0xAA // read temperature register
#define WRITE_TH 0x01 // write high temperature register
#define WRITE_TL 0x02 // write low temperature register
#define READ_TH 0xA1 // read high temperature register
#define READ_TL 0xA2 // read low temperature register
#define READ_CNTR 0xA0 // read counter register
#define READ_SLOPE 0xA9 // read slope register
#define START_CNV 0xEE // start temperature conversion
#define STOP_CNV 0x22 // stop temperature conversion
#define WRITE_CFG 0x0C // write configuration register
#define READ_CFG 0xAC // read configuration register

// DS1620 configuration bits

#define DONE B10000000 // conversion is done
#define THF B01000000 // high temp flag
#define TLF B00100000 // low temp flag
#define NVB B00010000 // non-volatile memory is busy
#define CPU B00000010 // 1 = use with CPU
#define ONE_SHOT B00000001 // 1 = one conversion; 0 = continuous conversion

void setup()
{
pinMode(DQ, INPUT); // start safely (this pin is bi-directional)
pinMode(CLK, OUTPUT);
digitalWrite(CLK, HIGH); // put clock in idle state
pinMode(RST, OUTPUT);
digitalWrite(RST, LOW); // de-activate DS1620

// setup for continuous conversion

digitalWrite(RST, HIGH);
delayMicroseconds(1);
ds1620Out(WRITE_CFG, 8);
ds1620Out(CPU, 8);
digitalWrite(RST, LOW);
delay(15);
digitalWrite(RST, HIGH);
delayMicroseconds(1);
ds1620Out(START_CNV, 8);
digitalWrite(RST, LOW);

Serial.begin(9600);
delay(5);
Serial.println("DS1620 Demo");
}

void loop()
{
int tC = 0;
int tenths = 0;

delay(1000); // allow conversion

digitalWrite(RST, HIGH);
delayMicroseconds(1);
ds1620Out(RD_TEMP, 8);
tC = ds1620In(9);
digitalWrite(RST, LOW);

tC *= 5; // convert to 1/10ths
if (tC < 0) {
tC = -tC; // fix for integer division
Serial.print("-"); // indicate negative
}
tenths = tC % 10;
tC /= 10;

Serial.print(tC);
Serial.print(".");
Serial.print(tenths);
Serial.println();
}

// Send value to DS1620

void ds1620Out(unsigned int outVal, int count)
{
pinMode(DQ, OUTPUT); // set DQ for write
for (int idx = 0; idx < count; idx++) {
if (outVal & 0x0001 == 1) // test LSB
digitalWrite(DQ, HIGH);
else
digitalWrite(DQ, LOW);
delayMicroseconds(1); // let bit settle
digitalWrite(CLK, LOW);
delayMicroseconds(1); // let clock settle
digitalWrite(CLK, HIGH); // clock it
outVal >>= 1; // get next bit
}
pinMode(DQ, INPUT); // make DQ safe
}

// Returns value from DS1620

int ds1620In(int count)
{
unsigned int inVal = 0;

pinMode(DQ, INPUT); // set DQ for read
for (int idx = 0; idx < count; idx++) {
inVal >>= 1; // prep for new bit
digitalWrite(CLK, LOW);
delayMicroseconds(1);
if (digitalRead(DQ) == HIGH)
inVal |= 0x8000; // set bit if DQ high
digitalWrite(CLK, HIGH);
delayMicroseconds(1);
}
inVal >>= (16-count); // correct bits for count
if (inVal & 0x0100 > 0) // if negative
inVal |= 0xFF00; // extend sign bits
return int(inVal);
}

Thank you very much indeed.

I will study and learn from your code.

BTW, your Haleween video is really cool.

Really appriciate your help.

samira

Great example!

Small bitwise logic correction to JonnyMac's demo code, the negative value detection and conversion should be something like this:

 if (inVal > 0xFF)       // if negative 
    inVal |= 0xFF00;     // extend sign bits
 return int(inVal);