Is There Life After HART?
4800 BPS HART: A Proposal
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.
E-Mail: stevea@analogservices.com