|
|||||||
![]() |
Forum Index > Projects > LED Pegboard and Matrix Projects | ||
Peggy 2 temperature monitor with DS1620 temperature chip |
|||
| | | Printable Version |
|
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. 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); } |
![]() Apprentice Status: offline
Registered: 04/24/09 |
||||||||
|
|||||||||
|
|
| All times are PDT. The time is now 02:31 AM. |
|
|
Octolively
Interactive LED kits
Meggy Jr RGB
LED matrix game
development kit.
Business-card sized
AVR target boards
Peggy 2
LED Pegboard kits