Calculating a Modulo 256 Checksum in NodeJS for an Access 2 Laboratory Instrument


I’ve recently had to figure out how to send a checksum with my messages to an Access 2 instrument. I did not find very many good resources for doing so, so I’m going to share what I’ve got here. I got my first clues from the examples in the Access 2 LIS documentation. Unfortunately, it appears that many of the checksums in that documentation are incorrect, so to be sure I got ahold of some raw messages from the device and their checksums, to check my work.

Several of the examples from the documentation are included, commented out, at the top. Unfortunately, I’ve found that not all of these were correct in the documentation.

var msgs = [];

msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161600' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '1'}); // should result in ascii [c1]=2 and [c2]=1
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161524' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '6'}); // should result in ascii [c1]=2 and [c2]=6
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161412' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '2'}); // should result in ascii [c1]=2 and [c2]=2
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161300' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '1', c2: 'E'}); // should result in ascii [c1]=1 and [c2]=E
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161224' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '3'}); // should result in ascii [c1]=2 and [c2]=3
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161148' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '8'}); // should result in ascii [c1]=2 and [c2]=8
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161112' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '1', c2: 'F'}); // should result in ascii [c1]=1 and [c2]=F
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028161036' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '4'}); // should result in ascii [c1]=2 and [c2]=4
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028140331' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '1', c2: 'F'}); // should result in ascii [c1]=1 and [c2]=F
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028140255' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '4'}); // should result in ascii [c1]=2 and [c2]=4
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028131152' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '0'}); // should result in ascii [c1]=2 and [c2]=0
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028131116' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '0'}); // should result in ascii [c1]=2 and [c2]=0
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028131040' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '1', c2: 'C'}); // should result in ascii [c1]=1 and [c2]=C
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028131004' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '1', c2: 'C'}); // should result in ascii [c1]=1 and [c2]=C
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161028130928' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: 'A'}); // should result in ascii [c1]=2 and [c2]=A
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161024120959' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '9'}); // should result in ascii [c1]=2 and [c2]=9
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161024120923' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '0'}); // should result in ascii [c1]=2 and [c2]=0
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161024120847' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '5'}); // should result in ascii [c1]=2 and [c2]=5
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161024120811' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '1', c2: 'C'}); // should result in ascii [c1]=1 and [c2]=C
msgs.push({str: '1H|\\^&|||ACCESS^511550|||||LIS||P|1|20161024120735' + String.fromCharCode(13)+ String.fromCharCode(3), c1: '2', c2: '1'}); // should result in ascii [c1]=2 and [c2]=1

for(var i = 0; i < msgs.length; i++) {
    var msg = msgs[i];
    console.log('');
    console.log(msg.str);
    var checksum = calcChecksum(msg.str);
    console.log('checksum: ' + checksum + '  expected checksum: ' + msg.c1 + msg.c2);
}

function calcChecksum(string) {
    var buf = new Buffer(string);
    // Calculate the modulo 256 checksum
    var sum = 0;
    for (var i = 0, l = buf.length; i < l; i++) {

        sum = (sum + buf[i]) % 256;
    }

    console.log('checksum (binary): ' + sum.toString(2));
    // Convert to a two byte uppercase hex value
    var chars = sum.toString(16).toUpperCase();
    if (chars.length == 1) chars = "0" + chars;
    return chars;
}

[amazon_link asins='1783287314,1491943122,1617292850,1785287524,1785881507' template='ProductCarousel' store='openmindspace-20' marketplace='US' link_id='aff56941-d2ad-11e6-adc6-31f5c1db1590']


Leave a Reply

Your email address will not be published. Required fields are marked *