// Test DS18B20, withough DallasTemperature lib
// Author: Darkman
#include <OneWire.h>
OneWire ds(4);
unsigned long start;
byte data[9];
// For further tests...
struct TempSensors
{
byte ROM[8];
} Devices[20];
byte addr[8];
int countDevices = 0;
void printHEX(byte a[], int count);
void setup()
{
Serial.begin(115200);
Serial.println(F("Temperature conversion test, without DallasTemperature library\n"));
}
bool read_scratchpad(uint8_t *addr, uint8_t *buff9) {
ds.reset();
ds.select(addr);
ds.write(0xBE); // read scratchpad
int idx;
for (idx = 0; idx < 9; idx++)
buff9[idx] = ds.read();
return 0 == OneWire::crc8(buff9, 9);
}
void loop()
{
int parasitePower = 0;
volatile float temp;
int countDevices = 0;
// Enumerate 1-Wire devicase
int idx = 0;
ds.reset_search();
while ( ds.search(addr)) {
Serial.print(idx + 1);
Serial.write(". ");
printHEX(addr, 8);
Serial.write(' ');
switch (addr[0])
{
case 0x10: Serial.print(F("DS18S20")); break;
case 0x22: Serial.print(F("DS1822")); break;
case 0x28: Serial.print(F("DS18B20")); break;
default: Serial.print(F("N/A"));
}
Serial.println();
if ((addr[0] == 0x28) | (addr[0] == 0x10) | (addr[0] == 0x22) )
{
memcpy(Devices[idx].ROM, addr, 8);
idx++;
countDevices++;
}
}
Serial.print(F("Devices found for DS18x family: "));
Serial.println(countDevices);
Serial.println();
ds.reset(); // Reset 1-Wire BUS
ds.write(0xCC); // Skip ROM command
ds.write(0xB4); // Read Power Supply
parasitePower = !ds.read();
Serial.print(F("Power: "));
if (parasitePower)
Serial.print(F("Parasite"));
else
Serial.print(F("Local"));
Serial.println();
idx = 0;
while (idx < countDevices)
{
temp = -127; // Ensure it indicate error if conversion fail
memcpy(addr, Devices[idx++].ROM, 8);
Serial.print(F("Device: "));
printHEX(addr, 8);
Serial.println();
// Resolution change. Just for test as numerous writing may destroy EEPROM
// on actual device!
//ds.reset(); // Reset 1-Wire BUS
//ds.select(addr);
//ds.write(0x4E); // Write Scratchpad
//ds.write(data[2]); // TH register
//ds.write(data[3]); // TL register
//ds.write(0x1F); // Resolution set to 11-bit
//ds.reset(); // Finish with reseting BUS
//if (!read_scratchpad(addr, data)) read_scratchpad(addr, data);
//Serial.print(F("New res: "));
//Serial.println((data[4] >> 5) + 9);
////Copy to EEPROM
//ds.reset(); // Reset 1-Wire BUS
//ds.select(addr);
//ds.write(0x48); // Copy Scratchpad
//delay(20); // Wait between 2 to 10ms to finish writing in EEPROM
// Temperature conversion
ds.reset(); // Reset 1-Wire BUS
//ds.write(0xCC); // Skip ROM command
ds.select(addr);
ds.write(0x44); // Start temp. conversion
//ds.write(0x44,1) // In parasite power configuration,
// but be careful not to mix such devices
// on the same line!
// Strong pull up my destroy them!
// Following is possible in non-parasite mode when bus is low during conversion
// while in parasite mode, strong pull-up is present
long ms = micros() ;
if (!parasitePower)
{
while (ds.read() == 0);
} else
{
// Maximum delay for 12-bit resolution is 750ms
delay(750);
}
ms = micros() - ms ;
read_scratchpad(addr, data);
Serial.print(F("Scratchpad: "));
printHEX(data, 9);
Serial.println();
Serial.print(F("Scratchpad CRC8 check: "));
int crc = ds.crc8(data, 8);
Serial.print(crc, HEX);
if ( crc != data[8])
Serial.print(F(" - BAD CRC!"));
Serial.println();
// Byte 4 of scratchpad shows resolution
// BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
// 0 R1 R0 1 1 1 1 1
// R1 R0 RESOLUTION
// (BITS) MAX CONVERSION TIME
// 0 0 9 93.75ms (tCONV/8)
// 0 1 10 187.5ms (tCONV/4)
// 1 0 11 375ms (tCONV/2)
// 1 1 12 750ms (tCONV
int res = (data[4] >> 5) + 9;
// Depending on resolution, some bits are undefined.
// Ensure to be cleared
if (res <= 11) data[0] = bitClear(data[0], 0);
if (res <= 10) data[0] = bitClear(data[0], 1);
if (res == 9) data[0] = bitClear(data[0], 2);
// Byte 0-LSB of temp 50H
// Byte 1-MSB of temp 05H
// Scratchpad: 50054B467FFF011095 means 85C
// Scratchpad: 90FC4B467FFF0110C6 means -55C
//
//BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
//LS BYTE 23 22 21 20 2^-1 2^-2 2^-3 2^-4
//BIT 15 BIT 14 BIT 13 BIT 12 BIT 11 BIT 10 BIT 9 BIT 8
//MS BYTE S S S S S 2^6 2^5 2^4
//S = SIGN
//data[0] = 0x90;
//data[1] = 0xFC;
int16_t raw = (data[1] << 8) | data[0];
temp = raw / 16.0;
Serial.print(F("Resolution: "));
Serial.print(res);
Serial.print(F(" bits\n"));
if (data[4] & 0b00011111 != 0b00011111)
Serial.println(F("WARNING! Resolution byte is wrong!"));
Serial.print(F("Conversion duration:"));
Serial.print(ms);
Serial.println(F("us"));
Serial.print(F("Should be max. :"));
Serial.print(750000 >> (12 - res) );
Serial.println(F("us"));
Serial.print(F("Temp: "));
Serial.print(temp, 4);
Serial.println('C');
Serial.println();
}
delay(1000);
}
void printHEX(byte a[], int count)
{
for (int i = 0; i < count; i++) {
if (a[i] < 10)
Serial.write('0');
Serial.print(a[i], HEX);
}
}