Long range inter-microcontroller communication.
Harrison H Jones
Posts: 22
Hey Parallax Sandbox People!
I have a project I'm starting that requires several different "modules" to communicate between each other over fair long distances(not wireless long, just a couple hundred feet of cable). I don't want to do wireless because of the cost(Xbee's are $35) and I have the time and space to run cable. I would expect serial communication wouldn't work because it would deteriorate over such a long distance. I would also like something a little more "modern" than serial. I was thinking of something like a Ethernet stack(ENC28J60) with all the modules plugged into a router. Would that work? The host computer could simply telnet into each module and communicate with it.
Any other suggestions or comments on my idea?
Post Edited (Harrison H Jones) : 9/28/2009 6:18:38 PM GMT
I have a project I'm starting that requires several different "modules" to communicate between each other over fair long distances(not wireless long, just a couple hundred feet of cable). I don't want to do wireless because of the cost(Xbee's are $35) and I have the time and space to run cable. I would expect serial communication wouldn't work because it would deteriorate over such a long distance. I would also like something a little more "modern" than serial. I was thinking of something like a Ethernet stack(ENC28J60) with all the modules plugged into a router. Would that work? The host computer could simply telnet into each module and communicate with it.
Any other suggestions or comments on my idea?
Post Edited (Harrison H Jones) : 9/28/2009 6:18:38 PM GMT
Comments
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
Edit: Just looked into ModBus.. Looks really interesting, i'll do some more research.
http://www.vanguard-co.com/download/basic_stamp_accesories/rs485Communication.pdf
I am into the same situation myself with communication-problems·because of too·long distance between the BS and a serial device. I have not tried this 75176-chip because I still havent received it from purcase but it should be here anytime.
My problem was to read a DS1620 through a cat-5 cable over a distance of 40 meters or so. With the SN75176 I guess I will need another BS microcontroller at the end of the cable to read the temperature sensor and then two SN75176-chips for the RS485-communication.
Reread Leon's post. He didn't say it won't work; he said it "won't be a problem", and he's right.
-Phil
@Harrison - just add a tcp/ip stack chip? In the PC world network cards are a dime a dozen but the resources required to run them pretty much rules them out for a lot of embedded use. But by the same token there are a lot of other more practical and efficient solutions to use such as RS-485 or RS-422 and a suitable protocol. MODBUS is a very basic protocol and it is also very easy to roll-your-own. In the embedded world it is an advantage to use 9-bit serial data instead of 8-bit as the 9th bit can be used to indicate data or non-data such as a bus address. This type of 9-bit coms I have used in RS-485 networks for decades and they work reliably over long distances with absolute minimum hardware and software.
*Peter*
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
*Peter*
Again, for small amounts of data, building in MODBUS protocol may not be needed/wanted unless there was some other reason to need it. You can very easily implement a master-slave protocol yourself with SERIN and SEROUT commands.
Cheers,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tom Sisk
http://www.siskconsult.com
·
Does anybody have any ideas on something that would do that?
·· If slave1 has something to send to slave2, the transaction is best handled by letting the master get the response and forward it on. You're going to have every module connected to the master anyway so theres no additional hardware.
·· Your protocol can include a byte that is used as a director so the master will know whether the message is meant to be kept or forwarded.
··· SN65HVD12D·should work. Note that it is designed for a 3.3 volt power supply. There are also 5 volt units. Just have a look on DigiKey as "rs485 transceiver".··
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tom Sisk
http://www.siskconsult.com
Post Edited (stamptrol) : 9/28/2009 4:34:20 PM GMT
Does anybody have any ideas on something that would do that?"
Ethernet is overkill for such a simple communications requirement. A simple RS485 half duplex protocol would work fine for this application. What you need is a simple csma/cd ( carrier sense multiple access with collision detection ) protocol.
Each station has a unique address.
1- A station listens to the data bus at all times and receives messages addressed to it.
2- A station only starts to transmit data to another station when there is no activity on the bus (carrier sense multiple access).
3- A station listens to the bus while it is sending to verify that the data on the bus is correct ( collision detect ).
4- If a collision is detected the station waits for a random period of time and repeats steps 2 and 3.
This is a fairly simple protocol to program on any micro. The first thing to do would be to decide on the message format. You could design your own format or use one of the many formats already standardized.
The alternative is to pass a "token" from one station to the next and allowing only the station with the token to transmit. That has it's own drawbacks, such as generating the token, and dealing with unimplemented addresses.
You're just looking for trouble if you want the slaves to transmit to the master "on their own terms". That opens up a really nasty can of worms involving collision detection, backoff, and retransmit. Why make life so hard? Just let the master do the polling and be done with it. It won't affect your throughput that much, and it makes life much simpler. The only thing that would be simpler still is a star hub, where the master has a transceiver for each of the slaves. But that entails a lot of extra hardware and extra cable, not to mention a higher-performance micro for the master to handle all those com channels at once.
-Phil
I work with alarm system design. We use a polling method to communicate with regular keypads and with graphics keypads. You really cannot tell that polling is being used even with a fully-loaded (31 devices) system.
We use a "general poll" method in which any device which wants to speak with the master "raises its hand", and then the master queries that device specifically. A result of this is that Device#1 has a higher priority than Device #30.
--Rich
I'm still thinking of implementing a method which requires collision detection but I'm tilting my head toward the polling method.
'
'This program interfaces a BASIC Stamp 2 to an RS485 network
' using the SN75176 Differential Bus Tranceiver chip from
' TI.· This program is meant to operate with another Stamp 2
' connected to the same RS485 network and is running the
' slave.bs2 program.
'
' Pins 2 and 3 of the SN75176 chip are connected to pin 0 of
'· the Stamp 2.· Pins 1 and 4 of the SN75176 chip are
'· connected to Pin 1 of the Stamp 2.
'
' This program expects an active-low button or switch to be
'· connected to pin 2 of the Stamp2. When the button or switch
'· sets pin 2 low, the character "L" is sent over the RS485
'· network.· When the button or switch sets pin 2 high then
'· the character "H" is sent over the network.
'
' Note. Setting pin 0 on the Stamp 2 high puts the SN75176 into
'· transmit mode.· So any serial data transmitted out of pin 1 on
'· the Stamp 2 will be transmitted over the RS485 network.
'
'========== Variables =============
btnWk var byte ····'Workspace for the BUTTON command
'========== Initialize ============
input 2·····'Make pin 2 the button input
output 0····'Make pin 0 an output
high 0·····'Put the SN75176 into transmit mode
'========== Begin Program =========
·if(in2<>1)then loop1:···'If pin 2 is initially High, send...
· SEROUT 1,16468,1,[noparse][[/noparse]"H"]··'... an "H" over the RS485 network
'========== Main Loop =============
loop1:
· BUTTON 2,0,255,0,btnWk,1,preloop2·'Wait till pin 2 is low
· goto loop1
preloop2:
·SEROUT 1,16468,1,[noparse][[/noparse]"L"]···'Send a "L" over the RS485 network.
loop2:
· BUTTON 2,1,255,250,btnWk,1,loop_again 'Wait till pin 2 goes high
· goto loop2
loop_again:
· SEROUT 1,16468,1,[noparse][[/noparse]"H"]··'Send an "H" over the rs485 network.
goto loop1:····'Loop forever
'Program: slave.bs2 (BS2 to RSS485 interface via a SN75176 chip)
'
'This program interfaces a BASIC Stamp 2 to an RS485 network
' using the SN75176 Differential Bus Tranceiver chip from
' TI.· This program is meant to operate with another Stamp 2
' connected to the same RS485 network and is running the
' control.bs2 program.
'
'Pins 2 and 3 of the SN75176 chip are connected to pin 0 of
'· the Stamp 2.· Pins 1 and 4 of the SN75176 chip are
'· connected to Pin 1 of the Stamp 2.
'
'This program expects an LED and resistor in series to be connected to
'· pin 2 of the Stamp 2.· When an "H" comes across the RS485 network
'· pin 2 is set high, turning on the LED.· When an "L" is received
'· pin 2 of the Stamp 2 is turned off.
'
'Note: Setting pin 0 on the Stamp 2 low puts the SN75176 into
'· receive mode.· So any serial data received on pin 1 of the
'· Stamp 2 will be read in with the SERIN command.
'
'============ Variables ==========
string var byte························ 'Used to hold the "H" or "L"
'============ Initialize==========
output 2······························· 'Make pin 2 the LED connected pin.
output 0······························· 'Make pin 0 an output pin.
low 0·································· 'Put the SN75176 into receive mode.
'============ Begin Program ======
loop1:
· SERIN 1,16468,60000,loop1,[noparse][[/noparse]string]··· 'Read a byte of data comming in.
· if(string<>"H")then is_low··········· 'If H, then ...
· high 2······························· '... set pin 2 high, truning on LED
· goto loop1
is_low:································ 'If not an H, then turn off the LED
· low 2
goto loop1····························· 'Loop forever
If you paste these two files into your editor please remember the
' {$STAMP BS2}
' {$PBASIC 2.5}
on top of each program.
The files control.bs2 and slave.bs2 can also be found·on the·Parallax CD. Go to Source Code, then Application Kits and then SN75176 RS-485 Communication.
Now if you want multi-master on a pure RS-485 it is possible as I have written protocols for this. One way is for the initiator to transmit a single address byte and if it receives the same reply (from the addressed unit) it then knows it has the bus. All units are always listening and any address or control bytes will cause them to start a bus busy timer unless they receive their address or a bus release control byte. This takes care of collisions as a garbled request will not receive the correct reply. I have used this protocol in POS systems and similar ones in alarm and fire control systems etc etc.
The other way is to modify the way the RS485 transceiver is driven as in the J1939 standard so that it operates more like a CAN transceiver in that it only ever drives the bus active and uses resistors to passively pull the bus into it's idle condition. The transmit data to the RS485 chip drives the TE (transmit enable) while the TX line is held low (active). So if two or more devices attempt to transmit at the same time then the drivers won't be "fighting" each other but one will gain the bus as the active condition overrides the inactive or passive condition. I have included a screenshot of a dual RS-485 circuit that supports the J1939 interface as well as normal RS-485 although in this circuit the RO outputs should be separate so as to monitor the bus to detect if it has arbitration.
As mentioned by others though it is far easier to have a designated master in that there is a unit that has mastery of the bus itself (it doesn't have to be the boss) and all slaves speak only when they are spoken to. It is no problem to do this and makes a lot of sense. From the slave's application software point of view it shouldn't be trying to talk to the bus, it only needs to be talking to it's "application interface registers" which are read and written by the master over the bus.
The "raise your hand" method mentioned is probably just a time-slot or fast poll from the master which can be implemented a number of ways. Either the master sends out a raise your hand signal and the other units reply within their time slot so as not to collide with each other or the master can do a quick "Billy!?....Bob!?.....Jim!?....." etc. Still a master is needed to coordinate this method, it's advantage is that a slave can request some priority but not immediate priority.
*Peter*
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
*Peter*
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
*Peter*