当前位置: 代码迷 >> QT开发 >> GSM发短信失败,是怎么回事呢?串口初始化部分没有关问题,是不是AT指令没有定义对?附部分程序,请高手指正啊小妹感激不尽了
  详细解决方案

GSM发短信失败,是怎么回事呢?串口初始化部分没有关问题,是不是AT指令没有定义对?附部分程序,请高手指正啊小妹感激不尽了

热度:374   发布时间:2016-04-25 02:59:33.0
GSM发短信失败,是咋回事呢?串口初始化部分没问题,是不是AT指令没有定义对?附部分程序,请高手指正啊,小妹感激不尽了

------解决思路----------------------
可能原因,
1. 大家对GSM不熟悉,不好回答
2. 你贴的图片不是文字,很多人的浏览器会直接过滤掉图片(比如我),从而看不到



题外:

char *s = a_q_string.toLatin1().data();
这种用法在 C++ 中,是错误的

------解决思路----------------------
发送短信是以字节"0x1a"结束,你的strEnd写法有问题。还有你可以讲GSM模块的返回打印出来,你这种不判断返回的,出错的概率会很大。调试GSM模块其实很简单,就是串口的简单应用,给串口发数据。处理串口返回的数据即可。
------解决思路----------------------
#include "gprs_msg.h"
#include "ui_gprs_msg.h"
#include <QTextCodec>  //添加头文件
#include <QChar>
#include<string.h>
#include<QDebug>
#include <QTimer>
gprs_msg::gprs_msg(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::gprs_msg)
{
    ui->setupUi(this);

}

gprs_msg::~gprs_msg()
{
    myCom->close();
    //readTimer->stop();
    delete ui;
}


/// <summary>
/// 针对国内短信编码(USC2)
/// </summary>




/// <summary>
/// 奇偶互换并补F
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
QString  gprs_msg::ParityChange(QString value)
{
    QString result ="";
    int length = value.length();
    for (int i = 1; i < length; i += 2)//奇偶互换
    {
        result += value[i];
        result += value[i - 1];
    }

    if (!(length % 2 == 0))//不是偶数则加上F,与最后一位互换
    {
        result += 'F';
        result += value[length - 1];
    }
    return result;
}

/// <summary>
/// 短信内容编码
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <remarks>
/// 采用Big-Endian 字节顺序的 Unicode 格式编码,将高低位互换
/// 将转换后的短信内容存进字节数组
/// 去掉在进行Unicode格式编码中,两个字节中的"-",例如:00-21,变成0021
/// 将整条短信内容的长度除2,保留两位16进制数
/// </remarks>

QString gprs_msg::EncodeingAddLength(QString value)
{
    QString result="";
    QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
    result = tr(value.toStdString().c_str());

    result=stringToUnicode(result);

    QString sHex=get_length(result);


    result = QString("%1%2").arg(sHex).arg(result);
    qDebug("content:");
    qDebug()<<result;
    return result;
}

/// <summary>
/// 短信中心号码编码
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
QString gprs_msg::DecodingCenter(QString phone)
{
    QString result = "";
    result = ParityChange(phone);

    result ="91"+result;

    QString sHex=get_length(result);

    result = QString("%1%2").arg(sHex).arg(result);
    qDebug("center:");
    qDebug()<<result;
    return result;
}

/// <summary>
/// 接收短信手机号码编码
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
QString gprs_msg::DecodingPhone(QString phone)
{
    QString result ="";

    if (NULL== phone 
------解决思路----------------------
 0 == phone.length())
    {
        return result;
    }

    if ('+' == phone[0])
    {
        phone = phone.remove(0,1);
    }

    if (!(phone.left(2)== "86"))//补86
    {
        phone="86"+phone;
    }

    result=ParityChange(phone);
    qDebug("phone:");
    qDebug()<<result;
    return result;

}

/// <summary>
/// 整个短信的编码
/// </summary>
/// <param name="center"></param>
/// <param name="phone"></param>
/// <param name="content"></param>
/// <param name="length">要发送内容的长度,由两部分组成,接收手机号加上要发送的内容</param>
/// <returns></returns>
QString gprs_msg::EncodingSMS(QString center, QString phone, QString content)
{
    center = DecodingCenter(center);
    QString result =center+"11000D91"+DecodingPhone(phone)+"000800"+EncodeingAddLength(content);
    return result;
}

/// <summary>
/// 超长短信
/// </summary>
/// <param name="center"></param>
/// <param name="phone"></param>
/// <param name="content"></param>
/// <param name="count"></param>
/// <param name="i"></param>
/// <param name="length"></param>
/// <returns></returns>
///
QString gprs_msg::EncodingSMS(QString center, QString phone, QString content,int count,int i)
{
    if (content.length()<=MAX_CHAR_COUNT)
    {
        return EncodingSMS(center, phone, content);
    }
    else
    {




        QString cotext=content.mid(i * (MAX_CHAR_COUNT),(i+1)*MAX_CHAR_COUNT);
//        center = DecodingCenter(center);
//      cotext = EncodeingAddLength( cotext).remove(0,2);

//       QString result = "";

//       int len=(content.length()+12)/2;  //内容长度
//     result=center+"51000D91"+DecodingPhone(phone)+"000800"+tosting_hex(len)+"05000300"+tosting_hex(count)+tosting_hex(i+1)+cotext;

//       return result;
        return EncodingSMS(center, phone, cotext);

    }
}

QString gprs_msg::tosting_hex(int len)
{
    QString sHex;
    sHex.setNum(len,16);

    if(sHex.length()==1)
    {
        sHex="0"+sHex;
    }
    if(sHex.length()>2)
    {
        sHex=sHex.right(2);
    }
    return  sHex;

}

QString gprs_msg::stringToUnicode(QString str)
{
    // 这里传来的字符串一定要加tr,main函数里可以加 QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
    //  例如:str=tr("你好");
    const QChar *q;

    QChar qtmp;

    QString str0, strout;

    int num;

    q=str.unicode();

    int len=str.count();

    for(int i=0;i<len;i++)

    {
        qtmp =(QChar)*q++;

        num= qtmp.unicode();

        if(num<255)

            strout+="00"; //英文或数字前加"00"

        str0=str0.setNum(num,16);//变成十六进制数

        strout+=str0;
    }
    return strout;
}


QString gprs_msg::get_length(QString value)
{
    int len=value.length()/2;  //内容长度
    QString sHex;
    sHex.setNum(len,16);

    if(sHex.length()==1)
    {
        sHex="0"+sHex;
    }
    if(sHex.length()>2)
    {
        sHex=sHex.right(2);
    }
    return sHex;
}

void gprs_msg::on_send_msg_clicked()
{
    openSerialPort();
    format_msg();
    send_length_and_context();
}
void gprs_msg::openSerialPort()
{
    struct PortSettings ComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,10}; //定义一个结构体,用来存放串口各个参数

    myCom = new Posix_QextSerialPort("/dev/ttySAC3",ComSetting,QextSerialBase::Polling);
    myCom->open(QIODevice::ReadWrite);  //以读写方式打开串口
    //    myCom = new Posix_QextSerialPort("/dev/ttySAC3",QextSerialBase::Polling);//新建串口名字为/dev/ttySAC2
    //     myCom->open(QIODevice::ReadWrite);  //以读写方式打开串口
    //     myCom->setBaudRate(BAUD9600);  //设置波特率为9600
    //     myCom->setDataBits(DATA_8);   //数据位为8
    //     myCom->setParity(PAR_NONE);    //无奇偶校验
    //     myCom->setStopBits(STOP_1);    //1个停止位
    //     myCom->setFlowControl(FLOW_OFF);  //无数据流控制
    //     myCom->setTimeout(10);  //设置延时为10ms


    //    readTimer = new QTimer(this);
    //    connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));
    //    readTimer->start(1000);
    //    QByteArray temp="ssss";
    //    myCom->write(temp);
    myCom->close();
    sleep(1);
    myCom->open(QIODevice::ReadWrite);

}

void gprs_msg::format_msg()
{
    QString s;
    QByteArray temp;
    QString qStrCmd= tr("AT\r");
    qDebug()<<qStrCmd;
    myCom->write(qStrCmd.toAscii());

    qDebug("at read:");
    sleep(2);
    temp = myCom->readAll();
    s.prepend(temp);
    qDebug()<<s;

    qStrCmd= tr("AT+CMGF=0\r");
    myCom->write(qStrCmd.toAscii());
    qDebug()<<qStrCmd;
    qDebug("format read:");
    sleep(3);
    temp = myCom->readAll();
    s.prepend(temp);
    qDebug()<<s;
}

void gprs_msg::send_length_and_context()
{
    QString s;
    QString context;

    QString center=ui->center_line->text();

    QString phone=ui->phone_line->text();

    QString content=ui->lineEdit->text();
    //        ,int count,int i,  QString length
    // QString context=EncodingSMS(center,phone,content);

    int count=0;
    int i=0;
    int leng=content.length();
    count=((leng-1)/MAX_CHAR_COUNT)+1;
    for(i=0;i<count;i++)
    {

        context=EncodingSMS(center, phone, content,count,i);
        int iLength=strlen(context.toStdString().c_str())/2;
        QString qStrCmd=tr("AT+CMGS=%1\r").arg(iLength-9);
        myCom->write(qStrCmd.toAscii());
        qDebug()<<qStrCmd;

        sleep(5);

        QByteArray temp = myCom->readAll();
        s.prepend(temp);
        qDebug("length read:");
        qDebug()<<s;

        qStrCmd=tr("%1").arg(context);
        myCom->write(qStrCmd.toAscii());
        qDebug()<<qStrCmd;
        char stp=0x1a;
        qStrCmd.append(stp);
        myCom->write(qStrCmd.toAscii());


        sleep(10);
        temp = myCom->readAll();
        s.prepend(temp);
        qDebug("content read:");
        qDebug()<<s;
    }
}

// void  gprs_msg::readMyCom()  //读取串口
//{
//      QByteArray temp = myCom->readAll();//读取缓冲区
//      QString ts=QString(temp);
//     qDebug()<<ts;
// }

#ifndef GPRS_MSG_H
#define GPRS_MSG_H

#include <QDialog>
#include"posix_qextserialport.h"
#include"qextserialbase.h"
#include <QTimer>
namespace Ui {
class gprs_msg;
}

#define  MAX_CHAR_COUNT 30//最长可发送汉字个数
class gprs_msg : public QDialog
{
    Q_OBJECT

public:
    explicit gprs_msg(QWidget *parent = 0);
    ~gprs_msg();
     QString EncodingOther(QString content);
     QString EncodingSMS(QString center, QString phone, QString content,int count,int i);
     Posix_QextSerialPort *myCom;
    //QTimer *readTimer;


private slots:
     void on_send_msg_clicked();
     // void readMyCom();   //读取串口

private:
    Ui::gprs_msg *ui;
     QString ParityChange(QString value);
    int Asc(char item);
    QString EncodeingAddLength(QString value);
    QString DecodingCenter(QString phone);
    QString DecodingPhone(QString phone);
    QString EncodingSMS(QString center, QString phone, QString content);
    int GetMaxEncodeCharCount();
    QString stringToUnicode(QString str);
    QString get_length(QString value);
    void openSerialPort();
    void format_msg();
    void send_length_and_context();
    QString tosting_hex(int len);
};

#endif // GPRS_MSG_H

给你段代码做参考,我调试通过了的
------解决思路----------------------
经验之谈,延时很重要
------解决思路----------------------
之前有用过一个GS1011的模块也是串口的,我记得命令不用自己加end的吧,默认就是0D 0A,另外数据段应该不是这么写的吧,肯定有固定格式的吧,比如头<ECS> 之类的,不然模块如何识别。另外建议你开一个线程去读串口的返回值,看看指令有没有写成功。可以在写指令之后调用waitforsignalObject()来实现等待,建议不要固定写延时,因为各个指令耗时还是有区别的。个人意见
------解决思路----------------------
1、短信设备一般都带有发送程序、COM组件、示例的。 
2、设备有USB接口、COM接口的。如果是COM接口,建议你找个软件AccessPort监控一个,看看测试程序发送的数据和你自己发送的区别就清楚问题在哪。
  相关解决方案