0

Below is my code. I want to send hex values and get the output as hex in the hyper terminal. I am not sure how to send it.

I am getting some garbage values in the hyperterminal output. It is reading but not sending the hex output.

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdint.h>
#define    BUFFERLENGTH 256


int main(void)
{
    HANDLE hComm;                          // Handle to the Serial port
    char ComPortName[] = "\\\\.\\COM6"; // Name of the Serial port(May Change) to be opened,
    BOOL   Status;
    DWORD dwEventMask;                     // Event mask to trigger
    unsigned char TempChar;             // Temperory Character
    char  SerialBuffer[256];               // Buffer Containing Rxed Data
    DWORD NoBytesRead;                     // Bytes read by ReadFile()
    int i = 0;


    printf("\n\n +==========================================+");
    printf("\n |  Serial Communication (Win32 API)         |");
    printf("\n +==========================================+\n");
    /*----------------------------------- Opening the Serial Port --------------------------------------------*/

    hComm = CreateFile(ComPortName,                       // Name of the Port to be Opened
        GENERIC_READ | GENERIC_WRITE,      // Read/Write Access
        0,                                 // No Sharing, ports cant be shared
        NULL,                              // No Security
        OPEN_EXISTING,                     // Open existing port only
        0,                                 // Non Overlapped I/O
        NULL);                             // Null for Comm Devices

    if (hComm == INVALID_HANDLE_VALUE)
        printf("\n   Error! - Port %s can't be opened", ComPortName);
    else
        printf("\n   Port %s Opened\n ", ComPortName);


    /*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/

    DCB dcbSerialParams = { 0 };                        // Initializing DCB structure
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    Status = GetCommState(hComm, &dcbSerialParams);     //retreives  the current settings

    if (Status == FALSE)
        printf("\n   Error! in GetCommState()");

    dcbSerialParams.BaudRate = CBR_9600;      // Setting BaudRate = 9600
    dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
    dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
    dcbSerialParams.Parity = EVENPARITY;      // Setting Parity = None 

    Status = SetCommState(hComm, &dcbSerialParams);  //Configuring the port according to settings in DCB 

    if (Status == FALSE)
    {
        printf("\n   Error! in Setting DCB Structure");
    }
    else
    {
        printf("\n   Setting DCB Structure Successfull\n");
        printf("\n       Baudrate = %d", dcbSerialParams.BaudRate);
        printf("\n       ByteSize = %d", dcbSerialParams.ByteSize);
        printf("\n       StopBits = %d", dcbSerialParams.StopBits);
        printf("\n       Parity   = %d", dcbSerialParams.Parity);
    }

    /*------------------------------------ Setting Timeouts --------------------------------------------------*/

    while (1)
    {

        COMMTIMEOUTS timeouts = { 0 };

        timeouts.ReadIntervalTimeout = 5000;
        timeouts.ReadTotalTimeoutConstant = 5000;
        timeouts.ReadTotalTimeoutMultiplier = 1000;
        timeouts.WriteTotalTimeoutConstant = 5000;
        timeouts.WriteTotalTimeoutMultiplier = 1000;

        if (SetCommTimeouts(hComm, &timeouts) == FALSE)
            printf("\n   Error! in Setting Time Outs");
        else
            printf("\n\n   Setting Serial Port Timeouts Successfull");

        printf("\n |---------  Serial Communication (Win32 API) --------|");

        printf("Starting to write......");

        //char   lpBuffer[] = "ABC";               // lpBuffer should be  char or byte array, otherwise write wil fail

        uint8_t message[15];
        message[0] = 0x16;
        message[1] = 0x16;
        message[2] = 0x02;
        message[3] = 0x01;
        message[4] = 0x07;
        message[5] = 0x08;
        message[6] = 0x00;
        message[7] = 0xFF;
        message[8] = 0xFF;
        message[9] = 0x01;
        message[10] = 0x00;
        message[11] = 0x01;
        message[12] = 0x00;
        message[13] = 0xFF;
        message[14] = 0xFF;

        //byte(bytestosend)[15] = { message[0], message[1], message[2], message[3], message[4], message[5], message[6], message[7], message[8], message[9],message[10], message[11],message[12], message[13], message[14] };

        DWORD  dNoOFBytestoWrite;              // No of bytes to write into the port
        DWORD  dNoOfBytesWritten = 0;          // No of bytes written to the port

        dNoOFBytestoWrite = sizeof(message); // Calculating the no of bytes to write into the port
        Status = WriteFile(hComm,               // Handle to the Serialport
            message,            // Data to be written to the port 
            dNoOFBytestoWrite,   // No of bytes to write into the port
            &dNoOfBytesWritten,  // No of bytes written to the port
            NULL);

        if (Status == TRUE)
            printf("\n\n    %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X- Written to %s", message[0], int(message[1]), int(message[2]), int(message[3]), int(message[4]), int(message[5]), int(message[6]), int(message[7]), int(message[8]), int(message[9]), int(message[10]), int(message[11]), int(message[12]), int(message[13]), int(message[14]), ComPortName);
        else
            printf("\n\n   Error %d in Writing to Serial Port", GetLastError());


        int k;
        for (k = 0; k < 50; k++)
        {
            printf("");
        }


        /*-----------------------------------Read --------------------------------------------*/


        int l;
        for (l = 0; l < 50; l++)
        {
            printf("");
        }


        printf("\n\n    Waiting for Data Reception");
        dwEventMask = 1;

        //Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received

        /*-------------------------- Program will Wait here till a Character is received ------------------------*/

        if (Status == FALSE)
        {
            printf("\n    Error! in Setting WaitCommEvent()");
        }
        else //If  WaitCommEvent()==True Read the RXed data using ReadFile();
        {
            printf("\n\n    Characters Received");

            do
            {
                //byte(TempChar)[15] = { message[0], message[1], message[2], message[3], message[4], message[5], message[6], message[7], message[8], message[9],message[10], message[11],message[12], message[13], message[14] };
                //if(! ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, NULL))
                if (!ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, NULL))
                ///*    ReadFile(
                //      _In_ HANDLE hFile,
                //      _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer,
                //      _In_ DWORD nNumberOfBytesToRead,
                //      _Out_opt_ LPDWORD lpNumberOfBytesRead,
                //      _Inout_opt_ LPOVERLAPPED lpOverlapped
                //  );*/
                //if (!ReadFile(hComm, SerialBuffer, BUFFERLENGTH, &NoBytesRead, NULL))
                {
                    printf("wrong character" );
                }

                //printf("/n /n %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X", int(TempChar[0]), int(TempChar[1]), int(TempChar[2]), int(TempChar[3]), int(TempChar[4]), int(TempChar[5]), int(TempChar[6]), int(TempChar[7]), int(TempChar[8]), int(TempChar[9]), int(TempChar[10]), int(TempChar[11]), int(TempChar[12]), int(TempChar[13]), int(TempChar[14]));
                SerialBuffer[i] = TempChar;
                //printf("%X is the read", SerialBuffer[i]);
                i++;
            } while (NoBytesRead > 0);

            /*------------Printing the RXed String to Console----------------------*/

            printf("\n\n    ");
            int j = 0;
            for (j = 0; j < i - 1; j++)     // j < i-1 to remove the dupliated last character
                printf("%X are the values read", SerialBuffer[j]);

        }
    }

    CloseHandle(hComm);//Closing the Serial Port
    printf("\n ==========================================\n");
    _getch();

}

I am giving this as input 16 16 02 01 07 08 FF FF 01 00 01 00 FF FF values, and I want the same to be read in hyperterminal. But I am getting some garbage values. I want the same hex values to be in the hyperterminal.

Sidharth Gokul
  • 111
  • 1
  • 6
  • 14
  • There is no such thing as "send as hex". All you are sending is bits. Not even necessarily 8bit chars. Serial hardware can often do 5, 6, 7 or 8 bits. But anything but "8n1" mode is very uncommon. But you don't configure the serial so what mode it is in is anyones guess. What garbage values are you getting? And where are you getting them? Your example code doesn't get anything, it only writes. – Goswin von Brederlow Jun 28 '18 at 10:53
  • @GoswinvonBrederlow Interesting point (5/6/7/8 bits) for illustration. Digging a little deeper: Actually, we send CHAR_BIT * bits of *payload*. It does not really matter how they are fragmented on the transport media - where we physically transmit even more bits (stop bit, parity bit, possibly stuff bits, ...). – Aconcagua Jun 28 '18 at 12:00
  • But sending to the serial port won't fragment your chars. It will simply send the lower 5/6/7/8 bit of your char. The BAUD rate also matters. You might be sending at 9600 BAUD and receiving garbage at 115200 BAUD. – Goswin von Brederlow Jun 28 '18 at 12:02

1 Answers1

0

At very first: What you send is just data. There is no such thing as decimal or hexadecimal data, all that you have is binary data, i. e. the bits stored in groups of (typically) 8 for your bytes. Decimal or hexadecimal literals are just different representations for one and the same (binary) values:

char a[] = { 0x61, 0x62, 0x63, 0 };
char b[] = {   97,   98,   99, 0 };

a and b will now contain exactly the same values, which happen, if interpreted as ASCII characters, to represent the string "abc"...

If, however, your intention is to represent arbitrary binary data in a human readable format (as Intel HEX files do), then you would need to represent each data byte by two chars, e. g. convert the data byte containing 'N', having ASCII value of 78, into a byte sequence of '4', 'e' or alternatively '4', 'E'.

However, this will double your communication overhead, so I'd do the conversion only after receiving the data:

std::vector<char> received = readFromSerial();
// assuming arbitrary data..

for(auto c : received)
    std::cout << std::setfill('0') << std::hex << std::setw(2)
        << static_cast<unsigned int>(static_cast<unsigned char>(c)) << std::endl;

Side note: you need the double cast to prevent sign extension for negative characters (at least if char is signed).

If you should prefer signed or unsigned char depends on if you want to represent data in the range of [-128;127] or of [0;255] respectively...

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • Please check my edited question. I was not sure what you are trying to say. My only concern is about how to send the data as "HEX" – Sidharth Gokul Jun 28 '18 at 10:44
  • @SidharthGokul What exactly do you mean by "as HEX"? As said already, there is no such thing natively. The bytes in your data, no matter if raw or textual, are just numerical values. You can *represent* these values in different forms, still they remain the same... The number of fingers on your hands does not change, no matter if you write it as 10 (decimal), A (hexadecimal) or 12 (octal)... – Aconcagua Jun 28 '18 at 11:39
  • @SidharthGokul Similarly: you referred to the string "ABC". Actually, this is just a *representation* as well, the underlying piece of data is four(!) bytes (including the terminating null character) containing the values 65, 66, 67 and 0. Values do not change, no matter if you write them decimally, hexadecimally (41, 42, 43, 0) or as characters/letters ('A', 'B', 'C', '\0'). – Aconcagua Jun 28 '18 at 11:52
  • I have given my full code here. Please check to it. I am getting some garbage values as output in the hyperterminal. I want the hex values which is the same as the input. – Sidharth Gokul Jun 29 '18 at 08:47
  • @SidharthGokul Just had a short look at, looked OK at first glance. Just one question: What is COM6 connected with on your machine? Are you sure the device reacts as you expect it to do? If you just want to test serial, I recommend to have a look at [com0com](http://com0com.sourceforge.net/). With it, you could connect COM10 to COM12, for instance, and then read at COM12 what you wrote to COM10 and vice versa... – Aconcagua Jun 29 '18 at 19:14