Go Down

Topic: Problem with DS1620 (Read 635 times) previous topic - next topic

samira

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

Code: [Select]
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 ) ;
}

JonnyMac

#1
Dec 27, 2007, 04:49 am Last Edit: Dec 27, 2007, 04:55 am by JonnyMac Reason: 1
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.

[font=Courier New]// 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);
}[/font]

Jon McPhalen
Hollywood, CA

samira

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

cdmiller

Great example!

Small bitwise logic correction to JonnyMac's demo code, the negative value detection and conversion should be something like this:
[font=Courier]
Code: [Select]

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

[/font]

Go Up