Search code examples
c++c++-clihex

Send Hex Bytes To A Serial Port


I am attempting to send hexadecimal bytes to a serial com port. The issue is that the segment that sends the command apparently wants a system string instead of an integer (error C2664 "cannot convert parameter 1 from 'int' to 'System::String ^'). I have looked for a way to send an integer instead but have had no luck. (I have tried sending string representations of the hexadecimal values, but the device did not recognize the commands)

Main part of Code

private: System::Void poll_Click(System::Object^  sender, System::EventArgs^  e) 
     {
            int i, end;
            double a = 1.58730159;
            String^ portscan = "port";
            String^ translate;
            std::string portresponse [65];
            std::fill_n(portresponse, 65, "Z");

            for (i=1;i<64;i++)
            {
                if(this->_serialPort->IsOpen)
                {
                    // Command 0 generator
                    int y = 2;
                    y += i;
                    int command0[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, dectohex(i), 0x00, 0x00, dectohex(y)};

                    for (end=0;end<10;end++)
                    {
                        this->_serialPort->WriteLine(command0[end]);
                    }

                    translate = (this->_serialPort->ReadLine());
                    MarshalString(translate, portresponse [i]);
                    if(portresponse [i] != "Z")
                    {
                        comboBox7->Items->Add(i);
                    }
                    this->progressBar1->Value=a;
                    a += 1.58730159;
                }
            }


     }

Here is the function dectohex:

    int dectohex(int i)
         {
            int x = 0;
            char hex_array[10];
            sprintf (hex_array, "0x%02X", i);
            string hex_string(hex_array);
            x = atoi(hex_string.c_str());
            return x;
         }

This is what solved my problem, courtesy of Jochen Kalmbach

auto data = gcnew array<System::Byte> { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x00, 0xBD };
_serialPort->Write(data, 0, data->Length);

Replaced this

this->_serialPort->WriteLine(command0[end]);

Solution

  • You cannot sent an integer over a serial line.... you can only sent BYTES (7-8 bit)!

    You need to choose what you want to do:

    • Sent characters: So the "number" 12 will be converted into the bytes

      _serialPort->Write(12.ToString());
      // => 0x49, 0x50
      
    • Sent the integer (4 bytes) as little endian

      auto data = System::BitConverter::GetBytes(12);
      _serialPort->Write(data, 0, data->Length);
      // => 0x0c, 0x00, 0x00, 0x00
      
    • Or you write just a single byte:

      auto data = gcnew array<System::Byte> { 12 };
      _serialPort->Write(data, 0, data->Length);
      // => 0x0c
      
    • Or write an byte array:

      auto data = gcnew array<System::Byte> { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x00, 0xBD };
      _serialPort->Write(data, 0, data->Length);
      // => 0xFF 0xFF 0xFF 0xFF 0xFF 0x02 0xBF 0x00 0x00 0xBD