Long-Distance SPI Communication - Line Termination - Page 1
Forum section: electronics / beginners

author: seancsnm
author_rank: Regular Contributor
timestamp: July 31, 2017, 08:03:41 pm
content: So the question of long-distance SPI communication has been brought up thousands of times. Because there is such a loose standard placed on SPI, the consensus is that there is no consensus and that you just have to take things on a case-by-case basis as far as what you can get away with, taking into account SPI frequency, component robustness, the type and length of transmission line used, and line termination. So I'll detail my setup then ask my question.I'm planning on using a single 50-ft cat 5e or cat 6 ethernet cable to communicate between 3 Arduino Uno's (slaves) on one end and a Raspberry Pi 2 (master) on the other end. I have verified that data can be reliably transferred from a slave arduino to a master arduino with the SPI frequency at ~500 kHz, but I haven't verified this setup yet with a Raspberry Pi because I have to deal with logic level conversion (and other unrelated reasons).While playing around with logic level conversion, the only level converter I had on hand was this bi-directional I2C level converter:http://www.ti.com/lit/ds/symlink/pca9306.pdfIt may do the trick, but relies on the transmitting and receiving devices to sink all of the driving current when in the low state. For the Arduino Uno, IO pins can source/sink up to about 50 mA, and the Pi can source/sink up to about 16 mA per pin. This in itself wouldn't normally be a problem, but it puts an upper limit on the frequency you can drive such a long transmission line, as the system has to overcome the line's capacitance.There is also the issue of ringing caused by improper line termination. How line termination and impedance matching works is still a bit muddy - I'll probably do a full review on it at some point to see if I can get a better grasp the second time around, but for I want to make sure I understand enough to be able to successfully implement this system. The Jhist seems to be that when a transmitting side of a line sends a pulse, that pulse will be reflected at the end of the line, and bounce back and forth between the beginning and end of the line until the power of that pulse is dissipated. This is obviously undesirable because it can skew your output to the point where it is unrecognizable, or in some cases can damage your sending/or receiving device. So a terminating resistor between the two conductors of the transmission line, at the end of the line, is usually used. In the case of Cat5 cable, it's usually 100 ohms. I played around with this using a scope, function generator, and 100 feet of ethernet cable. Without the line being terminated. both the sending and receiving side of the signal are quite skewed. But after a 100 ohm terminating resistor is added, both signals are quite clean.So it seems that I'll want to terminate the cable with resistors if I can, but that brings up a few of my questions. First, does it matter? No matter what you will have to deal with the data rate being limited by a propagation delay of ~2 ns/ft, multiplied by two when considering a signal coming back to the master from the slave. There is nothing I can do about this limitation if I'm using SPI, so would the distortion caused by improper line termination be worth getting rid of if no components are damaged, and if the communication frequency is already limited by propagation delay? The second question is, how would I go about terminating SPI lines? In effectively all examples I've seen, the terminating resistor is at the end of a differential line, not at the end of a common-ground and signal line. In this case, would I simply add a 100 ohm resistor at the end of the line between the MOSI, CLK, and SS lines and ground, then add a fourth resistor between the MISO line at the beginning of the transmission cable (since it is the receiving end of the transmitting slave device)? Also, would it be worth running separate ground lines with each data and clock line, or would running a single ground be adequate? Ethernet cable is obviously designed for use with differential pairs, and my implementation is effectively throwing that designation out the window, unless you consider several individual ground-paired lines differential pairs. There is also the issue of sourcing enough current to overcome the terminating resistor. Am I correct in saying that the transmitting device must be able to source enough current to satisfy the simple Ohm's law equation I = V(source) / R(terminating)? If so, the source current would need to be at least 50 mA for a 5V signal transmitting over a 100 ohm-terminated line. And this is above the recommended current levels for either the Arduino or the Pi, so some sort of buffer would be required, right?For those wondering why I insist on using SPI rather than a more suitable differential communication protocol, the answer is simple: SPI is available on both the Pi and Arduino, and clearly can work at decent frequencies over 50 ft (which is the distance I need to communicate over), so why go through the effort of adding additional circuitry and code complexity when I don't have to?

author: Benta
author_rank: Super Contributor
timestamp: July 31, 2017, 08:21:38 pm
content: QuoteThere's no "loose standard", it's just that SPI is not intended/designed for this.SPI is for IC interconnects on a PCB, or perhaps within an enclosure, using normal CMOS logic levels in a controlled environment.Using it on long cables is a fool's errand, and I have difficulty understanding why anyone would attempt this. I understand the limitations of the platforms you've selected, and your quest for simplicity, but there are limits to what you can do.I mean, does anyone transmit a 32-bit address bus and a 32-bit data bus plus control signals over a 50-ft ribbon cable? I've never seen it.Even a simple UART samples each bit 16 times to get a majority decision on whether a 1 or a 0 was received. And 50 feet is testing the envelope for RS232.I'd rethink the design and do it the right way instead. Multi-channel UART and RS485 come to mind.

author: miceuz
author_rank: Frequent Contributor
timestamp: July 31, 2017, 08:32:46 pm
content: I was doing some research about this couple of months ago - the consensus on the net is don't do it, there are too much underwater rocks. Like ringing on clock line adding ghost bits and similar. Use rs485 - both raspi and arduino have UART, you can use a cheap usb-to-rs485 dongle at raspi side, Arduino oriented rs485 modules are also plentiful and cheap.

author: Ian.M
author_rank: Super Contributor
timestamp: July 31, 2017, 08:50:41 pm
content: +1Use RS485 transceivers, (readily available shields for Pi and Arduino), run it at 1 Megabaud half duplex. Put an address byte in each packet and assign an address to each device. You'll loose a bit of bandwidth to the start and stop bits and packet overhead but it will be far more reliable. You are probably throwing away a significant number of the returned data bytes in each SPI frame so the odds are 1 Megabaud RS485 will actually have higher throughput than 500KHz SPI.On the Pi end, you don't actually need a USB RS485 adapter - its possible to free up the hardware serial port and run it at 1 Megabaud.Also, ask yourself "Do I *really* need 500Kbps duplex data throughput?"

author: seancsnm
author_rank: Regular Contributor
timestamp: July 31, 2017, 09:16:56 pm
content: Just for the record, I don't need a fast throughput. As I said, a 500 kHz was what I tested to work over a 50 foot cable, not the rate I need. I can probably go an order of magnitude slower and still be fine.I am a bit hesitant to switch to rs485 at this point because I have no experience actually using it, but I'll look into it some more to see how much effort it would be to integrate. I don't think I'll have time to purchase rs485 transceivers to test before I print a PCB with the implemented communication solution, so I'd need to be sure I can get it right the first time.Thank you for the input, but my original questions still remain. If anyone has enough knowledge/experience to answer them directly, my own understanding would be greatly enhanced!

author: tggzzz
author_rank: Super Contributor
timestamp: July 31, 2017, 09:39:42 pm
content: I haven't got time to teach you transmission line theory, but that doesn't matter since it is discussed ad nauseum in textbooks and application notes.You should be aware that the baud rate is irrelevant. All that matters is the transition time relative to the length of the transmission line. Google for "Bogotin's Rules of Thumb" and Howard Johnson's website.But that is irrelevant - with long interconnecting cables you have to be aware of the effects of ESD, EMI, different ground potentials, and even the different ends being powered from different mains phases. Those are easily and best avoided by simply using a fiber optic interconnection.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: July 31, 2017, 10:05:30 pm
content: SPI is fine over distances, but mind clock timing of course.It can be acceptable to use raw 5V, or even 3.3V logic outputs, as line drivers.Use shielded multiconductor cable, shield grounded to the circuit at both ends, and yes, terminate it. If you wish to keep things simple, use point-to-point links, with source and/or load termination, and a receive buffer like 74HC7014 (note the semi-precise threshold compared to 74HC14). Other network topologies are possible, of course you'll need more channels for the CS signals as well.Note that terminating the signal also attenuates it, hence the need for a line receiver of sorts. Alternately, you can use some kind of comparator against a modest threshold (an LM393 or MCP6562 is fast enough here, or use an RS-422 or LVDS receiver as a comparator -- it may even be cheaper!).For better results: add RS-422 transmitters and receivers at each end, and use twisted pair cable (it's differential). This doubles the number of wires, but if you were going to use CAT5 anyway, you're set. You still need a common ground, so you need shielded cable, or extra pairs to assign to ground (or supply, same thing from an AC perspective), or fixed bias terminators.RS-422 has the benefit that its impedance is constant (the driver isn't switching on and off, it's always active), and it's fully differential (there are no unbalanced symbols), so the line can be filtered very effectively to remove common mode noise. But as with all filters, that CM filter needs to be terminated somewhere. (The line itself is a filter of sorts, hence the need to terminate differential mode.)RS-232 can also be used for the physical layer (PHY), but it's rather slow for most SPI applications (you might struggle over 100kbps). This is better than logic level, because the amplitude is large (nominal +/-15V) and the slew rate is controlled (you hardly have to worry about EMC, even on unshielded multiconductor cables).DO NOT USE I2C. I2C is meant ONLY for on-board use. Pushing it onto cables of just a foot in length is already enough to cause EMC headaches; it's almost impossible to use over any distance, without stacking on piles of extenders and bridges and all. (And, yes, Philips / now NXP is more than happy to sell you all manners of interfaces you could ever want... for a price. Or you can use SPI, maybe with some cheap off the shelf interfaces, and you're done.)Indeed, you can get I2C extenders that bridge over a physical layer of -- guess what -- RS-422 or 485.This is worth considering if you're stuck with I2C some other time.Let me know if you want anything explained in greater detail; this is more a summary of approaches.Cheers,Tim

author: Ian.M
author_rank: Super Contributor
timestamp: July 31, 2017, 10:18:10 pm
content: Tgzz's suggested reading is easier to find if you spell Bogatin correctly:http://www.edn.com/collections/4435129/Bogatin-s-Rules-of-ThumbThe trouble with doing long distance SPI properly with line transmitters and receivers for each signal is the number of signals and thus line interface ICs required. 'Classic' SPI is 4 signals, with an extra /CS signal for each extra slave device. On very long links and at high SPI clock rates, you can also run into problems with clock skew. (Seehttp://www.siemon.com/us/white_papers/97-06-03-delayskew.asp) If you've already got intelligent slaves with MCUs with high speed hardware UARTs, a single chip transceiver RS485 link becomes quite attractive by comparison

author: tggzzz
author_rank: Super Contributor
timestamp: July 31, 2017, 10:44:03 pm
content: Quote from: Ian.M on July 31, 2017, 10:18:10 pmPicky picky pickyIn my defense, google givesmethe relevant page as the first link.

author: Ian.M
author_rank: Super Contributor
timestamp: July 31, 2017, 11:02:07 pm
content: Quote from: tggzzz on July 31, 2017, 10:44:03 pmEven if you google for it with the quotes?That's why when I post Google search terms and can't be arsed to link the actual search, I always bold them or on plain text forums put them on a line of their own.Also I assume you mean this Howard Johnson:http://www.sigcon.com/hj.html?Apologies for dropping a 'g' and a 'z' from your nym.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: August 01, 2017, 01:20:52 am
content: Quote from: Ian.M on July 31, 2017, 10:18:10 pmMeh, not a big deal. Use a quad rx and single tx, and vice versa at the other end. Or a bunch of singles, saving the lines in the project BOM.IIRC, the Intersil SOT-23-5 rx/tx parts are stupendously robust (16kV ESD), and competitively priced; but everyone makes the things, it's hard to go wrong.I used these with five-pair twist ribbon (this stuff:https://www.digikey.com/product-detail/en/3m/1700-10-100SF/MC10F-100-ND/145528) to provide +5V/0V and four data pairs (CS, CLK, MOSI, MISO) in an industrial product some years back. Never had a problem with it. The noise environment inside that product was worse than 10V/m (whereas most susceptibility testing is done at a mere 3V/m).Also practically trivial to isolate: add a DC-DC converter and a couple optos (6N136 or better, or use a monolithic digital isolator if your speed and size requirements are more demanding). Huge improvement in immunity!QuoteThere's very good reason RS485 is so popular in industry. CAN as well!Edges and overall signal strength degrade over distance as well, putting a limit on baud and distance. This can be solved by adding repeaters, though to solve clock skew in raw SPI (as opposed to self timed streams like RS-485 and Ethernet) you'd have to add some intermediate logic.Tim

author: seancsnm
author_rank: Regular Contributor
timestamp: August 01, 2017, 03:57:55 am
content: Thank you for the responses - they have been quite helpful, and have clarified the questions I have. I am fairly confident SPI will work well enough for this project, but the prospect of adding discrete line drivers/buffers to each signal vs. the use of a single-chip per device method like RS485 does make RS485 sound like an easier to implement solution from a hardware standpoint. Getting differential signal transmission for better noise tolerance (I don't think the noise level in the environment this will be implemented on will be high, but you never know), built-in level conversion (no need to convert 3.3V to 5V, just get 3.3V and 5V RS485 drivers for each device), not having to consider propagation delay when the slave sends data back to the master, and built-in line driving capabilities seems like a sweet deal.Tim, it sounds like using RS422 in the configuration you mentioned is very much like using a full duplex RS485 configuration, but it also sounds like it would only work for one "master" device and one "slave" device, since the protocol technically requires the transmitting device to always be driving. My setup uses a single master and three slave devices, all of which are within a few inches of each other at the end of the 50 ft transmission line.So at this point, my design will use rs485 (max485 on the Arduinos and max3072 on the Pi). If I think it will be useful, I'll post a schematic. But I'll most likely just use a readily available reference design, so my specific implementation should be pretty generic.Another for the record: I am a very recent EE grad so I should technically know all about the perils of line transmission and while the topic is somewhat familiar, the class that went over the subject matter was the one class that I very nearly failed. Besides this, it is one thing to do some abstract homework problems asking about propagation delay and maximum voltages seen by the transmitter, and a very different thing to actually sit there with an oscilloscope trying to figure out why your signal starts tripping out once you plug your transmission cable in. And then there's being presented with half a dozen or more communication protocols, half of which have never been seen (by me) before.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: August 01, 2017, 06:27:13 am
content: Quote from: seancsnm on August 01, 2017, 03:57:55 amYou can get by without much noise threshold, or shielding, for quite a long time, but expect nuisance errors. This is especially critical for SPI clock, but for data and everything else, expect random bit flips, dropped frames, lost connections and all that.To have a reliable connection, the logic threshold needs to exceed the expected noise level by a fair margin.Noise is expected statistically. At mosttimes, it might be quiet, with pops and bursts seen here and there. In mostplaces, it might be quiet, except for some areas where it may be incessant and intense (like at the base of a radio antenna).The recommendation for typical commercial stuff is 3V conducted or 3V/m radiated. So, a cable will have on the order of 3V/m * length induced on it, in such a field, at frequencies where its length happens to be resonant. Except it's usually a bit worse, just because of that: resonance. The Q factor of the cable (how much damping (ferrite beads, resistors) there is on it, and how strongly its voltage couples to the RF field) tells how much worse.So, signals with a threshold around 3V, are an awful idea to put on a cable. The 15V range that the RS-232, 422/485 and such standards provide is excellent for many situations.You can get by with less threshold, if the signal is tightly coupled to its reference: this is how you get differential signals. You must still observe common mode limitations of the circuitry, hence why RS485 receivers have a 12V CM input range, even though the threshold is merely ~100mV plus to minus (and the driven signal is only a couple volts at the strongest).You can get by with even less than that, if the cable is well shielded. USB, HDMI -- most high speed interfaces really, areonly possiblewith shielded cables. The shielding must be solid, from end to end, for this to work!(Ethernet is the standout, as it's transformer isolated, differential and unshielded. They really gilded the lily when they created it. It's good, and with good reason! The common mode range is 1.5kV, though the RF immunity isn'tquitethat good. The transformers have common mode rejection in the 30dB or better range, so, for a ~1V signal level, it would be expected to drop out at >15V noise -- which is comparable to RS485 and such.)QuoteYeah, consolidating your data into one channel is a good idea. The simplest would be to add extra channel(s) for addressing, as a straight-through CS for each device (3 pairs of CS). That can be improved with addressing (two pairs --> 1-of-4 selector), or multiplexing (make an address register that's selected somehow).I suppose best would be this: no extra pairs, just the single CS pair. CS high: address register enabled. Transmit a frame --> latch in a new address. (So, you get 256 addresses for free, but only need the 3. So, uh, it's scalable...) CS low: device enabled (address --> selector, with /CS --> enable). To reset the line state, toggle CS twice (thus de-asserting both the device and address registers, serving the same purpose as de-asserting CS in a normal SPI transaction).Obviously, this isa bitof added logic just for a few devices, so, another interesting method if the need arises, but not necessary here...QuoteAh, nice. Do take the time to read up on various standards -- there's very little they teach (andcanteach) about all these things. There's too much to cover, so it's up to you to figure things out later.You surely learned about logic voltage (or current) thresholds. That's mostly what these simplest of interfaces are: a voltage, current and time specification. Nothing could be simpler.The signal goes on a cable (whether it be single ended or differential), from a source with a nominal open-circuit voltage, with some source impedance or current capability, and speed determined by a bandwidth, rise time or slew rate. For differential signals, there's also the common mode range, rejection ratio (CMRR), and output balance (how much CM the driver produces).It's also not well stated anywhere, but almost all logic and driver outputs are some variation on "switch to +V / -V" (where the "switch" is usually something mostly resistive when on, and mostly open circuit when off).CMOS logic gates are the cleanest and most common example. Take the 74HC family: it's effectively ~70 ohms pulling up, and ~40 ohms pulling down. The equivalent circuit is a Thevenin source, with a voltage of VDD or VSS, and that resistance in series.If a manufacturer doesn't tell you what kind of output a chip has, it's pretty safe to assume it's a CMOS output, and will have a rail-to-rail voltage range!Old fashioned TTL is similar, but the pull-up voltage is more like 3.5V (not VCC), and the resistances are asymmetrical, more like ~100 ohms up and ~20 ohms down.RS-422/485 drivers are basically this type: CMOS switches. They have lower resistance than a logic driver, and are made to deliver higher currents, continuously. For 485, there are also series diodes to prevent backflow when not asserting the line. (But while driving the line, the line voltages are firmly referenced to the driver's supply/ground, so the common mode voltage is well defined.)LVDS drivers are an example that doesn't fit this pattern. They are nominally constant current outputs, so that the driven output voltage is rather small (a couple 100mV). The output isn't a perfect CCS, though, because that would leave common mode voltage undefined. As it turns out, they design these so that the common mode voltage is held around VDD/2, with a modest impedance (100s ohms), so that the common mode voltage is still well defined.None of the above standards make any presumption about what coding is used on the line! RS-232 is often colloquially understood to mean asynchronous serial -- after its most common application (the computer serial port, among many others back through history). But there's no specification in the standard about this, and you can run whatever you like (synchronous serial, SPI, any arbitrary data stream), within the limitations of that standard (namely, the voltage, current and speed).Other standards most definitely do: CANbus is kind of a mash-up of RS-485 (using a multi-master, differential line interface), I2C (the drivers are on/off, not high/low as in RS-485), and, I forget what the nuts-and-bolts of the actual line coding / protocol is, but it's packet based and very error tolerant.Tim

author: tggzzz
author_rank: Super Contributor
timestamp: August 01, 2017, 07:18:11 am
content: Quote from: Ian.M on July 31, 2017, 11:02:07 pmIndeed, but if someone couldn't use that information to get appropriate results on google, then I'mdefinitelynot going to have time to teach them the technical stuff!The one problem might be that google changes the results it delivers depending on what it guesses you are interested in. I don't know how to avoid that form of "echo chamber", other than to delete cookies, prevent javascript running, and not login to google.QuoteYup. I pounced on his Black Magic book when I found it in a bookstore almost a quarter of a century ago.QuoteI've survived worse

author: Gibson486
author_rank: Frequent Contributor
timestamp: August 01, 2017, 12:34:31 pm
content: None of those IC comms (SPI or I2C) are really made to come off the board.That being said, people have done it.However, with 50 feet of cable? The I2C spec says the max capacitance is, what, 400 pF? With 50 feet, you will be well beyond that on a cable that is multiwire. As someone mentioned, you will have to stack expanders/buffers at that point.The thing about SPI is that it is pretty loosely defined and with cause. There is no spec that says your line to meet spec.You biggest issue is going to be timing. How can you ensure your bits are aligned with the clock when you transfer from the source the receiver?

author: Ian.M
author_rank: Super Contributor
timestamp: August 01, 2017, 01:26:56 pm
content: Quote from: tggzzz on August 01, 2017, 07:18:11 amYes, short of using the TOR browser, or other separate locked down browser in private mode, with no pre-stored google cookies, via a remote proxy to avoid IP tracking, there's not much you can do about their targeted marketing driven f**kery with your search results.

author: retrolefty
author_rank: Super Contributor
timestamp: August 01, 2017, 07:55:44 pm
content: QuoteI saw a Digital Equipment PDP-70 minicomputer system in the 80s that was like 5 racks wide with added memory and used very wide ribbon cable that daisy-chained through out the racks and I wouldn't be surprised if it met or exceeded 50 ft. It was pretty fancy ribbon cable that had a full grounded backing layer ground plane and modified or special ribbon connectors. Of course memory cycle speed were pretty modest by today's standards, maybe 500 nsec cycle time?

author: T3sl4co1l
author_rank: Super Contributor
timestamp: August 02, 2017, 01:43:43 am
content: Quote from: retrolefty on August 01, 2017, 07:55:44 pmThe same phenomenon limited PCI bus speeds and dimensions, because the bus is laid out as a source-terminated bus with minimal stub lengths. When a source at the far end (typically the PCI bridge, or the card installed in the last slot) drives the line, it takes a full electrical length for the line to charge to VCC/2 (an indeterminate level), then reflect back and finish charging (to nearly VCC -- less losses). To avoid collision of indeterminate levels (which themselves are bad enough -- needs Schmitt triggers on all inputs), one bit time must be greater than one electrical length time.For the size of a motherboard, with up to 8 cards installed, that limit came to 66MHz.Tim

author: julian1
author_rank: Frequent Contributor
timestamp: August 02, 2017, 09:00:54 am
content: On the chance you haven't see them, and if price is a consideration - an esp8266 acting as a wifi modem for the arduino would be less expensive than the 50ft of ethernet cable. (cf cable is nice because of poe options).

author: capt bullshot
author_rank: Super Contributor
timestamp: August 02, 2017, 12:33:08 pm
content: I mentioned that somewhere else here, LT makes chips for SPI over single twisted pair cable:http://cds.linear.com/docs/en/datasheet/6820fb.pdf

author: GarthyD
author_rank: Regular Contributor
timestamp: August 03, 2017, 11:05:42 pm
content: I justed wanted to pop in to say that earlier on when I had even less experience than I do now (and I still consider myself a novice) I attempted exactly what you are describing: SPI comms over a non-trivial distance. The one thing I took away from the experience is: Don't do it.Just don't. SPI is amazing, but it breaks down once you add distance in to the equation.It is seductively easy to take a simple to understand and widely-supported bidirectional protocol like SPI and do something with it over distance. But bear in mind a few things:- It is not designed to run at distance. At all! Your protocol will need to be capable of correcting errors. You will not be able to trust a single thing you receive. You will be writing software fixes. Applying hardware fixes. An second identical setup will start failing when the first works.- It is based on the simultaneous exchange of single bits based on a clock. Consider what happens when you add a lot of distance to that. You need to give every bit time to settle before the next clock pulse. You have to drop the rate way down to compensate. What you are left with is an unreliable, low-speed protocol. You then need to ask yourself why you are using this protocol.I'd be looking at:- RS485, which should be good for 1km, which has already been suggested. Get some cheap interface chips and use them. For many, you talk to them, data goes in, data comes out. Everything just works. Magic.- USB, which is good for a few metres I think. There is a lot of learning involved getting it going but you have the advantage of fast comms and ubiquity if you pull it off. EDIT: Not suitable for the distances you are talking about, which are well beyond a few metres.So to recap: I have tried exactly what you propose, and it was a huge waste of time, and forced me to compromise on my original design after a long period of fighting it when it failed to work as I needed.If you want to go ahead anyway, test comms with a long cable right from the start. If you proceed anyway, please consider writing a post like this to warn the next person once you're done.

author: Ian.M
author_rank: Super Contributor
timestamp: August 03, 2017, 11:40:36 pm
content: +1 on avoiding SPI outside the same enclosure. If you are determined to try it, set up one or more slaves to echo the bytes received back to the master, have the master send frames of 0xFF, 0X00 then a block of N random bytes padded with enough zero bytes at the end and verify what comes back against what was sent a few bytes earlier. Torture test it thoroughly: e.g if you can fish out the inside end of a reel of whatever data cable you plan to use (there's often a stub tucked through a hole in the core of the reel you can splice onto) you can hook them up on your bench with 50 or 100 yards of cable between them. Take a power tool with a universal motor, wrap a few turns of its mains lead round the reel, and blip the trigger repeatedly while monitoring the data stream verification. Also look up the location and frequency of your nearest powerful radio station or TV transmitter and try again with 90% of a quaterwave of their carrier frequency unwound from the reel and oriented vertically if they use vertical polarisation or horizontal at rightangles to the station direction if they use horizontal polarisation. Odds are you'll dump the idea of long distance SPI P.D.Q. when you see actual error rates.Hopefully your SPI hardware resets its state machines at both ends when the master deasserts Slave Select - if not you may get a persistent loss of sync that on particularly sh!tty silicon can result in lockups that need a hardware reset or power cycling to resolve.USB is pretty sh!tty for distance - anything over a few yards needs active repeaters. Its really *NOT* worth it unless you need the USB connectivity anyway.

author: GarthyD
author_rank: Regular Contributor
timestamp: August 03, 2017, 11:48:29 pm
content: Quote from: Ian.M on August 03, 2017, 11:40:36 pmYou are entirely correct. I've edited my post to make it clear that USB would not be suitable for the distances being spoken of in the original post.

author: seancsnm
author_rank: Regular Contributor
timestamp: November 20, 2017, 09:54:38 pm
content: So I suppose a post-mortem update is in order regarding this. First off, thanks for all the advice.I ended up using the ISL8491EIBZ for RS-485 communication over the USART port on the Atmega328 in half-duplex mode (there is a jumper that allows the user to effectively select between half-duplex and full-duplex). The Arduino bootloader was used, so I was able to use the readily available SimpleModbusSlave (https://github.com/angeloc/simplemodbusng) on the microcontroller side. On the master side (the PC), a USB->RS485 adapter was used, and Python was used with the MinimalModbus (https://pypi.python.org/pypi/MinimalModbus/) library was used. CAT5 cable was used to connect the master and slave devices. For the most part, it all works like a charm, except for a timing issue that occurs when the master device attempts to communicate with the slave device too soon after the slave device sends a response. If a command is sent to the slave device too soon after the slave device sends a response to the previous command, the slave device will simply ignore the command. Interestingly, that minimum delay time seems to correspond with the loop time of the microcontroller slave device. So adding a hard delay between commands on the master device in addition to a bit of redundancy code that causes the master device to re-send a command if it doesn't get a response after a certain amount of time put a reliable bandaid on the problem. Additionally, I ensured that all time-sensitive actions occurred solely at the microcontroller level. Essentially, the Modbus communication allows the user to set test/system parameters, and push "go" to start a test, after which Modbus communication ceases until the test is over. Then, the master requests test results. This design is going to have a pretty short life cycle - it's essentially going to be used for a month or two before being discarded, as it's being used to control some mechanical tests.But all in all, I'm pretty happy with how things turned out. I've never attempted to do multi-device communication before, so it's pretty neat to now say that I have some experience dealing with that sort of thing.

author: rstofer
author_rank: Super Contributor
timestamp: November 20, 2017, 11:24:47 pm
content: Line turn-around on half duplex is a bit of an issue.Here is a dandy protocol for multi-master communications on RS485:http://www.bdmicro.com/code/robin/Search the page for 'duplex' to find a discussion on line turn-around. Basically, you have it right. You need to stall a bit before replying. Robin includes a timeout so you can't stall very long if you use that protocol. It also has collision detection.