Пример #1
0
	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;
	}
Пример #2
0
/*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);
}
Пример #3
0
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--;
		}
	}
}
Пример #4
0
	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;
	}
Пример #5
0
	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);
		}
	}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
	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;
	}
Пример #9
0
	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));
			}
		}
	}
Пример #10
0
	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;
	}
Пример #11
0
	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;
	}
Пример #12
0
/*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);
}
Пример #13
0
	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;
	}
Пример #14
0
unsigned char ds18b20_ConvertT(void){
	if (!OneWireReset()) return 0;
	OneWireWriteByte(0xcc); // SKIP ROM
	OneWireWriteByte(0x44); // CONVERT T
	return -1;
}
Пример #15
0
/*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;
}
Пример #16
0
	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;
	}
Пример #17
0
/**
 * 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;
}