added 18B20 and iButton support

master
Ondřej Hruška 6 years ago
parent 56320f7f26
commit 8ec65f2a25
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 98
      main.c
  2. 53
      onewire.c
  3. 9
      onewire.h

@ -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);
}
}

@ -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);

@ -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);

Loading…
Cancel
Save