0

I have a Windows Form with a serialPort component and I use the DataReceived event handler to process the data in the receive buffer. I use the ReadExisting method which returns a String^ since it is the most reliable way I can collect all the data in the receive buffer without missing any. Like so:

void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
  try{
    String^ receive = this->serialPort1->ReadExisting();
    StreamWriter^ swriter = gcnew StreamWriter("filename.txt", true, Encoding::Unicode);

    //Insert some code for encoding conversion here
    //Convert String^ receive to another String^ whose character encoding accepts character values from (DEC) 127-255.

    //Echo to serialPort the data received, so I can see in the terminal
    this->serialPort1->Write(receive);

    //Write to file using swriter
    this->swriter->Write(receive);
    this->swriter->Close();
  }catch(TimeoutException^){
    in ="Timeout Exception";
  }
}

The problem lies in the String^ value returned by ReadExisting() method. If I enter characters like "wêyÿØÿþÿý6" only characters with decimal values less than 127 are displayed so I read "w?y??????6" from the terminal.

What I want is for the String^ value returned by ReadExisting() method to be encoded in Windows-1252 encoding format so it can identify characters with values from 127-255. I need it to be a String^ variable so I can write it in my text file using the Write() method in StreamWriter.

I've tried searching and found this which is similar to what I would like to do. So here is what I did:

Encoding^ win1252 = Encoding::GetEncoding("Windows-1252");
Encoding^ unicode = Encoding::Unicode;
array <Byte>^ srcTextBytes = win1252->GetBytes(in);                 
array <Byte>^ destTextBytes = Encoding::Convert(win1252, unicode, srcTextBytes);
array <Char>^ destChars = gcnew array <Char>(unicode->GetCharCount(destTextBytes, 0, destTextBytes->Length));
unicode->GetChars(destTextBytes, 0, destTextBytes->Length, destChars, 0);
String^ converted= gcnew System::String(destChars);

Then I write String^ converted to the SerialPort and to StreamWriter. Still, to no avail. The output is still the same. Characters above 127 are still represented as '?'. What should be the proper way to do this? Maybe there is something wrong with the way I did it.

Community
  • 1
  • 1
Nico_Robin
  • 89
  • 1
  • 9
  • A `String` is **always** represented in UTF-16 internally. It's the `StreamWriter` that re-encodes it to the final format. Try to change the third parameter of its constructor. – Lucas Trzesniewski Feb 05 '15 at 08:43
  • @LucasTrzesniewski I have tried using Encoding::Default and Encoding::ASCII and have found the Encoding::Unicode works best as it is basically UTF-16 encoding. I also tried writing "ÿØÿþ" directly to the serial port component by passing that string as a parameter in the Write() method and still I read "????" in the terminal. – Nico_Robin Feb 05 '15 at 09:04
  • 1
    @LucasTrzesniewski What you said got me thinking that maybe it's not the `StreamWriter` which re-encodes the data received from the port. It's probably the `SerialPort` component itself. So I googled and found [this] (http://blogs.msdn.com/b/bclteam/archive/2006/05/26/608377.aspx) which suggests how to set the encoding format for the serial component. Now I can write and receive ascii values greater than 127. Thanks for the heads-up! :D – Nico_Robin Feb 05 '15 at 09:26

0 Answers0