串口发送AT指令给短信设备没有返回值
分享串口发送AT指令给短信设备没有返回值的问题:
请教一个关于串口连接短信设备发短信的问题,我看这里也有很多贴子时关于这个问题的,可是我没有我的答案,我用C#写的,打开串口后,发送“AT\r”,返回“OK”正常,但是再发送其他AT指令的话就都没有返回值了。但奇怪的是,我用超级终端打开过串口后,再在程序里打开串口,发送其他AT指令就会有正常的返回值了(例如:“AT+CGMI\r”)。请问有人知道是怎么回事吗?
回答:
我也碰到过这种问题研究了很长时间才解决,发送完号码时候要发送个特殊的内容,在超级终端里面是不用输入那个特殊的标志的
public class PortData { public event PortDataReceivedEventHandle Received; //接收事件 public event SerialErrorReceivedEventHandler Error; // 接收事件异常处理 private SerialPort port; //端口 private bool ReceiveEventFlag = false; //接收事件是否有效 false表示有效 private PDUdecoding PDU; //PDU 编码类 /// <summary> /// 构造函数 /// </summary> /// <param name="sPortName">端口名称 "com1,com2.... com255"</param> /// <param name="baudrate">波特率</param> /// <param name="parity">校验</param> /// <param name="dataBits">数据位</param> /// <param name="stopBits">停止位数</param> /// <param name="RtimeOut">读端口时间超时</param> /// <param name="WtimeOut">写端口时间超时</param> public PortData(string sPortName, int baudrate,Parity parity , int dataBits,StopBits stopBits,int RtimeOut,int WtimeOut) { port = new SerialPort(sPortName, baudrate, parity, 8, stopBits); this.PDU = new PDUdecoding(); port.RtsEnable = true; port.ReadTimeout = RtimeOut; port.WriteTimeout = WtimeOut; port.DataReceived += new SerialDataReceivedEventHandler(DataReceived); port.ErrorReceived += new SerialErrorReceivedEventHandler(ErrorEvent); this.Open(); } /// <summary> /// 析构函数 /// </summary> ~PortData() { Close(); } /// <summary> /// 打开com口 /// </summary> public void Open() { if (!port.IsOpen) { try { port.Open(); } catch(Exception ex) { throw ex; } } } /// <summary> /// 关闭com口 /// </summary> public void Close() { if (port.IsOpen) { try { port.Close(); } catch(Exception ex) { throw ex; } } } //数据发送 /// <summary> /// 暂无使用 /// </summary> /// <param name="data"></param> public void SendData(byte[] data) { if (port.IsOpen) { port.Write(data, 0, data.Length); } } /// <summary> /// 暂无使用 /// </summary> /// <param name="data"></param> /// <param name="offset"></param> /// <param name="count"></param> public void SendData(byte[] data,int offset,int count) { if (port.IsOpen) { port.Write(data, offset, count); } } /// <summary> /// 发送各种命令 /// </summary> /// <param name="Sendcmd">命令正文</param> /// <param name="ReceiveData">返回结果</param> /// <param name="Overtime">发送超时</param> /// <returns>发送标识</returns> private int SendCommand(string Sendcmd, ref string ReceiveData,int Overtime) { if (!port.IsOpen) { this.Open(); } if (port.IsOpen) { try { ReceiveEventFlag = true; //关闭接收事件 port.DiscardInBuffer(); //清空接收缓冲区 port.Write(Sendcmd); //写入命令 int num = 0, ret = 0; while (num++ < Overtime) { System.Threading.Thread.Sleep(1000); if (port.BytesToRead > 0) //存在需要读取的数据 { ret = port.BytesToRead; break; } else System.Threading.Thread.Sleep(1); //延时1毫秒 等待数据发送到端口上 } if (ret > 0) //如果要读取的数据存在 读取数据 并且 打开接收 { ReceiveData = port.ReadExisting(); //先读取再激活接收事件 ReadExecting() ReceiveEventFlag = false; //打开事件 } //如果是发送短信则休息3秒 if (ReceiveData.ToLower().Contains("cmgs:")) System.Threading.Thread.Sleep(3000); return ret; } catch (Exception ex) { throw ex; } } return -1; } /// <summary> /// 处理异常 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void ErrorEvent(object sender, SerialErrorReceivedEventArgs e) { if(Error != null) Error(sender, e); } /// <summary> /// 接收短信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void DataReceived(object sender, SerialDataReceivedEventArgs e) { //禁止接收事件时直接退出 if (ReceiveEventFlag) return; byte[] data = new byte[port.BytesToRead]; this. port.Read(data, 0, data.Length); if (Received != null) Received(sender, new PortDataReciveEventArgs(data)); } /// <summary> /// 判读 com口是不是打开的 /// </summary> /// <returns>打开 true ,否则 false</returns> public bool IsOpen() { return port.IsOpen; } /// <summary> /// 初始化 Modem /// </summary> public void Initial() { if (!this.IsOpen()) { this.Open(); } string result = ""; string all = ""; string newLine = Environment.NewLine; if (this.Check("AT" + Environment.NewLine, 100).ToLower() != "true") { this.port.Write("32"); //如果处于发送状态则强制结束 this.port.Write("AT"+Environment.NewLine); } this.SendCommand("AT+CMEE=1" + newLine, ref result, 1000); //设置报错方式 all += result; this.SendCommand("AT+CMGF=0"+newLine,ref result,500);//设置为PDU方式 all+=result ; this.SendCommand("AT+CNMI=2,2" + newLine, ref result, 500); //不接收短信,不接收小区广播方式 AT+CSMS=1,0,1,0 // AT+CNMI=2,2 设置为 all+=result ; this.SendCommand("AT+CSMP=17,167,0,8" + newLine, ref result, 500); //短信在短信中心保存24小时 all += result; this.SendCommand("AT&w"+newLine ,ref result ,500 ); //保存以上设置 all += result; if (all.Length - all.ToLower().Replace("ok", "").Length !=10) //结果中 不够 5个 ok { Exception e = new Exception("设置 ModeM出错"); throw e; } } /// <summary> /// 获得配置文件 /// </summary> /// <param name="key"></param> /// <returns></returns> /// public static string GetConfig(string key) { return ConfigurationSettings.AppSettings[key]; } /// <summary> /// 检测 短信猫 是否有信号 无信号可能说明没钱了 /// </summary> /// <param name="cmd"></param> /// <param name="time"></param> /// <returns></returns> public string Check(string cmd, int time) { string rst = ""; this.SendCommand(cmd, ref rst, 1000); if (rst.ToLower().Contains("ok")) return "true"; return rst; } /// <summary> /// 发送短息 包括超长短信 /// </summary> /// <param name="phone">接收方号码</param> /// <param name="msg">要发送的信息</param> /// <returns></returns> public int SendMessage(string phone, string msg) { int star = 0; //用于分割长短信 int last = msg.Length; //短信内容长度 string buffer = "more"; //用来标识长短信 参考参数 const int longmsg = 67; // 超长短信每条个容纳67个unicode字符 int i = 1; //用于计数发送的第几条短信 int result = 0; if (msg.Length == 0||phone .Length<11) // 如果短信长度为0 或者手机号码长度小于11返回 return 0; if (msg.Length > 70) //需要短信分页的 如果发送信息长度小于等于70则用 单条发送的方法 { string[] txt = new string[(msg.Length /67)+1]; //超长短信是67个汉字分割的,分割长几条发送 for (star = 0; star < txt.Length; star++) { txt[star] = msg.Substring(star *67, (last /67 - star) > 0 ? 67 : (last - star * 67)); //短信分页 } //以下是发送功能入口 foreach (string t in txt) { result=this.BaseSendMessage(phone, t, buffer,txt.Length,i); if (result>0) { i++; continue; } else //有一条发送失败则 返回 { //break; return result; } } return 1; //全部发送成功 } else { //单条短信发送方法入口 if (this.BaseSendMessage(phone, msg,"",0,0) > 0) //发送成功 return 1; else return 0; } } /// <summary> /// 发送短信的函数 /// </summary> /// <param name="phone">接收的号码</param> /// <param name="msg">单条发送内容</param> /// <param name="buffer">参考标识</param> /// <param name="count">长短信中共几条</param> /// <param name="index">长短信中当前是第几条</param> /// <returns>状态标志 1:发送成功 0:发送失败 2:AT+CMGS 失败 </returns> public int BaseSendMessage(string phone, string msg,string buffer,int count,int index) { string result = ""; //用于保存端口返回结果 string smg ; //用于保存编码后的发送信息 if (buffer.Length > 1) //长短信 编码后正文 smg = this.PDU.smsDecodedsms( phone, msg, count.ToString() , index.ToString() ) + "32"; else smg = this.PDU.smsDecodedsms(phone, msg) + "32"; //单条短信编码后的正文 //发送前的准备工作 if (this.Check("AT" + Environment.NewLine, 100).ToLower() != "true") { this.port.Write("32"); //如果处于发送状态则强制结束 this.port.Write("AT" + Environment.NewLine); } //发送 AT+CMGS 命令 this.SendCommand("AT+CMGS=" + this.PDU.nLength+ "\n", ref result, 1000); //+buffer.Length).ToString()+ if (result.ToLower().Contains(">")) { //短信正文发送 this.SendCommand(smg, ref result, 6000); //6秒钟的发送 时间足够 机器反应了 if (result.ToLower().Contains("ok")) { return 1; } else //正文发送失败再发送一次 { //发送 AT+CMGS 命令 this.SendCommand("AT+CMGS=" + this.PDU.nLength + "\n", ref result, 10000); //+buffer.Length).ToString()+ this.SendCommand(smg, ref result, 10000); //10秒钟的发送 时间足够 机器反应了 if (result.ToLower().Contains("ok")) { return 1; } else return 0; } }// AT+CMGS 命令失败 else { return 2; } } /// <summary> /// 检查信号 目前无效 /// </summary> /// <returns></returns> public bool CheckSingal() { string s = ""; //保存结果 if (this.Check("AT" + Environment.NewLine, 100).ToLower() != "true") { this.port.Write("32"); //如果处于发送状态则强制结束 this.port.Write("AT" + Environment.NewLine); } this.SendCommand("AT+CREG? " + Environment.NewLine, ref s, 5000); if (!s.Contains("CREG: 0,1")) // sim 没信号了 { MessageBox.Show("天线未接好,或者手机欠费了!"); return false ; } return true; } } /// <summary> /// 接收短信事件代理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public delegate void PortDataReceivedEventHandle(object sender, PortDataReciveEventArgs e); /// <summary> /// /// </summary> public class PortDataReciveEventArgs : EventArgs { /// <summary> /// /// </summary> public PortDataReciveEventArgs() { this.data = null; } /// <summary> /// /// </summary> /// <param name="data"></param> public PortDataReciveEventArgs(byte[] data) { this.data = data; } /// <summary> /// /// </summary> private byte[] data; /// <summary> /// /// </summary> public byte[] Data { get { return data; } set { data = value; } } }
回帖 ( 0 )