I want to push a bit stream through a series of *identical* devices and have (identical) software running on each determine if that particular device is being addressed, or not. It seems like the simplest way to do so is to require each device to examine an address field in the packet and, if '0', assume the data that follows is intended for its consumption. If not, decrement the address and pass the packet along. (I.e., the protocol would require a SERIAL_IN and SERIAL_OUT signals) Of course, this means a failure of any device renders those that follow it inaccessible. That's acceptable. It also means there is a latency proportional to the device address inherent in the protocol. Also acceptable (the data source can take that into consideration when creating the message stream). And, the incremental latency can be made pretty small. Another downside is the cost of updating data on *all* (multiple) devices as this requires N messages. An alternate message format (or, a cleverer encoding of the above) could be used to allow a single COMPOSITE message to be propagated in which a node encountering a '0' address field strips the data that is intended for its use and then reconstructs a message bearing a '0' address field with the BALANCE of the data that it then passes to the next device, in series. In effect, letting each subsequent device strip off "its" data before passing the remainder along. [When no data remains, the message dissipates] As such, you could "address" any set of contiguous addresses by creating an initial message of the form: <first_target_ID> <first_datum> ... <last_datum> where the number of data present in the message implicitly defines the *last_target_id* relative to the first_target_id. Any problems with this sort of kludged encapsulation?
Serial protocol with physical decoding
Started by ●May 4, 2017
Reply by ●May 4, 20172017-05-04
On 04/05/17 16:14, Don Y wrote:> I want to push a bit stream through a series of *identical* devices > and have (identical) software running on each determine if that > particular device is being addressed, or not. > > It seems like the simplest way to do so is to require each device > to examine an address field in the packet and, if '0', assume the > data that follows is intended for its consumption. If not, > decrement the address and pass the packet along. > > (I.e., the protocol would require a SERIAL_IN and SERIAL_OUT > signals) > > Of course, this means a failure of any device renders those that > follow it inaccessible. That's acceptable. > > It also means there is a latency proportional to the device address > inherent in the protocol. Also acceptable (the data source can > take that into consideration when creating the message stream). > And, the incremental latency can be made pretty small. > > Another downside is the cost of updating data on *all* (multiple) > devices as this requires N messages. > > An alternate message format (or, a cleverer encoding of the above) > could be used to allow a single COMPOSITE message to be propagated > in which a node encountering a '0' address field strips the data > that is intended for its use and then reconstructs a message > bearing a '0' address field with the BALANCE of the data that it > then passes to the next device, in series. In effect, letting > each subsequent device strip off "its" data before passing the > remainder along. > > [When no data remains, the message dissipates] > > As such, you could "address" any set of contiguous addresses > by creating an initial message of the form: > <first_target_ID> <first_datum> ... <last_datum> > where the number of data present in the message implicitly defines > the *last_target_id* relative to the first_target_id. > > Any problems with this sort of kludged encapsulation?Why daisy-chain? If all devices have to be listening anyhow, why not send the same data to all in parallel, and get each one to validate the checksum and determine if the message is intended for them. That way you can use broadcast (groups), and one software failure doesn't take down the chain. Otherwise you start getting into USB-style distribution trees with all the complexity of enumeration, routing, etc. Avoid that if you can, would be my advice. Clifford Heath.
Reply by ●May 4, 20172017-05-04
Il giorno giovedì 4 maggio 2017 08:13:50 UTC+2, Don Y ha scritto:> I want to push a bit stream through a series of *identical* devices > and have (identical) software running on each determine if that > particular device is being addressed, or not. > > It seems like the simplest way to do so is to require each device > to examine an address field in the packet and, if '0', assume the > data that follows is intended for its consumption. If not, > decrement the address and pass the packet along.> Another downside is the cost of updating data on *all* (multiple) > devices as this requires N messages.You can think of a special broadcast address that is not decremented but the device simply accept the message and ppass it over to the next. But if you put a checksum on the message, you need to recalculate the checksum every time the address is decremented (or you don't put the address in the checksum...) Bye Jack
Reply by ●May 4, 20172017-05-04
On 5/4/2017 12:28 AM, Jack wrote:> Il giorno giovedì 4 maggio 2017 08:13:50 UTC+2, Don Y ha scritto: >> I want to push a bit stream through a series of *identical* devices and >> have (identical) software running on each determine if that particular >> device is being addressed, or not. >> >> It seems like the simplest way to do so is to require each device to >> examine an address field in the packet and, if '0', assume the data that >> follows is intended for its consumption. If not, decrement the address >> and pass the packet along. > >> Another downside is the cost of updating data on *all* (multiple) devices >> as this requires N messages. > > You can think of a special broadcast address that is not decremented but the > device simply accept the message and ppass it over to the next.Yes, that's a good idea. My comment, above, was intended to deal with the case of sending DIFFERENT data to ALL devices vs. sending the SAME data to all of them. E.g., if I wanted to set the devices per the following table: ID Value 3 CC 4 D 5 EEEE 6 FFF I could send the message (ignore the obvious error, here): 3CCDEEEEFFF device 3 to peel off the "CC" and pass "0DEEEEFFF" along which would cause device 4 to peel off the "D" and pass "0EEEEFFF" along which would cause device 5 to peel off the "EEEE" and pass "0FFF" along which would cause device 6 to peel off the "FFF", dissipating the message (i.e., devices 7 and higher would see no traffic) By contrast, your suggestion would allow for a *XYZ message to be propagated, as is, to all subsequent devices (assume '*' is the "special broadcast address"). This would be useful in some cases.> But if you put a checksum on the message, you need to recalculate the > checksum every time the address is decremented (or you don't put the address > in the checksum...)Yes. And, each device would have to delay acting on the data until the balance of the message had been received -- even though it could begin propagating the data that follows its payload as soon as it has been received. Putting the checksum at the head of the message would require each device to buffer the ENTIRE message -- placing a limit on the length of the chain -- as it wouldn't be able to tweek the checksum until after it sees the entire message. [There's some hand-waving here; you could also adopt a message format that lets a "trailer byte" be modified to bias the checksum as needed AFTER the message has been passed through with the original, unmodified checksum]
Reply by ●May 4, 20172017-05-04
AT Thursday 04 May 2017 14:14, Don Y wrote:> I want to push a bit stream through a series of *identical* devices > and have (identical) software running on each determine if that > particular device is being addressed, or not. > > It seems like the simplest way to do so is to require each device > to examine an address field in the packet and, if '0', assume the > data that follows is intended for its consumption. If not, > decrement the address and pass the packet along. > > (I.e., the protocol would require a SERIAL_IN and SERIAL_OUT > signals) > > Of course, this means a failure of any device renders those that > follow it inaccessible. That's acceptable. > > It also means there is a latency proportional to the device address > inherent in the protocol. Also acceptable (the data source can > take that into consideration when creating the message stream). > And, the incremental latency can be made pretty small. > > Another downside is the cost of updating data on *all* (multiple) > devices as this requires N messages. > > An alternate message format (or, a cleverer encoding of the above) > could be used to allow a single COMPOSITE message to be propagated > in which a node encountering a '0' address field strips the data > that is intended for its use and then reconstructs a message > bearing a '0' address field with the BALANCE of the data that it > then passes to the next device, in series. In effect, letting > each subsequent device strip off "its" data before passing the > remainder along. > > [When no data remains, the message dissipates] > > As such, you could "address" any set of contiguous addresses > by creating an initial message of the form: > <first_target_ID> <first_datum> ... <last_datum> > where the number of data present in the message implicitly defines > the *last_target_id* relative to the first_target_id. > > Any problems with this sort of kludged encapsulation?Your second format reminds me of the Interbus. This is also a daisy-chained fieldbus. A packet contains data for all at fixed positions. Each client can take its part (as its input) and replace it with its output. The whole packet is protected be a crc that each client recalculates when it changes the message. This means of course that the size of inputs and output for each client must be equal. If a client has more out than in, the message from the master must be padded with dummies. During a config phase the master determines how long each clients part is and the client discover where in the message their part is. I once implemented something similar using simple uarts using RS422. Each client re-transmits the (modified) message. The output goes to the next client. At the end the loop is closed by connecting to a common rail back to the master. I even had some way two RS422 drivers. One always on for connecting to the next client, another that is connected to the common back rail and is only switched on by the client if it is the last in the ring. This was determined during initial config by the master and the last client setup accordingly. This even allowed to keep the ring working when one client failed. The ring was just closed before it. Of course every client after this point was cut off. This automatic ring closure is also part of the Interbus and I had taken the idea from there. -- Reinhardt
Reply by ●May 4, 20172017-05-04
On 5/4/2017 1:44 AM, Reinhardt Behm wrote:> AT Thursday 04 May 2017 14:14, Don Y wrote: > >> I want to push a bit stream through a series of *identical* devices >> and have (identical) software running on each determine if that >> particular device is being addressed, or not. >> >> It seems like the simplest way to do so is to require each device >> to examine an address field in the packet and, if '0', assume the >> data that follows is intended for its consumption. If not, >> decrement the address and pass the packet along. >> >> (I.e., the protocol would require a SERIAL_IN and SERIAL_OUT >> signals) >> >> Of course, this means a failure of any device renders those that >> follow it inaccessible. That's acceptable. >> >> It also means there is a latency proportional to the device address >> inherent in the protocol. Also acceptable (the data source can >> take that into consideration when creating the message stream). >> And, the incremental latency can be made pretty small. >> >> Another downside is the cost of updating data on *all* (multiple) >> devices as this requires N messages. >> >> An alternate message format (or, a cleverer encoding of the above) >> could be used to allow a single COMPOSITE message to be propagated >> in which a node encountering a '0' address field strips the data >> that is intended for its use and then reconstructs a message >> bearing a '0' address field with the BALANCE of the data that it >> then passes to the next device, in series. In effect, letting >> each subsequent device strip off "its" data before passing the >> remainder along. >> >> [When no data remains, the message dissipates] >> >> As such, you could "address" any set of contiguous addresses >> by creating an initial message of the form: >> <first_target_ID> <first_datum> ... <last_datum> >> where the number of data present in the message implicitly defines >> the *last_target_id* relative to the first_target_id. >> >> Any problems with this sort of kludged encapsulation? > > Your second format reminds me of the Interbus. This is also a daisy-chained > fieldbus. A packet contains data for all at fixed positions. Each client can > take its part (as its input) and replace it with its output. The whole > packet is protected be a crc that each client recalculates when it changes > the message. > This means of course that the size of inputs and output for each client must > be equal. If a client has more out than in, the message from the master must > be padded with dummies.Actually, that's not a requirement in my scheme. Consider a few approaches: <packet> ::= <ID> <messages> <CRC> ... <message> ::= <length> <content> Here, each message can be opaque -- yet its size IN THE PACKET can easily be determines by the <length> field introducing it. The number of messages can be deduced by parsing the <length> header of each successive <message> until you encounter one with a special <length> value (e.g., '0'). This then implies the location of the <CRC> to follow -- and the start f the NEXT packet. [Of course, it *requires* each device addressed in that packet to be targeteed for *some* sort of command -- even if that it a NOP (so its <length> field is != 0)] Another approach: <message> ::= <stop> | <start> | <speed> | <position> <stop> ::= STOP <start> ::= START <speed> ::= SPEED <percent> <position> ::= GOTO <X> <Y> (these might be manifest constants or literal ASCII character sequences) The "length" of each <message> is implicit in the message's identity. My requirement that the same/identical software run on all devices means EVERY device can understand ALL messages. A device doesn't have to know what TYPE of device it is or where in the chain it is located. The device upstream looks like its master and those downstream look like its peers.> During a config phase the master determines how long each clients part is > and the client discover where in the message their part is.Yes, a valid alternative. But, only if you want to support different TYPES of clients (devices).> I once implemented something similar using simple uarts using RS422. Each > client re-transmits the (modified) message. The output goes to the next > client. At the end the loop is closed by connecting to a common rail back to > the master.Actually, that might make some sense. I'd only pursued a unidirectional (output only) scheme. But, you could modify this to allow devices to append data that they want to return to the "master" -- by exploiting each subsequent device's mandate to propagate EVERYTHING that comes into it after eliding its particular payload (and injecting its reply).> I even had some way two RS422 drivers. One always on for connecting to the > next client, another that is connected to the common back rail and is only > switched on by the client if it is the last in the ring. This was determined > during initial config by the master and the last client setup accordingly. > This even allowed to keep the ring working when one client failed. The ring > was just closed before it. Of course every client after this point was cut > off.I don't think I need to include recovery mechanisms. If some portion of the "network" (field) can become inaccessible, then its likely that things need to be repaired. Otherwise, where a device sat in the chain would determine its relative importance -- you'd be inclined to spend effort reconfiguring the chain whenever its device content changed and you'd probably never be *assured* that you could find an optimal/satisfying configuration. [I'm looking for a cheap/simple solution, not necessarily an efficient one!] OTOH, closing the ring at least provides *some* diagnostic information to the master. If it fails to see some indication that its most recent packet had propagated through all devices, it could throw an error. Without that loop closing, it would have to assume all was well!> This automatic ring closure is also part of the Interbus and I had taken the > idea from there.
Reply by ●May 4, 20172017-05-04
On 5/4/2017 3:48 AM, Don Y wrote:> On 5/4/2017 12:28 AM, Jack wrote: >> Il giorno giovedì 4 maggio 2017 08:13:50 UTC+2, Don Y ha scritto: >>> I want to push a bit stream through a series of *identical* devices and >>> have (identical) software running on each determine if that particular >>> device is being addressed, or not. >>> >>> It seems like the simplest way to do so is to require each device to >>> examine an address field in the packet and, if '0', assume the data that >>> follows is intended for its consumption. If not, decrement the address >>> and pass the packet along. >> >>> Another downside is the cost of updating data on *all* (multiple) >>> devices >>> as this requires N messages. >> >> You can think of a special broadcast address that is not decremented >> but the >> device simply accept the message and ppass it over to the next. > > Yes, that's a good idea. > > My comment, above, was intended to deal with the case of sending > DIFFERENT data to ALL devices vs. sending the SAME data to all > of them. > > E.g., if I wanted to set the devices per the following table: > > ID Value > 3 CC > 4 D > 5 EEEE > 6 FFF > > I could send the message (ignore the obvious error, here): > > 3CCDEEEEFFF > > device 3 to peel off the "CC" and pass "0DEEEEFFF" along which would cause > device 4 to peel off the "D" and pass "0EEEEFFF" along which would cause > device 5 to peel off the "EEEE" and pass "0FFF" along which would cause > device 6 to peel off the "FFF", dissipating the message (i.e., devices > 7 and higher would see no traffic)What is the value of this vs. sending four messages? You could send the message to 7 first. Once that message has cleared the first unit send a message to 6, then 5, 4 and finally the message goes out to 3. When message 3 is received by device 3 the message for 7 is being received by 7. -- Rick C
Reply by ●May 4, 20172017-05-04
On Wed, 03 May 2017 23:14:09 -0700, Don Y wrote:> I want to push a bit stream through a series of *identical* devices and > have (identical) software running on each determine if that particular > device is being addressed, or not. > > It seems like the simplest way to do so is to require each device to > examine an address field in the packet and, if '0', assume the data that > follows is intended for its consumption. If not, decrement the address > and pass the packet along. > > (I.e., the protocol would require a SERIAL_IN and SERIAL_OUT signals) > > Of course, this means a failure of any device renders those that follow > it inaccessible. That's acceptable. > > It also means there is a latency proportional to the device address > inherent in the protocol. Also acceptable (the data source can take > that into consideration when creating the message stream). And, the > incremental latency can be made pretty small. > > Another downside is the cost of updating data on *all* (multiple) > devices as this requires N messages. > > An alternate message format (or, a cleverer encoding of the above) could > be used to allow a single COMPOSITE message to be propagated in which a > node encountering a '0' address field strips the data that is intended > for its use and then reconstructs a message bearing a '0' address field > with the BALANCE of the data that it then passes to the next device, in > series. In effect, letting each subsequent device strip off "its" data > before passing the remainder along. > > [When no data remains, the message dissipates] > > As such, you could "address" any set of contiguous addresses by creating > an initial message of the form: > <first_target_ID> <first_datum> ... <last_datum> > where the number of data present in the message implicitly defines the > *last_target_id* relative to the first_target_id. > > Any problems with this sort of kludged encapsulation?I've done this, it worked -- the customer went through some personnel changes and the project died before it could get shipped, but cest la vie. I wouldn't overthink things vis-a-vis the composite message -- just send lots of little messages and be happy. Complexity leads to bugs. Use all ones in the address field as a 'broadcast' address. Or do the address decrementing by shifting down one bit, and consider the message "yours" if the least significant bit is zero. That only allows eight devices, but if you foresee a lot of traffic with identical messages for selected sets of devices, this would move you on down the road. -- www.wescottdesign.com
Reply by ●May 4, 20172017-05-04
In article <590acce3$0$58351$b1db1813$19ace300@news.astraweb.com>, Clifford Heath <no.spam@please.net> wrote:> On 04/05/17 16:14, Don Y wrote: > > I want to push a bit stream through a series of *identical* devices > > and have (identical) software running on each determine if that > > particular device is being addressed, or not. > > > > Why daisy-chain? If all devices have to be listening anyhow, > why not send the same data to all in parallel, and get each > one to validate the checksum and determine if the message > is intended for them. That way you can use broadcast (groups), > and one software failure doesn't take down the chain. > > Otherwise you start getting into USB-style distribution trees > with all the complexity of enumeration, routing, etc. Avoid > that if you can, would be my advice. >If each device is identical, and running identical software, how do you get the devices to not all think the message is for them? How about a hybrid approach where the data stream is connected in parallel, but the enable is daisy chained. On initialization, only the first device would see the enable, and it would receive and acknowledge a message setting its address, then it would set the enable for the next device in the chain, and the initialization continues until each has received a unique address. This would also solve the synchronization issue since one address could be reserved as an 'all listen' address that could be used to initiate an action.
Reply by ●May 4, 20172017-05-04
On 5/4/2017 7:54 AM, Tim Wescott wrote:>> Any problems with this sort of kludged encapsulation? > > I've done this, it worked -- the customer went through some personnel > changes and the project died before it could get shipped, but cest la vie.I used the first format with cheap single-chip MCU's many years ago -- using a LONG SPACE to signal the start of the packet (to "resynchronize" any drifted clock; a VERY LONG BREAK would cause a one-shot in the device to trigger and hardware reset the device) But, the data rates were very low and the line interfaces had plenty of noise margin (EIA232). I'd like to come up with a scheme that I could apply to a variety of similarly "open ended" network configurations -- that have very different physical characteristics (e.g., a 10 ft long chain and a 300 ft long chain -- trading data rate for network size)> I wouldn't overthink things vis-a-vis the composite message -- just send > lots of little messages and be happy. Complexity leads to bugs.The problem with lots of messages comes from having to update many devices (nodes?) continuously. You incur the message overhead for every individual message. With the "composite" format, the master can just push an endless stream of data out and each node picks off what's important.> Use all ones in the address field as a 'broadcast' address. > > Or do the address decrementing by shifting down one bit, and consider the > message "yours" if the least significant bit is zero. That only allows > eight devices, but if you foresee a lot of traffic with identical > messages for selected sets of devices, this would move you on down the > road.I have to look at the different applications that I have in mind to see whether I want a "bit oriented" protocol or a byte-oriented. I.e., I don't want to get coerced (subconsciously) into letting a UART make me think in terms of "characters" when something more like a self-clocking JTAG might make more sense. The big downside that I see is handling transmission "problems". E.g., if node X detects a CRC error, it has no way of knowing if it's data is intact *or* if the error is part of the data that it will be propagating. If it *corrects* the CRC that it passes along (to coincide with that data content), then it has "blessed" that data (by hiding the CRC error from those downstream from it!). This suggests the node has EFFECTIVELY decided the error was in its portion of the data packet (if so, it definitely shouldn't be USING that data!) Repeat for cases where one or more nodes loses clock recovery or message synchronization (thus, *misinterprets* the serialized data stream) [Reinhardt's suggestion of "closing the loop" bears some merit! But, it alone doesn't ensure that everything handled the packet correctly]