3

I have a bar-code scanner which is connecting through RS232 serial port. I need to write a program to connect this device with the PC and transmit data. I already wrote some basic methods to initialize a communication link and tried to test by sending a BEEP command to the device but it is not beeping as expected. So I think there is something wrong with my source code. Please somebody help me complete the source code. Below is the written source code

01)DeviceRS232.h

#ifndef DEVICERS232_H
#define DEVICERS232_H

extern "C"
{
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
}

#include <string>

#define MAX_SERIAL_PORT_NO  30



class DeviceRS232
{
    public:
        DeviceRS232();
        virtual ~DeviceRS232();

        int fdRS232;                    //  file descriptor for the serial port

        void setSerialPort(std::string sp);
        void setBaudRate(long baud);
        void setDataBits(int dataBit);
        void setStopBits(int stopBit);
        void setNumberOfParityBits(int nparityBits);
        void setDefaultAttributes();
        long getBaudRate();
        std::string getSerialPort();
        int openSerialPort();
        int readUserConfiguration();
        int sendDataBuffer(const unsigned char *dataBuffer, size_t bufferSize);
        void closeSerialPort();


    protected:
        std::string serialPort;         //  Serial port like /dev/ttyS0
        long baudRate;                  //  Scanner baud rate
        int dataBits;                   //  data bits
        int stopBits;                   //  stop bits
        int numberOfParityBits;         //  number of parity bits
        termios oldSerialPortSetting;   //  Current values of termios structure for /dev/ttyS0
        termios newSerialPortSetting;   //  new termios attributes for /dev/ttyS0


    private:
};

#endif // DEVICERS232_H

2) DeviceRS232.cpp

#include "DeviceRS232.h"

DeviceRS232::DeviceRS232()
{
    //ctor
}

DeviceRS232::~DeviceRS232()
{
    //dtor
}

void DeviceRS232::setSerialPort(std::string sp)
{
    serialPort = sp;
}

void DeviceRS232::setBaudRate(long baud)
{
    baudRate = baud;
}

void DeviceRS232::setDataBits(int dataBit)
{
    dataBits = dataBit;
}

void DeviceRS232::setStopBits(int stopBit)
{
    stopBits = stopBit;
}

void DeviceRS232::setNumberOfParityBits(int nparityBits)
{
    numberOfParityBits = nparityBits;
}

void DeviceRS232::setDefaultAttributes()
{
    std::string sp = "/dev/ttyS0";
    long baud = 9600;
    int dataBit = 1;
    int stopBit = 1;
    int nparityBits = 0;

    setSerialPort(sp);
    setBaudRate(baud);
    setDataBits(dataBit);
    setStopBits(stopBit);
    setNumberOfParityBits(nparityBits);
}

long DeviceRS232::getBaudRate()
{
    return baudRate;
}

std::string DeviceRS232::getSerialPort()
{
    return serialPort;
}

int DeviceRS232::openSerialPort()
{
    int fd, baudr, status, portStatus;
    setDefaultAttributes();

    switch(getBaudRate())
    {
        case      50 : baudr = B50;
                       break;
        case      75 : baudr = B75;
                       break;
        case     110 : baudr = B110;
                       break;
        case     134 : baudr = B134;
                       break;
        case     150 : baudr = B150;
                       break;
        case     200 : baudr = B200;
                       break;
        case     300 : baudr = B300;
                       break;
        case     600 : baudr = B600;
                       break;
        case    1200 : baudr = B1200;
                       break;
        case    1800 : baudr = B1800;
                       break;
        case    2400 : baudr = B2400;
                       break;
        case    4800 : baudr = B4800;
                       break;
        case    9600 : baudr = B9600;
                       break;
        case   19200 : baudr = B19200;
                       break;
        case   38400 : baudr = B38400;
                       break;
        case   57600 : baudr = B57600;
                       break;
        case  115200 : baudr = B115200;
                       break;
        case  230400 : baudr = B230400;
                       break;
        case  460800 : baudr = B460800;
                       break;
        case  500000 : baudr = B500000;
                       break;
        case  576000 : baudr = B576000;
                       break;
        case  921600 : baudr = B921600;
                       break;
        case 1000000 : baudr = B1000000;
                       break;
        default      : printf("invalid baudrate\n");
                       return(1);
                       break;
    }

    //  Open serial port
    fd = open(getSerialPort().c_str(),  O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd == -1)
    {
        printf("Unable to open serial port...\n");
        return 1;
    }

    fdRS232 = fd;
    status = tcgetattr(fdRS232, &oldSerialPortSetting);
    if(status == -1)
    {
        close(fdRS232);
        printf("Unable to get serial port attributes...\n");
        return 1;
    }

    memset(&newSerialPortSetting, 0, sizeof(newSerialPortSetting));
    newSerialPortSetting.c_cflag = baudr | CS8 | CLOCAL | CREAD; //
    newSerialPortSetting.c_iflag = IGNPAR;
    newSerialPortSetting.c_oflag = 0;
    newSerialPortSetting.c_lflag = 0;
    newSerialPortSetting.c_cc[VMIN] = 0;
    newSerialPortSetting.c_cc[VTIME] = 0;

    status = tcsetattr(fdRS232, TCSANOW, &newSerialPortSetting);
    if(status==-1)
    {
        close(fdRS232);
        perror("unable to adjust portsettings ");
        return 1;
    }

    //  Get the status of opened serial port
    if(ioctl(fdRS232, TIOCMGET, &portStatus) == -1)
    {
        perror("Unable to get port status");
        return 1;
    }

    //  Tern on DTR and RTS
    portStatus |= TIOCM_DTR;
    portStatus |= TIOCM_RTS;

    //  Set the status of the port with new DTR, RTS values
    if(ioctl(fdRS232, TIOCMSET, &portStatus) == -1)
    {
        perror("Unable to set port status...");
        return 1;
    }

  return 0;
}

int DeviceRS232::sendDataBuffer(const unsigned char *dataBuffer, size_t bufferSize)
{
    return write(fdRS232, dataBuffer, bufferSize);
}

void DeviceRS232::closeSerialPort()
{
    int portStatus;

    if(ioctl(fdRS232, TIOCMGET, &portStatus) == -1)
    {
        perror("Unable to get the port status");
    }

    //  Tern off DTR and RTS
    portStatus &= ~TIOCM_DTR;
    portStatus &= ~TIOCM_RTS;

    //  Set the status of the port with new DTR, RTS values
    if(ioctl(fdRS232, TIOCMSET, &portStatus) == -1)
    {
        perror("Unable to set port status...");
    }

    close(fdRS232);
}

3) main.cpp

#include <iostream>
extern "C"
{
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
}
#include "DeviceRS232.h"

using namespace std;

int main()
{

    //char sendBuffer[4096] = "                        ";
    unsigned char sendBeep[] = {0x05, 0xE6, 0x04, 0x00, 0x0D, 0x00, 0x00};
    unsigned char ledOn[] = {0x05, 0xE7, 0x04, 0x00, 0x0D, 0x00};
    unsigned char val[7];

    cout << "********************** RS232 - SSI **********************" << endl << endl;
    DeviceRS232 dev_rs232;
    dev_rs232.setDefaultAttributes();
    dev_rs232.openSerialPort();

    //----------------------------------------------------
    //for(int x=0; x<10; x++)
    //{
    //    dev_rs232.sendDataBuffer(sendBeep, sizeof(sendBeep));
    //}
    //----------------------------------------------------

    int sizeSent = dev_rs232.sendDataBuffer(sendBeep, sizeof(sendBeep));
    if( sizeSent > 0)
    {
        printf("Data sent: %d...\n", sizeSent);
    }

    sleep(10);

    dev_rs232.closeSerialPort();
    cout << "*********************************************************" << endl;


    return 0;
}

unsigned char sendBeep[] = {0x05, 0xE6, 0x04, 0x00, 0x0D, 0x00, 0x00}; is written considering the bar-device's serial port communication protocol specification.

(Edited to add the output) Out put:

********************** RS232 - SSI **********************

Data sent: 7...
*********************************************************

Process returned 0 (0x0)   execution time : 10.006 s
Press ENTER to continue.

All helps and suggestions are welcome. Thanks.

Dig The Code
  • 658
  • 2
  • 15
  • 32
  • Have you tried connecting the computer's serial port to another computer [or the same computer, with a second serial port] and checking that you are at all sending data? Does your wiring use DTR/RTS? – Mats Petersson Mar 27 '14 at 08:37
  • @Mats Petersson: Actually no, I could not do it using 2 peer to peer computers because of lack of resources. Please if you can give me some hints to set-up a simulator for this. – Dig The Code Mar 27 '14 at 08:41
  • Does your computer have a USB port? If so, you could probably get a serial port that connnects to the USB, and first of all use for example minicom to "listen" to the serial port. Of course, you may want to change your code to send some readable text instead of "invisible" hex numbers like your message has now. – Mats Petersson Mar 27 '14 at 08:47
  • 1
    Can you point us to the documentation for device communication protocol so that we can verify that you are trying to send the correct data. – Shane Wealti Mar 27 '14 at 14:43
  • @Shane Wealti: Thanks for the hint to read the specification again. There is a problem with my data packet (last 2 bytes is the checksum of the message and it is equal to sum of 2's complement of the message data.). I corrected the byte structure and retried. This time it is worked. Thanks for helping. – Dig The Code Mar 28 '14 at 06:36
  • @DigTheCode : can you tell me which bar code you worked with..I just got a Motorola scanner and i am trying to understand how it is access under Linux..can you tel e which model u tried.. – Ragav Jul 31 '14 at 13:52

1 Answers1

1
#include <iostream>
extern "C"
{
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
}
#include "DeviceRS232.h"

using namespace std;

int main()
{

    unsigned char sendBuffer[4096] = "Test test test...";
    unsigned char sendBeep[] = {0x05, 0xE6, 0x04, 0x00, 0x11, 0x46, 0x00};
    unsigned char ledOn[] = {0x05, 0xE7, 0x04, 0x00, 0x0D, 0x00};
    unsigned char val[7];

    //-------------------------------------------------------------------------
    unsigned char commonBuffer[257];

    int iChecksum;
    int i;
    commonBuffer[ 1 ] = (unsigned char)0xC6;
    commonBuffer[ 2 ] = (unsigned char)0x04;
    commonBuffer[ 3 ] = (unsigned char)0x08; // Permanant Chnage
    commonBuffer[ 4 ] = (unsigned char)0x11; // Beep after setting. FF for No Beep
    commonBuffer[ 5 ] = (unsigned char)0xEE; // Decorder parameter to set (238)
    commonBuffer[ 6 ] = (unsigned char)0x01; // Value to set

    commonBuffer[ 0 ] = (unsigned char)0x07; // Length

    iChecksum = 0;
    for (i = 0; i < 7; i++)
    {
        iChecksum += commonBuffer[i];
    }

    commonBuffer[i++] = (char)(((-iChecksum) >> 8) & 0xFF); // Add Checksum into the command
    commonBuffer[i++] = (char)((-iChecksum) & 0xFF);
    //-------------------------------------------------------------------------


    cout << "********************** RS232 - SSI **********************" << endl << endl;
    DeviceRS232 dev_rs232;
    dev_rs232.setDefaultAttributes();
    dev_rs232.openSerialPort();

    //----------------------------------------------------
    //for(int x=0; x<10; x++)
    //{
    //    dev_rs232.sendDataBuffer(sendBeep, sizeof(sendBeep));
    //}
    //----------------------------------------------------

    int sizeSent = dev_rs232.sendDataBuffer(commonBuffer, sizeof(commonBuffer));
    if( sizeSent > 0)
    {
        printf("Data sent: %d...\n", sizeSent);
    }

    sleep(1);

    dev_rs232.closeSerialPort();
    cout << "*********************************************************" << endl;


    return 0;
}
Dig The Code
  • 658
  • 2
  • 15
  • 32