Difference between revisions of "EPEVER 485"

From Public Wiki
Jump to navigation Jump to search
(Created page with "==Synopsis== Issues 485 request and display result ==Notes== ==Code== <syntaxhighlight lang="C++" line='line'> //#include <SoftwareSerial.h> //const int SSERIAL_RX_PIN = 10;...")
 
 
(8 intermediate revisions by one other user not shown)
Line 2: Line 2:
 
Issues 485 request and display result
 
Issues 485 request and display result
 
==Notes==
 
==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==
 
==Code==
Line 16: Line 274:
 
#define BUFS 64  //Buffer size
 
#define BUFS 64  //Buffer size
 
short crc;
 
short crc;
 +
byte arry[6] = {0x00, 0x02, 0x02, 0x00, 0x02, 0x00};
 
byte Response[BUFS];
 
byte Response[BUFS];
 
byte Response_size;
 
byte Response_size;
 
+
byte countdown = 2;
 
//===============================================================================
 
//===============================================================================
 
//  Initialization
 
//  Initialization
Line 28: Line 287:
 
   delay(1000);
 
   delay(1000);
 
   Serial.println();
 
   Serial.println();
 +
 
  
   Response_size = zerofour(Response, 0x3302, 0x0012);
+
   Response_size=zeroone(Response,0x0002,0x0001 ); //number must be [1-0x07d0]
    if(Response_size==0) Serial.println("Received Error from 0x04");
+
 +
  Serial.print("Size  Redad Respponse  is  : ");
 +
  Serial.println(Response_size);
  
   //Print result
+
   Serial.print("Response Read Response string is : ");
 
   for(byte i=0;i<Response_size;i++)
 
   for(byte i=0;i<Response_size;i++)
 
   {
 
   {
 
     Serial.print("0x");
 
     Serial.print("0x");
 +
    if(Response[i]<16) Serial.print("0");
 
     Serial.print(Response[i],HEX);
 
     Serial.print(Response[i],HEX);
 
     Serial.print(" ");
 
     Serial.print(" ");
 
   }
 
   }
 
   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);
 +
//  }
 +
 
 +
 +
 
}
 
}
  
Line 48: Line 348:
 
void loop()  
 
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 rq[8];  //Always 8 bytes for 0x01
 +
  short c; //CRC value
 +
  byte i, j,sz;  //Counters, size
 +
 +
  //If there are no parameters selected or too many, then error, quit.
 +
  if(num==0 || num>0x07d0)
 +
  {
 +
    Serial.println("Illegal quantity of inputs");
 +
    return 0; 
 +
  }
 +
 +
 
 +
  rq[0]=DEVICE; //Global device IO
 +
  rq[1]=0x01;
 +
  rq[3]=byte(start&0x00FF);    //starting LSB address
 +
  rq[2]=byte((start&0xFF00)>>8);//starting MSB address
 +
  rq[5]=byte(num&0x00FF);      //number of coils LSB
 +
  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++)
 +
  {
 +
    Serial1.write(rq[i]);
 +
  }
 +
 +
  //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)
 +
  {
 +
    Serial.println("Buffer overflow prevented in 0x01.  Recompile with BUFS to a higher value");
 +
    return 0;
 +
  }
 +
  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; //Error packet is much shorter, always 5.
 +
      i++;
 +
    } 
 +
  }
 +
  if (rs[1]==0x83)
 +
  {
 +
    Serial.println("Remote system threw an error.");
 +
    return 0;
 +
  }
 +
  c=CRC16(rs,sz-2);
 +
  if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
 +
  {
 +
    Serial.println("CRC error in 'Read Coils' function 0x01");
 +
    return 0;
 +
  }
 +
  return sz;
 
}
 
}
  
//Assigns rs[] array, returns size or zero for CRC error
+
// Read discretes zerotwo - Read up to 2000 discrete inputs in a call.
//This does NOT detect broadcast CRC errors, or any exception
+
// Requires:
//handling at all
+
//  byte rs[] : Respose[]
 +
//   int start : starting address
 +
//   int num  : Number of inputs between 1..0x07D0
 
//
 
//
//    rs : Response[] array
+
byte zerotwo(byte rs[], int start, int num)
//  start : Starting address
+
{
//   num : Number of registers requested
+
  byte rq[8];  //Always 8 bytes
 +
  short c; //CRC value
 +
  byte i, j,sz;  //Counters, size
 +
 
 +
  rq[0]=DEVICE; //Global device IO
 +
  rq[1]=0x02;
 +
  rq[3]=byte(start&0x00FF);  //Starting address LSB
 +
  rq[2]=byte((start&0xFF00)>>8);  //Starting address MSB
 +
  rq[5]=byte(num&0x00FF);  //Number of bits LSB
 +
  rq[4]=byte((num&0xFF00)>>8); //Number of bits MSB
 +
 
 +
  c = CRC16(rq,6);
 +
  rq[7]=0x00FF & c;  //CRC LSB written
 +
  rq[6]=c>>8;      //CRC MSB written
 +
 
 +
 
 +
  //Deliver request to device
 +
  for(i=0;i<8;i++)
 +
  {
 +
     Serial1.write(rq[i]);
 +
  }
 +
 
 +
  //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)
 +
  {
 +
    Serial.println("Buffer overflow prevented in 0x02.  Recompile with BUFS to a higher value");
 +
    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; //Error packet is much shorter, always 5.
 +
      i++;
 +
    } 
 +
  }
 +
  if (rs[1]==0x83)
 +
  {
 +
    Serial.println("Remote system threw an error.");
 +
    return 0;
 +
  }
 +
 
 +
  //Verify CRC code
 +
  c=CRC16(rs,sz-2);
 +
  if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
 +
  {
 +
    Serial.println("CRC error in 0x02");
 +
    return 0;
 +
  }
 +
  return sz;
 +
}
 +
 
 +
// 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 rq[8];
 +
  short c; //CRC value
 +
  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[1]=0x03;
 +
  rq[3]=byte(start&0x00FF);
 +
  rq[2]=byte((start&0xFF00)>>8);
 +
  rq[5]=byte(num&0x00FF);
 +
  rq[4]=0x00;  //The number of registers MSB is always zero
 +
 
 +
  //Calculate and store CRC
 +
  c = CRC16(rq,6);
 +
  rq[7]=0x00FF & c;
 +
  rq[6]=c>>8;
 +
 
 +
  //Deliver request to device
 +
  for(i=0;i<8;i++)
 +
  {
 +
    Serial1.write(rq[i]);
 +
  }
 +
  sz = 5+num*2;
 +
  if(sz>BUFS)
 +
  {
 +
    Serial.println("Buffer overflow prevented in 0x03. Recompile with BUFS to a higher value");
 +
    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);
 +
  if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
 +
  {
 +
    Serial.println("CRC error in 0x03");
 +
    return 0;
 +
  }
 +
 
 +
  return sz;
 +
}
 +
 
 +
 
 +
// 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 65: 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]=byte((num&0xFF00)>>8);
+
   rq[4]=0x00;  //This is always zero for this function
 +
 
 +
  c = CRC16(rq,6);  //Generate CRC
 +
  rq[7]=0x00FF & c;  //Write LSB of CRC
 +
  rq[6]=c>>8; //Write MSB of CRC
 +
 
 +
  //Deliver request to device
 +
  for(i=0;i<8;i++)
 +
  {
 +
    Serial1.write(rq[i]);
 +
  }
 +
  sz = 5+num*2;
 +
  if(sz>BUFS)
 +
  {
 +
    Serial.println("Buffer overflow prevented in 0x04.  Recompile with BUFS to a higher value");
 +
    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);
 +
  if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
 +
  {
 +
    Serial.println("CRC error in 0x04");
 +
    return 0;
 +
  }
 +
 
 +
  return sz;
 +
}
 +
 
 +
// Write Single Coil zerofive - Write a coild 0xFF00 or 0x0000.
 +
// Requires:
 +
//  byte rs[] : Response[]
 +
//  int start : starting address
 +
//  bool set  : State of coil LOW or HIGH
 +
byte zerofive(byte rs[],int addr, bool set)
 +
{
 +
  byte rq[8];  //Always 8 bytes
 +
  short c; //CRC value
 +
  byte i, j,sz;  //Counters, size
 +
 
 +
 
 +
  rq[0]=DEVICE; //Global device IO
 +
  rq[1]=0x05;
 +
  rq[3]=byte(addr&0x00FF);
 +
  rq[2]=byte((addr&0xFF00)>>8);
 +
  rq[5]=0x00;  //Always zero
 +
  if(set) rq[4]=0xFF;
 +
  else rq[4]=0x00;
 +
 
  
 
   c = CRC16(rq,6);
 
   c = CRC16(rq,6);
Line 77: Line 660:
 
   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+rq[5]*2;
+
   sz = 8;  //Always 8 for this function
 +
  if(sz>BUFS)
 +
  {
 +
    Serial.println("Buffer overflow prevented in 0x03.  Recompile with BUFS to a higher value");
 +
    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);
 +
 
 +
  if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
 +
  {
 +
    Serial.println("CRC error in 0x05");
 +
    return 0;
 +
  }
 +
}
 +
 
 +
 
 +
// 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[255];
 +
  short c; //CRC value
 +
  byte i, j,sz;  //Counters, size
 +
 
 +
  if(num==0 || num>0x7B)
 +
  {
 +
    Serial.println("Invalid number of registers being written in 0x10.");
 +
    return 0;
 +
  }
 +
  rq[0]=DEVICE; //Global device IO
 +
  rq[1]=0x10;
 +
  rq[3]=byte(start&0x00FF);
 +
  rq[2]=byte((start&0xFF00)>>8);
 +
  rq[5]=byte(num&0x00FF);
 +
  rq[4]=0x00;  //always zero
 +
  rq[6]=num<<1;  //num*2
 +
 
 +
  for(int i=0;i<(num<<1);i++)
 +
  {
 +
    rq[7+i]=arr[i];
 +
  }
 +
 
 +
  c = CRC16(rq,7+(num<<1));
 +
  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)
 
   if(sz>BUFS)
 
   {
 
   {
Line 87: Line 743:
 
     return 0;
 
     return 0;
 
   }
 
   }
 +
 
 +
  sz=8;  //This response is always 8 bytes long
 +
  //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);
 
   if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
 
   if(c!=short((rs[sz-2]<<8 | rs[sz-1])))
Line 102: Line 769:
 
     return 0;
 
     return 0;
 
   }
 
   }
 
 
   return sz;
 
   return sz;
 
}
 
}
Line 188: Line 854:
 
   return short(uchCRCHi << 8 | uchCRCLo);
 
   return short(uchCRCHi << 8 | uchCRCLo);
 
}
 
}
 +
 +
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 06:05, 19 November 2020

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 }