unsigned short crc16table[256] =
{
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
};
unsigned int TForm1::calCrc(unsigned char *cp, int len)
{
int i, index, crc=0xffff;
for(i=0;i<len;i++,cp++) {
index = ((crc ^ *cp) & 0x00ff);
crc = ((crc >> 8) & 0x00ff) ^ crc16table[index];
}
return(crc);
}
void __fastcall TForm1::Timer3Timer(TObject *Sender)
{
Timer3->Enabled = false;
unsigned char mstr[1000];
char str[5000], s[10];
mstr[0] = address;
mstr[1] = 0x03;
mstr[2] = 0x00;
mstr[3] = 0x00;
mstr[4] = 0x00;
mstr[5] = 27;
unsigned int crc = calCrc(mstr,6);
mstr[6] = (unsigned char)(crc & 0x00ff);
mstr[7] = (unsigned char)(crc >> 8);
IdUDPClient1->SendBuffer(mstr, 8);
int b = IdUDPClient1->ReceiveBuffer(mstr, 1000, 3000);
sprintf(str,"%d: ", b);
for(int i=0;i<b;i++) {
sprintf(s,"%2.2x ",mstr[i]);
strcat(str,s);
}
Edit3->Text = str;
IdUDPClient1->Active = false;
}
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString buf = Socket->ReceiveText();
Memo1->Lines->Add(buf);
char command[100], add[100];
int a;
sscanf(buf.c_str(), "%s %s %d", command, add, &a);
IdUDPClient1->Host = add;
IdUDPClient1->Port = 10002; // port no used
IdUDPClient1->Active = true;
replySocket = Socket;
AnsiString c = StrUpper(command);
if(c == "RETRIEVE") {
mstr[0] = a;
mstr[1] = 0x03;
mstr[2] = 0x00;
mstr[3] = 0x00;
mstr[4] = 0x00;
mstr[5] = 27;
unsigned int crc = calCrc(mstr,6);
mstr[6] = (unsigned char)(crc & 0x00ff);
mstr[7] = (unsigned char)(crc >> 8);
mstrLen = 8;
// set to receive
Timer2->Enabled = true;
}
if(c == "CLEAR") {
mstr[0] = a;
mstr[1] = 0x06;
mstr[2] = 0x00;
mstr[3] = 0x00;
mstr[4] = 0x00;
mstr[5] = 0x00;
unsigned int crc = calCrc(mstr,6);
mstr[6] = (unsigned char)(crc & 0x00ff);
mstr[7] = (unsigned char)(crc >> 8);
mstrLen = 8;
// set to receive
Timer2->Enabled = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
Timer2->Enabled = false;
// set flag waiting for response
waitFlag = true;
// send command
char str[100], reply[1000];
IdUDPClient1->SendBuffer(mstr, mstrLen);
int b = IdUDPClient1->ReceiveBuffer(mstr, 1000, 3000);
if(b == 59) {
float f;
unsigned int val1, val2;
// translate
strcpy(reply,"");
val1 = (mstr[3] << 8) + mstr[4];
val2 = (mstr[5] << 8) + mstr[6];
f = (val1 * 0.0078125) + (val2 * 512.0); // KWH
sprintf(str,"%7.3f ", f);
strcat(reply,str);
// KW
val1 = (mstr[7] << 8) + mstr[8];
sprintf(str,"%7.3f ", val1 * 0.004);
strcat(reply,str);
// KVAR
val1 = (mstr[9] << 8) + mstr[10];
sprintf(str,"%7.3f ", val1 * 0.004);
strcat(reply,str);
// VA
val1 = (mstr[11] << 8) + mstr[12];
sprintf(str,"%7.3f ", val1 * 0.004);
strcat(reply,str);
// power factor
val1 = (mstr[13] << 8) + mstr[14];
sprintf(str,"%5.3f ", val1 * 0.000030518);
strcat(reply,str);
// volt
val1 = (mstr[15] << 8) + mstr[16];
sprintf(str,"%7.3f ", val1 * 0.03125);
strcat(reply,str);
// volt
val1 = (mstr[17] << 8) + mstr[18];
sprintf(str,"%7.3f ", val1 * 0.015625);
strcat(reply,str);
// amp
val1 = (mstr[19] << 8) + mstr[20];
sprintf(str,"%7.3f ", val1 * 0.0039063);
strcat(reply,str);
// kw
val1 = (mstr[21] << 8) + mstr[22];
sprintf(str,"%7.3f ", val1 * 0.001);
strcat(reply,str);
// kw
val1 = (mstr[23] << 8) + mstr[24];
sprintf(str,"%7.3f ", val1 * 0.001);
strcat(reply,str);
// kw
val1 = (mstr[25] << 8) + mstr[26];
sprintf(str,"%7.3f ", val1 * 0.001);
strcat(reply,str);
// power factor
val1 = (mstr[27] << 8) + mstr[28];
sprintf(str,"%5.3f ", val1 * 0.000030518);
strcat(reply,str);
// power factor
val1 = (mstr[29] << 8) + mstr[30];
sprintf(str,"%5.3f ", val1 * 0.000030518);
strcat(reply,str);
// power factor
val1 = (mstr[31] << 8) + mstr[32];
sprintf(str,"%5.3f ", val1 * 0.000030518);
strcat(reply,str);
// volt
val1 = (mstr[33] << 8) + mstr[34];
sprintf(str,"%7.3f ", val1 * 0.03125);
strcat(reply,str);
// volt
val1 = (mstr[35] << 8) + mstr[36];
sprintf(str,"%7.3f ", val1 * 0.03125);
strcat(reply,str);
// volt
val1 = (mstr[37] << 8) + mstr[38];
sprintf(str,"%7.3f ", val1 * 0.03125);
strcat(reply,str);
// volt
val1 = (mstr[39] << 8) + mstr[40];
sprintf(str,"%7.3f ", val1 * 0.015625);
strcat(reply,str);
// volt
val1 = (mstr[41] << 8) + mstr[42];
sprintf(str,"%7.3f ", val1 * 0.015625);
strcat(reply,str);
// volt
val1 = (mstr[43] << 8) + mstr[44];
sprintf(str,"%7.3f ", val1 * 0.015625);
strcat(reply,str);
// amps
val1 = (mstr[45] << 8) + mstr[46];
sprintf(str,"%7.3f ", val1 * 0.0039063);
strcat(reply,str);
// amps
val1 = (mstr[47] << 8) + mstr[48];
sprintf(str,"%7.3f ", val1 * 0.0039063);
strcat(reply,str);
// amps
val1 = (mstr[49] << 8) + mstr[50];
sprintf(str,"%7.3f ", val1 * 0.0039063);
strcat(reply,str);
// kw
val1 = (mstr[51] << 8) + mstr[52];
sprintf(str,"%7.3f ", val1 * 0.004);
strcat(reply,str);
// kw
val1 = (mstr[53] << 8) + mstr[54];
sprintf(str,"%7.3f ", val1 * 0.004);
strcat(reply,str);
// amps
val1 = (mstr[55] << 8) + mstr[56];
sprintf(str,"%7.3f ", val1 * 0.004);
strcat(reply,str);
// send to replySocket
replySocket->SendBuf(reply, strlen(reply));
// log
Memo1->Lines->Add(reply);
}
else {
// error
sprintf(str,"%d chars received - ",b);
if(!b)
strcpy(reply,"0"); // no reply
else {
if(mstr[1] == 0x06) {
// clear kWH, send MSB address 0001
mstr[3] = 0x01;
unsigned int crc = calCrc(mstr,6);
mstr[6] = (unsigned char)(crc & 0x00ff);
mstr[7] = (unsigned char)(crc >> 8);
IdUDPClient1->SendBuffer(mstr, mstrLen);
b = IdUDPClient1->ReceiveBuffer(mstr, 1000, 3000);
}
strcpy(reply,"OK"); // presumably ok
}
replySocket->SendBuf(reply, strlen(reply));
strcat(str,reply);
Memo1->Lines->Add(str);
}
IdUDPClient1->Active = false; // close connection
}
//---------------------------------------------------------------------------
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
by: Geert_GruwezPosted on 2009-08-25 at 07:13:17ID: 25177789
here is the CRC check unit
Select allOpen in new window