首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过串口打印收据(RS-232)

通过串口打印收据(RS-232)
EN

Stack Overflow用户
提问于 2015-06-24 12:12:26
回答 1查看 840关注 0票数 0

我想编写一个c++程序(windows应用程序)来打印从服务器(通过websocket)到本地连接(通过rs-232)收据打印机(NCR 7197 rev 1.0)的收据。我把websocket连接和串行句柄都准备好了。

我的问题是,我找不到任何例子来指导我的印刷过程,甚至如何开始。我的意思是,在开始将“文档”传递给打印机之前,是否必须编写一些字节或读取任何字节,或者是否需要编写任何配置字节或其他任何内容。

如果有人对从哪里开始有任何建议,或者最好是在c++中有任何例子,我会感激的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-19 21:13:45

当我清理旧的项目文件夹时,我偶然发现了我开发出来的解决方案。看到关于这个问题的数百种观点,我想贴出一个答案。这是我的解决方案,但可能已经过时了:

通过COM端口连接到设备的函数:

代码语言:javascript
复制
//  Serial port connection handle connect method
HANDLE connect_h(wchar_t* s_port, int s_flowcontrol, int s_baudrate, int s_bytesize, int s_stopbits, int s_parity) {
    wchar_t* port = s_port;

    std::wstring ws(port);
    std::string port_w(ws.begin(), ws.end());

    //  Open serial port
    HANDLE hSerial;
    hSerial = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if(hSerial == INVALID_HANDLE_VALUE) {
        if(GetLastError() == ERROR_FILE_NOT_FOUND) {
            //  Serial port does not exist. Inform user.
            std::cout << "Error: Serial port does not exists. Port: " << std::endl;

        }
        //  Some other error occurred. Inform user.
        std::cout << "Error: Cannot connect to port: " + port_w << std::endl;
        std::cout << "Error code: " + GetLastError() << std::endl;

    }

    //  Do some basic settings
    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    if(!GetCommState(hSerial, &dcbSerialParams)) {
        //  Error getting state
        std::cout << "Error: Cannot get port state. Port: " + port_w << std::endl;
        std::cout << "Error code: " + GetLastError() << std::endl;

    }
    dcbSerialParams.BaudRate = s_baudrate;
    dcbSerialParams.ByteSize = s_bytesize;
    dcbSerialParams.StopBits = s_stopbits;
    dcbSerialParams.Parity = s_parity;

    //  If flowcontrol set to XON/XOFF
    if(s_flowcontrol == 1) {
        dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE;
        dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
        dcbSerialParams.fOutX = true;
        dcbSerialParams.fInX = true;

        dcbSerialParams.XonChar = 0x11;
        dcbSerialParams.XoffChar = 0x16;

    }

    if(!SetCommState(hSerial, &dcbSerialParams)) {
        //  error setting serial port state
        std::cout << "Error: Cannot set port state. Port: " + port_w << std::endl;
        std::cout << "Error code: " + GetLastError() << std::endl;

    }

    //  Set timeouts
    COMMTIMEOUTS timeouts = { 0 };
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;
    if (!SetCommTimeouts(hSerial, &timeouts)) {
        //  Error occureed. Inform user
        std::cout << "Error: Cannot set port timeouts. Port: " + port_w << std::endl;
        std::cout << "Error code: " + GetLastError() << std::endl;

    }

    return hSerial;

}

关闭串口连接:

代码语言:javascript
复制
//  Serial port connection handle close method
void close_h(const HANDLE &hSerial) {
    CloseHandle(hSerial);

}

通过连接的COM端口打印的函数:

代码语言:javascript
复制
//  Printing recipe via serial port handle
std::string set_print(const HANDLE &hSerial, std::string &document) {
    std::string result = "";
    std::string printable = "";

    //  Format flags
    bool _bold_flag = false;
    bool _underline_flag = false;
    bool _italic_flag = false;

    //  Process document for printing
    for(int i = 0; i < (int)document.length(); ++i) {
        if(document[i] == '\\') {
            switch (document[i + 1]) {
                //  new line
                case 'n':
                    printable.push_back((char)(0x0A));
                    i++;

                    break;

                //  underline format begin/end
                case 'u':
                    if(!_underline_flag) {
                        printable.push_back((char)(0x1B));
                        printable.push_back((char)(0x2D));
                        printable.push_back('1');
                        _underline_flag = true;

                    }
                    else {
                        printable.push_back((char)(0x1B));
                        printable.push_back((char)(0x2D));
                        printable.push_back('0');
                        _underline_flag = false;

                    }

                    i++;

                    break;

                //  bold format begin/end
                case 'b':
                    if (!_bold_flag) {
                        printable.push_back((char)(0x1B));
                        printable.push_back((char)(0x47));
                        printable.push_back('1');
                        _bold_flag = true;

                    }
                    else {
                        printable.push_back((char)(0x1B));
                        printable.push_back((char)(0x47));
                        printable.push_back('0');
                        _bold_flag = false;

                    }

                    i++;

                    break;

                //  italic format begin/end
                case 'i':
                    if (!_italic_flag) {
                        printable.push_back((char)(0x1B));
                        printable.push_back((char)(0x49));
                        printable.push_back('1');
                        _italic_flag = true;

                    }
                    else {
                        printable.push_back((char)(0x1B));
                        printable.push_back((char)(0x49));
                        printable.push_back('0');
                        _italic_flag = false;

                    }

                    i++;

                    break;

                //  if not recognized
                default:
                    printable.push_back(document[i]);

                    break;

            }

        }
        else {
            printable.push_back(document[i]);

        }

    }
    //  Additional push
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    printable.push_back((char)(0x0A));
    //  Add EOF bytes
    printable.push_back((char)(0x03));
    printable.push_back((char)(0x04));
    //  Add knife cut command
    printable.push_back((char)(0x19));
    printable.push_back((char)(0x1B));
    printable.push_back((char)(0x76));

    //  Convert to hexadecimal
    int* hex_print = new int[printable.length()];
    for(int i = 0; i < (int)printable.length(); ++i) {
        hex_print[i] = (int)printable[i];

    }

    //  Print
    for(int i = 0; i < (int)printable.length(); ++i) {
        int rq[1] = { hex_print[i] };
        DWORD rqBytesWritten = 0;
        if(!WriteFile(hSerial, rq, 1, &rqBytesWritten, NULL)) {
            //  error occurred. Report to user.
            std::cout << "Error: Can't write byte. written: " + rqBytesWritten << std::endl;

        }
    }

    //  return status
    return result;

}

以及测试主要功能,以演示这些功能的用法:

代码语言:javascript
复制
// MAIN()
int main(int argc, char* argv[]) {
    //  Create connection on COM port 1
    HANDLE sh_printer = connect_h(L"COM1", 0, 38400);

    //  Print a string povided in first argument
    set_print(sh_printer, args[1]);

    //  Close the COM port connection
    close_h(sh_printer);

    return 0; 

}

我希望我能对任何一个人有所帮助,他们厌倦了用这种古老的方式打印收据。:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31026219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档