Created Fri, 15 Mar 2013 13:47:51 +0000 by majenko
Fri, 15 Mar 2013 13:47:51 +0000
I am working on a library to allow simple packetised serial communication between boards. I started it on Arduinos, but want to get it to work the same on ChipKit boards.
All is fine and dandy, as long as I don't try and communicate at more that 57600 baud. Any faster than that (say 115200 baud) and the packets just don't get through. It's almost like it's a mis-match in the baud rate. I have tried at higher rates too, and it still doesn't work.
I am testing with a direct cross-over wiring between an Arduino and an UNO32 (tx->rx, rx->tx, gnd->gnd). It works perfectly between two Arduinos at 115200 baud, but not between an Arduino and a ChipKit (this is with the chipkit as the receiver and the Arduino as the sender - not sure about the other way around, I'll test it out).
I have never had any problems communicating with pic32 chips at mega-baud levels before now, and regularly work at speeds higher than 115200 baud with RetroBSD. I have communicated with the Arduino at 11500 baud (through MAX-232) before quite happily, too, and if the Arduino didn't work at 115200 baud I'm sure someone would have noticed by now...
Is it just pure chance that the two won't talk together (baud rate differences just enough apart to break it), or is there something more fundamental with how the ChipKit calculates its BRG values?
Fri, 15 Mar 2013 14:17:41 +0000
A correct packet, transmitted at 57600 looks like this:
0x01 <- SOH 0x02 <- Destination 0x01 <- Source 0x52 <- Command 0x00 <- Length 0x02 <- STX 0x03 <- ETX 0x55 <- Checksum 0x04 <- EOT
The same packet transmitted at 115200 baud is received as:
0x0E 0x30 0x0E 0x30 0xCE 0x30 0x3E 0xCE 0xCE 0x00
Yet I can send the word "Hello" between the Arduino and a ChipKit at 115200 baud, and it works fine.
Fri, 15 Mar 2013 16:03:11 +0000
Ok, ok, ok, I put my hand up, I'm stupid.
That's the problem with switching between 32-bit and 8-bit all the time - I forgot that 115200 baud won't fit into an unsigned int on an 8 bit Arduino... The ChipKit was working fine - but the Arduino was actually working at 49664 baud... Worked fine between two arduinos as they were the same rate...
Fixed it now...
So yes, there's a nice inter-chip serial communications library to play with. Help yourselves.
Fri, 15 Mar 2013 19:45:13 +0000
Oh, I've now added a Linux C library so you can use ICSC to communicate with the ChipKit from your Linux PC or Pi.
Fri, 15 Mar 2013 21:53:20 +0000
Interesting. Provided I have got 4 modules, each has its own RX, TX, GND. How shall I connect them together? Pito
Fri, 15 Mar 2013 23:36:26 +0000
For 4 modules you really want an rs485 bus. If you are going for one master and three slaves you can go for full duplex. If you want peer to peer then you will have to limit yourself to half duplex.
Sat, 16 Mar 2013 22:49:15 +0000
When I implemented a similar async version of the "IBM Bi-Sync" protocol many years ago, I started by sending 6 SYN characters before the STX. I think I had to see 3 consecutive SYNs before I would start looking for the packed header. It helps to make resyncing after a framing error easier. YMMV. :D
Sat, 16 Mar 2013 23:20:56 +0000
Nice. I'm using the SOH/STX characters as frame syncing. The incoming bytes pass through a fall-through buffer. When the SOH and STX bytes are in the right places, and the station ID matches, then it takes it as a frame. Also, the length byte has to be within the bounds of the maximum message size. Anything that doesn't fit the bill gets passed over. It's kind of like a window on the data stream - when the window sees what it should, regardless of what went before, it latches on to it.
Hasn't failed me yet :)
Mon, 18 Mar 2013 00:39:37 +0000
Great! Similar technique.
I did run into one application where the noise was so bad that a simple 8-bit checksum wasn't catching all of the multi-bit errors that were occurring. It was a wire guided vehicle system communicating over a leaky coax. I couldn't switch to a CRC-16, but a contact at Bell Labs created an 8-bit Hamming code that did the trick.
Mon, 18 Mar 2013 00:46:08 +0000
Great! Similar technique. I did run into one application where the noise was so bad that a simple 8-bit checksum wasn't catching all of the multi-bit errors that were occurring. It was a wire guided vehicle system communicating over a leaky coax. I couldn't switch to a CRC-16, but a contact at Bell Labs created an 8-bit Hamming code that did the trick. James
I have tried to keep the checksum as simple as possible (and limited to 8 bits) because the code has to run on a lowly Arduino, so I try and shy away from 16 bit if I can help it. But a more robust 8 bit checksum would be really nice, yes.
There are lots of things I want to do to this library to improve it, like add collision detection on half duplex lines (a la CSMA), but that can come later when I have built myself a small multi-node RS-485 bus to try it out on.
Mon, 18 Mar 2013 18:59:52 +0000
Please keep us up to date on your enhancements.
I want to use it over an rf link TBD. Maybe a Nordic BOB from Sparkfun. Have to get a second chipKIT UNO first.
Mon, 18 Mar 2013 19:13:37 +0000
Certainly will do. It'll be great to see how it performs for other people in situations I can't even begin to conceive ;)
At the moment I am working on an options TX/RX signal for half-duplex lines (for RS-485 this would be the DE / RE# signal, for RF links it might be a TX/RX signal, etc) which is synchronised with the actual transmission of data. I have seen many circuits involving monitoring of the TX line to decide if the DE line should be driven or not, mostly involving a FET - but one using a 555 - but none of them have been satisfactory. Hit anything like a decent transmit speed and you don't get anything at all. The 555 works better than the FET, but to cope with slow baud rates it has to keep the DE line alive for ages - and then you use a high baud rate, and your DE line is lingering around for far too long.
So a proper TX/RX signal is really needed...
It's easy on the Arduino 1.0.4 as the Serial.flush() function works properly. Not so easy on earlier Arduino versions, and nigh on impossible without querying the hardware directly on the chipkit as flush() should be renamed flushMyDataDownTheToilet()... It the moment I am just delaying for 8 characters worth of serial data, which is not really ideal when used on a chip with only a 4 character FIFO buffer...
Mon, 18 Mar 2013 21:49:22 +0000
Release 13 is now available.
This adds support for RS-485 DE/RE# lines including (at the moment) rudimentary transmit signal timing. Timing will improve as ChipKit core facilities improve.
I have just built myself a two-node RS-485 network and had an UNO and an UNO32 communicating at 218000 baud (I was trying for 230400 baud, but at 230400 baud the Arduino is actually transmitting at around 218000 baud) and it worked nicely.
All I need now is to dismantle some more network cards to get the RJ-45 sockets off them and I can build myself a third node to check out a multi-node system.
Tue, 19 Mar 2013 16:05:33 +0000
Yep, I can confirm it works on a 3-node rs485 network :)
At least for controlling some LEDs it does :D
Sat, 23 Mar 2013 11:45:02 +0000
I have just released r17. This version fixes a problem with the Linux serial port routines, and now includes a 5 SOH preamble to all packets.
I have also used the Linux library on my Pi controlling a MAX3485 chip using a GPIO line.