> Does a slave node need information generated by another slave in order to
> operate sensibly? This could complicate matters slightly. However, there are
> schemes and I have seen others mention RTU's which is where this need seemd
> like it could find a solution.
No, it's not important.
> You should probably form a definite pattern for sending and receiving data
> that includes the slave node addresses. Whether such addresses are provided
> as hard-wired switches or are part of a discovery scheme is something you
> may need to think about. In the end, all your slaves will need a unique node
> address.
Of course, I already developed a discovery mechanism that is based on a
unique 32-bit serial number hard-wired in each slave. During discovery
phase, the master assign a 8-bit addres to each slave. This 8-bit
address is used during normal communications.
> There are schemes like CEC (part of the HDMI specification and used
> for consumer device control). Some standards exist like ModBus, IEC60870,
> DNP3 and IEC61850. The HDMI CEC bit is in
> <http://www.microprocessor.org/HDMISpecification.pdf>.
The link level of the protocol is inspired to HDLC. Now I have to
develop the application-level protocol.
> You should probably keep all communicable data in specific memory blocks to
> aid easy transfer (one for TX and one for RX). Keep the size of these blocks
> small and include some form of communications heartbeat function within the
> protocol you select (this should be regular enough and distinct enough to
> know the link status in both directions).
>
> The master station should always be the commanding node and slaves should
> obey. You can include acknowledgements so that the master knows that the
> commands are received and acted upon. Regular status enquiries could collect
> the receivable data in response or just a status byte that states the slave
> is healthy and there is data to transfer (something you will have to decide)
>
> Keep the protocol you select as simple as will suit your needs as possible.
Everything you have written is already implemented in the link-layer of
the protocol.
Reply by Paul E Bennett●December 1, 20142014-12-01
pozzugno wrote:
> Il 30/11/2014 17:46, Paul E Bennett ha scritto:
>> pozz wrote:
> >
>> [...]
>>> Do you have other better strategies to propose?
>>
>> There are plenty of strategies but which will be most suitable for you
>> rather depends on the end use of your system. Is this a commercial
>> product or just something you are playing with?
>
> I'm just playing with this gadget at the moment, but I hope to sell some
> piece. Anyway I try to use "professional" methods even in projects I
> develop during spare time for hobby.
>
>
>> There are things you could do to help yourself, without busting your
>> available memory or comms bandwidth budget, but end use of the
>> information is something I would want to know before I suggest anything
>> as there may be Safety Integrity Implications that you have not yet
>> stated anything about. To make assumptions otherwise would be wrong.
>
> It's not a critical application (such as aerospace, avionics, medical or
> safety). This is for sure.
OK.
Does a slave node need information generated by another slave in order to
operate sensibly? This could complicate matters slightly. However, there are
schemes and I have seen others mention RTU's which is where this need seemd
like it could find a solution.
You should probably form a definite pattern for sending and receiving data
that includes the slave node addresses. Whether such addresses are provided
as hard-wired switches or are part of a discovery scheme is something you
may need to think about. In the end, all your slaves will need a unique node
address. There are schemes like CEC (part of the HDMI specification and used
for consumer device control). Some standards exist like ModBus, IEC60870,
DNP3 and IEC61850. The HDMI CEC bit is in
<http://www.microprocessor.org/HDMISpecification.pdf>.
You should probably keep all communicable data in specific memory blocks to
aid easy transfer (one for TX and one for RX). Keep the size of these blocks
small and include some form of communications heartbeat function within the
protocol you select (this should be regular enough and distinct enough to
know the link status in both directions).
The master station should always be the commanding node and slaves should
obey. You can include acknowledgements so that the master knows that the
commands are received and acted upon. Regular status enquiries could collect
the receivable data in response or just a status byte that states the slave
is healthy and there is data to transfer (something you will have to decide)
Keep the protocol you select as simple as will suit your needs as possible.
--
********************************************************************
Paul E. Bennett IEng MIET.....<email://Paul_E.Bennett@topmail.co.uk>
Forth based HIDECS Consultancy.............<http://www.hidecs.co.uk>
Mob: +44 (0)7811-639972
Tel: +44 (0)1235-510979
Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..
********************************************************************
Reply by Les Cargill●December 1, 20142014-12-01
pozzugno wrote:
> Il 30/11/2014 19:14, Les Cargill ha scritto:
> > [...]
>> You're reinventing MODBUS RTU. It kinda sucks. You can make it work if
>> you have a low enough number of "registers" on a small enough set of
>> "nodes". You trade for latency and the only noise management strategy
>> is retransmission of requests by the master node.
>
> I know the MODBUS RTU, but I don't know how it is the answer to my
> question.
>
It's an attempt to name a very similar protocol which might trigger
some strategies to cope amongst the participants.
I think the comparison to RTU it does help. You're bandwidth
constrained and will have to trade latency for bandwidth.
> Should the Master (implementing Modbus protocol) sends all the registers
> values every 1 second, even if they don't change, or should it send only
> values that change? What is the approach in Modbus network?
>
I am very sure that this varies. I can't give you "should"; I don't
have enough information. But there's usually no reason to send
information you don't have to over a bandwidth constrained
network. Usually. The ugly part of MODBUS RTU is having
to poll everything for state changes.
Since you're half duplex, I doubt you can have asynchronous events fired
from edge nodes. You'd have to poll for them.
--
Les Cargill
Reply by pozzugno●December 1, 20142014-12-01
Il 30/11/2014 19:14, Les Cargill ha scritto:
> [...]
> You're reinventing MODBUS RTU. It kinda sucks. You can make it work if
> you have a low enough number of "registers" on a small enough set of
> "nodes". You trade for latency and the only noise management strategy
> is retransmission of requests by the master node.
I know the MODBUS RTU, but I don't know how it is the answer to my question.
Should the Master (implementing Modbus protocol) sends all the registers
values every 1 second, even if they don't change, or should it send only
values that change? What is the approach in Modbus network?
Reply by pozzugno●December 1, 20142014-12-01
Il 30/11/2014 18:32, upsidedown@downunder.com ha scritto:
> On Sun, 30 Nov 2014 16:27:37 +0100, pozz <pozzugno@gmail.com> wrote:
>
>> I have a "smart device" SD that is the master on a RS485 master/slaves
>> half-duplex network.
>
> In any half duplex network, the relative throughput at higher speeds
> drops quite rapidly due to latencies at both, including software
> delays as well as transceivers turn around times. So even if you can
> run RS-485 at 115k2 to 1000 m or Profibus-DP at 12 Mbit/s for 100 m,
> the actual throughput might not be what you expected.
>
> Using long message frames and avoiding too much pol/ack sequences will
> help.
This is an interesting comment. I tend to use lower bitrate, in the
range 9600-57600bps, even if the distance is small (maximum 100 meters).
I agree with you about the delay that is introduced by software, mainly
the delay for the slave to answer to the master (1ms delay corresponds
to about 4 bytes at 38400bps), but the transceivers turn around time is
very small at those speeds and can be safely ignored.
>> The user interact with a "dumb device" DD (slave)
>> and he should have the illusion to interact directly with the SD.
>>
>> All the relevant (for the user) info (status and settings) about the SD
>> must be spread among the DDs, through a suitable protocol on the RS485
>> network. Some variables are read-only: they changes autonomously over
>> time and can't be changed by the user (for example, a temperature).
>> Other variables are read-write and can be changed only by the user (they
>> don't change autonomously).
>
> So you must poll each DD to check if it has something to send.
Yes, it is what I'm doing.
>> One simple strategy is to send all the current status and settings to
>> all the slaves every 1 second. If the data to be spread are big, the
>> number of slaves is high and most of the data changes slowly (as it
>> happens in my application), a lot of network bandwith will be wasted to
>> send always the same data.
>> I could alleviate this problem by sending data through a broadcast
>> message on the network, but I don't like it. The master should be sure
>> if a slave is present and has well received the status, such that it
>> could generate an alarm if a slave is failed and can't communicate on
>> the network. So the master must poll each slave and waits for an answer
>>from it (this can't be done with broadcast messages).
>
> If the same data needs to be sent to all slaves, broadcast would be
> the natural solution. Also sending a few small different values to all
> slaves could be done with a broadcast message, just locate the value
> for a specific slave at a predefined location in the frame.
>
> The broadcast frame should also contain a common revision number.
>
> Since you are going to poll the slaves anyway for input data, include
> the most recent successfully received broadcast frame revision number
> in the poll response, thus the master will know if there are old data
> in some slaves and repeat the broadcast. This should quite quickly
> remove any transient errors and all slaves will return the most recent
> broadcast frame revision number and there should not be a need to
> repeat the periodic updates, until some data on the master side has
> changed and a new revision number assigned.
>
> Of course, if the slave has some real data to send, the poll response
> should contain the broadcast frame revision number as well as the data
> to be sent to the master, thus minimizing the unproductive message
> exchanges.
I don't think there's a great difference between (M=Master, S=Slave):
M: Hey all, this is message number 13 and my current state is this
M: Hey Slave 1, nothing to say?
S1: Last frame received from you is 13 and nothing to say.
M: Hey Slave 2, nothing to say?
S2: Last frame received from you is 12(!!!?) and nothing to say
and
M: Hey Slave 1, this is my current state. Nothing to say?
S1: Ok, nothing to say
M: Hey Salve 2, this is my current state. Nothing to say?
S2: Ok, the user wants to switch off garden lamp
...
> Such practices have been used at least since the HDLC days.
Indeed my protocol (at the link level) is inspired to HDLC. The master
manages a session for each slave and, for each session, there are two
numbers: the sequence number of last frame send and the sequence number
of last frame received. This is a good approach to identify failed
slaves and failed transmissions to avoid retransmissions with side effetcs.
But this is at the link level. I was discussing about the protol at the
application level on top of link level.
Reply by pozzugno●December 1, 20142014-12-01
Il 30/11/2014 17:46, Paul E Bennett ha scritto:
> pozz wrote:
>
> [...]
>> Do you have other better strategies to propose?
>
> There are plenty of strategies but which will be most suitable for you
> rather depends on the end use of your system. Is this a commercial product
> or just something you are playing with?
I'm just playing with this gadget at the moment, but I hope to sell some
piece. Anyway I try to use "professional" methods even in projects I
develop during spare time for hobby.
> There are things you could do to help yourself, without busting your
> available memory or comms bandwidth budget, but end use of the information
> is something I would want to know before I suggest anything as there may be
> Safety Integrity Implications that you have not yet stated anything about.
> To make assumptions otherwise would be wrong.
It's not a critical application (such as aerospace, avionics, medical or
safety). This is for sure.
Reply by Les Cargill●November 30, 20142014-11-30
pozz wrote:
> I have a "smart device" SD that is the master on a RS485 master/slaves
> half-duplex network. The user interact with a "dumb device" DD (slave)
> and he should have the illusion to interact directly with the SD.
>
> All the relevant (for the user) info (status and settings) about the SD
> must be spread among the DDs, through a suitable protocol on the RS485
> network. Some variables are read-only: they changes autonomously over
> time and can't be changed by the user (for example, a temperature).
> Other variables are read-write and can be changed only by the user (they
> don't change autonomously).
>
> One simple strategy is to send all the current status and settings to
> all the slaves every 1 second. If the data to be spread are big, the
> number of slaves is high and most of the data changes slowly (as it
> happens in my application), a lot of network bandwith will be wasted to
> send always the same data.
> I could alleviate this problem by sending data through a broadcast
> message on the network, but I don't like it. The master should be sure
> if a slave is present and has well received the status, such that it
> could generate an alarm if a slave is failed and can't communicate on
> the network. So the master must poll each slave and waits for an answer
> from it (this can't be done with broadcast messages).
>
> Another strategy is to send by difference: only if one piece of info (a
> variable, a byte or a group of variables) changes, the master sends all
> the data to each slave.
> The problem with this technique is the amount of memory needed in the
> master (it could be a small 8-bit microcontroller with modest size of
> RAM). It should allocate a data buffer for *each* slave with the last
> values sent to it over the network. Every 1 second, a function compare
> the actual values against the last sent values for each slave and send
> new values if they differ.
> If the data is 100 bytes and slaves are 10, the master needs 1KB of RAM
> only for that.
> This strategy could be changed to decrease the network bandwith needed
> to refresh the new status. If only one variable is changed, only that
> (or some other related variables) can be sent over the network.
>
> Another strategy is similar to the previous, but saves a lot of memory:
> the master set only a flag that triggers a status refresh to all the
> slaves. The network protocol task routine checks for this flag and if
> it is set, sends current values to all the slaves.
> The problem with this strategy is in the "core" code that manages the
> status variables. Every time in the code a variable is written in the
> RAM, a comparison with the old value must be made and, if there's a
> difference, the refresh flag must be set. I could try to change the
> "core" code in order to manage the refresh flag for the network, but I
> don't like it for several reasons.
> The "core" code is already written and tested.
> In the future, I'm sure I'll forget to correctly manage the refresh flag.
> The "core" code would be strongly coupled with other completely
> different modules (network protocol).
> The "core" code would be more dirty with network refresh flag
> management: every time I have to set a variable
>
> status.temperature = sensor_read_temperature();
>
> I need to make a comparison with the old value:
>
> new_temperature = sensor_read_temperature();
> if (new_temperature != status.temperature) {
> status.temperature = new_temperature;
> network.refresh_flag = 1;
> }
>
> One possibility to alleviate those problems is to create an intermediate
> module that manages the status. This module provides getter and setter
> functions.
>
> status_temperature_set(sensor_read_temperature());
>
> void status_temperature_set(int new_temperature) {
> if (status.temperature != new_temperature) {
> status.temperature = new_temperature;
> network.refresh_flag = 1;
> }
> }
>
> Even this strategy has some inefficiencies. The module should manage
> the status that is relevant for the slaves (and for the protocol). The
> "core" code should call status module setters for some variables and
> should use normal assignment for other variables (that aren't related to
> network protocol). In this case too, the "core" code is coupled with
> another, completely logically different, module.
>
>
> Do you have other better strategies to propose?
You're reinventing MODBUS RTU. It kinda sucks. You can make it work if
you have a low enough number of "registers" on a small enough set of
"nodes". You trade for latency and the only noise management strategy
is retransmission of requests by the master node.
--
Les Cargill
Reply by ●November 30, 20142014-11-30
On Sun, 30 Nov 2014 16:27:37 +0100, pozz <pozzugno@gmail.com> wrote:
>I have a "smart device" SD that is the master on a RS485 master/slaves
>half-duplex network.
In any half duplex network, the relative throughput at higher speeds
drops quite rapidly due to latencies at both, including software
delays as well as transceivers turn around times. So even if you can
run RS-485 at 115k2 to 1000 m or Profibus-DP at 12 Mbit/s for 100 m,
the actual throughput might not be what you expected.
Using long message frames and avoiding too much pol/ack sequences will
help.
>The user interact with a "dumb device" DD (slave)
>and he should have the illusion to interact directly with the SD.
>
>All the relevant (for the user) info (status and settings) about the SD
>must be spread among the DDs, through a suitable protocol on the RS485
>network. Some variables are read-only: they changes autonomously over
>time and can't be changed by the user (for example, a temperature).
>Other variables are read-write and can be changed only by the user (they
>don't change autonomously).
So you must poll each DD to check if it has something to send.
>One simple strategy is to send all the current status and settings to
>all the slaves every 1 second. If the data to be spread are big, the
>number of slaves is high and most of the data changes slowly (as it
>happens in my application), a lot of network bandwith will be wasted to
>send always the same data.
>I could alleviate this problem by sending data through a broadcast
>message on the network, but I don't like it. The master should be sure
>if a slave is present and has well received the status, such that it
>could generate an alarm if a slave is failed and can't communicate on
>the network. So the master must poll each slave and waits for an answer
>from it (this can't be done with broadcast messages).
If the same data needs to be sent to all slaves, broadcast would be
the natural solution. Also sending a few small different values to all
slaves could be done with a broadcast message, just locate the value
for a specific slave at a predefined location in the frame.
The broadcast frame should also contain a common revision number.
Since you are going to poll the slaves anyway for input data, include
the most recent successfully received broadcast frame revision number
in the poll response, thus the master will know if there are old data
in some slaves and repeat the broadcast. This should quite quickly
remove any transient errors and all slaves will return the most recent
broadcast frame revision number and there should not be a need to
repeat the periodic updates, until some data on the master side has
changed and a new revision number assigned.
Of course, if the slave has some real data to send, the poll response
should contain the broadcast frame revision number as well as the data
to be sent to the master, thus minimizing the unproductive message
exchanges. Such practices have been used at least since the HDLC days.
Reply by Paul E Bennett●November 30, 20142014-11-30
pozz wrote:
> I have a "smart device" SD that is the master on a RS485 master/slaves
> half-duplex network. The user interact with a "dumb device" DD (slave)
> and he should have the illusion to interact directly with the SD.
>
> All the relevant (for the user) info (status and settings) about the SD
> must be spread among the DDs, through a suitable protocol on the RS485
> network. Some variables are read-only: they changes autonomously over
> time and can't be changed by the user (for example, a temperature).
> Other variables are read-write and can be changed only by the user (they
> don't change autonomously).
>
> One simple strategy is to send all the current status and settings to
> all the slaves every 1 second. If the data to be spread are big, the
> number of slaves is high and most of the data changes slowly (as it
> happens in my application), a lot of network bandwith will be wasted to
> send always the same data.
> I could alleviate this problem by sending data through a broadcast
> message on the network, but I don't like it. The master should be sure
> if a slave is present and has well received the status, such that it
> could generate an alarm if a slave is failed and can't communicate on
> the network. So the master must poll each slave and waits for an answer
> from it (this can't be done with broadcast messages).
>
> Another strategy is to send by difference: only if one piece of info (a
> variable, a byte or a group of variables) changes, the master sends all
> the data to each slave.
> The problem with this technique is the amount of memory needed in the
> master (it could be a small 8-bit microcontroller with modest size of
> RAM). It should allocate a data buffer for *each* slave with the last
> values sent to it over the network. Every 1 second, a function compare
> the actual values against the last sent values for each slave and send
> new values if they differ.
> If the data is 100 bytes and slaves are 10, the master needs 1KB of RAM
> only for that.
> This strategy could be changed to decrease the network bandwith needed
> to refresh the new status. If only one variable is changed, only that
> (or some other related variables) can be sent over the network.
>
> Another strategy is similar to the previous, but saves a lot of memory:
> the master set only a flag that triggers a status refresh to all the
> slaves. The network protocol task routine checks for this flag and if
> it is set, sends current values to all the slaves.
> The problem with this strategy is in the "core" code that manages the
> status variables. Every time in the code a variable is written in the
> RAM, a comparison with the old value must be made and, if there's a
> difference, the refresh flag must be set. I could try to change the
> "core" code in order to manage the refresh flag for the network, but I
> don't like it for several reasons.
> The "core" code is already written and tested.
> In the future, I'm sure I'll forget to correctly manage the refresh flag.
> The "core" code would be strongly coupled with other completely
> different modules (network protocol).
> The "core" code would be more dirty with network refresh flag
> management: every time I have to set a variable
>
> status.temperature = sensor_read_temperature();
>
> I need to make a comparison with the old value:
>
> new_temperature = sensor_read_temperature();
> if (new_temperature != status.temperature) {
> status.temperature = new_temperature;
> network.refresh_flag = 1;
> }
>
> One possibility to alleviate those problems is to create an intermediate
> module that manages the status. This module provides getter and setter
> functions.
>
> status_temperature_set(sensor_read_temperature());
>
> void status_temperature_set(int new_temperature) {
> if (status.temperature != new_temperature) {
> status.temperature = new_temperature;
> network.refresh_flag = 1;
> }
> }
>
> Even this strategy has some inefficiencies. The module should manage
> the status that is relevant for the slaves (and for the protocol). The
> "core" code should call status module setters for some variables and
> should use normal assignment for other variables (that aren't related to
> network protocol). In this case too, the "core" code is coupled with
> another, completely logically different, module.
>
>
> Do you have other better strategies to propose?
There are plenty of strategies but which will be most suitable for you
rather depends on the end use of your system. Is this a commercial product
or just something you are playing with?
There are things you could do to help yourself, without busting your
available memory or comms bandwidth budget, but end use of the information
is something I would want to know before I suggest anything as there may be
Safety Integrity Implications that you have not yet stated anything about.
To make assumptions otherwise would be wrong.
--
********************************************************************
Paul E. Bennett IEng MIET.....<email://Paul_E.Bennett@topmail.co.uk>
Forth based HIDECS Consultancy.............<http://www.hidecs.co.uk>
Mob: +44 (0)7811-639972
Tel: +44 (0)1235-510979
Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..
********************************************************************
Reply by pozz●November 30, 20142014-11-30
I have a "smart device" SD that is the master on a RS485 master/slaves
half-duplex network. The user interact with a "dumb device" DD (slave)
and he should have the illusion to interact directly with the SD.
All the relevant (for the user) info (status and settings) about the SD
must be spread among the DDs, through a suitable protocol on the RS485
network. Some variables are read-only: they changes autonomously over
time and can't be changed by the user (for example, a temperature).
Other variables are read-write and can be changed only by the user (they
don't change autonomously).
One simple strategy is to send all the current status and settings to
all the slaves every 1 second. If the data to be spread are big, the
number of slaves is high and most of the data changes slowly (as it
happens in my application), a lot of network bandwith will be wasted to
send always the same data.
I could alleviate this problem by sending data through a broadcast
message on the network, but I don't like it. The master should be sure
if a slave is present and has well received the status, such that it
could generate an alarm if a slave is failed and can't communicate on
the network. So the master must poll each slave and waits for an answer
from it (this can't be done with broadcast messages).
Another strategy is to send by difference: only if one piece of info (a
variable, a byte or a group of variables) changes, the master sends all
the data to each slave.
The problem with this technique is the amount of memory needed in the
master (it could be a small 8-bit microcontroller with modest size of
RAM). It should allocate a data buffer for *each* slave with the last
values sent to it over the network. Every 1 second, a function compare
the actual values against the last sent values for each slave and send
new values if they differ.
If the data is 100 bytes and slaves are 10, the master needs 1KB of RAM
only for that.
This strategy could be changed to decrease the network bandwith needed
to refresh the new status. If only one variable is changed, only that
(or some other related variables) can be sent over the network.
Another strategy is similar to the previous, but saves a lot of memory:
the master set only a flag that triggers a status refresh to all the
slaves. The network protocol task routine checks for this flag and if
it is set, sends current values to all the slaves.
The problem with this strategy is in the "core" code that manages the
status variables. Every time in the code a variable is written in the
RAM, a comparison with the old value must be made and, if there's a
difference, the refresh flag must be set. I could try to change the
"core" code in order to manage the refresh flag for the network, but I
don't like it for several reasons.
The "core" code is already written and tested.
In the future, I'm sure I'll forget to correctly manage the refresh flag.
The "core" code would be strongly coupled with other completely
different modules (network protocol).
The "core" code would be more dirty with network refresh flag
management: every time I have to set a variable
status.temperature = sensor_read_temperature();
I need to make a comparison with the old value:
new_temperature = sensor_read_temperature();
if (new_temperature != status.temperature) {
status.temperature = new_temperature;
network.refresh_flag = 1;
}
One possibility to alleviate those problems is to create an intermediate
module that manages the status. This module provides getter and setter
functions.
status_temperature_set(sensor_read_temperature());
void status_temperature_set(int new_temperature) {
if (status.temperature != new_temperature) {
status.temperature = new_temperature;
network.refresh_flag = 1;
}
}
Even this strategy has some inefficiencies. The module should manage
the status that is relevant for the slaves (and for the protocol). The
"core" code should call status module setters for some variables and
should use normal assignment for other variables (that aren't related to
network protocol). In this case too, the "core" code is coupled with
another, completely logically different, module.
Do you have other better strategies to propose?