Difference between revisions of "EPEVER 485"
(→Code) |
|||
(2 intermediate revisions by one other user not shown) | |||
Line 263: | Line 263: | ||
==Code== | ==Code== | ||
<syntaxhighlight lang="C++" line='line'> | <syntaxhighlight lang="C++" line='line'> | ||
+ | |||
//#include <SoftwareSerial.h> | //#include <SoftwareSerial.h> | ||
//const int SSERIAL_RX_PIN = 10; //Soft Serial Receive pin | //const int SSERIAL_RX_PIN = 10; //Soft Serial Receive pin | ||
Line 286: | Line 287: | ||
delay(1000); | delay(1000); | ||
Serial.println(); | Serial.println(); | ||
+ | |||
− | + | Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Serial.print("Size Redad Respponse is : "); | |
− | |||
− | |||
− | Serial.print("Size is : "); | ||
Serial.println(Response_size); | Serial.println(Response_size); | ||
− | Serial.print("Response string is : "); | + | Serial.print("Response Read Response string is : "); |
for(byte i=0;i<Response_size;i++) | for(byte i=0;i<Response_size;i++) | ||
{ | { | ||
Line 316: | Line 303: | ||
} | } | ||
Serial.println(); | Serial.println(); | ||
+ | /* | ||
+ | // for(int k = 0; k < 10; k++) | ||
+ | // { | ||
+ | Response_size=zerofive(Response,0x0002, HIGH); | ||
+ | Serial.print("Size 05 is : "); | ||
+ | Serial.println(Response_size); | ||
+ | |||
+ | Serial.print("Response 05string is : "); | ||
+ | for(byte i=0;i<Response_size;i++) | ||
+ | { | ||
+ | Serial.print("0x"); | ||
+ | if(Response[i]<16) Serial.print("0"); | ||
+ | Serial.print(Response[i],HEX); | ||
+ | Serial.print(" "); | ||
+ | } | ||
+ | Serial.println(); | ||
+ | delay(500); | ||
+ | /* | ||
+ | Response_size=zerofive(Response,0x0002, LOW); | ||
+ | Serial.print("Size is : "); | ||
+ | Serial.println(Response_size); | ||
+ | |||
+ | Serial.print("Response string is : "); | ||
+ | for(byte i=0;i<Response_size;i++) | ||
+ | { | ||
+ | Serial.print("0x"); | ||
+ | if(Response[i]<16) Serial.print("0"); | ||
+ | Serial.print(Response[i],HEX); | ||
+ | Serial.print(" "); | ||
+ | } | ||
+ | */ | ||
+ | Serial.println(); | ||
+ | delay(500); | ||
+ | // } | ||
+ | |||
+ | |||
− | |||
− | |||
} | } | ||
+ | |||
+ | //=============================================================================== | ||
+ | // Main | ||
+ | //=============================================================================== | ||
+ | void loop() | ||
+ | { | ||
+ | Response_size=zerofive(Response,0x0002, HIGH); | ||
+ | Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0] | ||
+ | if(Response[3]>0) Serial.println("Device is ON."); | ||
+ | delay(10000); | ||
+ | Response_size=zerofive(Response,0x0002, LOW); | ||
+ | Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0] | ||
+ | if(Response[3]==0) Serial.println("Device is OFF."); | ||
+ | delay(10000); | ||
+ | |||
+ | } | ||
+ | // Read coils zeroone - Read up to 2000 coils in a call. | ||
+ | // Requires: | ||
+ | // byte rs[] : Respose[] | ||
+ | // int start : starting address | ||
+ | // int num : Number of coils between 1..0x07D0 | ||
+ | // | ||
byte zeroone(byte rs[],int start, int num) | byte zeroone(byte rs[],int start, int num) | ||
{ | { | ||
− | byte rq[8]; //Always 8 bytes | + | byte rq[8]; //Always 8 bytes for 0x01 |
− | |||
− | |||
short c; //CRC value | short c; //CRC value | ||
byte i, j,sz; //Counters, size | byte i, j,sz; //Counters, size | ||
− | if(num==0 || num> | + | //If there are no parameters selected or too many, then error, quit. |
+ | if(num==0 || num>0x07d0) | ||
{ | { | ||
Serial.println("Illegal quantity of inputs"); | Serial.println("Illegal quantity of inputs"); | ||
Line 338: | Line 380: | ||
rq[0]=DEVICE; //Global device IO | rq[0]=DEVICE; //Global device IO | ||
rq[1]=0x01; | rq[1]=0x01; | ||
− | rq[3]=byte(start&0x00FF); | + | rq[3]=byte(start&0x00FF); //starting LSB address |
− | rq[2]=byte((start&0xFF00)>>8); | + | rq[2]=byte((start&0xFF00)>>8);//starting MSB address |
− | rq[5]=byte(num&0x00FF); | + | rq[5]=byte(num&0x00FF); //number of coils LSB |
− | rq[4]=byte((num&0xFF00)>>8); | + | rq[4]=byte((num&0xFF00)>>8); //number of coils MSB |
+ | |||
+ | c = CRC16(rq,6); //Calculate CRC | ||
+ | |||
+ | rq[7]=0x00FF & c; //CRC LSB | ||
+ | rq[6]=c>>8; //CRC MSB | ||
− | |||
− | |||
− | |||
+ | //Transmit the Request array onto bus. | ||
for(i=0;i<8;i++) | for(i=0;i<8;i++) | ||
{ | { | ||
Serial1.write(rq[i]); | Serial1.write(rq[i]); | ||
} | } | ||
− | sz = 5+ | + | |
− | + | //Because the number of coils is in bits and they are returned as bytes, modulo artithmetic | |
+ | //is needed to ensure a fractional byte always rounds upwards to an additioanl byte | ||
+ | sz=5+num/8; | ||
+ | if(num%8>0) sz++; | ||
+ | |||
if(sz>BUFS) | if(sz>BUFS) | ||
{ | { | ||
Line 363: | Line 412: | ||
{ | { | ||
rs[i]=Serial1.read(); | rs[i]=Serial1.read(); | ||
− | if(i==1 && rs[i]==0x83) sz=5; | + | if(i==1 && rs[i]==0x83) sz=5; //Error packet is much shorter, always 5. |
i++; | i++; | ||
− | } | + | } |
− | + | } | |
+ | if (rs[1]==0x83) | ||
+ | { | ||
+ | Serial.println("Remote system threw an error."); | ||
+ | return 0; | ||
} | } | ||
c=CRC16(rs,sz-2); | c=CRC16(rs,sz-2); | ||
if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | ||
{ | { | ||
− | Serial.println("CRC error in 0x01"); | + | Serial.println("CRC error in 'Read Coils' function 0x01"); |
return 0; | return 0; | ||
} | } | ||
− | |||
return sz; | return sz; | ||
} | } | ||
− | + | // Read discretes zerotwo - Read up to 2000 discrete inputs in a call. | |
+ | // Requires: | ||
+ | // byte rs[] : Respose[] | ||
+ | // int start : starting address | ||
+ | // int num : Number of inputs between 1..0x07D0 | ||
+ | // | ||
byte zerotwo(byte rs[], int start, int num) | byte zerotwo(byte rs[], int start, int num) | ||
{ | { | ||
byte rq[8]; //Always 8 bytes | byte rq[8]; //Always 8 bytes | ||
− | |||
− | |||
short c; //CRC value | short c; //CRC value | ||
byte i, j,sz; //Counters, size | byte i, j,sz; //Counters, size | ||
Line 389: | Line 444: | ||
rq[0]=DEVICE; //Global device IO | rq[0]=DEVICE; //Global device IO | ||
rq[1]=0x02; | rq[1]=0x02; | ||
− | rq[3]=byte(start&0x00FF); | + | rq[3]=byte(start&0x00FF); //Starting address LSB |
− | rq[2]=byte((start&0xFF00)>>8); | + | rq[2]=byte((start&0xFF00)>>8); //Starting address MSB |
− | rq[5]=byte(num&0x00FF); | + | rq[5]=byte(num&0x00FF); //Number of bits LSB |
− | rq[4]=byte((num&0xFF00)>>8); | + | rq[4]=byte((num&0xFF00)>>8); //Number of bits MSB |
c = CRC16(rq,6); | c = CRC16(rq,6); | ||
− | rq[7]=0x00FF & c; | + | rq[7]=0x00FF & c; //CRC LSB written |
− | rq[6]=c>>8; | + | rq[6]=c>>8; //CRC MSB written |
+ | |||
+ | //Deliver request to device | ||
for(i=0;i<8;i++) | for(i=0;i<8;i++) | ||
{ | { | ||
Serial1.write(rq[i]); | Serial1.write(rq[i]); | ||
} | } | ||
− | sz = 5+ | + | |
+ | //Because the number of coils is in bits and they are returned as bytes, modulo artithmetic | ||
+ | //is needed to ensure a fractional byte always rounds upwards to an additional byte | ||
+ | sz=5+num/8; | ||
+ | if(num%8>0) sz++; | ||
+ | |||
if(sz>BUFS) | if(sz>BUFS) | ||
{ | { | ||
Line 408: | Line 470: | ||
return 0; | return 0; | ||
} | } | ||
+ | |||
+ | //Listen for response | ||
for(i=0;i<sz;) | for(i=0;i<sz;) | ||
{ | { | ||
− | |||
if (Serial1.available()) //Data from the Slave is available | if (Serial1.available()) //Data from the Slave is available | ||
{ | { | ||
rs[i]=Serial1.read(); | rs[i]=Serial1.read(); | ||
+ | if(i==1 && rs[i]==0x83) sz=5; //Error packet is much shorter, always 5. | ||
i++; | i++; | ||
− | } | + | } |
+ | } | ||
+ | if (rs[1]==0x83) | ||
+ | { | ||
+ | Serial.println("Remote system threw an error."); | ||
+ | return 0; | ||
} | } | ||
+ | |||
+ | //Verify CRC code | ||
c=CRC16(rs,sz-2); | c=CRC16(rs,sz-2); | ||
if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | ||
Line 426: | Line 497: | ||
} | } | ||
+ | // Read Holding Registers zerothree - Read up to 125 registers in a call. | ||
+ | // Requires: | ||
+ | // byte rs[] : Response[] | ||
+ | // int start : starting address | ||
+ | // int num : Number of inputs between 1..0x0007D | ||
+ | // | ||
+ | // Note: Even though the number of inputs will never exceed 8 bits, | ||
+ | // the standard requires a 16-bit type cast. | ||
byte zerothree(byte rs[],int start, int num) | byte zerothree(byte rs[],int start, int num) | ||
{ | { | ||
− | byte rq[8] | + | byte rq[8]; |
− | |||
− | |||
short c; //CRC value | short c; //CRC value | ||
byte i, j,sz; //Counters, size | byte i, j,sz; //Counters, size | ||
− | if(num==0 || num> | + | if(num==0 || num>0x007d) |
{ | { | ||
Serial.println("Illegal quantity of inputs"); | Serial.println("Illegal quantity of inputs"); | ||
Line 446: | Line 523: | ||
rq[2]=byte((start&0xFF00)>>8); | rq[2]=byte((start&0xFF00)>>8); | ||
rq[5]=byte(num&0x00FF); | rq[5]=byte(num&0x00FF); | ||
− | rq[4]= | + | rq[4]=0x00; //The number of registers MSB is always zero |
+ | //Calculate and store CRC | ||
c = CRC16(rq,6); | c = CRC16(rq,6); | ||
rq[7]=0x00FF & c; | rq[7]=0x00FF & c; | ||
rq[6]=c>>8; | rq[6]=c>>8; | ||
+ | //Deliver request to device | ||
for(i=0;i<8;i++) | for(i=0;i<8;i++) | ||
{ | { | ||
Serial1.write(rq[i]); | Serial1.write(rq[i]); | ||
} | } | ||
− | sz = 5+ | + | sz = 5+num*2; |
if(sz>BUFS) | if(sz>BUFS) | ||
{ | { | ||
Line 462: | Line 541: | ||
return 0; | return 0; | ||
} | } | ||
+ | //Listen for Response | ||
for(i=0;i<sz;) | for(i=0;i<sz;) | ||
{ | { | ||
Line 469: | Line 549: | ||
if(i==1 && rs[i]==0x83) sz=5; | if(i==1 && rs[i]==0x83) sz=5; | ||
i++; | i++; | ||
− | } | + | } |
− | + | } | |
+ | if (rs[1]==0x83) | ||
+ | { | ||
+ | Serial.println("Remote system threw an error."); | ||
+ | return 0; | ||
} | } | ||
c=CRC16(rs,sz-2); | c=CRC16(rs,sz-2); | ||
Line 483: | Line 567: | ||
+ | // Read Input Registers zerofour - Read up to 125 registers in a call. | ||
+ | // Requires: | ||
+ | // byte rs[] : Response[] | ||
+ | // int start : starting address | ||
+ | // int num : Number of inputs between 1..0x0007D | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
byte zerofour(byte rs[],int start, int num) | byte zerofour(byte rs[],int start, int num) | ||
{ | { | ||
Line 498: | Line 580: | ||
short c; //CRC value | short c; //CRC value | ||
byte i, j,sz; //Counters, size | byte i, j,sz; //Counters, size | ||
+ | |||
+ | if(num==0 || num>0x007d) | ||
+ | { | ||
+ | Serial.println("Illegal quantity of inputs"); | ||
+ | return 0; | ||
+ | } | ||
rq[0]=DEVICE; //Global device IO | rq[0]=DEVICE; //Global device IO | ||
rq[1]=0x04; | rq[1]=0x04; | ||
− | rq[3]=byte(start&0x00FF); | + | rq[3]=byte(start&0x00FF); //LSB of starting register |
− | rq[2]=byte((start&0xFF00)>>8); | + | rq[2]=byte((start&0xFF00)>>8); //MSB of starting register |
rq[5]=byte(num&0x00FF); | rq[5]=byte(num&0x00FF); | ||
− | rq[4]= | + | rq[4]=0x00; //This is always zero for this function |
− | c = CRC16(rq,6); | + | c = CRC16(rq,6); //Generate CRC |
− | rq[7]=0x00FF & c; | + | rq[7]=0x00FF & c; //Write LSB of CRC |
− | rq[6]=c>>8; | + | rq[6]=c>>8; //Write MSB of CRC |
+ | //Deliver request to device | ||
for(i=0;i<8;i++) | for(i=0;i<8;i++) | ||
{ | { | ||
Serial1.write(rq[i]); | Serial1.write(rq[i]); | ||
} | } | ||
− | sz = 5+ | + | sz = 5+num*2; |
if(sz>BUFS) | if(sz>BUFS) | ||
{ | { | ||
Line 520: | Line 609: | ||
return 0; | return 0; | ||
} | } | ||
+ | //Listen for Response | ||
for(i=0;i<sz;) | for(i=0;i<sz;) | ||
{ | { | ||
− | |||
if (Serial1.available()) //Data from the Slave is available | if (Serial1.available()) //Data from the Slave is available | ||
{ | { | ||
rs[i]=Serial1.read(); | rs[i]=Serial1.read(); | ||
+ | if(i==1 && rs[i]==0x83) sz=5; | ||
i++; | i++; | ||
− | } | + | } |
+ | } | ||
+ | |||
+ | if (rs[1]==0x83) | ||
+ | { | ||
+ | Serial.println("Remote system threw an error."); | ||
+ | return 0; | ||
} | } | ||
c=CRC16(rs,sz-2); | c=CRC16(rs,sz-2); | ||
Line 538: | Line 634: | ||
return sz; | return sz; | ||
} | } | ||
− | |||
− | //rs[] : Response | + | // Write Single Coil zerofive - Write a coild 0xFF00 or 0x0000. |
− | // | + | // Requires: |
− | //set : | + | // byte rs[] : Response[] |
− | + | // int start : starting address | |
− | byte zerofive(byte rs[],int addr, bool set | + | // bool set : State of coil LOW or HIGH |
+ | byte zerofive(byte rs[],int addr, bool set) | ||
{ | { | ||
byte rq[8]; //Always 8 bytes | byte rq[8]; //Always 8 bytes | ||
− | |||
− | |||
short c; //CRC value | short c; //CRC value | ||
byte i, j,sz; //Counters, size | byte i, j,sz; //Counters, size | ||
Line 557: | Line 651: | ||
rq[3]=byte(addr&0x00FF); | rq[3]=byte(addr&0x00FF); | ||
rq[2]=byte((addr&0xFF00)>>8); | rq[2]=byte((addr&0xFF00)>>8); | ||
− | rq[ | + | rq[5]=0x00; //Always zero |
− | if(set) rq[ | + | if(set) rq[4]=0xFF; |
− | else rq[ | + | else rq[4]=0x00; |
Line 565: | Line 659: | ||
rq[7]=0x00FF & c; | rq[7]=0x00FF & c; | ||
rq[6]=c>>8; | rq[6]=c>>8; | ||
− | + | ||
+ | //Deliver request to device | ||
+ | for(i=0;i<8;i++) | ||
{ | { | ||
− | + | Serial1.write(rq[i]); | |
− | |||
− | |||
− | |||
} | } | ||
− | sz = | + | sz = 8; //Always 8 for this function |
if(sz>BUFS) | if(sz>BUFS) | ||
{ | { | ||
Line 578: | Line 671: | ||
return 0; | return 0; | ||
} | } | ||
− | + | ||
+ | //Listen for Response | ||
+ | for(i=0;i<sz;) | ||
{ | { | ||
− | + | if (Serial1.available()) //Data from the Slave is available | |
{ | { | ||
− | + | rs[i]=Serial1.read(); | |
− | + | if(i==1 && rs[i]==0x83) sz=5; | |
− | + | i++; | |
− | + | } | |
− | |||
− | |||
− | } | ||
} | } | ||
− | + | if (rs[1]==0x83) | |
{ | { | ||
− | + | Serial.println("Remote system threw an error."); | |
− | + | return 0; | |
− | |||
− | |||
− | |||
} | } | ||
+ | |||
c=CRC16(rs,sz-2); | c=CRC16(rs,sz-2); | ||
+ | |||
if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | ||
{ | { | ||
− | Serial.println("CRC error in | + | Serial.println("CRC error in 0x05"); |
return 0; | return 0; | ||
} | } | ||
} | } | ||
− | //////////// | + | |
− | byte onezero(byte rs[],int start, int num, byte arr[] | + | |
+ | // Write multiple registers onezero - Read up to 123 registers in a call. | ||
+ | // Requires: | ||
+ | // byte rs[] : Response[] | ||
+ | // int start : starting address | ||
+ | // int num : Number of inputs between 1..0x0007B | ||
+ | // byte arr[]: Array containing registers being written | ||
+ | byte onezero(byte rs[],int start, int num, byte arr[]) | ||
{ | { | ||
− | byte rq[ | + | byte rq[255]; |
short c; //CRC value | short c; //CRC value | ||
byte i, j,sz; //Counters, size | byte i, j,sz; //Counters, size | ||
Line 622: | Line 720: | ||
rq[2]=byte((start&0xFF00)>>8); | rq[2]=byte((start&0xFF00)>>8); | ||
rq[5]=byte(num&0x00FF); | rq[5]=byte(num&0x00FF); | ||
− | rq[4]= | + | rq[4]=0x00; //always zero |
+ | rq[6]=num<<1; //num*2 | ||
− | |||
− | |||
− | |||
− | |||
− | |||
for(int i=0;i<(num<<1);i++) | for(int i=0;i<(num<<1);i++) | ||
{ | { | ||
Line 634: | Line 728: | ||
} | } | ||
− | |||
c = CRC16(rq,7+(num<<1)); | c = CRC16(rq,7+(num<<1)); | ||
− | + | rq[8+(num<<1)]=0x00FF & c; | |
− | + | rq[7+(num<<1)]=c>>8; | |
− | |||
− | rq[8+(num<<1)] = 0x00FF & c; | ||
− | rq[7+(num<<1)] = c>>8; | ||
− | + | for(i=0;i<9+(num<<1);i++) | |
+ | { | ||
+ | Serial1.write(rq[i]); | ||
+ | } | ||
+ | |||
+ | sz = 9+(num<<1); //9 byzes + 2*num | ||
+ | if(sz>BUFS) | ||
{ | { | ||
− | + | Serial.println("Buffer overflow prevented in 0x04. Recompile with BUFS to a higher value"); | |
− | + | return 0; | |
− | |||
− | |||
} | } | ||
− | + | ||
+ | sz=8; //This response is always 8 bytes long | ||
+ | //Listen for Response | ||
+ | for(i=0;i<sz;) | ||
{ | { | ||
− | + | if (Serial1.available()) //Data from the Slave is available | |
{ | { | ||
− | rs[i]= | + | rs[i]=Serial1.read(); |
− | } | + | if(i==1 && rs[i]==0x83) sz=5; |
+ | i++; | ||
+ | } | ||
} | } | ||
− | + | ||
− | if( | + | if (rs[1]==0x83) |
{ | { | ||
− | Serial.println(" | + | Serial.println("Remote system threw an error."); |
return 0; | return 0; | ||
} | } | ||
− | if( | + | |
+ | |||
+ | c=CRC16(rs,sz-2); | ||
+ | if(c!=short((rs[sz-2]<<8 | rs[sz-1]))) | ||
{ | { | ||
− | + | Serial.println("CRC error in 0x04"); | |
− | + | return 0; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
return sz; | return sz; | ||
} | } | ||
− | |||
short CRC16(byte array[],byte s) | short CRC16(byte array[],byte s) | ||
Line 768: | Line 854: | ||
return short(uchCRCHi << 8 | uchCRCLo); | return short(uchCRCHi << 8 | uchCRCLo); | ||
} | } | ||
+ | |||
+ | |||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 06:05, 19 November 2020
Contents
Synopsis
Issues 485 request and display result
Notes
9000-9100 Registers
0xFFFF9000 : 0x00 0xFFFF9001 : 0x70 0xFFFF9002 : 0x00 0xFFFF9003 : 0x86 0xFFFF9004 : 0x68 0xFFFF9005 : 0x5E 0xFFFF9006 : 0x54 0xFFFF9007 : 0x54 0xFFFF9008 : 0xC8 0xFFFF9009 : 0x50 0xFFFF900A : 0x00 0xFFFF900B : 0x00 0xFFFF900C : 0x60 0xFFFF900D : 0xAC 0xFFFF900E : 0x48 0xFFFF900F : 0x00 0xFFFF9010 : 0x64 0xFFFF9011 : 0x00 0xFFFF9012 : Error 0x02 0xFFFF9013 : 0x27 0xFFFF9014 : 0x15 0xFFFF9015 : 0x0B 0xFFFF9016 : 0x1E 0xFFFF9017 : 0x4C 0xFFFF9018 : 0x00 0xFFFF9019 : 0x1C 0xFFFF901A : 0x40 0xFFFF901B : 0x34 0xFFFF901C : 0x4C 0xFFFF901D : 0x02 0xFFFF901E : 0xE8 0xFFFF901F : 0x0A 0xFFFF9020 : 0xB0 0xFFFF9021 : 0x0A 0xFFFF9022 : Error 0x02 0xFFFF9023 : Error 0x02 0xFFFF9024 : Error 0x02 0xFFFF9025 : Error 0x02 0xFFFF9026 : Error 0x02 0xFFFF9027 : Error 0x02 0xFFFF9028 : Error 0x02 0xFFFF9029 : Error 0x02 0xFFFF902A : Error 0x02 0xFFFF902B : Error 0x02 0xFFFF902C : Error 0x02 0xFFFF902D : Error 0x02 0xFFFF902E : Error 0x02 0xFFFF902F : Error 0x02 0xFFFF9030 : Error 0x02 0xFFFF9031 : Error 0x02 0xFFFF9032 : Error 0x02 0xFFFF9033 : Error 0x02 0xFFFF9034 : Error 0x02 0xFFFF9035 : Error 0x02 0xFFFF9036 : Error 0x02 0xFFFF9037 : Error 0x02 0xFFFF9038 : Error 0x02 0xFFFF9039 : Error 0x02 0xFFFF903A : Error 0x02 0xFFFF903B : Error 0x02 0xFFFF903C : Error 0x02 0xFFFF903D : 0x00 0xFFFF903E : 0x00 0xFFFF903F : 0x00 0xFFFF9040 : Error 0x02 0xFFFF9041 : Error 0x02 0xFFFF9042 : 0x00 0xFFFF9043 : 0x00 0xFFFF9044 : 0x13 0xFFFF9045 : 0x00 0xFFFF9046 : 0x00 0xFFFF9047 : 0x06 0xFFFF9048 : 0x00 0xFFFF9049 : 0x00 0xFFFF904A : 0x13 0xFFFF904B : 0x00 0xFFFF904C : 0x00 0xFFFF904D : 0x06 0xFFFF904E : Error 0x02 0xFFFF904F : Error 0x02 0xFFFF9050 : Error 0x02 0xFFFF9051 : Error 0x02 0xFFFF9052 : Error 0x02 0xFFFF9053 : Error 0x02 0xFFFF9054 : Error 0x02 0xFFFF9055 : Error 0x02 0xFFFF9056 : Error 0x02 0xFFFF9057 : Error 0x02 0xFFFF9058 : Error 0x02 0xFFFF9059 : Error 0x02 0xFFFF905A : Error 0x02 0xFFFF905B : Error 0x02 0xFFFF905C : Error 0x02 0xFFFF905D : Error 0x02 0xFFFF905E : Error 0x02 0xFFFF905F : Error 0x02 0xFFFF9060 : Error 0x02 0xFFFF9061 : Error 0x02 0xFFFF9062 : Error 0x02 0xFFFF9063 : 0x1E 0xFFFF9064 : 0x02 0xFFFF9065 : 0x00 0xFFFF9066 : Error 0x02 0xFFFF9067 : 0x02 0xFFFF9068 : Error 0x02 0xFFFF9069 : 0x00 0xFFFF906A : 0x00 0xFFFF906B : 0x78 0xFFFF906C : 0x50 0xFFFF906D : 0x1E 0xFFFF906E : 0x50 0xFFFF906F : 0x28 0xFFFF9070 : 0x00 0xFFFF9071 : Error 0x02 0xFFFF9072 : Error 0x02 0xFFFF9073 : Error 0x02 0xFFFF9074 : Error 0x02 0xFFFF9075 : Error 0x02 0xFFFF9076 : Error 0x02 0xFFFF9077 : Error 0x02 0xFFFF9078 : Error 0x02 0xFFFF9079 : Error 0x02 0xFFFF907A : Error 0x02 0xFFFF907B : Error 0x02 0xFFFF907C : Error 0x02 0xFFFF907D : Error 0x02 0xFFFF907E : Error 0x02 0xFFFF907F : Error 0x02 0xFFFF9080 : Error 0x02 0xFFFF9081 : Error 0x02 0xFFFF9082 : Error 0x02 0xFFFF9083 : Error 0x02 0xFFFF9084 : Error 0x02 0xFFFF9085 : Error 0x02 0xFFFF9086 : Error 0x02 0xFFFF9087 : Error 0x02 0xFFFF9088 : Error 0x02 0xFFFF9089 : Error 0x02 0xFFFF908A : Error 0x02 0xFFFF908B : Error 0x02 0xFFFF908C : Error 0x02 0xFFFF908D : Error 0x02 0xFFFF908E : Error 0x02 0xFFFF908F : Error 0x02 0xFFFF9090 : 0x00 0xFFFF9091 : 0x00 0xFFFF9092 : 0x00 0xFFFF9093 : 0x00 0xFFFF9094 : 0x57 0xFFFF9095 : 0x00 0xFFFF9096 : 0x00 0xFFFF9097 : 0x38 0xFFFF9098 : 0xEE 0xFFFF9099 : Error 0x02 0xFFFF909A : Error 0x02 0xFFFF909B : Error 0x02 0xFFFF909C : Error 0x02 0xFFFF909D : Error 0x02 0xFFFF909E : Error 0x02 0xFFFF909F : Error 0x02 0xFFFF90A0 : 0x00 0xFFFF90A1 : 0x00 0xFFFF90A2 : 0x00 0xFFFF90A3 : 0x00 0xFFFF90A4 : 0x00 0xFFFF90A5 : Error 0x02 0xFFFF90A6 : Error 0x02 0xFFFF90A7 : Error 0x02 0xFFFF90A8 : Error 0x02 0xFFFF90A9 : Error 0x02 0xFFFF90AA : Error 0x02 0xFFFF90AB : Error 0x02 0xFFFF90AC : Error 0x02 0xFFFF90AD : Error 0x02 0xFFFF90AE : Error 0x02 0xFFFF90AF : Error 0x02 0xFFFF90B0 : 0xD2 0xFFFF90B1 : 0x60 0xFFFF90B2 : 0x13 0xFFFF90B3 : 0x7A 0xFFFF90B4 : 0x00 0xFFFF90B5 : 0xA7 0xFFFF90B6 : 0x89 0xFFFF90B7 : 0x35 0xFFFF90B8 : 0x75 0xFFFF90B9 : 0x87 0xFFFF90BA : 0x00 0xFFFF90BB : 0x00 0xFFFF90BC : Error 0x02 0xFFFF90BD : 0x00 0xFFFF90BE : 0x00 0xFFFF90BF : 0xE0 0xFFFF90C0 : Error 0x02 0xFFFF90C1 : Error 0x02 0xFFFF90C2 : Error 0x02 0xFFFF90C3 : Error 0x02 0xFFFF90C4 : Error 0x02 0xFFFF90C5 : Error 0x02 0xFFFF90C6 : Error 0x02 0xFFFF90C7 : Error 0x02 0xFFFF90C8 : Error 0x02 0xFFFF90C9 : Error 0x02 0xFFFF90CA : Error 0x02 0xFFFF90CB : Error 0x02 0xFFFF90CC : Error 0x02 0xFFFF90CD : Error 0x02 0xFFFF90CE : Error 0x02 0xFFFF90CF : Error 0x02 0xFFFF90D0 : Error 0x02 0xFFFF90D1 : Error 0x02 0xFFFF90D2 : Error 0x02 0xFFFF90D3 : Error 0x02 0xFFFF90D4 : Error 0x02 0xFFFF90D5 : Error 0x02 0xFFFF90D6 : Error 0x02 0xFFFF90D7 : Error 0x02 0xFFFF90D8 : Error 0x02 0xFFFF90D9 : Error 0x02 0xFFFF90DA : Error 0x02 0xFFFF90DB : Error 0x02 0xFFFF90DC : Error 0x02 0xFFFF90DD : Error 0x02 0xFFFF90DE : Error 0x02 0xFFFF90DF : Error 0x02 0xFFFF90E0 : Error 0x02 0xFFFF90E1 : Error 0x02 0xFFFF90E2 : Error 0x02 0xFFFF90E3 : Error 0x02 0xFFFF90E4 : Error 0x02 0xFFFF90E5 : Error 0x02 0xFFFF90E6 : Error 0x02 0xFFFF90E7 : Error 0x02 0xFFFF90E8 : Error 0x02 0xFFFF90E9 : Error 0x02 0xFFFF90EA : Error 0x02 0xFFFF90EB : Error 0x02 0xFFFF90EC : Error 0x02 0xFFFF90ED : Error 0x02 0xFFFF90EE : Error 0x02 0xFFFF90EF : Error 0x02 0xFFFF90F0 : Error 0x02 0xFFFF90F1 : Error 0x02 0xFFFF90F2 : Error 0x02 0xFFFF90F3 : Error 0x02 0xFFFF90F4 : Error 0x02 0xFFFF90F5 : Error 0x02 0xFFFF90F6 : Error 0x02 0xFFFF90F7 : Error 0x02 0xFFFF90F8 : Error 0x02 0xFFFF90F9 : Error 0x02 0xFFFF90FA : Error 0x02 0xFFFF90FB : Error 0x02 0xFFFF90FC : Error 0x02 0xFFFF90FD : Error 0x02 0xFFFF90FE : Error 0x02 0xFFFF90FF : Error 0x02
Code
1 //#include <SoftwareSerial.h>
2 //const int SSERIAL_RX_PIN = 10; //Soft Serial Receive pin
3 //const int SSERIAL_TX_PIN = 11; //Soft Serial Transmit pin
4
5 // Create Soft Serial Port object and define pins to use
6 //SoftwareSerial RS485Serial(SSERIAL_RX_PIN, SSERIAL_TX_PIN); // RX, TX
7
8 #define DEVICE 0x01
9 #define BUFS 64 //Buffer size
10 short crc;
11 byte arry[6] = {0x00, 0x02, 0x02, 0x00, 0x02, 0x00};
12 byte Response[BUFS];
13 byte Response_size;
14 byte countdown = 2;
15 //===============================================================================
16 // Initialization
17 //===============================================================================
18 void setup()
19 {
20 Serial.begin(115200); // Start the built-in serial port
21 Serial1.begin(115200); // Start the RS485 soft serial port
22 delay(1000);
23 Serial.println();
24
25
26 Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0]
27
28 Serial.print("Size Redad Respponse is : ");
29 Serial.println(Response_size);
30
31 Serial.print("Response Read Response string is : ");
32 for(byte i=0;i<Response_size;i++)
33 {
34 Serial.print("0x");
35 if(Response[i]<16) Serial.print("0");
36 Serial.print(Response[i],HEX);
37 Serial.print(" ");
38 }
39 Serial.println();
40 /*
41 // for(int k = 0; k < 10; k++)
42 // {
43 Response_size=zerofive(Response,0x0002, HIGH);
44 Serial.print("Size 05 is : ");
45 Serial.println(Response_size);
46
47 Serial.print("Response 05string is : ");
48 for(byte i=0;i<Response_size;i++)
49 {
50 Serial.print("0x");
51 if(Response[i]<16) Serial.print("0");
52 Serial.print(Response[i],HEX);
53 Serial.print(" ");
54 }
55 Serial.println();
56 delay(500);
57 /*
58 Response_size=zerofive(Response,0x0002, LOW);
59 Serial.print("Size is : ");
60 Serial.println(Response_size);
61
62 Serial.print("Response string is : ");
63 for(byte i=0;i<Response_size;i++)
64 {
65 Serial.print("0x");
66 if(Response[i]<16) Serial.print("0");
67 Serial.print(Response[i],HEX);
68 Serial.print(" ");
69 }
70 */
71 Serial.println();
72 delay(500);
73 // }
74
75
76
77 }
78
79
80 //===============================================================================
81 // Main
82 //===============================================================================
83 void loop()
84 {
85 Response_size=zerofive(Response,0x0002, HIGH);
86 Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0]
87 if(Response[3]>0) Serial.println("Device is ON.");
88 delay(10000);
89 Response_size=zerofive(Response,0x0002, LOW);
90 Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0]
91 if(Response[3]==0) Serial.println("Device is OFF.");
92 delay(10000);
93
94 }
95 // Read coils zeroone - Read up to 2000 coils in a call.
96 // Requires:
97 // byte rs[] : Respose[]
98 // int start : starting address
99 // int num : Number of coils between 1..0x07D0
100 //
101 byte zeroone(byte rs[],int start, int num)
102 {
103 byte rq[8]; //Always 8 bytes for 0x01
104 short c; //CRC value
105 byte i, j,sz; //Counters, size
106
107 //If there are no parameters selected or too many, then error, quit.
108 if(num==0 || num>0x07d0)
109 {
110 Serial.println("Illegal quantity of inputs");
111 return 0;
112 }
113
114
115 rq[0]=DEVICE; //Global device IO
116 rq[1]=0x01;
117 rq[3]=byte(start&0x00FF); //starting LSB address
118 rq[2]=byte((start&0xFF00)>>8);//starting MSB address
119 rq[5]=byte(num&0x00FF); //number of coils LSB
120 rq[4]=byte((num&0xFF00)>>8); //number of coils MSB
121
122 c = CRC16(rq,6); //Calculate CRC
123
124 rq[7]=0x00FF & c; //CRC LSB
125 rq[6]=c>>8; //CRC MSB
126
127
128 //Transmit the Request array onto bus.
129 for(i=0;i<8;i++)
130 {
131 Serial1.write(rq[i]);
132 }
133
134 //Because the number of coils is in bits and they are returned as bytes, modulo artithmetic
135 //is needed to ensure a fractional byte always rounds upwards to an additioanl byte
136 sz=5+num/8;
137 if(num%8>0) sz++;
138
139 if(sz>BUFS)
140 {
141 Serial.println("Buffer overflow prevented in 0x01. Recompile with BUFS to a higher value");
142 return 0;
143 }
144 for(i=0;i<sz;)
145 {
146 if (Serial1.available()) //Data from the Slave is available
147 {
148 rs[i]=Serial1.read();
149 if(i==1 && rs[i]==0x83) sz=5; //Error packet is much shorter, always 5.
150 i++;
151 }
152 }
153 if (rs[1]==0x83)
154 {
155 Serial.println("Remote system threw an error.");
156 return 0;
157 }
158 c=CRC16(rs,sz-2);
159 if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
160 {
161 Serial.println("CRC error in 'Read Coils' function 0x01");
162 return 0;
163 }
164 return sz;
165 }
166
167 // Read discretes zerotwo - Read up to 2000 discrete inputs in a call.
168 // Requires:
169 // byte rs[] : Respose[]
170 // int start : starting address
171 // int num : Number of inputs between 1..0x07D0
172 //
173 byte zerotwo(byte rs[], int start, int num)
174 {
175 byte rq[8]; //Always 8 bytes
176 short c; //CRC value
177 byte i, j,sz; //Counters, size
178
179 rq[0]=DEVICE; //Global device IO
180 rq[1]=0x02;
181 rq[3]=byte(start&0x00FF); //Starting address LSB
182 rq[2]=byte((start&0xFF00)>>8); //Starting address MSB
183 rq[5]=byte(num&0x00FF); //Number of bits LSB
184 rq[4]=byte((num&0xFF00)>>8); //Number of bits MSB
185
186 c = CRC16(rq,6);
187 rq[7]=0x00FF & c; //CRC LSB written
188 rq[6]=c>>8; //CRC MSB written
189
190
191 //Deliver request to device
192 for(i=0;i<8;i++)
193 {
194 Serial1.write(rq[i]);
195 }
196
197 //Because the number of coils is in bits and they are returned as bytes, modulo artithmetic
198 //is needed to ensure a fractional byte always rounds upwards to an additional byte
199 sz=5+num/8;
200 if(num%8>0) sz++;
201
202 if(sz>BUFS)
203 {
204 Serial.println("Buffer overflow prevented in 0x02. Recompile with BUFS to a higher value");
205 return 0;
206 }
207
208 //Listen for response
209 for(i=0;i<sz;)
210 {
211 if (Serial1.available()) //Data from the Slave is available
212 {
213 rs[i]=Serial1.read();
214 if(i==1 && rs[i]==0x83) sz=5; //Error packet is much shorter, always 5.
215 i++;
216 }
217 }
218 if (rs[1]==0x83)
219 {
220 Serial.println("Remote system threw an error.");
221 return 0;
222 }
223
224 //Verify CRC code
225 c=CRC16(rs,sz-2);
226 if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
227 {
228 Serial.println("CRC error in 0x02");
229 return 0;
230 }
231 return sz;
232 }
233
234 // Read Holding Registers zerothree - Read up to 125 registers in a call.
235 // Requires:
236 // byte rs[] : Response[]
237 // int start : starting address
238 // int num : Number of inputs between 1..0x0007D
239 //
240 // Note: Even though the number of inputs will never exceed 8 bits,
241 // the standard requires a 16-bit type cast.
242 byte zerothree(byte rs[],int start, int num)
243 {
244 byte rq[8];
245 short c; //CRC value
246 byte i, j,sz; //Counters, size
247
248 if(num==0 || num>0x007d)
249 {
250 Serial.println("Illegal quantity of inputs");
251 return 0;
252 }
253
254
255 rq[0]=DEVICE; //Global device IO
256 rq[1]=0x03;
257 rq[3]=byte(start&0x00FF);
258 rq[2]=byte((start&0xFF00)>>8);
259 rq[5]=byte(num&0x00FF);
260 rq[4]=0x00; //The number of registers MSB is always zero
261
262 //Calculate and store CRC
263 c = CRC16(rq,6);
264 rq[7]=0x00FF & c;
265 rq[6]=c>>8;
266
267 //Deliver request to device
268 for(i=0;i<8;i++)
269 {
270 Serial1.write(rq[i]);
271 }
272 sz = 5+num*2;
273 if(sz>BUFS)
274 {
275 Serial.println("Buffer overflow prevented in 0x03. Recompile with BUFS to a higher value");
276 return 0;
277 }
278 //Listen for Response
279 for(i=0;i<sz;)
280 {
281 if (Serial1.available()) //Data from the Slave is available
282 {
283 rs[i]=Serial1.read();
284 if(i==1 && rs[i]==0x83) sz=5;
285 i++;
286 }
287 }
288 if (rs[1]==0x83)
289 {
290 Serial.println("Remote system threw an error.");
291 return 0;
292 }
293 c=CRC16(rs,sz-2);
294 if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
295 {
296 Serial.println("CRC error in 0x03");
297 return 0;
298 }
299
300 return sz;
301 }
302
303
304 // Read Input Registers zerofour - Read up to 125 registers in a call.
305 // Requires:
306 // byte rs[] : Response[]
307 // int start : starting address
308 // int num : Number of inputs between 1..0x0007D
309
310 byte zerofour(byte rs[],int start, int num)
311 {
312 byte rq[8]; //Always 8 bytes
313 //int addr;
314 //int len;
315 short c; //CRC value
316 byte i, j,sz; //Counters, size
317
318 if(num==0 || num>0x007d)
319 {
320 Serial.println("Illegal quantity of inputs");
321 return 0;
322 }
323
324 rq[0]=DEVICE; //Global device IO
325 rq[1]=0x04;
326 rq[3]=byte(start&0x00FF); //LSB of starting register
327 rq[2]=byte((start&0xFF00)>>8); //MSB of starting register
328 rq[5]=byte(num&0x00FF);
329 rq[4]=0x00; //This is always zero for this function
330
331 c = CRC16(rq,6); //Generate CRC
332 rq[7]=0x00FF & c; //Write LSB of CRC
333 rq[6]=c>>8; //Write MSB of CRC
334
335 //Deliver request to device
336 for(i=0;i<8;i++)
337 {
338 Serial1.write(rq[i]);
339 }
340 sz = 5+num*2;
341 if(sz>BUFS)
342 {
343 Serial.println("Buffer overflow prevented in 0x04. Recompile with BUFS to a higher value");
344 return 0;
345 }
346 //Listen for Response
347 for(i=0;i<sz;)
348 {
349 if (Serial1.available()) //Data from the Slave is available
350 {
351 rs[i]=Serial1.read();
352 if(i==1 && rs[i]==0x83) sz=5;
353 i++;
354 }
355 }
356
357 if (rs[1]==0x83)
358 {
359 Serial.println("Remote system threw an error.");
360 return 0;
361 }
362 c=CRC16(rs,sz-2);
363 if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
364 {
365 Serial.println("CRC error in 0x04");
366 return 0;
367 }
368
369 return sz;
370 }
371
372 // Write Single Coil zerofive - Write a coild 0xFF00 or 0x0000.
373 // Requires:
374 // byte rs[] : Response[]
375 // int start : starting address
376 // bool set : State of coil LOW or HIGH
377 byte zerofive(byte rs[],int addr, bool set)
378 {
379 byte rq[8]; //Always 8 bytes
380 short c; //CRC value
381 byte i, j,sz; //Counters, size
382
383
384 rq[0]=DEVICE; //Global device IO
385 rq[1]=0x05;
386 rq[3]=byte(addr&0x00FF);
387 rq[2]=byte((addr&0xFF00)>>8);
388 rq[5]=0x00; //Always zero
389 if(set) rq[4]=0xFF;
390 else rq[4]=0x00;
391
392
393 c = CRC16(rq,6);
394 rq[7]=0x00FF & c;
395 rq[6]=c>>8;
396
397 //Deliver request to device
398 for(i=0;i<8;i++)
399 {
400 Serial1.write(rq[i]);
401 }
402 sz = 8; //Always 8 for this function
403 if(sz>BUFS)
404 {
405 Serial.println("Buffer overflow prevented in 0x03. Recompile with BUFS to a higher value");
406 return 0;
407 }
408
409 //Listen for Response
410 for(i=0;i<sz;)
411 {
412 if (Serial1.available()) //Data from the Slave is available
413 {
414 rs[i]=Serial1.read();
415 if(i==1 && rs[i]==0x83) sz=5;
416 i++;
417 }
418 }
419 if (rs[1]==0x83)
420 {
421 Serial.println("Remote system threw an error.");
422 return 0;
423 }
424
425 c=CRC16(rs,sz-2);
426
427 if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
428 {
429 Serial.println("CRC error in 0x05");
430 return 0;
431 }
432 }
433
434
435 // Write multiple registers onezero - Read up to 123 registers in a call.
436 // Requires:
437 // byte rs[] : Response[]
438 // int start : starting address
439 // int num : Number of inputs between 1..0x0007B
440 // byte arr[]: Array containing registers being written
441 byte onezero(byte rs[],int start, int num, byte arr[])
442 {
443 byte rq[255];
444 short c; //CRC value
445 byte i, j,sz; //Counters, size
446
447 if(num==0 || num>0x7B)
448 {
449 Serial.println("Invalid number of registers being written in 0x10.");
450 return 0;
451 }
452 rq[0]=DEVICE; //Global device IO
453 rq[1]=0x10;
454 rq[3]=byte(start&0x00FF);
455 rq[2]=byte((start&0xFF00)>>8);
456 rq[5]=byte(num&0x00FF);
457 rq[4]=0x00; //always zero
458 rq[6]=num<<1; //num*2
459
460 for(int i=0;i<(num<<1);i++)
461 {
462 rq[7+i]=arr[i];
463 }
464
465 c = CRC16(rq,7+(num<<1));
466 rq[8+(num<<1)]=0x00FF & c;
467 rq[7+(num<<1)]=c>>8;
468
469 for(i=0;i<9+(num<<1);i++)
470 {
471 Serial1.write(rq[i]);
472 }
473
474 sz = 9+(num<<1); //9 byzes + 2*num
475 if(sz>BUFS)
476 {
477 Serial.println("Buffer overflow prevented in 0x04. Recompile with BUFS to a higher value");
478 return 0;
479 }
480
481 sz=8; //This response is always 8 bytes long
482 //Listen for Response
483 for(i=0;i<sz;)
484 {
485 if (Serial1.available()) //Data from the Slave is available
486 {
487 rs[i]=Serial1.read();
488 if(i==1 && rs[i]==0x83) sz=5;
489 i++;
490 }
491 }
492
493 if (rs[1]==0x83)
494 {
495 Serial.println("Remote system threw an error.");
496 return 0;
497 }
498
499
500 c=CRC16(rs,sz-2);
501 if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
502 {
503 Serial.println("CRC error in 0x04");
504 return 0;
505 }
506 return sz;
507 }
508
509 short CRC16(byte array[],byte s)
510 {
511 static const byte auchCRCHi[] = {
512 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
513 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
514 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
515 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
516 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
517 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
518 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
519 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
520 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
521 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
522 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
523 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
524 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
525 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
526 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
527 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
528 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
529 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
530 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
531 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
532 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
533 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
534 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
535 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
536 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
537 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
538 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
539 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
540 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
541 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
542 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
543 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;
544
545 static const byte auchCRCLo[] = {
546 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2,
547 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04,
548 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
549 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
550 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
551 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
552 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6,
553 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,
554 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
555 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
556 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE,
557 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
558 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA,
559 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C,
560 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
561 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,
562 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62,
563 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
564 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE,
565 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
566 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
567 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C,
568 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76,
569 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
570 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
571 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
572 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
573 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
574 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A,
575 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
576 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86,
577 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;
578
579 byte uchCRCHi = 0xFF;
580 byte uchCRCLo = 0xFF;
581 byte uIndex;
582
583 while(s--)
584 {
585 uIndex = uchCRCHi ^ *array++ ;
586 uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
587 uchCRCLo = auchCRCLo[uIndex] ;
588 }
589 return short(uchCRCHi << 8 | uchCRCLo);
590 }