Serial IO in VisualStudio 2011 / C++
I needed to hack together a quick windows application to read data over a serial port and write it to a file. Unfortunately I think VisualStudio is probably still the best way of writing Win32 GUI apps. However I’ve not really used VisualStudio since the VisualStudio.net beta, and most of the stuff I did before that was on VisualStudio 6.
Man Microsoft have really murdered C++… are these proprietary garbage collection extensions all over the place? I couldn’t see a way of writing a pure C++, unmanaged GUI app in VS 2011…
Anyway, to get Serial IO working in a GUI application I needed to add the following methods, these were all added to the Form itself, like I say this was a quick hack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | public : // members String^ comport; String^ dump_filepath; String^ current_filename; SerialPort^ serialn; // initalise serial port void init_acquire() { int baudRate=9600; serialn = gcnew SerialPort(comport, baudRate); serialn->ReadTimeout = 50; serialn->Open(); } // Read from serial port String^ acquire() {; String^ s; try { s = serialn->ReadLine(); } catch (TimeoutException ^) { } return s; } // Button handler, starts thread private : System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { dumped_lines = 0; dumped_file_count = 0; dump_filepath = this ->drop_location_textbox->Text; current_filename = dump_filepath + dumped_file_count + ".txt" ; comport = comport_textbox->Text; ThreadStart ^myThreadDelegate = gcnew ThreadStart( this , &Form1::repeat); trd = gcnew Thread(myThreadDelegate); trd->IsBackground = true ; trd->Start(); dumped_lines = 0; } // Thread code delegate void DelegateThreadTask(); private : void ThreadTask() { // This weirdness is required because setting the TextBox text is not thread safe. if (data_textbox->InvokeRequired == false ) { String ^data = acquire(); this ->data_textbox->Text = this ->data_textbox->Text + data; //current_filename StreamWriter^ sw = gcnew StreamWriter(current_filename, true ); sw->WriteLine(data); sw->Close(); } else { DelegateThreadTask ^myThreadDelegate = gcnew DelegateThreadTask( this ,&Form1::ThreadTask); this ->Invoke(myThreadDelegate); } } // Thread loop (reads from serial, dumps to file/textbox. private : void repeat() { init_acquire(); while ( true ) { ThreadTask(); Thread::Sleep(100); } } |
You’ll also need to add the following headers:
1 2 3 | using namespace System::IO::Ports; using namespace System::Threading; using namespace System::IO; |