u8 DS18B20StartMeasure(u8 pin, u8 num, u8 resolution) { u8 res, busy = LOW; u8 temp_lsb, temp_msb; u16 temp; switch (resolution) { case RES12BIT: res = 0b01100000; break; // 12-bit resolution case RES11BIT: res = 0b01000000; break; // 11-bit resolution case RES10BIT: res = 0b00100000; break; // 10-bit resolution case RES9BIT: res = 0b00000000; break; // 9-bit resolution default: res = 0b00000000; break; // 9-bit resolution /// NB: The power-up default of these bits is R0 = 1 and R1 = 1 (12-bit resolution) } if (!DS18B20Configure(pin, num, 0, 0, res)) return FALSE; // no alarm if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device if (!DS18B20MatchRom(pin, num)) return FALSE; } OneWireWrite(pin, CONVERT_T); // Start temperature conversion return TRUE; }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "select", "generate" : "jswrap_onewire_select", "params" : [ ["rom","JsVar","The device to select (get this using `OneWire.search()`)"] ] } Select a ROM - always performs a reset first */ void jswrap_onewire_select(JsVar *parent, JsVar *rom) { Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return; if (!jsvIsString(rom) || jsvGetStringLength(rom)!=16) { jsExceptionHere(JSET_TYPEERROR, "Invalid OneWire device address %q", rom); return; } // perform a reset OneWireReset(pin); // decode the address unsigned long long romdata = 0; JsvStringIterator it; jsvStringIteratorNew(&it, rom, 0); int i; for (i=0;i<8;i++) { char b[3]; b[0] = jsvStringIteratorGetChar(&it); jsvStringIteratorNext(&it); b[1] = jsvStringIteratorGetChar(&it); jsvStringIteratorNext(&it); b[2] = 0; romdata = romdata | (((unsigned long long)stringToIntWithRadix(b,16,NULL,NULL)) << (i*8)); } jsvStringIteratorFree(&it); // finally write data out OneWireWrite(pin, 8, 0x55); OneWireWrite(pin, 64, romdata); }
void OneWireSearchRom(void) { unsigned char bit,bit_complementary,pozycja,buffer[NUM_OF_THERMS]; for(unsigned char i=0;i < NUM_OF_THERMS;i++) { buffer[i]=0; } for(unsigned char i=0;i < NUM_OF_THERMS;i++) { pozycja=0; if (!OneWireReset()) return; OneWireWriteByte(0xF0); for(unsigned char bitNo=0;bitNo<64;bitNo++) { bit=OneWireReadBit(); bit_complementary=OneWireReadBit(); if ((!(bit|bit_complementary))&1) { if(buffer[pozycja+1]==0) { buffer[pozycja]++; } OneWireWriteBit((buffer[pozycja]-1)); ROM[i][bitNo/8]|=((buffer[pozycja]-1))<<(bitNo%8); pozycja++; } else { OneWireWriteBit(bit); ROM[i][bitNo/8]|=bit<<(bitNo%8); } } while(buffer[pozycja-1]==2) { buffer[pozycja]=0; pozycja--; } } }
u8 DS18B20MatchRom(u8 pin, u8 num) { u8 i; if (OneWireReset(pin)) return FALSE; OneWireWrite(pin, MATCHROM); // Match Rom for (i = 0; i < 8; i++) // Send the Address ROM Code. OneWireWrite(pin, DS18B20Rom[num][i]); return TRUE; }
void DS18B20ReadRom(u8 pin, u8 *romcode) { u8 i; if (!OneWireReset(pin)) { OneWireWrite(pin, READROM); for (i = 0; i < 8; i++) // Reads the ROM Code from a device romcode[i] = OneWireRead(pin); } }
int ds18b20_SetResolution(char resolution) { if(resolution == 12){ resolution = 0x7F; } else if(resolution == 11){ resolution = 0x5F; } else if(resolution == 10){ resolution = 0x3F; } else if(resolution == 9){ resolution = 0x1F; } else{ resolution = 0x7F; } for(int i=0;i < NUM_OF_THERMS;i++){ if (!OneWireReset()) {return 0;} if(NUM_OF_THERMS > 1){ OneWireWriteByte(0x55); for(int j=0;j<8;j++){ OneWireWriteByte(ROM[i][j]); } } else{ OneWireWriteByte(0xcc); } OneWireWriteByte(0x4E); OneWireWriteByte(0x00); OneWireWriteByte(0x00); OneWireWriteByte(resolution); if (!OneWireReset()) {return 0;} OneWireWriteByte(0x55); for(int j=0;j<8;j++){ OneWireWriteByte(ROM[i][j]); } OneWireWriteByte(0x48); _delay_ms(10); } return 1; }
int ds18b20_Read(){ for(int i=0;i < NUM_OF_THERMS;i++){ unsigned char scratchpad[2]; if (!OneWireReset()) {return 0;} if(NUM_OF_THERMS > 1){ OneWireWriteByte(0x55); for(int j=0;j<8;j++){ OneWireWriteByte(ROM[i][j]); } } else{ OneWireWriteByte(0xcc); } OneWireWriteByte(0xBE); for(int k=0; k<2; k++) scratchpad[k] = OneWireReadByte(); temperatures[i]= ((scratchpad[1] << 8) + scratchpad[0]) / 16.0; } return 1; }
u8 DS18B20Configure(u8 pin, u8 num, u8 TH, u8 TL, u8 config) { if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device DS18B20MatchRom(pin, num); } OneWireWrite(pin, WRITE_SCRATCHPAD); // Allows the master to write 3 bytes of data to the scratchpad OneWireWrite(pin, TH); // The first data byte is written into the TH register (byte 2 of the scratchpad) OneWireWrite(pin, TL); // The second byte is written into the TL register (byte 3) OneWireWrite(pin, config); // The third byte is written into the configuration register (byte 4) return TRUE; }
void DS18B20Find(u8 pin) { u8 m; if (!OneWireReset(pin)) // Detects presence of devices { if (DS18B20GetFirst(pin)) // Begins when at least one part is found { numROMs=0; do { numROMs++; // serialprint("Device #"); for(m = 0; m < 8; m++) { // Identifies ROM number on found device DS18B20Rom[numROMs][m] = ROM[m]; } //Continues until no additional devices are found } while (DS18B20GetNext(pin)&&(numROMs<10)); } } }
u8 DS18B20Read(u8 pin, u8 num, u8 resolution, DS18B20_Temperature * t) { u8 res, busy = LOW; u8 temp_lsb, temp_msb; u16 temp; switch (resolution) { case RES12BIT: res = 0b01100000; break; // 12-bit resolution case RES11BIT: res = 0b01000000; break; // 11-bit resolution case RES10BIT: res = 0b00100000; break; // 10-bit resolution case RES9BIT: res = 0b00000000; break; // 9-bit resolution default: res = 0b00000000; break; // 9-bit resolution /// NB: The power-up default of these bits is R0 = 1 and R1 = 1 (12-bit resolution) } if (!DS18B20Configure(pin, num, 0, 0, res)) return FALSE; // no alarm if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device if (!DS18B20MatchRom(pin, num)) return FALSE; } OneWireWrite(pin, CONVERT_T); // Start temperature conversion while (busy == LOW) // Wait while busy ( = bus is low) busy = OneWireRead(pin); if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device if (!DS18B20MatchRom(pin, num)) return FALSE; } OneWireWrite(pin, READ_SCRATCHPAD);// Read scratchpad temp_lsb = OneWireRead(pin); // byte 0 of scratchpad : temperature lsb temp_msb = OneWireRead(pin); // byte 1 of scratchpad : temperature msb if (OneWireReset(pin)) return FALSE; // Calculation // --------------------------------------------------------------------- // Temperature Register Format // BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 // LS BYTE 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 // BIT15 BIT14 BIT13 BIT12 BIT11 BIT10 BIT9 BIT8 // MS BYTE S S S S S 2^6 2^5 2^4 // S = SIGN temp = temp_msb; temp = (temp << 8) + temp_lsb; // combine msb & lsb into 16 bit variable if (temp_msb & 0b11111000) // test if sign is set, i.e. negative { t->sign = 1; temp = (temp ^ 0xFFFF) + 1; // 2's complement conversion } else { t->sign = 0; } t->integer = (temp >> 4) & 0x7F; // fractional part is removed, leaving only integer part /* t->fraction = 0; // fractional part if (BitRead(temp, 0)) t->fraction += 625; if (BitRead(temp, 1)) t->fraction += 1250; if (BitRead(temp, 2)) t->fraction += 2500; if (BitRead(temp, 3)) t->fraction += 5000; */ t->fraction = (temp & 0x0F) * 625; t->fraction /= 100; // two digits after decimal return TRUE; }
u8 DS18B20ReadMeasure(u8 pin, u8 num, DS18B20_Temperature * t) { u8 res, busy = LOW; u8 temp_lsb, temp_msb; u16 temp; if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device if (!DS18B20MatchRom(pin, num)) return FALSE; } OneWireWrite(pin, READ_SCRATCHPAD);// Read scratchpad temp_lsb = OneWireRead(pin); // byte 0 of scratchpad : temperature lsb temp_msb = OneWireRead(pin); // byte 1 of scratchpad : temperature msb if (OneWireReset(pin)) return FALSE; // Calculation // --------------------------------------------------------------------- // Temperature Register Format // BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 // LS BYTE 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 // BIT15 BIT14 BIT13 BIT12 BIT11 BIT10 BIT9 BIT8 // MS BYTE S S S S S 2^6 2^5 2^4 // S = SIGN temp = temp_msb; temp = (temp << 8) + temp_lsb; // combine msb & lsb into 16 bit variable if (temp_msb & 0b11111000) // test if sign is set, i.e. negative { t->sign = 1; temp = (temp ^ 0xFFFF) + 1; // 2's complement conversion } else { t->sign = 0; } t->integer = (temp >> 4) & 0x7F; // fractional part is removed, leaving only integer part /* t->fraction = 0; // fractional part if (BitRead(temp, 0)) t->fraction += 625; if (BitRead(temp, 1)) t->fraction += 1250; if (BitRead(temp, 2)) t->fraction += 2500; if (BitRead(temp, 3)) t->fraction += 5000; */ t->fraction = (temp & 0x0F) * 625; t->fraction /= 100; // two digits after decimal return TRUE; }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "reset", "generate" : "jswrap_onewire_reset", "return" : ["bool","True is a device was present (it held the bus low)"] } Perform a reset cycle */ bool jswrap_onewire_reset(JsVar *parent) { Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return 0; return OneWireReset(pin); }
u8 DS18B20Read(u8 pin, u8 num, u8 resolution, TEMPERATURE * t) { u8 res, busy = 0; u8 temp_lsb, temp_msb; switch (resolution) { case RES12BIT: res = Bin(01100000); break; // 12-bit resolution case RES11BIT: res = Bin(01000000); break; // 11-bit resolution case RES10BIT: res = Bin(00100000); break; // 10-bit resolution case RES9BIT: res = Bin(00000000); break; // 9-bit resolution default: res = Bin(00000000); break; // 9-bit resolution /// NB: The power-up default of these bits is R0 = 1 and R1 = 1 (12-bit resolution) } DS18B20Configure(pin, num, 0, 0, res); // no alarm if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device DS18B20MatchRom(pin, num); } OneWireWrite(pin, CONVERT_T); // Start temperature conversion while (busy == 0) // Wait while busy ( = bus is low) busy = OneWireRead(pin); if (OneWireReset(pin)) return FALSE; if (num == SKIPROM) { // Skip ROM, address all devices OneWireWrite(pin, SKIPROM); } else { // Talk to a particular device DS18B20MatchRom(pin, num); } OneWireWrite(pin, READ_SCRATCHPAD);// Read scratchpad temp_lsb = OneWireRead(pin); // byte 0 of scratchpad : temperature lsb temp_msb = OneWireRead(pin); // byte 1 of scratchpad : temperature msb OneWireReset(pin); // Calculation // --------------------------------------------------------------------- // Temperature Register Format // BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 // LS BYTE 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 // BIT15 BIT14 BIT13 BIT12 BIT11 BIT10 BIT9 BIT8 // MS BYTE S S S S S 2^6 2^5 2^4 // S = SIGN if (temp_msb >= Bin(11111000)) // test if temperature is negative { t->sign = 1; temp_msb -= Bin(11111000); } else { t->sign = 0; } t->integer = temp_lsb >> 4; // fractional part is removed, it remains only integer part t->integer |= (temp_msb << 4); // integer part from temp_msb is added t->fraction = 0; // fractional part ( if (BitRead(temp_lsb, 0)) t->fraction += 625; if (BitRead(temp_lsb, 1)) t->fraction += 1250; if (BitRead(temp_lsb, 2)) t->fraction += 2500; if (BitRead(temp_lsb, 3)) t->fraction += 5000; t->fraction /= 100; // two digits after decimal return TRUE; }
unsigned char ds18b20_ConvertT(void){ if (!OneWireReset()) return 0; OneWireWriteByte(0xcc); // SKIP ROM OneWireWriteByte(0x44); // CONVERT T return -1; }
/*JSON{ "type" : "method", "class" : "OneWire", "name" : "search", "generate" : "jswrap_onewire_search", "params" : [ ["command","int32","(Optional) command byte. If not specified (or zero), this defaults to 0xF0. This can could be set to 0xEC to perform a DS18B20 'Alarm Search Command'"] ], "return" : ["JsVar","An array of devices that were found"] } Search for devices */ JsVar *jswrap_onewire_search(JsVar *parent, int command) { // search - code from http://www.maximintegrated.com/app-notes/index.mvp/id/187 Pin pin = onewire_getpin(parent); if (!jshIsPinValid(pin)) return 0; JsVar *array = jsvNewEmptyArray(); if (!array) return 0; if (command<=0 || command>255) command = 0xF0; // normal search command // global search state unsigned char ROM_NO[8]; int LastDiscrepancy; int LastFamilyDiscrepancy; int LastDeviceFlag; // reset the search state LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; int search_result = true; while (search_result) { int id_bit_number; int last_zero, rom_byte_number; unsigned char id_bit, cmp_id_bit; unsigned char rom_byte_mask, search_direction; // initialize for search id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = 0; // if the last call was not the last one if (!LastDeviceFlag) { // 1-Wire reset if (!OneWireReset(pin)) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return array; } // issue the search command OneWireWrite(pin, 8, (unsigned long long)command); // loop to do the search do { // read a bit and its complement id_bit = (unsigned char)OneWireRead(pin, 1); cmp_id_bit = (unsigned char)OneWireRead(pin, 1); // check for no devices on 1-wire if ((id_bit == 1) && (cmp_id_bit == 1)) break; else { // all devices coupled have 0 or 1 if (id_bit != cmp_id_bit) search_direction = id_bit; // bit write value for search else { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < LastDiscrepancy) search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); else // if equal to last pick 1, if not then pick 0 search_direction = (id_bit_number == LastDiscrepancy); // if 0 was picked then record its position in LastZero if (search_direction == 0) { last_zero = id_bit_number; // check for Last discrepancy in family if (last_zero < 9) LastFamilyDiscrepancy = last_zero; } } // set or clear the bit in the ROM byte rom_byte_number // with mask rom_byte_mask if (search_direction == 1) ROM_NO[rom_byte_number] |= rom_byte_mask; else ROM_NO[rom_byte_number] &= (unsigned char)~rom_byte_mask; // serial number search direction write bit OneWireWrite(pin, 1, search_direction); // increment the byte counter id_bit_number // and shift the mask rom_byte_mask id_bit_number++; rom_byte_mask = (unsigned char)(rom_byte_mask << 1); // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask if (rom_byte_mask == 0) { rom_byte_number++; rom_byte_mask = 1; } } } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 // if the search was successful then if (!((id_bit_number < 65))) { // search successful so set LastDiscrepancy,LastDeviceFlag,search_result LastDiscrepancy = last_zero; // check for last device if (LastDiscrepancy == 0) LastDeviceFlag = TRUE; search_result = TRUE; } } // if no device found then reset counters so next 'search' will be like a first if (!search_result || !ROM_NO[0]) { LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; search_result = FALSE; } if (search_result) { int i; char buf[17]; for (i=0;i<8;i++) { buf[i*2] = itoch((ROM_NO[i]>>4) & 15); buf[i*2+1] = itoch(ROM_NO[i] & 15); } buf[16]=0; jsvArrayPushAndUnLock(array, jsvNewFromString(buf)); } NOT_USED(LastFamilyDiscrepancy); } return array; }
u8 DS18B20GetNext(u8 pin) { u8 m = 1; // ROM Bit index u8 n = 0; // ROM Byte index u8 k = 1; // bit mask u8 x = 0; u8 discrepMarker = 0; // discrepancy marker u8 g; // Output bit u8 nxt; // return value int flag; nxt = FALSE; // set the next flag to false dowcrc = 0; // reset the dowcrc flag = OneWireReset(pin); // reset the 1-wire if(flag||doneFlag) // no parts -> return false { lastDiscrep = 0; // reset the search return FALSE; } // send SearchROM command for all eight bytes OneWireWrite(pin, SEARCHROM); do { x = 0; if(OneWireReadBit(pin) == 1) x = 2; //myDelay_10us(12); if(OneWireReadBit(pin) == 1 ) x |= 1; if(x == 3) break; else { if(x > 0) // all devices coupled have 0 or 1 g = x >> 1; // bit write value for search else { // if this discrepancy is before the last // discrepancy on a previous Next then pick // the same as last time if(m < lastDiscrep) g = ( (ROM[n] & k) > 0); else // if equal to last pick 1 g = (m == lastDiscrep); // if not then pick 0 // if 0 was picked then record position with mask k if (g == 0) discrepMarker = m; } if (g == 1) // isolate bit in ROM[n] with mask k ROM[n] |= k; else ROM[n] &= ~k; OneWireWriteBit(pin, g); // ROM search write m++; // increment bit counter m k = k << 1; // and shift the bit mask k if(k == 0) // if the mask is 0 then go to new ROM { // byte n and reset mask DS18B20_crc(ROM[n]); // accumulate the CRC n++; k++; } } } while (n < 8); // loop until through all ROM bytes 0-7 if(m < 65 || dowcrc) // if search was unsuccessful then lastDiscrep=0; // reset the last discrepancy to 0 else // search was successful, so set lastDiscrep, lastOne, nxt { lastDiscrep = discrepMarker; doneFlag = (lastDiscrep == 0); nxt = TRUE; // indicates search is not complete yet, more parts remain } return nxt; }
/** * The 'OneWireSearch' function does a general search. This function continues from * the previous search state. The search state can be reset by using the * 'OneWireFirst' function. * * @retval true When a 1-Wire device was found and its Serial Number placed in * the global ROM * @retval false When no new device was found. Either the last search was * the last device or there are no devices on the 1-Wire Net. */ unsigned char OneWireSearch(void) { unsigned char id_bit_number; unsigned char last_zero, rom_byte_number, search_result; unsigned char id_bit, cmp_id_bit; unsigned char rom_byte_mask, search_direction, status; // initialize for search id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = false; // if the last call was not the last one if (!LastDeviceFlag) { // 1-Wire reset if (!OneWireReset()) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = false; LastFamilyDiscrepancy = 0; return false; } // issue the search command OneWireWriteByte(0xF0); // loop to do the search do { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < LastDiscrepancy) { if ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0) search_direction = 1; else search_direction = 0; } else { // if equal to last pick 1, if not then pick 0 if (id_bit_number == LastDiscrepancy) search_direction = 1; else search_direction = 0; } // Perform a triple operation on the DS2482 which will perform // 2 read bits and 1 write bit status = DS2482SearchTriplet(search_direction); // check bit results in status byte id_bit = ((status & DS2482_STATUS_SBR) == DS2482_STATUS_SBR); cmp_id_bit = ((status & DS2482_STATUS_TSB) == DS2482_STATUS_TSB); search_direction = ((status & DS2482_STATUS_DIR) == DS2482_STATUS_DIR) ? (unsigned char) 1 : (unsigned char) 0; // check for no devices on 1-Wire if ((id_bit) && (cmp_id_bit)) break; else { if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0)) { last_zero = id_bit_number; // check for Last discrepancy in family if (last_zero < 9) LastFamilyDiscrepancy = last_zero; } // set or clear the bit in the ROM byte rom_byte_number // with mask rom_byte_mask if (search_direction == 1) ROM_NO[rom_byte_number] |= rom_byte_mask; else ROM_NO[rom_byte_number] &= (unsigned char) ~rom_byte_mask; // increment the byte counter id_bit_number // and shift the mask rom_byte_mask id_bit_number++; rom_byte_mask <<= 1; // if the mask is 0 then go to new SerialNum byte rom_byte_number // and reset mask if (rom_byte_mask == 0) { rom_byte_number++; rom_byte_mask = 1; } } } while (rom_byte_number < 8); // loop until through all ROM bytes 0-7 // if the search was successful then if (!(id_bit_number < 65)) { // search successful so set LastDiscrepancy,LastDeviceFlag // search_result LastDiscrepancy = last_zero; // check for last device if (LastDiscrepancy == 0) LastDeviceFlag = true; search_result = true; } } // if no device found then reset counters so next // 'search' will be like a first if (!search_result || (ROM_NO[0] == 0)) { LastDiscrepancy = 0; LastDeviceFlag = false; LastFamilyDiscrepancy = 0; search_result = false; } return search_result; }