Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2287 - 1
///============================================================================
2
/// This file is part of MIKROKOPTER SERIAL CONTROL TUTORIAL.
3
/// by JOHN C. MACDONALD at Ira A. Fulton College of Engineering and Technology
4
/// (http://hdl.lib.byu.edu/1877/2747)
5
/// (http://hdl.lib.byu.edu/1877/2748)
6
///============================================================================
7
 
8
using System;
9
using System.Collections.Generic;
10
using System.Linq;
11
using System.Text;
12
using System.Threading.Tasks;
13
using System.Windows;
14
using System.Windows.Controls;
15
using System.Windows.Data;
16
using System.Windows.Documents;
17
using System.Windows.Input;
18
using System.Windows.Media;
19
using System.Windows.Media.Imaging;
20
using System.Windows.Navigation;
21
using System.Windows.Shapes;
22
using System.IO.Ports;
23
 
24
namespace MKLiveView
25
{
26
    public partial class SerialPortCtrl : UserControl
27
    {
28
        private SerialPort port;
29
 
30
        public event PortOpenedHandler PortOpened;
31
        public delegate void PortOpenedHandler();
32
        public event PortClosedHandler PortClosed;
33
        public delegate void PortClosedHandler();
34
        public event DataReceivedHandler DataReceived;
35
        public delegate void DataReceivedHandler(byte[] buffer);
36
 
37
        public SerialPortCtrl()
38
        {
39
            InitializeComponent();
40
            port = new SerialPort();
41
            port.ReadTimeout = 10000;
42
            port.WriteTimeout = 1000;
43
            textBoxStatus.Text = "closed";
44
            textBoxBaudRate.Text = "57600";
45
            textBoxDataBits.Text = port.DataBits.ToString();
46
            populateComboBoxes();
47
            setComboBoxDefaultValues();
48
        }
49
 
50
        public SerialPort Port
51
        {
52
            get
53
            {
54
                return port;
55
            }
56
        }
57
 
58
        public void Connect(bool bConn)
59
        {
60
            if (bConn)
61
                Dispatcher.Invoke((Action)(() => buttonOpen_Click(null, null)));
62
            else
63
                Dispatcher.Invoke((Action)(() => buttonClose_Click(null, null)));
64
        }
65
        private void buttonOpen_Click(object sender, RoutedEventArgs e)
66
        {
67
            try
68
            {
69
                if (port.IsOpen == true)
70
                {
71
                    port.DataReceived -= SerialPortDataReceived;
72
                    port.Close();
73
                }
74
 
75
                lastoffset = 0;
76
                append = false;
77
 
78
                port.PortName = comboBoxPortName.Text;
79
                port.BaudRate = Convert.ToInt32(textBoxBaudRate.Text);
80
                port.DataBits = Convert.ToInt32(textBoxDataBits.Text);
81
                port.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBoxStopBits.Text);
82
                port.Parity = (Parity)Enum.Parse(typeof(Parity), comboBoxParity.Text);
83
                port.DataReceived += SerialPortDataReceived;
84
 
85
                port.Open();
86
                textBoxStatus.Text = "open";
87
                textBoxStatus.Background = Brushes.LightGreen;
88
                if (PortOpened != null)
89
                {
90
                    // PortOpened(port.BaseStream);
91
                    PortOpened();
92
                }
93
            }
94
            catch (Exception ex)
95
            {
96
                textBoxStatus.Text = "error: " + ex;
97
                textBoxStatus.Background = Brushes.Coral;
98
            }
99
        }
100
        private void buttonClose_Click(object sender, RoutedEventArgs e)
101
        {
102
            port.DataReceived -= SerialPortDataReceived;
103
            port.Close();
104
            if (PortClosed != null)
105
                PortClosed();
106
            textBoxStatus.Text = "closed";
107
            textBoxStatus.Background = Brushes.LightGray;
108
            lastoffset = 0;
109
            append = false;
110
        }
111
 
112
        public string[] getPortNameValues()
113
        {
114
            try
115
            {
116
                return SerialPort.GetPortNames().Reverse().ToArray();
117
            }
118
            catch
119
            {
120
                return new string[0];
121
            }
122
        }
123
 
124
        public string[] getStopBitValues()
125
        {
126
            return Enum.GetNames(typeof(StopBits));
127
        }
128
 
129
        public string[] getParityValues()
130
        {
131
            return Enum.GetNames(typeof(Parity));
132
        }
133
 
134
        private void populateComboBoxes()
135
        {
136
            comboBoxPortName.ItemsSource = getPortNameValues();
137
            comboBoxStopBits.ItemsSource = getStopBitValues();
138
            comboBoxParity.ItemsSource = getParityValues();
139
        }
140
 
141
        private void setComboBoxDefaultValues()
142
        {
143
            try { comboBoxPortName.SelectedIndex = 0; }
144
            catch { }
145
            try { comboBoxStopBits.SelectedIndex = 1; }
146
            catch { }
147
            try { comboBoxParity.SelectedIndex = 0; }
148
            catch { }
149
        }
150
 
151
        byte[] messageBuffer = new byte[4096];
152
        int lastoffset = 0;
153
        bool append = false;
154
        byte sentinel = Convert.ToByte('\r');
155
 
156
        object oLock = 0;
157
        private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
158
        {
159
            System.Threading.Monitor.Enter(oLock);
160
            int offset = 0;
161
            try
162
            {
163
                byte[] buffer = new byte[port.BytesToRead];
164
                port.Read(buffer, 0, port.BytesToRead);
165
 
166
                bool bFound = false;
167
                for (int i = 0; (i < buffer.Length) && port.IsOpen; i++)
168
                {
169
                    if (buffer[i] == sentinel)
170
                    {
171
                        if (!append)
172
                        {
173
                            byte[] message = new byte[i + 1 - offset];
174
                            if (buffer[offset] != '#')
175
                                System.Diagnostics.Debug.Print(buffer[offset].ToString());
176
                            Buffer.BlockCopy(buffer, offset, message, 0, i + 1 - offset);
177
                            if (DataReceived != null)
178
                                DataReceived(message);
179
                        }
180
                        else
181
                        {
182
 
183
                            Buffer.BlockCopy(buffer, 0, messageBuffer, lastoffset, i + 1);
184
                            byte[] message = new byte[lastoffset + i + 1];
185
                            Buffer.BlockCopy(messageBuffer, 0, message, 0, message.Length);
186
                            messageBuffer.Initialize();
187
                            append = false;
188
                            lastoffset = 0;
189
                            //  System.Diagnostics.Debug.Print(message.Length.ToString());
190
                            //   System.Diagnostics.Debug.Print(BitConverter.ToString(message));
191
                            if (DataReceived != null)
192
                                DataReceived(message);
193
                        }
194
                        offset = i + 1;
195
                        if (buffer.Length > i + 1)
196
                        {
197
                            //offset = i + 1;
198
                            bFound = false;
199
                        }
200
                        else
201
                        {
202
                            // offset = 0;
203
                            bFound = true;
204
                        }
205
 
206
 
207
                    }
208
 
209
                }
210
                if (!bFound && port.IsOpen)
211
                {
212
                    if (!append)
213
                    {
214
                        if (buffer[offset] != '#')
215
                            System.Diagnostics.Debug.Print(buffer[offset].ToString("X2"));
216
                        Buffer.BlockCopy(buffer, offset, messageBuffer, 0, buffer.Length - offset);
217
                        lastoffset = (buffer.Length - offset);
218
                    }
219
                    else
220
                    {
221
                        if (messageBuffer[0] != '#')
222
                            System.Diagnostics.Debug.Print(buffer[0].ToString("X2"));
223
                        Buffer.BlockCopy(buffer, offset, messageBuffer, lastoffset, buffer.Length - offset);
224
 
225
                        lastoffset += (buffer.Length - offset);
226
                    }
227
                    append = true;
228
 
229
                }
230
            }
231
            catch (Exception ex)
232
            {
233
                System.Diagnostics.Debug.Print(ex.Message);
234
            }
235
            finally
236
            {
237
                System.Threading.Monitor.Exit(oLock);
238
            }
239
 
240
 
241
        }
242
 
243
        private void btnRefresh_Click(object sender, RoutedEventArgs e)
244
        {
245
            if (!port.IsOpen)
246
            {
247
               // comboBoxPortName.Items.Clear();
248
                comboBoxPortName.ItemsSource = getPortNameValues();
249
            }
250
            else
251
                MessageBox.Show("Port has to be closed!");
252
        }
253
 
254
    }
255
 
256
}