using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; //引用串口类库
using System.IO.Ports; namespace Demo_5
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public delegate void showReceiveDelegate(string text); //当采用响应模式,应申明一个委托,实现不同线程的控件实验 SerialPort com = new SerialPort();
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
} /// <summary>
/// 窗体加载事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//获取本机所有串口的名字
string[] strPortName = SerialPort.GetPortNames();
//将本机所有串口名称赋值给cmbPort控件
cmbPort.ItemsSource = strPortName; //下拉框初始化
//如果本机串口数量不为0,则将cmbPort的Item第一个索引
if (strPortName.Length > ) cmbPort.SelectedIndex = ;
//将波特率下拉框cmbBaudRate的Item第一个索引
cmbBaudRate.SelectedIndex = ;
//将数据位下拉框cmbDataBits的Item第一个索引
cmbDataBits.SelectedIndex = ;
//将停止位下拉框cmbStopBits的Item第一个索引
cmbStopBits.SelectedIndex = ;
//将奇偶校验下拉框cmbParity的Item第一个索引
cmbParity.SelectedIndex = ;
//接收模式初始化(设置为响应模式)
rbResponse.IsChecked = true;
} /// <summary>
/// 打开按钮点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpen_Click_1(object sender, RoutedEventArgs e)
{
//如果按钮内容是“打开串口”则进行打开串口否则进行关闭串口操作
if (btnOpen.Content.ToString() == "打开串口")
{
//尝试执行串口打开,出错则在界面进行提示
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);//数据位

switch (cmbStopBits.SelectedIndex)//停止位
{
case :
com.StopBits = StopBits.One; break;
case :
com.StopBits = StopBits.Two; break;
case :
com.StopBits = StopBits.OnePointFive; break;
case :
com.StopBits = StopBits.None; break;
}
switch (cmbParity.SelectedIndex)//奇偶校验
{
case : com.Parity = Parity.None; break;
case : com.Parity = Parity.Odd; break;
case : com.Parity = Parity.Even; break;
}
//设置串口参数**************************************结束
com.Open();//打开串口
101 }
//设置按钮内容为关闭串口
btnOpen.Content = "关闭串口";
//界面显示信息“串口已打开!”
txtStatus.Text = "串口已打开!";
//启用发送按钮
btnSend.IsEnabled = true;
//如果界面选择应答模式,则启用接收按钮
if ((bool)rbAck.IsChecked)
btnReceive.IsEnabled = true; //应答模式,接收按钮有效
}
catch
{ txtStatus.Text = "串口打开错误或串口不存在!"; }
}
else //关闭串口 117 try
118 {
119 if (com.IsOpen)
120 com.Close(); //关闭串口
121 btnOpen.Content = "打开串口";
txtStatus.Text = "串口已关闭!";
btnSend.IsEnabled = false;
if ((bool)rbAck.IsChecked)
btnReceive.IsEnabled = false; //应答模式,接收按钮无效
}
catch
{ txtStatus.Text = "串口关闭错误或串口不存在!"; }
}
/// <summary>
/// 发送按钮点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click_1(object sender, RoutedEventArgs e)
{
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);
}
catch (Exception err)
{ txtStatus.Text = err.ToString(); }
}
/// <summary>
/// 接收按钮点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnReceive_Click_1(object sender, RoutedEventArgs e)
{
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(); }
} /// <summary>
/// 响应模式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rbResponse_Checked_1(object sender, RoutedEventArgs e)
{
try
{
//设置接收按钮的启用属性
btnReceive.IsEnabled = (bool)rbAck.IsChecked;
if ((bool)rbResponse.IsChecked)
com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived); //加载接收事件
}
catch (Exception err)
{ txtStatus.Text = err.ToString(); }
}
/// <summary>
/// 应答模式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rbAck_Checked_1(object sender, RoutedEventArgs e)
{
try
{
btnReceive.IsEnabled = (bool)rbAck.IsChecked;
if ((bool)rbAck.IsChecked)
com.DataReceived -= new SerialDataReceivedEventHandler(com_DataReceived); //移除接收事件
}
catch (Exception err)
{ txtStatus.Text = err.ToString(); }
}
/// <summary>
/// 响应模式时,串口接收数据事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
bool RecHex = false;
Dispatcher.Invoke(new Action(() =>
{
//获取界面控件复选框是否以16进制显示
RecHex = (bool)chkRecHex.IsChecked;
}));
//获取串口缓冲区字节数
int count = com.BytesToRead;
//实例化接收串口数据的数组
byte[] readBuffer = new byte[count];
//从串口缓冲区读取数据
com.Read(readBuffer, , count);
string strReceive = "";
if (RecHex)
strReceive = getStringFromBytes(readBuffer); //转十六进制
else
strReceive = Encoding.Default.GetString(readBuffer); //字母、数字、汉字转换为字符串 Dispatcher.Invoke(new Action(() =>
{
txtReceive.Text = strReceive;
})); }
catch (Exception err)
{
Dispatcher.Invoke(new Action(() =>
{
txtStatus.Text = err.ToString();
}));
} }
/// <summary>
/// 以十六进制数据发送转换时,显示转换对应数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void chkSendHex_CheckedChanged(object sender, EventArgs e)
{
try
{
if ((bool)chkSendHex.IsChecked)
txtSend.Text = getStringFromBytes(Encoding.Default.GetBytes(txtSend.Text));
else
txtSend.Text = Encoding.Default.GetString(getBytesFromString(txtSend.Text));
}
catch
{ txtStatus.Text = "数据转换出错,请输入正确的数据格式"; }
}
/// <summary>
/// 以十六进制数据显示接收数据时,显示对应数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void chkRecHex_CheckedChanged(object sender, EventArgs e)
{
try
{
if ((bool)chkRecHex.IsChecked)
txtReceive.Text = getStringFromBytes(Encoding.Default.GetBytes(txtReceive.Text));
else
txtReceive.Text = Encoding.Default.GetString(getBytesFromString(txtReceive.Text));
}
catch
{ txtStatus.Text = "数据转换出错,请输入正确的数据格式"; }
} /// <summary>
/// 把十六进制格式的字符串转换成字节数组。
/// </summary>
/// <param name="pString">要转换的十六进制格式的字符串</param>
/// <returns>返回字节数组。</returns>
public static byte[] getBytesFromString(string pString)
{
string[] str = pString.Split(' '); //把十六进制格式的字符串按空格转换为字符串数组。
byte[] bytes = new byte[str.Length]; //定义字节数组并初始化,长度为字符串数组的长度。
for (int i = ; i < str.Length; i++) //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量。
bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], ));
return bytes; //返回字节数组。
} /// <summary>
/// 把字节数组转换为十六进制格式的字符串。
/// </summary>
/// <param name="pByte">要转换的字节数组。</param>
/// <returns>返回十六进制格式的字符串。</returns>
public static string getStringFromBytes(byte[] pByte)
{
string str = ""; //定义字符串类型临时变量。
//遍历字节数组,把每个字节转换成十六进制字符串,不足两位前面添“0”,以空格分隔累加到字符串变量里。
for (int i = ; i < pByte.Length; i++)
str += (pByte[i].ToString("X").PadLeft(, '') + " ");
str = str.TrimEnd(' '); //去掉字符串末尾的空格。
return str; //返回字符串临时变量。
}
}
}
 package com.example.fandemonew;

 import com.example.demo.library.SerialPort;
import com.example.demo.library.ShareData;
import com.example.demo.library.ZigBeeService;
import com.newland.jni.Linuxc; import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast; public class MainActivity extends Activity { //风扇1命令
private char[] fanOpenCommand= {0xFF,0xF5,0x05,0x02,0x34,0x12,0x00,0x01,0x00};
private char[] fanCloseCommand= {0xFF,0xF5,0x05,0x02,0x34,0x12,0x00,0x02,0x00};
//风扇2命令
private char[] fan2OpenCommand= {0xFF,0xF5,0x05,0x02,0x01,0x00,0x00,0x01,0x03};
private char[] fan2CloseCommand= {0xFF,0xF5,0x05,0x02,0x01,0x00,0x00,0x02,0x02};
//控制对象
private String mControlName; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//打开串口
OpenZigBee();
//初始化UI
initView();
} //打开串口
private void OpenZigBee() {
//判断串门是否打开,如果打开则关闭
if (ShareData.com_fdZigBee > )
SerialPort.closePort(ShareData.com_fdZigBee);
// 读取串口设置值,无线传感网默认值为0
ShareData.com_fdZigBee = SerialPort.openPort(, , );
if (ShareData.com_fdZigBee == -) {
Toast.makeText(this, "串口打开失败", Toast.LENGTH_LONG).show();
}
//开启硬件交互服务
Intent intent = new Intent(this, ZigBeeService.class);
this.startService(intent);
} //初始化UI
private void initView(){
//初始化下拉框,及填充下拉框的值
String[] strs = {"请选择","风扇1","风扇2"};
Spinner sp = (Spinner) findViewById(R.id.sp);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strs);
sp.setAdapter(adapter);
//下拉框项
sp.setOnItemSelectedListener(new OnItemSelectedListener() { @Override
public void onItemSelected(AdapterView<?> parent, View arg1,
int position, long arg3) {
String itemName = parent.getItemAtPosition(position).toString();
mControlName = itemName;
} @Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub }
});
//设置打开按钮监听
findViewById(R.id.open_btn).setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
if("风扇1".equals(mControlName)){
sendCMD(fanOpenCommand);
}else if("风扇2".equals(mControlName)){
sendCMD(fan2OpenCommand);
}
}
});
//设置关闭按钮监听
findViewById(R.id.close_btn).setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
if("风扇1".equals(mControlName)){
sendCMD(fanCloseCommand);
}else if("风扇2".equals(mControlName)){
sendCMD(fan2CloseCommand);
}
}
});
} //发送命令
private static void sendCMD(char[] cmd) {
String strcmd = String.valueOf(cmd);
Linuxc.sendMsgUartHex(ShareData.com_fdZigBee, strcmd, strcmd.length());
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
04-16 04:50