Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
90 gunterl 1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.IO.Ports;
5
using System.Threading;
6
 
7
namespace Robotics.Serial
8
{
9
    class SerialCom
10
    {
11
       public delegate void BotEventHandler(object sender, EventArgs ev);
12
       public static event BotEventHandler BotEvent;
13
 
14
       public string ComPort = "COM1";
15
       public static SerialPort serialPort1;// = new SerialPort();
16
       public bool isOpen = false;
17
 
18
       // ---------------------------------------------------------------------------
19
       /// <summary>
20
       /// Decode Message from the Roboboard
21
       /// </summary>
22
       /// <param name="message"></param>
23
       /// <returns></returns>
24
       // ---------------------------------------------------------------------------
25
       public static string DecodeMessage(string command)
26
       {
27
           string message = command.Substring(0, command.Length - 2);
28
           string target = "";
29
           target += (char)command[command.Length - 2];
30
           target += (char)command[command.Length - 1];
31
           //-----------------------------------------------------------
32
           // check CRC
33
           Int16 tmpcrc = 0;
34
           for (int i = 0; i < message.Length; i++)
35
           {
36
               tmpcrc += (Int16)message[i];
37
           }
38
           tmpcrc %= 4096;
39
 
40
           string crc = "";
41
           crc += (char)((byte)'=' + (tmpcrc / 64));
42
           crc += (char)((byte)'=' + (tmpcrc % 64));
43
 
44
           if (crc != target) return "";
45
           //-----------------------------------------------------------
46
           // decode message 
47
           target = "";
48
           message = command.Substring(3, command.Length - 5);
49
 
50
           int index = 0;
51
           uint a, b, c, d;
52
           uint x, y, z;
53
           int len = message.Length;
54
           message = message + "=====";
55
 
56
           while (index <= len)
57
           {
58
               a = (uint)message[index++] - '=';
59
               b = (uint)message[index++] - '=';
60
               c = (uint)message[index++] - '=';
61
               d = (uint)message[index++] - '=';
62
 
63
               x = (a << 2) | (b >> 4);
64
               y = ((b & 0x0f) << 4) | (c >> 2);
65
               z = ((c & 0x03) << 6) | d;
66
 
67
               target += (char)x;
68
               target += (char)y;
69
               target += (char)z;
70
           }
71
           return target;
72
       }
73
 
74
       // ---------------------------------------------------------------------------
75
       /// <summary>
76
       /// Encode Message to send to the Board
77
       /// </summary>
78
       /// <param name="message"></param>
79
       /// <returns></returns>
80
       // ---------------------------------------------------------------------------
81
       public static string EncodeMessage(string message)
82
       {
83
           string target = "";
84
           byte a, b, c;
85
           int len = message.Length;
86
           int ptr = 0;
87
 
88
           while (len > 0)
89
           {
90
               if (len > 0) { a = (byte)message[ptr++]; len--; } else a = 0;
91
               if (len > 0) { b = (byte)message[ptr++]; len--; } else b = 0;
92
               if (len > 0) { c = (byte)message[ptr++]; len--; } else c = 0;
93
               target += (char)((a >> 2) + (byte)'=');
94
               target += (char)((((a & 0x03) << 4) | ((b & 0xf0) >> 4)) + (byte)'=');
95
               target += (char)((((b & 0x0f) << 2) | ((c & 0xc0) >> 6)) + (byte)'=');
96
               target += (char)((c & 0x3f) + (byte)'=');
97
           }
98
           return target;
99
       }
100
 
101
       // ---------------------------------------------------------------------------
102
       /// <summary>
103
       /// Creates a complete message including the command and the address byte 
104
       /// header. It calls thr EncodeMessage function to encode the message body.
105
       /// command and adress byte will not be encoded. An additional 2 Byte CRC will
106
       /// be added at the end of the message
107
       /// </summary>
108
       /// <param name="cmd"></param>
109
       /// <param name="adr"></param>
110
       /// <param name="message"></param>
111
       /// <returns></returns>
112
       // ---------------------------------------------------------------------------
113
       public string CreateMessage(char cmd, char adr, string message)
114
       {
115
           string target = "";
116
           target += '#';
117
           target += adr;
118
           target += cmd;
119
           target += EncodeMessage(message);
120
 
121
           //-----------------------------------------------------------
122
           //add CRC
123
           Int16 tmpcrc = 0;
124
           for (int i = 0; i < target.Length; i++)
125
           {
126
               tmpcrc += (Int16)target[i];
127
           }
128
           tmpcrc %= 4096;
129
           target += (char)((byte)'=' + (tmpcrc / 64));
130
           target += (char)((byte)'=' + (tmpcrc % 64));
131
           //-----------------------------------------------------------
132
           target += (char)'\r';
133
           return target;
134
       }
135
 
136
       // ---------------------------------------------------------------------------
137
       /// <summary>
138
       /// Initialize the COM Port. ComPort must be set before calling this function
139
       /// </summary>
140
       /// <returns></returns>
141
       // ---------------------------------------------------------------------------
142
       public int InitPort()
143
       {
144
            serialPort1 = new SerialPort();
145
            serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived);
146
            try
147
            {
148
                serialPort1.PortName = ComPort;
149
                serialPort1.BaudRate = 57600;
150
                serialPort1.DataBits = 8;
151
                serialPort1.Open();
152
                serialPort1.DiscardInBuffer();
153
                serialPort1.DiscardOutBuffer();
154
                isOpen = true;
155
            }
156
            catch
157
            {
158
                isOpen = false;
159
                return 1;
160
            }
161
            return 0;
162
       }
163
 
164
       // ---------------------------------------------------------------------------
165
       /// <summary>
166
       /// Writes a string to the Com Port
167
       /// </summary>
168
       /// <param name="data"></param>
169
       // ---------------------------------------------------------------------------
170
       public void SerialWrite(string data)
171
       {
172
            serialPort1.Write(data);
173
       }
174
 
175
       // ---------------------------------------------------------------------------
176
       /// <summary>
177
       /// Writes a string to the comport and adds a CR/LF at the end
178
       /// </summary>
179
       /// <param name="data"></param>
180
       // ---------------------------------------------------------------------------
181
       public void SerialWriteLine(string data)
182
       {
183
            serialPort1.WriteLine(data);
184
       }
185
 
186
       // ---------------------------------------------------------------------------
187
       /// <summary>
188
       /// colse the COm port if open
189
       /// </summary>
190
       // ---------------------------------------------------------------------------
191
       public void ClosePort()
192
       {
193
           if (isOpen)
194
           {
195
               serialPort1.Close();
196
           }
197
       }
198
 
199
       // ---------------------------------------------------------------------------
200
       /// <summary>
201
       /// Message functions
202
       /// </summary>
203
       // ---------------------------------------------------------------------------       
204
        public string GetLastMessage()
205
        {
206
            if (messagevalid == true)
207
            {
208
                return botmessage;
209
            }
210
            else return "";
211
        }
212
 
213
        public bool IsMessageValid()
214
        {
215
            return messagevalid;
216
        }
217
 
218
        public bool IsMessageError()
219
        {
220
            return messageerror;
221
        }
222
 
223
        public bool IsMessageOverrun()
224
        {
225
            return messageoverrun;
226
        }
227
 
228
        public void InvalidateMessage()
229
        {
230
            messagevalid = false;
231
            messageerror = false;
232
            messageoverrun = false;
233
        }
234
 
235
        public char GetMessageCmd()
236
        {
237
            return message_cmd;
238
        }
239
 
240
        public char GetMessageAdr()
241
        {
242
            return message_adr;
243
        }
244
 
245
        public string MessageAddByte(byte value, string command)
246
        {
247
            command = command + (char)value;
248
            return command;
249
        }
250
 
251
        public string MessageAddInt16(Int16 value, string command)
252
        {
253
            byte s = 0;
254
            s = (byte)value;
255
            command = command + (char)s;
256
            Int16 value1 = (Int16)(value >> 8);
257
            s = (byte)value1;
258
            command = command + (char)s;
259
            return command;
260
        }
261
 
262
        public string MessageAddInt32(Int32 value, string command)
263
        {
264
            byte s = 0;
265
            s = (byte)value;
266
            command = command + (char)s;
267
            Int32 value1 = (Int32)(value >> 8);
268
            s = (byte)value1;
269
            command = command + (char)s;
270
            value1 = (Int32)(value >> 8);
271
            s = (byte)value1;
272
            command = command + (char)s;
273
            value1 = (Int32)(value >> 8);
274
            s = (byte)value1;
275
            command = command + (char)s;
276
            return command;
277
        }
278
 
279
        public byte MessageReadByte(string command)
280
        {
281
            byte bvalue = (byte)command[0];
282
            return bvalue;
283
        }
284
 
285
        public Int16 MessageReadInt16(string command)
286
        {
287
            int index = 0;
288
            Int16 tmp2;
289
            Int16 result;
290
 
291
            Int16 tmp;
292
            tmp2 = (Int16)command[index++];
293
            result = (Int16)command[index++];
294
            result = (Int16)(result << 8);
295
            result += (Int16)tmp2;
296
            return result;
297
        }
298
 
299
        public Int32 MessageReadInt32(string command)
300
        {
301
            int index = 0;
302
            Int32 tmp0;
303
            Int32 tmp1;
304
            Int32 tmp2;
305
            Int32 result;
306
 
307
            Int16 tmp;
308
            tmp0 = (Int32)command[index++];
309
            tmp1 = (Int32)command[index++];
310
            tmp2 = (Int32)command[index++];
311
            result = (Int32)command[index++];
312
            result = (Int32)(result << 8);
313
            result += (Int32)tmp2;
314
            result = (Int32)(result << 8);
315
            result += (Int32)tmp1;
316
            result = (Int32)(result << 8);
317
            result += (Int32)tmp0;
318
            return result;
319
        }
320
 
321
 
322
       // ---------------------------------------------------------------------------
323
       /// <summary>
324
       /// serial data receive message handler.  
325
       /// </summary>
326
       /// <param name="sender"></param>
327
       /// <param name="e"></param>
328
       // ---------------------------------------------------------------------------
329
       private static string command;
330
       private static bool messagevalid = false;
331
       private static bool messageerror = false;
332
       private static bool messageoverrun = false;
333
       private static char message_cmd = (char)0;
334
       private static char message_adr = (char)0;
335
       private static int receiver_status = 0;
336
       private static string botmessage;
337
 
338
       private static void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
339
       {
340
            int data;
341
            EventArgs ev = new EventArgs();
342
            while (serialPort1.BytesToRead > 0)
343
            {
344
                data = serialPort1.ReadChar();
345
                //Console.Write((char)data);
346
                switch (receiver_status)
347
                {
348
                    case 0:
349
                        if (data.CompareTo('#') == 0)
350
                        {
351
                            command = "#";
352
                            receiver_status++;
353
                        }
354
                        break;
355
                    case 1:
356
                        message_adr = (char)data;
357
                        command = command + (char)data;
358
                        receiver_status++;
359
                        break;
360
                    case 2:
361
                        message_cmd = (char)data;
362
                        command = command + (char)data;
363
                        receiver_status++;
364
                        break;
365
                    case 3:
366
                        if ((data.CompareTo(13) != 0) && (data.CompareTo(10) != 0))
367
                        {
368
                            command = command + (char)data;
369
                            if (command.Length > 350)
370
                            {
371
                                command = "";
372
                                serialPort1.DiscardInBuffer();
373
                            }
374
                        }
375
                        else
376
                        {
377
                            if (messagevalid == true)
378
                            {
379
                                messageoverrun = true;
380
                            }
381
                            else
382
                            {
383
                                botmessage = DecodeMessage(command);
384
                                if (botmessage == "")
385
                                {
386
                                    messageerror = true;
387
                                }
388
                                else
389
                                {
390
                                    messagevalid = true;
391
                                }
392
                            }
393
                            BotEvent(sender, ev);
394
                            receiver_status = 0;
395
                            command = "";
396
                        }
397
                        break;
398
                }
399
 
400
            }
401
       }
402
    }
403
}