1-wire serial communication protocol


klimas

Recommended Posts

Is it plugged into your serial (RS232) port? Or is it just a serial 1-wire plugged into an adapter into USB or something? If the first (I doubt it), you'd need to know the protocol and if your 1-wire to 232 converter is doing anything besides hardware translation. If the second, then you need to get the DLL provided with the adapter and access it using the extern() function. I know that others have successfully done this with little effort.

Link to comment
Share on other sites

  • 3 weeks later...
  • 1 month later...

Any luck with 1-wire comm's #63?

This was going to be my next little project for DF but after reading over maxim's literature I doubt I could do it without some help.

I did set up a 4 18S20 temp sensor network to the serial adapter and maxim's Java program sees them all and gets the temp values from them but there is no way to log the temps.

RJE

Link to comment
Share on other sites

  • 2 weeks later...

This is just some preliminary info on the DS18S20 1-wire temp sensor that I have learned so far. It doesn't seem to be as bad as I thought.

This unit is being replaced with the DS18B20 temp sensor but I have 10 of the 18S20 sensors that I would like to use with DF.

My network will be powered (not parasite power) and use the serial adapter DS9097U which takes commands from the serial port and then out to the 1-wire network. I believe this unit has the DS2480B 1-wire driver chip in it, so called the master.

Each DS18S20 temp sensor has a unique 64 bit rom ID that is used for addressing each one on the 1-wire bus. I used Maxim's Java app to get the rom id of each of my sensors so this way I don't have to clutter my DF script with rom searching etc.

One of my sensors has a rom ID of $10, $03, $88, $6B, $01, $08, $00, $4A.

Operation as I understand it right now:

Tx $C1 send reset command, puts all 1-wire units into idle

Rx $CD this is the presence response meaning there are devices listening

Tx $55 send match rom ID command to master - looking for specific sensor

Tx send the sensors rom ID

Tx $44 send convert temp command to the selected sensor wait for conversion

(time unknown right now)

Tx $C1 reset command

Rx $CD presence response

Tx $55 send match rom ID command to master

Tx send the sensors rom ID

Tx $BE send read sensorsscratch memory

Rx 9 bytes back

The first eight bytes are temp info and the ninth byte back is the CRC of the first 8 with which the master uses to check if the data is good.

The scratch memory map of the DS18S20 is:

0 - Temp LSB

1 - Temp MSB

2 - Th register

3 - Tl register

4 - Reserved

5 - Reserved

6 - Count Remain

7 - Count per deg C

8 - CRC

Using the Count Remain and Count per deg C values in the temp calcs you can increase your resolution but I haven't gotten that far yet.

I'll carry on and let you know how things progress.

RJE

Link to comment
Share on other sites

Well things are never easy are they? The commands are spread across several of the 1-wire documents and that makes it difficult to figure things out.

So far I'm up to starting the conversion process in the temp sensor (I think). After the start conversion command I have to send the command for "read time slots", this command tells the master to do its work with the one wire bus to get the done command back from the sensor. The Rx byte will have bit 0 set to 0 if not done and set to 1 if done, all other bits are 'don't care'.

This is where I always get confused, what to do with the Rx byte. My basic loop is this.

device.one_wire.Write(chr(0x44))			 //start conversion command

delay(1)									 //wait for conversion

private stat = 0
private resp

while (stat == 0)

   device.one_wire.Purge()
   device.one_wire.Write(chr(0x95))
   delay(0.1)
   private data = device.one_wire.Read(1)
   resp = to.uByte(data)
   stat = (resp && 1)

endwhile

The Comm window shows I'm getting 97 back but my loop just keeps looping. Where am I going wrong?

RJE

Link to comment
Share on other sites

First, && is a boolean AND. I think you want & which is the bitwise AND.

Second, you can use asc() intead of to.uByte()

Other than that, I don't see anything. Try either adding some debug ? statements (of the contents of resp and stat), or just step through the code using the debugger and look at these directly.

Link to comment
Share on other sites

Well it's crude and rude and maybe socially unacceptable but it works. The 1-wire sensor matches my calibrated Fluke meter with its temperature probe.

private alive

private tempL
private tempH
private regH
private regL
private res1
private res2
private CR
private CP

device.one_wire.Purge()

device.one_wire.Write(chr(0xE3))			 //set master to COMMAND MODE
device.one_wire.write(chr(0xC1))			 //send MASTER RESET
delay(0.1)
device.one_wire.Write(chr(0xE1))			 //set master to DATA MODE

alive = device.one_wire.Read(1)			  //0xCD returned will indicate devices on the bus (nothing done with this yet)

device.one_wire.write(chr(0x55))			 //send match ROM command

device.one_wire.write(chr(0x10))			 //send specific device ROM id
device.one_wire.write(chr(0xD3))
device.one_wire.write(chr(0x88))
device.one_wire.write(chr(0x6B))
device.one_wire.write(chr(0x01))
device.one_wire.write(chr(0x08))
device.one_wire.write(chr(0x00))
device.one_wire.write(chr(0x4A))

delay(0.1)

device.one_wire.Write(chr(0x44))			 //send start conversion command

delay(1)									 //wait for conversion usually 0.75 secs

private stat = 0
private resp

while (stat == 0)							//send read time slots until bit0 = 1 which means conversion done

   device.one_wire.Purge()
   device.one_wire.Write(chr(0x95))
   delay(0.1)
   private string data = device.one_wire.Read(1)
   resp = asc(data)
   stat = (resp & 1)

endwhile

device.one_wire.Write(chr(0xE3))			//set master to COMMAND MODE
device.one_wire.Write(chr(0xC1))			//send MASTER RESET command
delay(0.1)
device.one_wire.Write(chr(0xE1))			//set master to DATA MODE

alive = device.one_wire.Read(1)			 //0xCD returned will indicate devices on the bus

device.one_wire.Write(chr(0x55))			//send match ROM command

device.one_wire.Write(chr(0x10))
device.one_wire.write(chr(0xD3))
device.one_wire.write(chr(0x88))
device.one_wire.write(chr(0x6B))
device.one_wire.write(chr(0x01))
device.one_wire.write(chr(0x08))
device.one_wire.write(chr(0x00))
device.one_wire.write(chr(0x4A))

delay(0.1)

device.one_wire.write(chr(0xBE))		  //send master READ SCRATCH PAD command

device.one_wire.Purge()				   //send write time slots to get device conversion data
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string firstdata = device.one_wire.Read(2)	//for some reason 0xBE is echoed back first then data

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte2 = device.one_wire.Read(1)

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte3 = device.one_wire.Read(1)

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte4 = device.one_wire.Read(1)

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte5 = device.one_wire.Read(1)

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte6 = device.one_wire.Read(1)

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte7 = device.one_wire.Read(1)

device.one_wire.Purge()
device.one_wire.Write(chr(0xFF))
delay(0.1)
private string byte8 = device.one_wire.Read(1)

private string byte1 = Right(firstdata,1)	   //get rid of first byte that's echoed back

tempL = asc(byte1)
tempH = asc(byte2)
regH = asc(byte3)
regL = asc(byte4)
res1 = asc(byte5)
res2 = asc(byte6)
CR = asc(byte7)
CP = asc(byte8)

private count = (16 - CR) / 16				  //calc temp using higher resolution method

private temp = (tempL / 2) - 0.25 + count

Temp_1.AddValue(temp)

Now on to adding more sensors to the 1-wire bus. There is no error detection or anything so user beware and you must know the ROM ID of the sensor you want data from.

RJE

Link to comment
Share on other sites

You can probably replace the long chain of write() with a single write. Ie, this:

device.one_wire.write(chr(0x10)) //send specific device ROM id

device.one_wire.write(chr(0xD3))

device.one_wire.write(chr(0x88))

device.one_wire.write(chr(0x6B))

device.one_wire.write(chr(0x01))

device.one_wire.write(chr(0x08))

device.one_wire.write(chr(0x00))

device.one_wire.write(chr(0x4A))

to this:

device.one_wire.write(chra({0x10,0xD3,0x88,0x6B,0x01,0x08,0x00,0x4A}))

Link to comment
Share on other sites

Hi

Yes I know but since each device's ROM id will be in the script I thought this would be easier to make sure I entered it right.

One thing I haven't figured out yet is the docs say the data back is in 2's compliment form but the MS byte back of the 2 bytes back is the sign. See the attached pic. Still have to figure this out for the outdoor temp sensors.

I'm waiting for delivery of my 6 channel master 1-wire hub to arrive so that I can start adding multiple sensors.

Working on the DS2438 chip which has a 0 - 10V AD input plus a current sense input, this will be used to get the humidity values from my Honeywell sensors.

Onward we shall go!

RJE

post-4150-1270686921_thumb.jpg

Link to comment
Share on other sites

The docs are just being confusing. They are saying the upper byte is all sign, when really they are just using a signed word value to represent their values. The upper byte presumably is always either 0 or 0xff because the sensor never goes above 127C or below -127C. Just treat the incoming value as a signed word (use the To. and From. functions) and it should come out right. Don't forget to divide by 2.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.