summaryrefslogtreecommitdiff
path: root/software/lib/ds1820.c
diff options
context:
space:
mode:
Diffstat (limited to 'software/lib/ds1820.c')
-rw-r--r--software/lib/ds1820.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/software/lib/ds1820.c b/software/lib/ds1820.c
new file mode 100644
index 0000000..ca1ff16
--- /dev/null
+++ b/software/lib/ds1820.c
@@ -0,0 +1,167 @@
+/*
+ * spreadspace avr utils - usb-1wire example
+ *
+ *
+ * Copyright (C) 2013 Bernhard Tittelbach <xro@realraum.at>
+ * based on code from:
+ * http://www.pjrc.com/teensy/td_libs_OneWire.html
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "ds1820.h"
+#include "onewire.h"
+#include "util/delay.h"
+
+uint8_t owi_ds1820_addr_[MAX_OWI_DEVICES][8];
+uint8_t num_ds1820_found_;
+
+uint8_t ds1820_discover(void)
+{
+ uint8_t d=0;
+ num_ds1820_found_ = 0;
+ if (! owi_reset()) //if no devices on bus, return now
+ return 0;
+ owi_reset_search();
+ _delay_ms(250);
+
+ //Search only for DS1820 temp sensors
+ owi_target_search(DS1820_FAMILY_ID);
+
+ while ( owi_search(owi_ds1820_addr_[ d ]))
+ {
+ d++;
+ if ( d >= MAX_OWI_DEVICES)
+ break;
+ }
+ num_ds1820_found_ = d;
+ return num_ds1820_found_;
+}
+
+void ds1820_set_resolution(uint8_t d, uint8_t bits)
+{
+ uint8_t resolution;
+ if (d >= num_ds1820_found_ || bits < 9 || bits > 12)
+ return;
+
+ owi_reset();
+ owi_select(owi_ds1820_addr_[d]);
+
+ owi_write(DS1820_WRITE_SCRATCHPAD, 0);
+ owi_write(0xFF, 0);
+ owi_write(0x7F, 0);
+
+ resolution = (bits - 9) << 5;
+ owi_write(resolution | 0x1F, 0);
+}
+
+void ds1820_start_measuring(uint8_t d)
+{
+ owi_reset();
+ owi_select(owi_ds1820_addr_[d]);
+ owi_write(DS1820_START_CONVERSION, 1);
+}
+
+uint16_t ds1820_get_conversion_time_ms(uint8_t bits)
+{
+ switch (bits)
+ {
+ case 9: return DS1820_TCONV_MS_9BITS;
+ case 10: return DS1820_TCONV_MS_10BITS;
+ case 11: return DS1820_TCONV_MS_11BITS;
+ default: return DS1820_TCONV_MS_12BITS;
+ }
+}
+
+void ds1820_wait_conversion_time(uint8_t bits)
+{
+ switch (bits)
+ {
+ case 9: _delay_ms(DS1820_TCONV_MS_9BITS); break;
+ case 10: _delay_ms(DS1820_TCONV_MS_10BITS); break;
+ case 11: _delay_ms(DS1820_TCONV_MS_11BITS); break;
+ default: _delay_ms(DS1820_TCONV_MS_12BITS); break;
+ }
+}
+
+int16_t ds1820_read_temperature(uint8_t d)
+{
+ uint8_t data[9];
+ int16_t raw = 0;
+ uint8_t type_s=0;
+ uint8_t cfg, i;
+
+ owi_reset();
+ owi_select(owi_ds1820_addr_[d]);
+ owi_write(DS1820_READ_SCRATCHPAD, 0); // Read Scratchpad
+ for (i = 0; i < 9; i++) { // we need 9 bytes
+ data[i] = owi_read();
+ }
+ #if (ONEWIRE_CRC == 1)
+ uint8_t crc_result = owi_crc8(data,8);
+ if (crc_result != data[8])
+ return DS1820_ERROR;
+ #endif
+
+ // the first ROM byte indicates which chip
+ switch (owi_ds1820_addr_[d][0])
+ {
+ case 0x10:
+ type_s = 1;
+ break;
+ case 0x28:
+ case 0x22:
+ type_s = 0;
+ break;
+ default:
+ break;
+ }
+
+ // Convert the data to actual temperature
+ // because the result is a 16 bit signed integer, it should
+ // be stored to an "int16_t" type, which is always 16 bits
+ // even when compiled on a 32 bit processor.
+ raw = (data[1] << 8) | data[0];
+ if (type_s)
+ {
+ raw = raw << 3; // 9 bit resolution default
+ if (data[7] == 0x10) {
+ // "count remain" gives full 12 bit resolution
+ raw = (raw & 0xFFF0) + 12 - data[6];
+ }
+ } else {
+ cfg = (data[4] & 0x60);
+ // at lower res, the low bits are undefined, so let's zero them
+ if (cfg == DS1820_RESOLUTION_9BITS)
+ raw = raw & ~7; // 9 bit resolution, 93.75 ms
+ else if (cfg == DS1820_RESOLUTION_10BITS)
+ raw = raw & ~3; // 10 bit res, 187.5 ms
+ else if (cfg == DS1820_RESOLUTION_11BITS)
+ raw = raw & ~1; // 11 bit res, 375 ms
+ //// default is 12 bit resolution, 750 ms conversion time
+ }
+
+ return raw;
+}
+
+float ds1820_raw_temp_to_celsius(int16_t t)
+{
+ if ( t == DS1820_ERROR )
+ return DS1820_ERROR;
+ else
+ return ((float) t) / 16.0;
+}