View previous topic :: View next topic |
Author |
Message |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
Packet over serial: Header and values collisions |
Posted: Wed Jan 21, 2015 6:07 pm |
|
|
I need to send very simple packets from PC to PIC very fast! (100 times per sec.)
Interfacing PC to PIC is not the problem.
I will have some conflicts with the packet start header and the packets values.
The 16 values are 12-bit.
So I thought of doing:
Code: |
START (2 bytes) PACKET CONTENT
0x01 0x02 0xFFF 0xFFF....
|
When the packet values are gonna be 1 and 2 (chance that 2 bytes will be in this order is possible) and the pic will be confused about where the packet start.
I thought of using ASCII digits but this use more bytes in term of data flow.
Sending a 12-bit value will use 4 bytes instead of 3.
What do you think?
I think modbus would be overkill and induce a lot of overhead judging by the CCS demo.
BTW, it's just a brainstorming nothing concrete for now. _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Wed Jan 21, 2015 6:40 pm |
|
|
Choose unique START and STOP ASCII characters. The only legal place they can occur is at the start and stop, respectively, of a packet.
Legal packet:
[START] [n bytes of data] [STOP]
If, in the middle of your packet you need to transmit a START or STOP (as part of your data stream), insert an escape sequence instead. Take the standard ASCII escape - 0x1B.
0x1B 0x1B = one byte that is 0x1B
0x1B 0x1C = one byte that is START
0x1B 0x1D = one byte that is STOP
You can make your scheme more robust by also transmitting the number of bytes in the stream and/or a checksum. |
|
![](templates/subSilver/images/spacer.gif) |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Jan 21, 2015 8:09 pm |
|
|
newguy wrote: | Choose unique START and STOP ASCII characters. The only legal place they can occur is at the start and stop, respectively, of a packet.
Legal packet:
[START] [n bytes of data] [STOP]
If, in the middle of your packet you need to transmit a START or STOP (as part of your data stream), insert an escape sequence instead. Take the standard ASCII escape - 0x1B.
0x1B 0x1B = one byte that is 0x1B
0x1B 0x1C = one byte that is START
0x1B 0x1D = one byte that is STOP
You can make your scheme more robust by also transmitting the number of bytes in the stream and/or a checksum. |
Your suggesting using ASCII values instead of directly sending real 8-bit hex...
I forgot to say that packet have FIXED length so stop is redundant.
Great alternative!
I still like to know if there a way to transfer raw bytes over serial with a header...
I just wished the serial was 9-bit so I could flag outside of the 8-bit sending. _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Wed Jan 21, 2015 9:24 pm |
|
|
Doesn't have to be ASCII. Just set aside two unique characters (start/stop) and a further "escape" character that allows you to insert the start/stop within your datastream. |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Wed Jan 21, 2015 9:32 pm |
|
|
Be very careful transferring raw bytes over the serial line - especially if one side is the PC. You often don't have access to the low level drivers for the PC and can get unpleasant surprises when the data happens to look like special characters to the PC (CR, LF and others come to mind, having been bitten by that in the past where raw 0x0D got an automatic LF (0x0A) appended by the driver (this was some time ago). I would test a full range of raw data through the PC just to make sure it is not going to "help" you.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
![](templates/subSilver/images/spacer.gif) |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Jan 22, 2015 5:21 am |
|
|
newguy wrote: | Doesn't have to be ASCII. Just set aside two unique characters (start/stop) and a further "escape" character that allows you to insert the start/stop within your datastream. |
Alright thanks!
gpsmikey wrote: | Be very careful transferring raw bytes over the serial line - especially if one side is the PC. You often don't have access to the low level drivers for the PC and can get unpleasant surprises when the data happens to look like special characters to the PC (CR, LF and others come to mind, having been bitten by that in the past where raw 0x0D got an automatic LF (0x0A) appended by the driver (this was some time ago). I would test a full range of raw data through the PC just to make sure it is not going to "help" you. |
Good observation.
I will test this first.
Thank you guys!
![Smile](images/smiles/icon_smile.gif) _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Jan 22, 2015 8:28 am |
|
|
Are you 'locked' to 8bit serial?.
If not, consider using 9bits. Use bit 9 as the 'marker'. So start header with bit 9 set, then data packet with bit 9 off.
This is quite common on some RS485 protocols, where the 'target address' is sent with bit 9 on. |
|
![](templates/subSilver/images/spacer.gif) |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Jan 22, 2015 10:56 am |
|
|
Ttelmah wrote: | Are you 'locked' to 8bit serial?.
If not, consider using 9bits. Use bit 9 as the 'marker'. So start header with bit 9 set, then data packet with bit 9 off.
This is quite common on some RS485 protocols, where the 'target address' is sent with bit 9 on. |
I wonder how you can manage to read the ninth bit with PIC.
I've looked quickly found nothing concrete applicable to packet receiving...
I'll continue to look more when I'm back from work. _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Thu Jan 22, 2015 11:44 am |
|
|
I was looking into using the 9th bit to indicate it was an address quite a while ago when I found one of the new (at the time) 8751 family (FX?) supported the 9th bit as an address flag according to the data sheet. No other info so I called the Intel FAE - his response was "it does?? - I'll have to check it out and get back to you on that". Still waiting for that call back :-) I have seen some uarts that do handle the 9 bits, but I would definitely check out the hardware I was going to use before I assumed that it did support 9 bits.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Thu Jan 22, 2015 1:31 pm |
|
|
Motorola has(had) an addressable UART 'MC14469' used the 9th bit. Might be useful info in the app note. been 15 years since I used them though.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Jan 22, 2015 3:16 pm |
|
|
gpsmikey wrote: | I was looking into using the 9th bit to indicate it was an address quite a while ago when I found one of the new (at the time) 8751 family (FX?) supported the 9th bit as an address flag according to the data sheet. No other info so I called the Intel FAE - his response was "it does?? - I'll have to check it out and get back to you on that". Still waiting for that call back :-) I have seen some uarts that do handle the 9 bits, but I would definitely check out the hardware I was going to use before I assumed that it did support 9 bits.
mikey |
So 9-bit UART aren't universal?
I'll double check if the FT232R support it (bridge between PIC and PC). _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Jan 22, 2015 3:19 pm |
|
|
gpsmikey wrote: | I was looking into using the 9th bit to indicate it was an address quite a while ago when I found one of the new (at the time) 8751 family (FX?) supported the 9th bit as an address flag according to the data sheet. No other info so I called the Intel FAE - his response was "it does?? - I'll have to check it out and get back to you on that". Still waiting for that call back :-) I have seen some uarts that do handle the 9 bits, but I would definitely check out the hardware I was going to use before I assumed that it did support 9 bits.
mikey |
So 9-bit UART aren't universal?
I'll double check if the FT232R support it (bridge between PIC and PC).
The MC14469 ... well ... is old!
Quote: | Guaranteed Data Rates to 4800 Baud @ 5 V, to 9600 Baud @ 12 V |
Isssh!! _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Jan 22, 2015 3:21 pm |
|
|
The PIC UART can handle 9 bit data. You normally write this with the parity bit (since except for some of the DsPIC's, the PIC does not generate parity in hardware), but the CCS functions offer the ability to send the 9th bit if you use a 16bit value to the routines.
Even the earliest PC can also generate 9bit data, but it takes a bit of coding. You 'cheat', and use a look up table to code for every byte value, whether even, or odd parity would generate a 0 or a 1 in the 9th bit, and then toggle the UART setup for each byte.
Many modern PC's allow 9bit to be directly sent. It's only older ones with a plain UART that can't. Later boards use an emulation of the 16C950, that has a micro-controller mode giving 9bit support. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Thu Jan 22, 2015 3:48 pm |
|
|
re: ...
The MC14469 ... well ... is old! ...
gee , thanks, makes me feel like a dinosaur....
I do have equipment running at 24 baud( yes, 24 bits per second) for the past 20 years on direct wire over 15 miles( yes, miles) of copper.
Don't know if the PC can handle 9 bits though, might need to make a 'bridge' unit. Who knows what's inside a PC these dayze !
Jay |
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: Packet over serial: Header and values collisions |
Posted: Thu Jan 22, 2015 11:49 pm |
|
|
ELCouz wrote: | I need to send very simple packets from PC to PIC very fast! (100 times per sec.)
Interfacing PC to PIC is not the problem.
I will have some conflicts with the packet start header and the packets values.
The 16 values are 12-bit.
So I thought of doing:
Code: |
START (2 bytes) PACKET CONTENT
0x01 0x02 0xFFF 0xFFF....
|
When the packet values are gonna be 1 and 2 (chance that 2 bytes will be in this order is possible) and the pic will be confused about where the packet start.
I thought of using ASCII digits but this use more bytes in term of data flow.
Sending a 12-bit value will use 4 bytes instead of 3.
What do you think?
I think modbus would be overkill and induce a lot of overhead judging by the CCS demo.
BTW, it's just a brainstorming nothing concrete for now. |
As you have already determined modbus would be an overkill however the basic method of detecting the start of a modbus transmission is sound.
In your case it is even easier because your packets are always the same length. You can detect the start of a message frame by detecting an idle period on the serial interface. Modbus uses 3.5 character times to determine an idle bus condition. In your case you could detect the start of a frame as receiving a byte after an idle timeout period and then you can validate the frame simply by determining the length of the frame on detection of the next idle period. If it is not exactly the length you are expecting you ignore the frame as though it never happened. If you wanted to add more confidence to the payload you could define a start-of-message byte, a CRC or checksum and an end-of-message byte _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
![](templates/subSilver/images/spacer.gif) |
|