From 8ec65f2a25f71a3926ecbed419046f17fb883412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 14 Aug 2018 22:12:12 +0200 Subject: [PATCH] added 18B20 and iButton support --- main.c | 98 ++++++++++++++++++++++++++++++++++++++++--------------- onewire.c | 53 +++++++++++++++++++++++------- onewire.h | 9 ++--- 3 files changed, 118 insertions(+), 42 deletions(-) diff --git a/main.c b/main.c index 1ee3bff..7741069 100644 --- a/main.c +++ b/main.c @@ -55,53 +55,99 @@ void main() char charbuf[21]; int dots = 0; + bool signal = false, last_signal; while (1) { - bool signal = ow_reset(OW_PIN); + last_signal = signal; + signal = ow_reset(OW_PIN); if (!signal) { - lcd_clear(); - lcd_puts("No 1-Wire detected..."); + if (last_signal) { + lcd_clear(); + } + lcd_puts_xy(0,0,"No 1-Wire detected.."); dots = 0; } else { + if (!last_signal) { + lcd_clear(); + } + ow_write(OW_PIN, 0x33); ow_read_arr(OW_PIN, addr, 8); - lcd_clear(); + // Show chip type + switch (addr[0]) { + case 0x10: + sprintf(charbuf, "18S20 "); + break; + case 0x28: + sprintf(charbuf, "18B20 "); + break; + + case 0x01: + sprintf(charbuf, "iButton"); + break; + + default: + sprintf(charbuf, "UNKNOWN"); + break; + } + lcd_puts_xy(12, 0, charbuf); + + // Show address char *p = charbuf; for(uint8_t i = 0; i < 4; i++) { p += sprintf(p, "%02X", addr[i]); if (i < 3) *p++ = ':'; } - lcd_puts(charbuf); - lcd_xy(0, 1); + lcd_puts_xy(0, 0, charbuf); + p = charbuf; for(uint8_t i = 0; i < 4; i++) { p += sprintf(p, "%02X", addr[4+i]); if (i < 3) *p++ = ':'; } - lcd_puts(charbuf); - - ds1820_single_measure(OW_PIN); - uint16_t cels = ds1820_read_temp_c(OW_PIN); + lcd_puts_xy(0, 1, charbuf); + + // Measure temperature + int16_t cels; + if (addr[0] == 0x10 || addr[0] == 0x28) { + ds18x20_single_measure(OW_PIN); + if (addr[0] == 0x10) { + // 18S20 + cels = ds18s20_read_temp_c(OW_PIN); + } else { + // 18B20 + cels = ds18b20_read_temp_c(OW_PIN); + } - if (cels == 850) { - lcd_xy(12, 0); - for(uint8_t i = 0; i <= dots; i++) { - lcd_putc('.'); + if (cels == TEMP_ERROR || cels == 850) { + lcd_xy(12, 1); + for (uint8_t i = 0; i <= dots; i++) { + lcd_putc('.'); + } + dots = (dots + 1) % 3; + } + else { + p = charbuf; + + if (cels < 0) { + *p++ = '-'; + cels = -cels; + } + + p += sprintf(p, "%d", cels / 10); + *p++ = '.'; + p += sprintf(p, "%d", cels % 10); + *p++ = 0xDF; // ring symbol + *p++ = 'C'; + *p++ = ' '; // padding to prevent artifacts if the number shrinks (we're not clearing screen when 1w is connected) + *p++ = ' '; + *p++ = ' '; + *p = 0; + + lcd_puts_xy(12, 1, charbuf); } - dots = (dots+1)%3; - } else { - p = charbuf; - p += sprintf(p, "%d", cels/10); - *p++ = '.'; - p += sprintf(p, "%d", cels%10); - *p++ = 0xDF; - *p++ = 'C'; - *p++ = 0; - - lcd_xy(12, 0); - lcd_puts(charbuf); } } diff --git a/onewire.c b/onewire.c index 0cca651..fb11b55 100644 --- a/onewire.c +++ b/onewire.c @@ -189,9 +189,8 @@ uint8_t crc8(uint8_t *addr, uint8_t len) // --- utils for DS1820 --- - -/** Read temperature in 0.0625°C, or TEMP_ERROR on error */ -int16_t ds1820_read_temp(uint8_t pin) +/** Read temperature in 0.0625°C */ +int16_t ds18s20_read_temp(uint8_t pin) { ow_write(pin, READ_SCRATCHPAD); uint8_t bytes[9]; @@ -213,24 +212,54 @@ int16_t ds1820_read_temp(uint8_t pin) } } +int16_t conv0_0625to0_1(int32_t temp) { + temp *= 625; + uint16_t rem = temp % 1000; + temp /= 1000; + if (rem >= 500) temp++; + return (int16_t) temp; +} + /** Read temperature in 0.1°C, or TEMP_ERROR on error */ -int16_t ds1820_read_temp_c(uint8_t pin) +int16_t ds18s20_read_temp_c(uint8_t pin) +{ + int16_t value = ds18s20_read_temp(pin); + if (value == TEMP_ERROR) return TEMP_ERROR; + return conv0_0625to0_1(value); +} + +/** Read temperature in 0.0625°C */ +uint16_t ds18b20_read_temp(uint8_t pin) { - int32_t temp = ds1820_read_temp(pin); + ow_write(pin, READ_SCRATCHPAD); + uint8_t bytes[9]; + ow_read_arr(pin, bytes, 9); - if (temp == TEMP_ERROR) + uint8_t crc = crc8(bytes, 8); + if (crc != bytes[8]) { return TEMP_ERROR; + } - temp *= 625; - uint16_t rem = temp % 1000; - temp /= 1000; - if (rem >= 500) temp++; + int32_t value = bytes[0] | ((bytes[1] & 0x7) << 8); // value in 0.0625 + if (bytes[1] & 0x80) { + value = -value; + } + if (value == 0x0550) { + return TEMP_ERROR; + } - return (int16_t) temp; + return value; } +/** Read temperature in 0.1°C, or TEMP_ERROR on error */ +int16_t ds18b20_read_temp_c(uint8_t pin) +{ + int16_t value = ds18b20_read_temp(pin); + if (value == TEMP_ERROR) return TEMP_ERROR; + return conv0_0625to0_1(value); +} -bool ds1820_single_measure(uint8_t pin) +bool ds18x20_single_measure(uint8_t pin) { ow_reset(pin); ow_write(pin, SKIP_ROM); diff --git a/onewire.h b/onewire.h index 32a31fe..63dda9f 100644 --- a/onewire.h +++ b/onewire.h @@ -40,14 +40,15 @@ uint8_t crc8(uint8_t *addr, uint8_t len); * Read temperature in 0.0625°C, or TEMP_ERROR on error * Use this where you'd normally use READ_SCRATCHPAD */ -int16_t ds1820_read_temp(uint8_t pin); - +int16_t ds18s20_read_temp(uint8_t pin); /** * Read temperature in 0.1°C, or TEMP_ERROR on error * Use this where you'd normally use READ_SCRATCHPAD */ -int16_t ds1820_read_temp_c(uint8_t pin); +int16_t ds18s20_read_temp_c(uint8_t pin); + +int16_t ds18b20_read_temp_c(uint8_t pin); /** * Perform a temperature measurement with single DS1820 device on the line @@ -55,4 +56,4 @@ int16_t ds1820_read_temp_c(uint8_t pin); * * Returns false on failure (device not connected) */ -bool ds1820_single_measure(uint8_t pin); +bool ds18x20_single_measure(uint8_t pin);