0% found this document useful (0 votes)
39 views19 pages

VC++ WinForms Serial Port App

This document contains code for a C# Windows Forms application that communicates with a serial port. It defines a form with text boxes and buttons to send and receive data from the serial port. When the application loads, it initializes the serial port settings. The send button writes data to the port and the receive event handler displays incoming data in a text box. The exit button closes the port and exits the application.

Uploaded by

Tân Trần
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views19 pages

VC++ WinForms Serial Port App

This document contains code for a C# Windows Forms application that communicates with a serial port. It defines a form with text boxes and buttons to send and receive data from the serial port. When the application loads, it initializes the serial port settings. The send button writes data to the port and the receive event handler displays incoming data in a text box. The exit button closes the port and exits the application.

Uploaded by

Tân Trần
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

VC++CLR WINFORM SERIAL PORT Project VCSerialPort

//[Link]

#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
int main(array<String^>^ args) {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
VCSerialPort::MyForm form;
Application::Run(%form);
}

//MyForm.h

#pragma once

namespace VCSerialPort {

using namespace System;


using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO::Ports;
using namespace System::Threading;

/// <summary>
/// Summary for MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{

public:
MyForm(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
public: String^ datain;
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~MyForm()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::TextBox^ tbSend;
private: System::Windows::Forms::TextBox^ tbReceive;
protected:
private: System::Windows::Forms::Button^ btSend;
private: System::Windows::Forms::Button^ btExit;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::Windows::Forms::Label^ label1;
private: System::ComponentModel::IContainer^ components;
protected:

private:
/// <summary>
/// Required designer variable.
/// </summary>

#pragma region Windows Form Designer generated code


/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew
System::ComponentModel::Container());
this->tbSend = (gcnew
System::Windows::Forms::TextBox());
this->tbReceive = (gcnew
System::Windows::Forms::TextBox());
this->btSend = (gcnew
System::Windows::Forms::Button());
this->btExit = (gcnew
System::Windows::Forms::Button());
this->serialPort1 = (gcnew
System::IO::Ports::SerialPort(this->components));
this->label1 = (gcnew
System::Windows::Forms::Label());
this->SuspendLayout();
//
// tbSend
//
this->tbSend->Location = System::Drawing::Point(36,
67);
this->tbSend->Name = L"tbSend";
this->tbSend->Size = System::Drawing::Size(100, 22);
this->tbSend->TabIndex = 0;
//
// tbReceive
//
this->tbReceive->Location =
System::Drawing::Point(175, 67);
this->tbReceive->Name = L"tbReceive";
this->tbReceive->Size = System::Drawing::Size(83,
22);
this->tbReceive->TabIndex = 1;
//
// btSend
//
this->btSend->Location = System::Drawing::Point(47,
122);
this->btSend->Name = L"btSend";
this->btSend->Size = System::Drawing::Size(75, 23);
this->btSend->TabIndex = 2;
this->btSend->Text = L"SEND";
this->btSend->UseVisualStyleBackColor = true;
this->btSend->Click += gcnew
System::EventHandler(this, &MyForm::btSend_Click);
//
// btExit
//
this->btExit->Location = System::Drawing::Point(183,
122);
this->btExit->Name = L"btExit";
this->btExit->Size = System::Drawing::Size(75, 23);
this->btExit->TabIndex = 3;
this->btExit->Text = L"EXIT";
this->btExit->UseVisualStyleBackColor = true;
this->btExit->Click += gcnew
System::EventHandler(this, &MyForm::btExit_Click);
//
// serialPort1
//
this->serialPort1->PortName = L"COM5";
this->serialPort1->DataReceived += gcnew
System::IO::Ports::SerialDataReceivedEventHandler(this,
&MyForm::serialPort1_DataReceived);
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(62,
44);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(64, 17);
this->label1->TabIndex = 4;
this->label1->Text = L"CLOSED";
//
// MyForm
//
this->AutoScaleDimensions =
System::Drawing::SizeF(8, 16);
this->AutoScaleMode =
System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(323, 255);
this->Controls->Add(this->label1);
this->Controls->Add(this->btExit);
this->Controls->Add(this->btSend);
this->Controls->Add(this->tbReceive);
this->Controls->Add(this->tbSend);
this->Name = L"MyForm";
this->Text = L"MyForm";
this->Load += gcnew System::EventHandler(this,
&MyForm::MyForm_Load);
this->ResumeLayout(false);
this->PerformLayout();

}
#pragma endregion

private: System::Void MyForm_Load(System::Object^ sender,


System::EventArgs^ e)
{
serialPort1->PortName = "COM5";
serialPort1->BaudRate = 9600;
serialPort1->Parity = Parity::None;
serialPort1->StopBits = StopBits::One;
serialPort1->DataBits = 8;
serialPort1->Handshake = Handshake::None;
serialPort1->Open();
if (serialPort1->IsOpen == true) { label1->Text = "OPENED"; }
else
label1->Text = "CLOSED";

}
private: System::Void btSend_Click(System::Object^ sender,
System::EventArgs^ e)
{
serialPort1->Write(tbSend->Text);
}
private: System::Void DisplayText(System::Object^ sender,
System::EventArgs^ e) {
tbReceive->Text=(datain);
}
private: System::Void serialPort1_DataReceived(System::Object^
sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
datain = serialPort1->ReadExisting();
this->Invoke(gcnew EventHandler(this, &MyForm::DisplayText));
}
private: System::Void btExit_Click(System::Object^ sender,
System::EventArgs^ e)
{
serialPort1->Close();
this->Close();
}
};
}

C#SerialPort Project SerialCS


using System;
using [Link];
using [Link];
namespace SerialCS
{
public partial class Form1 : Form
{
SerialPort ComPort = new SerialPort();
internal delegate void
SerialDataReceivedEventHandlerDelegate(
object sender, SerialDataReceivedEventArgs e);
delegate void SetTextCallback(string text);
string InputData = [Link];
int RcvNumber;
Label[] lamp = new Label[8];
public Form1()
{
InitializeComponent();
[Link] +=
new SerialDataReceivedEventHandler(Received_1);
}
private void Exit_Click(object sender, EventArgs e)
{
[Link]();
[Link]();
}
private void Settings_Click(object sender, EventArgs e)
{
string[] ArrayComPortsNames = null;
int index = -1;
string ComPortName = null;
//Com Ports
ArrayComPortsNames = [Link]();
do
{
index += 1;
[Link](ArrayComPortsNames[index]);
}
while (!((ArrayComPortsNames[index] == ComPortName) ||
(index == [Link](0))));
[Link](ArrayComPortsNames);
if (index == [Link](0))
{
ComPortName = ArrayComPortsNames[0];
}
[Link] = ArrayComPortsNames[0];
//Baud Rate
[Link](9600);
[Link](19200);
[Link](38400);
[Link](57600);
[Link](115200);
[Link]();
//get first item print in text
[Link] = [Link][0].ToString();
//Data Bits
[Link](7);
[Link](8);
[Link] = [Link][0].ToString();
//Stop Bits
[Link]("One");
[Link]("OnePointFive");
[Link]("Two");
[Link] = [Link][0].ToString();
//Parity
[Link]("None");
[Link]("Even");
[Link]("Mark");
[Link]("Odd");
[Link]("Space");
[Link] = [Link][0].ToString();
//Handshake
[Link]("None");
[Link]("XOnXOff");
[Link]("RequestToSend");
[Link]("RequestToSendXOnXOff");
[Link] =
[Link][0].ToString();
}
private void Open_Click(object sender, EventArgs e)
{
if ([Link] == "CLOSED")
{
[Link] = [Link]([Link]);
[Link] =
Convert.ToInt32([Link]);
[Link] =
Convert.ToInt16([Link]);
[Link] =
(StopBits)[Link](typeof(StopBits), [Link]);
[Link] =
(Handshake)[Link](typeof(Handshake), [Link]);
[Link] = (Parity)[Link](typeof(Parity),
[Link]);
[Link] = 4000;
[Link] = 6000;
try
{
[Link]();
if ([Link])
{
[Link] = "OPENED";
[Link] = true;
[Link] = false;
[Link] = false;
[Link] = false;
}
}
catch (UnauthorizedAccessException ex)
{
[Link]([Link]);
}
}
else if ([Link] == "OPENED")
{
[Link] = "CLOSED";
[Link]();
[Link] = false;
[Link] = true;
[Link] = true;
[Link] = true;
}
}
private void Received_1(object sender,
SerialDataReceivedEventArgs e)
{
if (![Link] == true)
{
InputData = [Link]();
if (InputData != [Link])
{
//Show data in Rich Text Box
BeginInvoke(new SetTextCallback(SetText), new object[]
{ InputData });

}
}
else
{
int number = [Link];
byte[] buffer = new byte[number];
[Link](buffer, 0, number);
String data = [Link](buffer);
//Show received Hex in Rich Text box
BeginInvoke(new SetTextCallback(SetText), new object[]
{ data });
//Show first byte in TextBox tbDec
int firstbyte = buffer[0];
BeginInvoke(new SetTextCallback(SetTextBox), new
object[] { [Link]( )});
//Show 8 bits in color of Labels
int i;
for (i = 7; i >= 0; i--)
{
byte a = buffer[0];
byte c = (byte)([Link](2, i));
if ((a & c) == c)
lamp[i].BackColor =
[Link];
else
lamp[i].BackColor =
[Link];

}
}

}
private void SetTextBox(string num)
{
[Link] = num;//Show string in TextBox
}
private void SetText(string text)
{
//Show received Data in Rich Text Box
[Link] += text + "\n";//Show string in TextBox

//Show decimal number in Text Box


if ([Link] == true)
{
try
{
RcvNumber = Convert.ToInt32(text);
[Link] = [Link]();
}
catch { }
}

}
private void btSend_Click(object sender, EventArgs e)
{
if (![Link] == true)
try
{
[Link] = "";
[Link]([Link]);
}
catch
{ }
else
{
try
{
byte[] data = StringToByteArray([Link]);
[Link](data, 0, [Link]);
}
catch
{ }
}

public static byte[] StringToByteArray(string s)


{
s = [Link](" ", "");//delete spaces
byte[] buffer = new byte[[Link] / 2];
for (int i = 0; i< [Link]; i += 2)
buffer[i / 2] = (byte)[Link]([Link](i, 2),
16);
return buffer;
}
private void rbText_CheckedChanged(object sender, EventArgs
e)
{
if ([Link] == false)
{ [Link] = 8; [Link] = "8"; }
}

private void Form1_Load(object sender, EventArgs e)


{
int i = 0;
//Draw label to show 8 bit value in red and green
for (i = 0; i<8; i++)
{
lamp[i] = new Label();
lamp[i].Text = "";
lamp[i].BackColor = [Link];
lamp[i].Size = new [Link](20, 20);
lamp[i].Location = new [Link](300-i *
30, 350);
[Link](lamp[i]);

}
}
C# ĐƠN GIẢN MÔ PHỎNG KẾT NỐI PC PIC RS232 ĐIỀU KHIỂN HAI LED

Project Project_Comport1
//Use serialPort on ToolBox
using System;
using [Link];
using [Link];

namespace Project_Comport1
{
public partial class Form1 : Form
{

delegate void SetTextCallback(string text);


public Form1()
{
InitializeComponent();
}

private void btt_KetNoi_Click(object sender, EventArgs e)


{
string NamePort;
if ([Link] == false)
{
[Link]();
NamePort = [Link];
[Link]("Bạn đã mở thành công " + NamePort);
[Link]("Send 0, 1,2, or 3");
btt_KetNoi.Enabled = false;
}

private void btExit_Click(object sender, EventArgs e)


{
if ([Link] == true)
{
[Link]();
}
[Link]();

private void btt_Gui_Click(object sender, EventArgs e)


{
if ([Link] == true)
{
if (cb_LED1.Checked == false && cb_LED2.Checked ==
false)
{
[Link]("0");
}
if (cb_LED1.Checked == true && cb_LED2.Checked ==
false)
{
[Link]("1");
}
if (cb_LED1.Checked == false && cb_LED2.Checked ==
true)
{
[Link]("2");
}
if (cb_LED1.Checked == true && cb_LED2.Checked ==
true)
{
[Link]("3");
}

}
else
{
[Link]("Bạn chưa mở cổng COM");
}
}

private void DisplayText(string received)


{
[Link] = received;
if ((received=="1") || (received == "3") )
{ [Link] = [Link]; }
else { [Link] = [Link]; }
if ((received == "2") || (received == "3"))
{ [Link] = [Link]; }
else { [Link] = [Link]; }
}

private void serialPort1_DataReceived(object sender,


[Link] e)
{
String data = [Link]();
BeginInvoke(new SetTextCallback(DisplayText), new
object[] {data});

}
}

#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

//============================
void main()
{
char c;
Set_tris_D(0x00);
Output_D(0xFF);
while(1)
{
c = getc();
if(c=='0')
{
output_d(0b11111111);
}
if(c=='1')
{
output_d(0b11111110);
}
if(c=='2')
{
output_d(0b11111101);
}
if(c=='3')
{
output_d(0b11111100);
}
}
}
TRUYỀN FILE GIỮA HAI MÁY
Truyền file giữa hai máy dùng cổng COM bây giờ ít dùng nhưng
nghiên cứu lập trình cũng khá lý thú. Phân biệt truyền file text và
file binary, cài đặt WriteBufferSize và ReadBufferSize đến giá trị
tối đa mong muốn (số chẵn), mặc định là 2048.Cần phải sử dụng kiểu
bắt tay để điều khiển luồng dữ liệu.
Chọn file Text,có đuôi txt,c,…, lưu tên file vào TextBox và
hiển thị nội dung file vào RichTextBox
//Created by Nguyen Duc Thanh
using System;
using [Link];

namespace FileTrasferCS
{
public partial class Form1 : Form
{
delegate void SetTextCallback(string text);
String data;
public Form1()
{
InitializeComponent();
}

private void btSendFile_Click(object sender, EventArgs e)


{
OpenFileDialog ofd = new OpenFileDialog();
if ([Link]() == [Link])
{
[Link] = [Link];
[Link] =
[Link]([Link]);
[Link] = "Press SEND FILE";
[Link] = true;
}
}

private void btSend_Click(object sender, EventArgs e)


{
[Link] = "";

[Link]([Link]([Link]));
[Link] = "Send Completed";
}

private void btExit_Click(object sender, EventArgs e)


{
[Link]();
[Link]();
}

private void Form1_Load(object sender, EventArgs e)


{
[Link] = (int)[Link](2, 16);//64K
Bytes
[Link] = (int)[Link](2, 16);//64K
Bytes
[Link]();
if ([Link] == true) { [Link] = "Opened
" + [Link]; }
else { [Link] = "Closed " + [Link]; }
string c = Char.ConvertFromUtf32(0x31);
[Link] = "d:/[Link]";
[Link] = false;
}

private void DisplayText(string received)


{
[Link] += received;
}
private void SaveF(string path)
{
using ([Link](path)) ;
rtFileRcv .SaveFile(path,
[Link]);
[Link] = "File Saved ";
}
private void serialPort1_DataReceived(object sender,
[Link] e)
{
String datain = [Link]();
data += datain;

BeginInvoke(new SetTextCallback(DisplayText), new


object[] { datain });
string c = Char.ConvertFromUtf32(0x31);
string d = [Link]([Link] - 1, 1);
if (c == d)
{
BeginInvoke(new SetTextCallback(SaveF), new object[]
{ [Link] });

}
}
}
}

Common questions

Powered by AI

In the VC++CLR WINFORM project, the serial port is initialized directly within the MyForm_Load method with fixed parameters such as 'COM5' as the port name and a baud rate of 9600 . It uses the System::IO::Ports namespace, and communication is event-driven with the SerialDataReceivedEventHandler. The C# SerialPort project, on the other hand, initializes the serial port on form load and provides a more interactive interface for changing port settings like baud rate, parity, and data bits through user controls before opening the port. It uses delegates for handling data received events and allows dynamic settings adjustments .

The event-driven approach in these applications enables asynchronous data handling, preventing the main application thread from being blocked while waiting for serial data . In both projects, data received from the serial port triggers the DataReceived event, which initiates actions such as updating the UI or processing input data via delegate methods like SetTextCallback in C# and DisplayText in VC++CLR . This decouples data processing from the main thread, allowing other UI interactions to continue smoothly.

Thread management plays a crucial role in managing and processing serial port data without hindering the main application performance. By offloading data handling to a separate thread, as practiced in both environments, these applications prevent the main thread from blocking and maintain application responsiveness. The VC++CLR application uses asynchronous invocations to update the UI based on incoming data, while the C# application similarly uses delegates and asynchronous invocations to safely manage UI updates . Such thread management ensures that the main application's performance remains unaffected by data operations, improving responsiveness and user experience.

These applications use different techniques for converting and displaying serial data. The VC++CLR application updates a TextBox with incoming data by reading it as a string through the ReadExisting method and then invoking a method to update the UI asynchronously . The C# application offers conversions into both text and hexadecimal formats and includes bit manipulation to visually represent byte values using colored labels. This is achieved by converting data to a string or byte array and updating UI components with callbacks like SetTextCallback and SetTextBox . This not only visually presents the data but also provides a flexible way to handle different data formats.

Error handling and resource management differ notably between these environments. In VC++ CLR, resource management is explicit with destructors, as observed in MyForm’s destructor ~MyForm(), which cleans up components . There is less visible error handling for serial operations. In contrast, the C# environment employs try-catch blocks around critical code segments such as opening and writing to the serial port to manage UnauthorizedAccessException and other potential errors, demonstrating a more explicit exception-handling strategy . Furthermore, the C# environment benefits from automatic garbage collection, reducing explicit resource management needs.

These applications provide user feedback on port status changes through UI elements. In the VC++CLR application, the status of a serial port is displayed on a label (label1), which changes text to "OPENED" or "CLOSED" based on the port's actual state after opening attempts . In the C# application, this status change is represented by toggling button text and enabling/disabling UI components (e.g., setting "OPENED" on the Open button) to indicate the current port status and allow further actions like data sending . This feedback is critical for informing users about operational status and avoiding operation attempts on closed ports.

Serial port configuration is essential for ensuring compatible communication settings between the port and the connected device, which affects data integrity and transmission reliability. In the VC++CLR application, configuration parameters such as port name, baud rate, and data format (data bits, stop bits, parity) are predefined in the code, limiting user interaction . The C# application provides a more comprehensive approach, allowing these settings to be dynamically adjusted through a graphical user interface, granting the user more control and flexibility before the port is opened . Such configurability ensures greater adaptability to different devices and situations.

"BeginInvoke" is crucial for safely updating the UI from a non-UI thread, preventing cross-thread operation exceptions. In both applications, it is used to asynchronously execute delegate methods on the UI thread without blocking the main application. In the C# project, BeginInvoke is applied within the Received_1 method to update the UI with incoming serial data using SetTextCallback . Similarly, the VC++CLR uses this approach within the serialPort1_DataReceived method to call DisplayText, ensuring that UI updates occur on the main thread . This approach maintains UI responsiveness and thread safety.

The primary user interface components in the VC++ CLR WINFORM for serial communication include TextBoxes (tbSend and tbReceive) for sending and displaying data, Buttons (btSend and btExit) for sending data and closing the application, and a Label (label1) that indicates the serial port status . These components are part of the MyForm class and are initialized within the InitializeComponent method.

Buffer management in file transfer is optimized by setting high WriteBufferSize and ReadBufferSize values, enhancing the efficiency of data flow control by allowing larger data chunks to be processed at once . This reduces the number of read/write cycles necessary, limiting idle time and maximizing throughput. By configuring the buffer sizes to their optimal values (e.g., 64K Bytes in the C# application), the application can handle larger sections of data seamlessly, reducing fragmentation and the potential bottleneck when sending or receiving large files. Effective buffer management is critical for avoiding overflows and ensuring smooth operation, especially in large file transfers.

You might also like