/* * ds18b20.c - single sensor support * k4be 2019 * License: BSD */ #include #include #include #include "main.h" #include "ds18b20.h" #include "1wire.h" union { signed int t; unsigned char owbuffer[9]; } t; #define MAX_ERRORS 5 void gettemp(void){ unsigned char i, crc=0, tmp; static unsigned char error_cnt; unsigned char temp_ok_out = 0; float temp; if(System.timers.owire) return; _delay_ms(1); /* No presence pulse (bus short, or no sensor at all): skip straight to * the error accounting below instead of returning here - an early * return would skip re-arming System.timers.owire at the end of this * function, so with no sensor ever connected, this whole function would * run on every single main loop pass (never gated by the timer again) * instead of the intended once-per-4s poll. */ if(_1WireInit() == 1){ _1WireWriteByte(0xcc); _1WireWriteByte(0xbe); for(i=0;i<9;i++){ tmp = _1WireReadByte(); t.owbuffer[i] = tmp; crc = _crc_ibutton_update(crc, tmp); } if(!crc){ /* Reject the power-on-reset scratchpad default (85.0C) still in * place if a conversion never actually completed. */ if(t.owbuffer[0] != 0x50 || t.owbuffer[1] != 0x05 || t.owbuffer[5] != 0xff || t.owbuffer[7] != 0x10){ temp = (float)t.t*0.0625; System.temperature = temp; temp_ok_out = 1; } } } if(!temp_ok_out){ if(error_cnt > MAX_ERRORS){ System.temperature_ok = 0; } else { error_cnt++; } } else { error_cnt = 0; System.temperature_ok = 1; } if(_1WireInit() == 1){ _1WireWriteByte(0xcc); _1WireWriteBytePR(0x44); } atomic_set_uint(&System.timers.owire, ms(4000)); }