1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.Windows;
  7 using System.Windows.Controls;
  8 using System.Windows.Data;
  9 using System.Windows.Documents;
 10 using System.Windows.Input;
 11 using System.Windows.Media;
 12 using System.Windows.Media.Imaging;
 13 using System.Windows.Navigation;
 14 using System.Windows.Shapes;
 15 
 16 //引用串口类库
 17 using System.IO.Ports;
 18 
 19 namespace Demo_5
 20 {
 21     /// <summary>
 22     /// MainWindow.xaml 的交互逻辑
 23     /// </summary>
 24     public partial class MainWindow : Window
 25     {
 26         public delegate void showReceiveDelegate(string text); //当采用响应模式,应申明一个委托,实现不同线程的控件实验
 27 
 28         SerialPort com = new SerialPort();
 29         public MainWindow()
 30         {
 31             InitializeComponent();
 32             this.Loaded += MainWindow_Loaded;
 33         }
 34 
 35         /// <summary>
 36         /// 窗体加载事件
 37         /// </summary>
 38         /// <param name="sender"></param>
 39         /// <param name="e"></param>
 40         void MainWindow_Loaded(object sender, RoutedEventArgs e)
 41         {
 42             //获取本机所有串口的名字
 43             string[] strPortName = SerialPort.GetPortNames();
 44             //将本机所有串口名称赋值给cmbPort控件
 45             cmbPort.ItemsSource = strPortName;
 46 
 47             //下拉框初始化
 48             //如果本机串口数量不为0,则将cmbPort的Item第一个索引
 49             if (strPortName.Length > 0) cmbPort.SelectedIndex = 0;
 50             //将波特率下拉框cmbBaudRate的Item第一个索引
 51             cmbBaudRate.SelectedIndex = 0;
 52             //将数据位下拉框cmbDataBits的Item第一个索引
 53             cmbDataBits.SelectedIndex = 0;
 54             //将停止位下拉框cmbStopBits的Item第一个索引
 55             cmbStopBits.SelectedIndex = 0;
 56             //将奇偶校验下拉框cmbParity的Item第一个索引
 57             cmbParity.SelectedIndex = 0;
 58             //接收模式初始化(设置为响应模式)
 59             rbResponse.IsChecked = true;
 60         }
 61 
 62         /// <summary>
 63         /// 打开按钮点击事件
 64         /// </summary>
 65         /// <param name="sender"></param>
 66         /// <param name="e"></param>
 67         private void btnOpen_Click_1(object sender, RoutedEventArgs e)
 68         {
 69             //如果按钮内容是“打开串口”则进行打开串口否则进行关闭串口操作
 70             if (btnOpen.Content.ToString() == "打开串口")
 71             {
 72                 //尝试执行串口打开,出错则在界面进行提示
 73                 try
 74                 {
 75                     //判断串口是否已经打开
 76                     if (!com.IsOpen)
 77                     {
 78                         //设置串口参数**************************************开始
 79                         com.PortName = cmbPort.Text;//串口号
 80                         com.BaudRate = int.Parse(cmbBaudRate.Text);//波特率
 81                         com.DataBits = int.Parse(cmbDataBits.Text);//数据位
 82                         switch (cmbStopBits.SelectedIndex)//停止位
 83                         {
 84                             case 0:
 85                                 com.StopBits = StopBits.One; break;
 86                             case 1:
 87                                 com.StopBits = StopBits.Two; break;
 88                             case 2:
 89                                 com.StopBits = StopBits.OnePointFive; break;
 90                             case 3:
 91                                 com.StopBits = StopBits.None; break;
 92                         }
 93                         switch (cmbParity.SelectedIndex)//奇偶校验
 94                         {
 95                             case 0: com.Parity = Parity.None; break;
 96                             case 1: com.Parity = Parity.Odd; break;
 97                             case 2: com.Parity = Parity.Even; break;
 98                         }
 99                         //设置串口参数**************************************结束
100                         com.Open();//打开串口
101                     }
102                     //设置按钮内容为关闭串口
103                     btnOpen.Content = "关闭串口";
104                     //界面显示信息“串口已打开!”
105                     txtStatus.Text = "串口已打开!";
106                     //启用发送按钮
107                     btnSend.IsEnabled = true;
108                     //如果界面选择应答模式,则启用接收按钮
109                     if ((bool)rbAck.IsChecked)
110                         btnReceive.IsEnabled = true; //应答模式,接收按钮有效
111                 }
112                 catch
113                 { txtStatus.Text = "串口打开错误或串口不存在!"; }
114             }
115             else //关闭串口
116 
117                 try
118                 {
119                     if (com.IsOpen)
120                         com.Close(); //关闭串口
121                     btnOpen.Content = "打开串口";
122                     txtStatus.Text = "串口已关闭!";
123                     btnSend.IsEnabled = false;
124                     if ((bool)rbAck.IsChecked)
125                         btnReceive.IsEnabled = false; //应答模式,接收按钮无效
126                 }
127                 catch
128                 { txtStatus.Text = "串口关闭错误或串口不存在!"; }
129         }
130         /// <summary>
131         /// 发送按钮点击事件
132         /// </summary>
133         /// <param name="sender"></param>
134         /// <param name="e"></param>
135         private void btnSend_Click_1(object sender, RoutedEventArgs e)
136         {
137             try
138             {
139                 //发送的数据
140                 byte[] data = null;
141                 //是否16进制发送
142                 if ((bool)chkSendHex.IsChecked)
143                     data = getBytesFromString(txtSend.Text);//将数据转为16进制字符串
144                 else
145                     data = Encoding.Default.GetBytes(txtSend.Text);//将数据转为字符串
146                 //向串口写入数据
147                 com.Write(data, 0, data.Length);
148             }
149             catch (Exception err)
150             { txtStatus.Text = err.ToString(); }
151         }
152         /// <summary>
153         /// 接收按钮点击事件
154         /// </summary>
155         /// <param name="sender"></param>
156         /// <param name="e"></param>
157         private void btnReceive_Click_1(object sender, RoutedEventArgs e)
158         {
159             try
160             {
161                 //应答模式
162                 //获取串口缓冲区字节数
163                 int count = com.BytesToRead;
164                 //实例化接收串口数据的数组
165                 byte[] readBuffer = new byte[count];
166                 //从串口缓冲区读取数据
167                 com.Read(readBuffer, 0, count);
168 
169                 if ((bool)chkRecHex.IsChecked)
170                     txtReceive.Text = getStringFromBytes(readBuffer);  //转十六进制
171                 else
172                     txtReceive.Text = Encoding.Default.GetString(readBuffer);  //字母、数字、汉字转换为字符串 
173 
174             }
175             catch (Exception err)
176             { txtStatus.Text = err.ToString(); }
177         }
178  
179         /// <summary>
180         /// 响应模式
181         /// </summary>
182         /// <param name="sender"></param>
183         /// <param name="e"></param>
184         private void rbResponse_Checked_1(object sender, RoutedEventArgs e)
185         {
186             try
187             {
188                 //设置接收按钮的启用属性
189                 btnReceive.IsEnabled = (bool)rbAck.IsChecked;
190                 if ((bool)rbResponse.IsChecked)
191                     com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);  //加载接收事件
192             }
193             catch (Exception err)
194             { txtStatus.Text = err.ToString(); }
195         }
196         /// <summary>
197         /// 应答模式
198         /// </summary>
199         /// <param name="sender"></param>
200         /// <param name="e"></param>
201         private void rbAck_Checked_1(object sender, RoutedEventArgs e)
202         {
203             try
204             {
205                 btnReceive.IsEnabled = (bool)rbAck.IsChecked;
206                 if ((bool)rbAck.IsChecked)
207                     com.DataReceived -= new SerialDataReceivedEventHandler(com_DataReceived);  //移除接收事件
208             }
209             catch (Exception err)
210             { txtStatus.Text = err.ToString(); }
211         }
212         /// <summary>
213         /// 响应模式时,串口接收数据事件
214         /// </summary>
215         /// <param name="sender"></param>
216         /// <param name="e"></param>
217         private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
218         {
219             try
220             {
221                 bool RecHex = false;
222                 Dispatcher.Invoke(new Action(() =>
223                 {
224                     //获取界面控件复选框是否以16进制显示
225                     RecHex = (bool)chkRecHex.IsChecked;
226                 }));
227                 //获取串口缓冲区字节数
228                 int count = com.BytesToRead;
229                 //实例化接收串口数据的数组
230                 byte[] readBuffer = new byte[count];
231                 //从串口缓冲区读取数据
232                 com.Read(readBuffer, 0, count);
233                 string strReceive = "";
234                 if (RecHex)
235                     strReceive = getStringFromBytes(readBuffer);  //转十六进制
236                 else
237                     strReceive = Encoding.Default.GetString(readBuffer);  //字母、数字、汉字转换为字符串  
238 
239 
240                 Dispatcher.Invoke(new Action(() =>
241                 {
242                     txtReceive.Text = strReceive;
243                 }));
244 
245             }
246             catch (Exception err)
247             {
248                 Dispatcher.Invoke(new Action(() =>
249                 {
250                     txtStatus.Text = err.ToString();
251                 }));
252             }
253 
254         }
255         /// <summary>
256         /// 以十六进制数据发送转换时,显示转换对应数据
257         /// </summary>
258         /// <param name="sender"></param>
259         /// <param name="e"></param>
260         private void chkSendHex_CheckedChanged(object sender, EventArgs e)
261         {
262             try
263             {
264                 if ((bool)chkSendHex.IsChecked)
265                     txtSend.Text = getStringFromBytes(Encoding.Default.GetBytes(txtSend.Text));
266                 else
267                     txtSend.Text = Encoding.Default.GetString(getBytesFromString(txtSend.Text));
268             }
269             catch
270             { txtStatus.Text = "数据转换出错,请输入正确的数据格式"; }
271         }
272         /// <summary>
273         /// 以十六进制数据显示接收数据时,显示对应数据
274         /// </summary>
275         /// <param name="sender"></param>
276         /// <param name="e"></param>
277         private void chkRecHex_CheckedChanged(object sender, EventArgs e)
278         {
279             try
280             {
281                 if ((bool)chkRecHex.IsChecked)
282                     txtReceive.Text = getStringFromBytes(Encoding.Default.GetBytes(txtReceive.Text));
283                 else
284                     txtReceive.Text = Encoding.Default.GetString(getBytesFromString(txtReceive.Text));
285             }
286             catch
287             { txtStatus.Text = "数据转换出错,请输入正确的数据格式"; }
288         }
289 
290         /// <summary>
291         /// 把十六进制格式的字符串转换成字节数组。
292         /// </summary>
293         /// <param name="pString">要转换的十六进制格式的字符串</param>
294         /// <returns>返回字节数组。</returns>
295         public static byte[] getBytesFromString(string pString)
296         {
297             string[] str = pString.Split(' ');     //把十六进制格式的字符串按空格转换为字符串数组。
298             byte[] bytes = new byte[str.Length];     //定义字节数组并初始化,长度为字符串数组的长度。
299             for (int i = 0; i < str.Length; i++)     //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量。
300                 bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], 16));
301             return bytes;     //返回字节数组。
302         }
303 
304         /// <summary>
305         /// 把字节数组转换为十六进制格式的字符串。
306         /// </summary>
307         /// <param name="pByte">要转换的字节数组。</param>
308         /// <returns>返回十六进制格式的字符串。</returns>
309         public static string getStringFromBytes(byte[] pByte)
310         {
311             string str = "";     //定义字符串类型临时变量。
312             //遍历字节数组,把每个字节转换成十六进制字符串,不足两位前面添“0”,以空格分隔累加到字符串变量里。
313             for (int i = 0; i < pByte.Length; i++)
314                 str += (pByte[i].ToString("X").PadLeft(2, '0') + " ");
315             str = str.TrimEnd(' ');     //去掉字符串末尾的空格。
316             return str;     //返回字符串临时变量。
317         }
318     }
319 }

 

  1 package com.example.fandemonew;
  2 
  3 import com.example.demo.library.SerialPort;
  4 import com.example.demo.library.ShareData;
  5 import com.example.demo.library.ZigBeeService;
  6 import com.newland.jni.Linuxc;
  7 
  8 import android.os.Bundle;
  9 import android.app.Activity;
 10 import android.content.Intent;
 11 import android.view.Menu;
 12 import android.view.View;
 13 import android.view.View.OnClickListener;
 14 import android.widget.AdapterView;
 15 import android.widget.AdapterView.OnItemSelectedListener;
 16 import android.widget.ArrayAdapter;
 17 import android.widget.Spinner;
 18 import android.widget.Toast;
 19 
 20 public class MainActivity extends Activity {
 21 
 22     //风扇1命令
 23     private char[]  fanOpenCommand= {0xFF,0xF5,0x05,0x02,0x34,0x12,0x00,0x01,0x00}; 
 24     private char[]  fanCloseCommand= {0xFF,0xF5,0x05,0x02,0x34,0x12,0x00,0x02,0x00}; 
 25     //风扇2命令
 26     private char[]  fan2OpenCommand= {0xFF,0xF5,0x05,0x02,0x01,0x00,0x00,0x01,0x03}; 
 27     private char[]  fan2CloseCommand= {0xFF,0xF5,0x05,0x02,0x01,0x00,0x00,0x02,0x02};
 28     //控制对象
 29     private String mControlName;
 30     
 31     @Override
 32     protected void onCreate(Bundle savedInstanceState) {
 33         super.onCreate(savedInstanceState);
 34         setContentView(R.layout.activity_main);
 35         //打开串口
 36         OpenZigBee();
 37         //初始化UI
 38         initView();
 39     }
 40     
 41     //打开串口
 42     private void OpenZigBee() {
 43         //判断串门是否打开,如果打开则关闭
 44         if (ShareData.com_fdZigBee > 0)
 45             SerialPort.closePort(ShareData.com_fdZigBee);
 46         // 读取串口设置值,无线传感网默认值为0
 47         ShareData.com_fdZigBee = SerialPort.openPort(1, 0, 5);
 48         if (ShareData.com_fdZigBee == -1) {
 49             Toast.makeText(this, "串口打开失败", Toast.LENGTH_LONG).show();
 50         }
 51         //开启硬件交互服务
 52         Intent intent = new Intent(this, ZigBeeService.class);
 53         this.startService(intent);
 54     }
 55     
 56     //初始化UI
 57     private void initView(){
 58         //初始化下拉框,及填充下拉框的值
 59         String[] strs = {"请选择","风扇1","风扇2"};
 60         Spinner sp = (Spinner) findViewById(R.id.sp);
 61         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strs);
 62         sp.setAdapter(adapter);
 63         //下拉框项
 64         sp.setOnItemSelectedListener(new OnItemSelectedListener() {
 65 
 66             @Override
 67             public void onItemSelected(AdapterView<?> parent, View arg1,
 68                     int position, long arg3) {
 69                 String itemName = parent.getItemAtPosition(position).toString();
 70                 mControlName = itemName;
 71             }
 72 
 73             @Override
 74             public void onNothingSelected(AdapterView<?> arg0) {
 75                 // TODO Auto-generated method stub
 76                 
 77             }
 78         });
 79         //设置打开按钮监听
 80         findViewById(R.id.open_btn).setOnClickListener(new OnClickListener() {
 81             
 82             @Override
 83             public void onClick(View arg0) {
 84                 if("风扇1".equals(mControlName)){
 85                     sendCMD(fanOpenCommand);
 86                 }else if("风扇2".equals(mControlName)){
 87                     sendCMD(fan2OpenCommand);
 88                 }
 89             }
 90         });
 91         //设置关闭按钮监听
 92         findViewById(R.id.close_btn).setOnClickListener(new OnClickListener() {
 93             
 94             @Override
 95             public void onClick(View arg0) {
 96                 if("风扇1".equals(mControlName)){
 97                     sendCMD(fanCloseCommand);
 98                 }else if("风扇2".equals(mControlName)){
 99                     sendCMD(fan2CloseCommand);
100                 }
101             }
102         });
103     }
104     
105     //发送命令
106     private static void sendCMD(char[] cmd) {
107         String strcmd = String.valueOf(cmd);
108         Linuxc.sendMsgUartHex(ShareData.com_fdZigBee, strcmd, strcmd.length());
109     }
110 
111     @Override
112     public boolean onCreateOptionsMenu(Menu menu) {
113         // Inflate the menu; this adds items to the action bar if it is present.
114         getMenuInflater().inflate(R.menu.main, menu);
115         return true;
116     }
117 
118 }