Serial communications with other MCU's
Hi there,
working on an application with a Flip that I need to send and receive data from and to other MCU's ,I was following the tutorial on https://learn.parallax.com/tutorials/language/propeller-c/propeller-c-simple-protocols/full-duplex-serial and seems pretty straight forward, but there are some stuff isn't covered on the tutorial. what if I need more devices on the serial network , how do i give them an identifier in the serial network? how much wire distance is allowed? i'm limited on pins the only pins available are 28 & 29. I know I can't use i2c since the distance between the MCU's will be close to 25 feet, apparently serial comms. are good on the 25 feet range, I also thought about CAN bus but the available module consumes 4 pins (SPI comms) unless I can use 28,29 + 30 & 31
but don't know if 30 & 31 can be used since there are the programing pins
Regards,
Comments
Yes, you can use 31 and 30 for your custom serial coms -- you just need to be aware of hardware when you're putting code into the Propeller.
Consider RS-485, as a typical chip will let you connect to up to 32 nodes. I find it cleanest to use three pins (RX, TX, TXE). I've used this circuit in many projects:
(This is embedded in my half-duplex RS-485 driver). The pulldown on pins 2 and 3 defaults the chip to RX mode. When you want to transmit, you make that pin high, wait just a bit, then start sending your message. When you're done transmitting (and have allowed all the bits to go out), you take the TXE pin back low so that you can listen for the response. Easy-peasy. I write code for my friend John at JonyJib.com and many of his products use this RS-485 circuit and my driver (I code his products in Spin). In our case it's usually a master-slave relationship, but we have done master/multi-slave projects a couple times.
The hardware is easy. What YOU have to do then is create a protocol so that you know who's talking to whom. Do some research on MODBUS for ideas (though your protocol can be much simpler).
I'll second what Jon said about using RS485. To add to his post:
-Phil
My $0.02:
janaxelson.com/spc.htm
Highly recommended. To conserve a pin, there is an example of auto TXE, using the TX data. I since became aware that there are RS485 devices that have this feature built-in.
FWIW: There are also devices that are no-longer limited to 32-nodes.
I use 4-wire (422/485 full-duplex) multi-drop. The TX line is permanently enabled by the Master and the RX is a Slave-shared response line. Even with a strict command-response arrangement, it just feels good that the Master can TX at any time.
I have adopted a protocol from another product-line because I really like it. The packets are of a format where they must make sense to the recipient and so a simple checksum, as opposed to a CRC is quite adequate.
@"Phil Pilgrim (PhiPi)"
Very interesting, the current-draw has always bothered me
One of these days, I intend to play with @"Beau Schwabe" High-Speed Net, for giggles. IIRC, it's good for 8MbpS
Craig
I'll add another vote to RS485 due to the popularity of RS485 ... Be aware that the auto switcher for data direction can be sensitive to different bauds.
Another Option is a CANBUS physical layer as opposed to an RS485 physical layer. I have a current project using CANBUS with more than 300 individually addressed Nodes. Each Node has a load resistor which acts like a transmission line.
Something to Note with RS485 : If you are transmitting from an Arduino, make sure that you use the 'flush' command after every transmission.
Why? .... Arduino in its infinite wisdom sends serial data in background mode. For the most part this is great, it allows you to do other stuff without having the serial transmission do any significant blocking. But if you are sending data via RS485 and switch data direction after you have sent something, you can potentially cut off the data before all of it has been sent over the RS485 line. Using the 'flush' command forces the serial command on the Arduino to act like a blocking command, waiting until the transmission is complete. CANBUS doesn't have this issue since there is no mechanism to switch data direction.
EDIT: Our CANBUS approach is a custom variation of the standard. Because of supply chain issues and working on a project where we would need over 10 k multi drop devices total, procurement was an issue. An off the shelf CANBUS solution would only allow up to 32 Nodes which wouldn't work for our requirements. We have simulated our custom solution to handle up to 1000 Nodes, but we are only using 300 Nodes per customer build. We looked at RS485, but CANBUS was easier to implement with discrete available components.
Guys,
Thanks for the recommendation, will explore it a little more and start playing around with it.
Beau to your point...Yes an Arduino Due will be the master, may be 4 propeller flips will be slaves so no more than 5 nodes
Why the Arduino? Why not 100% Prop?
P2 is mind-blowing
Craig
As above, you will need some external cable driving support.
For identifiers, there are some choices :
If you make the network a ring connection (eg with RS422 buffers) , your protocol can extract N bytes and echo the rest, so behaves like the RGB led strings, but with UARTs.
There is no message based address needed, as the physical location in the ring defines the identifier.
Advantages of a ring network are simplicity of coding, and lowest MCU pins, but it does need 4 wire terminations on the board (2 for RX-In and 2 for TX-out)
RS422/RS485 use similar differential drivers, the RS422 ones have separate TX/RX pins, whilst RS485 need to tristate the buffer when not sending.
RS422 works with just 2 MCU pins, RS485 needs 3 pins (see #2), unless you get an auto-direction buffer.
New parts like TI's
THVD1406, THVD1426 3.3-V to 5-V RS-485 Transceivers with Auto-direction Control and ±12-kV IEC ESD Protection
have a simple monostable on the TXD pin release, and offset RX threshold so they are open/short cable fail-safe.
The slower 500kHz parts have slower slew rates on the data pins for better EMI, and they also have longer auto-monostable times (typ 8us vs 800ns)
If you make it multidrop (eg with RS485) then you do need some means to assign an identifier.
If every item has a unique HW serial number, that can be used, or you can hard-code some number, or there are schemes that try to poll nodes and assign identifiers as each is found.
Some MCUs support a 9 bit mode, where the 9th bit tags Address or data fields. PC's can support that using parity bit force.
A system that I use (costs pins) has Addr_In and Addr_out pins. The first node has its Addr_in tied high. On power-up If it has no assigned address, it takes
the first address that is broadcast. Then it sets its Addr_out pin high which feeds the Addr_in of the next node. So the next node has a high Addr_in and no assigned address and it takes the next address that is broadcast, etc, etc.
Uses extra pins but any node can be replaced without needing to config.
Craig
When I designed the HC-8+ for EFX-TEK, Disneyland was a prime driver of project features and they really wanted a physical DMX address switch (the HC-8+ has RS-485 onboard to support DMX in or out). To save pins, we used a 74x165 input shift register; this gave us 8 switches using 3 pins, and the 9th switch connected directly to the P1.
Hi Ardillolambo,
I'm late to the conversation, but I'm curious about what you are doing. If is a hobby and you want to get results fast with minimal hardware within the constraints you stated (2 pins, send and receive), it is one thing, quite another if you are developing an industrial application that should follow best practices. You didn't say anything about the kind of data you need to transfer or how fast it needs to happen, or the environment. Motor control?
Generally you can have longer lines when the rx/tx speed and overall updates to the endpoints are slow and when the environment is benign in terms of electrical noise. That applies to i2c as well as to other forms of serial. Even one-wire can service long cables, if the pullup resistor is strong enough.
You might get by with native RS232 from the Arduino with connection to all 5 of the propellers at say 9600 baud. Transmit/receive lines on Arduino go to receive/transmit on all 5 propellers, with resistors for current limiting and level shifting if necessary. Only the propeller addressed can take its turn at talking back. You asked about identifiers. If you don't want to pursue a standard, you can make something up. Say, start a transmission from the master with a "!", followed by one identifier byte in the range n = 1 to 5, then the bytes you need to transmit, either as ascii or whatever works. The packet might be a fixed length; certainly other refinements can pile on. In any case, once finished, propeller n can go to transmit mode and respond. Maybe n=0 is a one way broadcast to all 5 at once. So many possibilities!
Tracy,
Speaking on 1-wire, have you ever used a 'strong pull-up' on the Propeller?
No, my longer runs with i2c have always included power, a 3-core cable with ground, data, and +3V. The longest I recall was a 16 meter string, with DS18B20 sensors at 1 meter intervals along that length, plus a 2 meter leader. The purpose was to do temperature depth profiles in a lake/reservoir. One issue with using parasite power was speed. My firmware broadcast a convert command (skip rom) to all the sensors at once and then read out results from all sixteen in succession. You can only apply parasite power during the conversion time. Restructuring the firmware to address them for conversion one at a time would have been slower, but maybe that would have been okay. Timing for one-wire slots is on the order of 10 microseconds, so it takes a pretty stiff pullup resistor.
I