Is There Life After HART?

4800 BPS HART:  A Proposal

by Analog Services, Inc.


    Coding

    [Click   here  to return to main document]

    The goal of the coding is to create frequent transitions and to control errors without adding too many extra bits.  Existing HART uses eleven bit times to send only 8 bits.  This makes it possible to limit same-bit string lengths to 3.  The sequence of the code words must also be considered, to prevent the creation of a long string of the same bit out of adjacent portions of two words.  The proposed set of coding rules is as follows:

        1.    Code words are transmitted most-significant-bit first.  (This is an
                arbitrary decision.  A different set of code words could also be
                created for transmission of LSB first.)

        2.    The words are divided into 4 groups, according to the first two bits
                (most significant two bits).  Words that start with 01 or 10 are sent
                as is.  Words that start with 11 are alternates for those that start
                with 00.  That is, there are two possible code words for some of
                the input bytes.  Words that begin with 00 are sent as is if the last
                bit (least significant) of the previous word was a 1.  Words that
                begin with 00 are replaced with alternates if the last bit of the previous
                word was a 0.

        3.    No word may contain a group of 4 contiguous identical bits (i.e.,
                can't be 0000 or 1111).

        4.    The last 3 bits (least significant 3 bits) of a word must not all be
                the same (i.e., can't be 000 or 111).

        5.    The words 01010101010 (decimal 682)  and 10101010101
                (decimal 1365) are reserved as preamble words.

    The coding as just described ignores error checking.  The 9th bit in existing HART that was used for error control was discarded.  We still need something equivalent to this for the proposed scheme.  Otherwise a single bit error in the code word could produce another valid code word and lead to the selection of the wrong byte at the decoder.  We would then have to rely entirely on the checksum at the end of the message for all of the error control.  And it is known that just a checksum alone is not adequate.

    Error control can be re-instated by allowing only code words with odd parity (odd number of 1 bits).  This allows the decoder to catch any odd number of bit errors, which is the same as in existing HART.  For a further discussion of errors and error control click    here  .)  With the requirement of odd parity, the acceptable number of code words is reduced, but still exceeds 256, along with alternates.

    Another consideration is to maintain a balance between the number of 1's and 0's transmitted.   Therefore, an additional rule is that words with either 5 or 7 one bits are acceptable.  Those with only 3 are eliminated.

    A final coding consideration is that the preamble be recognizeable using a minimum number of bits.   It turns out that with the exclusion of two words, 19 bits of preamble are sufficient to differentiate the preamble from normal data.  The two words that need  to be excluded are 01010101001 (decimal 681) and 10101010100 (decimal 1364).

    Applying these rules results in 82 words that begin with 00, 223 words that begin with either 01 or 10, and 96 words that begin with 11.  All 223 of those that begin with either 01 or 10 are chosen.  Among the 82 that begin with 00, 33 are chosen.  And, among the 96 that begin with 11, 33 are chosen as alternates.  The table of proposed code words is listed below.   A C program was written to generate the acceptable code words and to check the number of alternating 1's and 0's in all possible combinations of adjacent words.  The C program listing is also given below.

    From an implementation viewpoint, the coder and decoder are reasonably sized.  If implemented in ROM, the coder uses only 512 locations of 11 bits each.  (It is 512 instead of 256 because an extra bit is used from the preceding output word.)  The decoder uses 2048 locations of 9 bits each (8 bit byte + parity).

    There are 2048 possible code words that can be constructed from 11 bits, and only 256 of these are being used to represent data.  If an error occurs and the receiver encounters a word that is not one of the allowed 256, then it must indicate this to its respective microcontroller.  This is easily done by having it generate some convenient dummy byte + bad (even) parity.  Thus, 1792 of the 2048 ROM locations in the receiver would contain this dummy byte.

Input Code Code Alt Code Alt Code
Byte Word Word Word Word
(decimal) (decimal) (binary) (decimal) (binary)
0 555 01000101011
1 557 01000101101
2 558 01000101110
3 563 01000110011
4 565 01000110101
5 566 01000110110
6 569 01000111001
7 570 01000111010
8 587 01001001011
9 589 01001001101
10 590 01001001110
11 595 01001010011
12 597 01001010101
13 598 01001010110
14 601 01001011001
15 602 01001011010
16 604 01001011100
17 611 01001100011
18 613 01001100101
19 614 01001100110
20 617 01001101001
21 618 01001101010
22 620 01001101100
23 625 01001110001
24 626 01001110010
25 628 01001110100
26 651 01010001011
27 653 01010001101
28 654 01010001110
29 659 01010010011
30 661 01010010101
31 662 01010010110
32 665 01010011001
33 666 01010011010
34 668 01010011100
35 675 01010100011
36 677 01010100101
37 678 01010100110
38 684 01010101100
39 689 01010110001
40 690 01010110010
41 692 01010110100
42 699 01010111011
43 709 01011000101
44 710 01011000110
45 713 01011001001
46 714 01011001010
47 716 01011001100
48 721 01011010001
49 722 01011010010
50 724 01011010100
51 731 01011011011
52 733 01011011101
53 738 01011100010
54 740 01011100100
55 747 01011101011
56 749 01011101101
57 750 01011101110
58 787 01100010011
59 789 01100010101
60 790 01100010110
61 793 01100011001
62 794 01100011010
63 796 01100011100
64 803 01100100011
65 805 01100100101
66 806 01100100110
67 809 01100101001
68 810 01100101010
69 812 01100101100
70 817 01100110001
71 818 01100110010
72 820 01100110100
73 827 01100111011
74 837 01101000101
75 838 01101000110
76 841 01101001001
77 842 01101001010
78 844 01101001100
79 849 01101010001
80 850 01101010010
81 852 01101010100
82 859 01101011011
83 861 01101011101
84 866 01101100010
85 868 01101100100
86 875 01101101011
87 877 01101101101
88 878 01101101110
89 883 01101110011
90 885 01101110101
91 886 01101110110
92 905 01110001001
93 906 01110001010
94 908 01110001100
95 913 01110010001
96 914 01110010010
97 916 01110010100
98 923 01110011011
99 925 01110011101
100 930 01110100010
101 932 01110100100
102 939 01110101011
103 941 01110101101
104 942 01110101110
105 947 01110110011
106 949 01110110101
107 950 01110110110
108 953 01110111001
109 954 01110111010
110 1099 10001001011
111 1101 10001001101
112 1102 10001001110
113 1107 10001010011
114 1109 10001010101
115 1110 10001010110
116 1113 10001011001
117 1114 10001011010
118 1116 10001011100
119 1123 10001100011
120 1125 10001100101
121 1126 10001100110
122 1129 10001101001
123 1130 10001101010
124 1132 10001101100
125 1137 10001110001
126 1138 10001110010
127 1140 10001110100
128 1163 10010001011
129 1165 10010001101
130 1166 10010001110
131 1171 10010010011
132 1173 10010010101
133 1174 10010010110
134 1177 10010011001
135 1178 10010011010
136 1180 10010011100
137 1187 10010100011
138 1189 10010100101
139 1190 10010100110
140 1193 10010101001
141 1194 10010101010
142 1196 10010101100
143 1201 10010110001
144 1202 10010110010
145 1204 10010110100
146 1211 10010111011
147 1221 10011000101
148 1222 10011000110
149 1225 10011001001
150 1226 10011001010
151 1228 10011001100
152 1233 10011010001
153 1234 10011010010
154 1236 10011010100
155 1243 10011011011
156 1245 10011011101
157 1250 10011100010
158 1252 10011100100
159 1259 10011101011
160 1261 10011101101
161 1262 10011101110
162 1299 10100010011
163 1301 10100010101
164 1302 10100010110
165 1305 10100011001
166 1306 10100011010
167 1308 10100011100
168 1315 10100100011
169 1317 10100100101
170 1318 10100100110
171 1321 10100101001
172 1322 10100101010
173 1324 10100101100
174 1329 10100110001
175 1330 10100110010
176 1332 10100110100
177 1339 10100111011
178 1349 10101000101
179 1350 10101000110
180 1353 10101001001
181 1354 10101001010
182 1356 10101001100
183 1361 10101010001
184 1362 10101010010
185 1371 10101011011
186 1373 10101011101
187 1378 10101100010
188 1380 10101100100
189 1387 10101101011
190 1389 10101101101
191 1390 10101101110
192 1395 10101110011
193 1397 10101110101
194 1398 10101110110
195 1417 10110001001
196 1418 10110001010
197 1420 10110001100
198 1425 10110010001
199 1426 10110010010
200 1428 10110010100
201 1435 10110011011
202 1437 10110011101
203 1442 10110100010
204 1444 10110100100
205 1451 10110101011
206 1453 10110101101
207 1454 10110101110
208 1459 10110110011
209 1461 10110110101
210 1462 10110110110
211 1465 10110111001
212 1466 10110111010
213 1476 10111000100
214 1483 10111001011
215 1485 10111001101
216 1486 10111001110
217 1491 10111010011
218 1493 10111010101
219 1494 10111010110
220 1497 10111011001
221 1498 10111011010
222 1500 10111011100
223 155 00010011011 1571 11000100011
224 157 00010011101 1573 11000100101
225 171 00010101011 1574 11000100110
226 173 00010101101 1577 11000101001
227 174 00010101110 1578 11000101010
228 179 00010110011 1580 11000101100
229 181 00010110101 1585 11000110001
230 182 00010110110 1586 11000110010
231 185 00010111001 1588 11000110100
232 186 00010111010 1595 11000111011
233 203 00011001011 1605 11001000101
234 205 00011001101 1606 11001000110
235 206 00011001110 1609 11001001001
236 211 00011010011 1610 11001001010
237 213 00011010101 1612 11001001100
238 214 00011010110 1617 11001010001
239 217 00011011001 1618 11001010010
240 218 00011011010 1620 11001010100
241 220 00011011100 1627 11001011011
242 227 00011100011 1629 11001011101
243 229 00011100101 1634 11001100010
244 230 00011100110 1636 11001100100
245 233 00011101001 1643 11001101011
246 234 00011101010 1645 11001101101
247 236 00011101100 1646 11001101110
248 283 00100011011 1651 11001110011
249 285 00100011101 1653 11001110101
250 299 00100101011 1654 11001110110
251 301 00100101101 1673 11010001001
252 302 00100101110 1674 11010001010
253 307 00100110011 1676 11010001100
254 309 00100110101 1681 11010010001
255 310 00100110110 1682 11010010010

 

/*  gen10.c
    Modified to exclude 681 and 1364.
    Modified from gen9.c to locate words that, when
    combined can have some chosen number of alternating 1's and 0's.
    Modified from gen8.c so that it skips the special preamble
    characters (decimal 682 and 1365).
    Table generator.
    Stephen D. Anderson --- November 22, 1999.

*/

#define MASK 524287L
//#define MASK 131071L
//#define MASK 32767L
//#define MASK 8191L

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "dos.h"

main()
{
    unsigned long int two_word;
    unsigned long int part_two_word;
    unsigned int i;      /*  running number. */
    int good_count = 0;     /*  number of acceptable values. */
    FILE *fout;         /*   pointer to output file.  */
    int j;
    int k;
    char flag;
    int local_i;
    int sum;
    char s[15];
    char *ps;
    unsigned long int good_values[500];
    char bad_count;

    //Open output file.
    if ((fout = fopen("out.dat","w")) == 0)
    {
        printf("Can't open output file.");
        exit(0);
    }

    //  Generate all possible values.
    for (i=0; i<2048; ++i)
    {

        flag = 0;

        //  Remove preamble chars.
        local_i =i;
        if (local_i == 682) flag = 1;
        if (local_i == 1365) flag = 1;

        //  Exclude 681 and 1364.
        if (local_i == 681) flag = 1;
        if (local_i == 1364) flag = 1;

        //  Remove words with last 3 bits same.
        local_i = i;
        k = local_i & 7;
        if (k == 7) flag = 1;
        if (k == 0) flag = 1;

        //  Check combinations of 4 bits.
        local_i = i;
        for (j=0; j<8; ++j)
        {
            k = local_i & 0xf;       /*  mask off.  */
            if (k==0) {flag = 1; break; }
            if (k==0xf) {flag = 1; break; }
            local_i = local_i/2;
        }

        //  Check parity.
        local_i = i;
        k = 1;
        sum = 0;
        for (j=0; j<11; ++j)
        {
            if ((k & local_i) != 0) ++sum;
            k = 2*k;
        }
        if (sum%2 == 0) flag = 1;

        //  Throw out words that have 3 ones.
        if (sum ==3) flag = 1;

        //  Get binary version of number.
        local_i = i;
        ps = s;
        k = 0x400;
        for (j=0; j<11; ++j)
        {
            if ((k & local_i) != 0)
                *ps++ = '1';
            else
                *ps++ = '0';
            k = k/2;
        }
        *ps = 0;

        if (flag==0)
        {
            ++good_count;
            fprintf(fout, "%d    %d   %s   %d\n", good_count,i,s,sum);
//    printf("%d\n", good_count);
           good_values[good_count-1] = i;
        }
    }
    fclose(fout);

    // Try all combinations of two code words.  See if any have
    // a 19 bit section that looks like preamble.
    bad_count = 0;
    for (i=0; i<good_count-1; ++i)
    {
        for (j=0; j<good_count-1; ++j)
        {
            two_word = 2048L*good_values[i] + good_values[j];
            //  Get each 19-bit section.
            for (k=0; k<3; ++k)
            {
                part_two_word = MASK & (two_word>>k);
                if (part_two_word == 174762L)
                {
                    printf("%d %ld %d %ld\n", i,good_values[i],j,good_values[j]);
                    ++bad_count;
                    if (bad_count > 5) exit(0);
                }
            }
        }
    }
}

 


For more information on how Analog Services, Inc. can help solve your circuit/system problems, call or e-mail us today.

Contact Analog Services, Inc.

E-Mail: stevea@analogservices.com

home