Forum Index > Projects > LED Pegboard and Matrix Projects
 Peggy 2 temperature monitor with DS1620 temperature chip
 |  Printable Version
By: lagomorph (offline) on Wednesday, May 27 2009 @ 06:15 PM PDT (Read 2103 times)  
lagomorph

The DS1620 is old and probably not available anymore but I've used them a fair amount over the years. I wrote a little peggy 2 program to display current, min, and max temperature in 4x6 numbers. Next to that it has a basic chart showing comparisons with the last sample and last 5 minute, 20 minute, and 60 minute samples. A temperature is requested from the DS1620 every 5 seconds. The DS1620 can also be set up to continuously update its temperature but sending it commands and polling it is more fun. Smile

On the hardware side I'm reusing D0 and D1 for the DS1620 data and clock lines. I could have used the PORTC pins but I didn't want to have to remove my buttons or worry about shorting pins by pressing them accidentally. C5 is used for the DS1620 reset line. I put a 330 ohm resistor between D0 and the DS1620 data pin as it's used for both input and output just to be safe. I tried a 1K initially but it was unreliable.

Maybe this will be of interest to someone in whole or in parts. Enjoy!

PHP Formatted Code

/*
 * Copyright (c) 2009 John L. Scarfone
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    - Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <Peggy2.h>

/***  DS1620 connections
D0 -> DQ(1)  (via 330 resistor)
D1 -> CLK(2)
C5 -> !RST(3)
***/

const uint8_t START_CONV = 0xee;
const uint8_t READ_TEMP = 0xaa;
const uint8_t READ_CONF = 0xac;
const uint8_t READ_CTR = 0xa0;
const uint8_t READ_SLOPE = 0xa9;  /* this is documented but doesn't work on my chip */
const uint8_t LOAD_SLOPE = 0x41;  /* this is undocumented but works on my chip, apparently there are at least two DS1620s */

/* data for digits 0-9 */
long numbers[] =
{
  0x699996,
  0xe44464,
  0xf12496,
  0x698496,
  0x88e999,
  0x69871f,
  0x69971e,
  0x22248f,
  0x699696,
  0x78e996
};

Peggy2 frame;
float minTemp = 99.9;
float maxTemp = 0.;
float lastTemp = 0;
float lastTemp5Minute = 0;
float lastTemp20Minute = 0;
float lastTemp60Minute = 0;
int count = 0;

void setup()
{
  frame.HardwareInit();
  frame.Clear();

  DDRC |= _BV(5);  /* C5 output */
  rstLow();        /* excommunicate DS1620 */
}

void loop()
{
  float temp;
 
  if (getTemp(&temp))
  {
    if (temp > maxTemp)
      maxTemp = temp;
    if (temp < minTemp)
      minTemp = temp;
 
    printTemp(temp, 0);
    printTemp(minTemp, 7);
    printTemp(maxTemp, 14);
    printTempDiff(temp);
    lastTemp = temp;
    if (count % 60 == 0)
    {
      printTempDiff5Minute(temp);
      lastTemp5Minute = temp;
    }
    if (count % 240 == 0)
    {
      printTempDiff20Minute(temp);
      lastTemp20Minute = temp;
    }
    if (count % 720 == 0)
    {
      printTempDiff60Minute(temp);
      lastTemp60Minute = temp;
      count = 0;
    }
  }
  else
  {
    printNoTemp(0);
    printTemp(minTemp, 7);
    printTemp(maxTemp, 14);
  }  
  frame.RefreshAll(5575);
  ++count;
}

/****/

void printNum(uint8_t num, uint8_t x, uint8_t y)
{
  uint8_t i, j;
  long bPos;
  long numVal;
 
  numVal = numbers[num];
  bPos = 1;
  for (i=0; i<6; ++i)
    for (j=0; j<4; ++j)
    {
      if (numVal & bPos)
        frame.SetPoint(x+j, y+i);
      else
        frame.ClearPoint(x+j, y+i);
      bPos <<= 1;
    }
}

void clearNum(uint8_t x, uint8_t y)
{
  uint8_t i, j;
 
  for (i=0; i<6; ++i)
    for (j=0; j<4; ++j)
      frame.ClearPoint(x+j, y+i);
}

void printDash(uint8_t x, uint8_t y)
{
  uint8_t i, j;
 
  for (i=0; i<2; ++i)
    for (j=0; j<4; ++j)
      frame.ClearPoint(x+j, y+i);
  for (j=0; j<4; ++j)
    frame.SetPoint(x+j, y+2);
  for (i=3; i<6; ++i)
    for (j=0; j<4; ++j)
      frame.ClearPoint(x+j, y+i);
}

void printTemp(float temp, uint8_t y)
{
  int iTemp;
  uint8_t digit;

  frame.SetPoint(10, 5+y);

  if (temp >= 100)
    temp = 99.9;
  else if (temp <= 0)
    temp = 0.;

  iTemp = round(temp*10);

  digit = iTemp % 10;
  iTemp /= 10;
  printNum(digit, 12, y);

  digit = iTemp % 10;
  iTemp /= 10;
  printNum(digit, 5, y);

  digit = iTemp % 10;
  if (digit == 0)
    clearNum(0, y);
  else
    printNum(digit, 0, y);
}

void printNoTemp(uint8_t y)
{
  frame.SetPoint(10, 5+y);
  printDash(0, y);
  printDash(5, y);
  printDash(12, y);
}

void printTempDiff(float temp)
{
  int barLength, i;

  if (lastTemp == 0)
    return;

  for (i=0; i<25; ++i)
    frame.ClearPoint(18, i);
  for (i=17; i<25; ++i)
    frame.SetPoint(i, 12);

  barLength = round((temp - lastTemp) / .01);
  if (barLength > 0)
  {
    if (barLength > 12)
      barLength = 12;
    for (i=0; i<barLength; ++i)
      frame.SetPoint(18, 11-i);
  }
  else
  {
    if (barLength < -12)
      barLength = -12;
    for (i=0; i>barLength; --i)
      frame.SetPoint(18, 13-i);
  }
}

void printTempDiff5Minute(float temp)
{
  int barLength, i;

  if (lastTemp5Minute == 0)
    return;

  for (i=0; i<25; ++i)
    frame.ClearPoint(20, i);
  frame.SetPoint(20, 12);

  barLength = round((temp - lastTemp5Minute) / .1);
  if (barLength > 0)
  {
    if (barLength > 12)
      barLength = 12;
    for (i=0; i<barLength; ++i)
      frame.SetPoint(20, 11-i);
  }
  else
  {
    if (barLength < -12)
      barLength = -12;
    for (i=0; i>barLength; --i)
      frame.SetPoint(20, 13-i);
  }
}

void printTempDiff20Minute(float temp)
{
  int barLength, i;

  if (lastTemp20Minute == 0)
    return;

  for (i=0; i<25; ++i)
    frame.ClearPoint(22, i);
  frame.SetPoint(22, 12);

  barLength = round((temp - lastTemp20Minute) / .25);
  if (barLength > 0)
  {
    if (barLength > 12)
      barLength = 12;
    for (i=0; i<barLength; ++i)
      frame.SetPoint(22, 11-i);
  }
  else
  {
    if (barLength < -12)
      barLength = -12;
    for (i=0; i>barLength; --i)
      frame.SetPoint(22, 13-i);
  }
}

void printTempDiff60Minute(float temp)
{
  int barLength, i;

  if (lastTemp60Minute == 0)
    return;

  for (i=0; i<25; ++i)
    frame.ClearPoint(24, i);
  frame.SetPoint(24, 12);

  barLength = round((temp - lastTemp60Minute) / .5);
  if (barLength > 0)
  {
    if (barLength > 12)
      barLength = 12;
    for (i=0; i<barLength; ++i)
      frame.SetPoint(24, 11-i);
  }
  else
  {
    if (barLength < -12)
      barLength = -12;
    for (i=0; i>barLength; --i)
      frame.SetPoint(24, 13-i);
  }
}

/** DS1620 routines **/

boolean getTemp(float *temp)
{
  uint8_t i;
  int data, ctr, cntPerC;

  frame.SetPoint(24, 0);
 
  clkHigh();
  rstHigh();
  write8Bit(START_CONV);
  rstLow();

  /* the DS1620 takes some time to finish the conversion so
     update the display while we're waiting */
  frame.RefreshAll(250);
  for (i=0; i<5; ++i)
  {
    /* check status */
    clkHigh();
    rstHigh();
    write8Bit(READ_CONF);
    if (read8Bit() & 0x80)
    {
      /* ready to read temp */
      rstLow();
      break;
    }
    /* still not ready */
    rstLow();
    frame.RefreshAll(250);
  }

  if (i == 5)
  {
    frame.ClearPoint(24, 0);
    return false;
  }

  frame.RefreshAll(10);
 
  /* read temp */
  clkHigh();
  rstHigh();
  write8Bit(READ_TEMP);
  data = read9Bit();
  rstLow();

  frame.RefreshAll(10);
 
  /* read counter */
  clkHigh();
  rstHigh();
  write8Bit(READ_CTR);
  ctr = read9Bit();
  rstLow();
 
  frame.RefreshAll(10);

  /* load slope */
  clkHigh();
  rstHigh();
  write8Bit(LOAD_SLOPE);
  rstLow();
 
  frame.RefreshAll(10);

  /* read counter */
  clkHigh();
  rstHigh();
  write8Bit(READ_CTR);
  cntPerC = read9Bit();
  rstLow();

  frame.RefreshAll(10);

  data >>= 1;  /* strip last bit and divide by two */
  if (data & 0x80)  /* neg, need to sign extend */
    data |= ~0xff;
  *temp = (float)data - .25 + (cntPerC - ctr)/(float)cntPerC;
  *temp = *temp * 9. / 5. + 32.;
  frame.ClearPoint(24, 0);
  return true;
}

void write8Bit(uint8_t data)
{
  uint8_t i;
 
  for (i=0; i<8; ++i)
  {
    outBit(data & 1);
    data >>= 1;
  }
}

uint8_t read8Bit(void)
{
  uint8_t data = 0;
  uint8_t i, bit;
 
  DDRD &= 0xfe;  /* D0 input */
  PORTD &= 0xfe;

  for (i=0; i<8; ++i)
  {
    clkLow();
    bit = PIND & 0x01;
    clkHigh();
    data |= bit << i;
  }

  DDRD |= 0x01;  /* D0 output */

  return data;
}

int read9Bit(void)
{
  int data = 0;
  uint8_t i, bit;
 
  DDRD &= 0xfe;  /* D0 input */
  PORTD &= 0xfe;

  for (i=0; i<9; ++i)
  {
    clkLow();
    bit = PIND & 0x01;
    clkHigh();
    data |= bit << i;
  }

  DDRD |= 0x01;  /* D0 output */

  return data;
}

void outBit(uint8_t bit)
{
  if (bit)
    PORTD |= 0x01;
  else
    PORTD &= 0xfe;
  clkLow();
  clkHigh();
}

void clkHigh()
{
  PORTD |= 0x02;
  delayMicroseconds(1);
}

void clkLow()
{
  PORTD &= 0xfd;
  delayMicroseconds(1);
}

void rstHigh()
{
  PORTC |= 0x20;
  delayMicroseconds(1);
}

void rstLow()
{
  PORTC &= 0xdf;
  delayMicroseconds(1);
}
 


Forum Apprentice
Apprentice

Status: offline

Registered: 04/24/09
Posts: 14

Profile Email    
   



 All times are PDT. The time is now 02:31 AM.
Normal Topic Normal Topic
Locked Topic Locked Topic
Sticky Topic Sticky Topic
New Post New Post
Sticky Topic W/ New Post Sticky Topic W/ New Post
Locked Topic W/ New Post Locked Topic W/ New Post
View Anonymous Posts 
Able to Post 
Filtered HTML Allowed 
Censored Content 

Evil Mad Scientist Forum Archives — Read only!

Please visit our new forums for new discussions.


DIY Hardware for Electronic Art


The Original Egg-Bot Kit


Octolively
Interactive LED kits


Meggy Jr RGB
LED matrix game
development kit.


Business-card sized
AVR target boards


Peggy 2
LED Pegboard kits

My Account






Lost your password?