我是C#
的新手,我正在尝试使用一种常见的串口来实现3种不同的形式:Form2, Form3, Form4
Form1.cs
,因为只需要启动其他表单的程序。基本上,所有3个表单必须同时从同一个串行端口接收数据。我面临的问题是只有一个表单可以从串口接收数据,但其他两个表单不能。
我发现了类似的问题:
Using same serial port data received event on two different forms
这个问题与我的相似吗?如果是,我可以知道在哪里将示例代码放在我的代码中的上述链接中吗?
有人可以帮忙吗?提前谢谢!
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
Form3 f3 = new Form3();
f3.Show();
Form4 f4 = new Form4();
f4.Show();
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
public partial class Form2 : Form
{
GMapControl MainMap = new GMapControl();
//Initialise data type for latituide and longitude
double lat, lng;
//Initialise customise marker (plane maker). Declared as m.
GMapMarkerImage m = new GMapMarkerImage(new PointLatLng());
GMapOverlay overlayOne;
public Form2()
{
InitializeComponent();
SuspendLayout();
overlayOne = new GMapOverlay(MainMap, "OverlayOne");
MainMap.MapProvider = GMapProviders.YahooMap;
MainMap.SetCurrentPositionByKeywords("Singapore");
MainMap.MinZoom = 1;
MainMap.MaxZoom = 24;
MainMap.Zoom = 13;
MainMap.CanDragMap = true;
MainMap.DragButton = MouseButtons.Left;
MainMap.Dock = DockStyle.Fill;
MainMap.Manager.Mode = AccessMode.ServerAndCache;
Controls.Add(MainMap);
ResumeLayout(true);
}
public void button1_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen) //if serial port is not open
try
{
serialPort1.Open(); //Open Serial Port
if (lat != 0 && lng != 0) //Display marker only when GPS has receive data
{
overlayOne.Markers.Add(m); //Add marker on the position given to the overlayOne layer
MainMap.Overlays.Add(overlayOne); //Add overlayOne layer to the MainMap layer
}
}
catch
{
//A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in.
MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in.");
}
}
public void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen) // if Serial Port is open
{
serialPort1.Close(); //Close Serial
overlayOne.Markers.Remove(m);
}
}
//When microsoft visual studio receive data
public void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(DoUpdate)); //for function DoUpdate
//Pause Microsoft Visual Studio for 100 milliseconds from receiving data,
//to ensure serialPort can be close successfully
Thread.Sleep(100);
}
//Function for updating data. Declared as DoUpdate.
public void DoUpdate(object sender, EventArgs e)
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
lat = Convert.ToDouble(c[9]); //Convert Latitude string data to double data
lng = Convert.ToDouble(c[10]); //Convert Longitude string data to double data
//Input lat and lng data in m.
//Updating the position of the marker
m.Position = new PointLatLng(lat, lng);
}
}
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen) //if serial port is not open
try
{
serialPort1.Open(); //Open Serial Port
//Enable blocks to have colour
// ...
}
catch
{
//A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in.
MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in.");
}
}
private void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen) // if serial port is open
{
serialPort1.Close(); // Close serial Port
//Clear data in textboxes
FrontSonar.Text = " ";
LeftSonar.Text = " ";
RightSonar.Text = " ";
//Clear colours in the boxes
// ...
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) //When microsoft visual studio receive data
{
this.Invoke(new EventHandler(DoUpdate1)); //To update and ensure sonar data infront of UAV can be displayed without error
this.Invoke(new EventHandler(DoUpdate2)); //To update and ensure sonar data left side of UAV can be displayed without error
this.Invoke(new EventHandler(DoUpdate3)); //To update and ensure sonar data on the right side of UAV can be displayed without error
Thread.Sleep(100);
}
private void DoUpdate1(object s, EventArgs e) //Display for Sonar infront of UAV
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
FrontSonar.Text = c[1] + "\n";
double d = Convert.ToDouble(c[1]);
if (d > 500)
{
//Fill blocks with green
this.rectangleShape1.FillColor = System.Drawing.Color.Green;
this.rectangleShape2.FillColor = System.Drawing.Color.Green;
this.rectangleShape3.FillColor = System.Drawing.Color.Green;
}
else
if (d > 400 && d <= 500)
{
//Fill block with Orange colour
this.rectangleShape1.FillColor = System.Drawing.Color.Orange;
this.rectangleShape2.FillColor = System.Drawing.Color.Orange;
//Fill block with Lavender colour
this.rectangleShape3.FillColor = System.Drawing.Color.Lavender;
}
else
if (d <= 400)
{
//Fill block with red colour
this.rectangleShape1.FillColor = System.Drawing.Color.Red;
//Fill block with Lavender colour
this.rectangleShape2.FillColor = System.Drawing.Color.Lavender;
this.rectangleShape3.FillColor = System.Drawing.Color.Lavender;
}
}
private void DoUpdate2(object s, EventArgs e) //Display for Sonar on the left side of UAV
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
// ....
}
private void DoUpdate3(object s, EventArgs e) //Display for Sonar on the right side of UAV
{
string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function
// ...
}
}
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
}
}
答案 0 :(得分:1)
是的,你可以。以下是实现这一目标的关键点:
打开串口一次,你的方法if (!port.IsOpened) { port.Open(); }
是正确的,用静态方法提取它并调用每种形式(f2,f3,f4)以避免复制/粘贴这段代码片段。 / p>
serialPort
变量应该在所有三个表单中共享,因此所有表单都可以访问相同的打开和初始化的端口实例。考虑你提供的代码,创建和初始化,在Form1
类中打开端口,然后通过构造函数注入将初始化的serialPort实例传递给其他表单类,基本上为SerialPort port
添加Form2,3,4
构造函数参数课程然后:
// renamed button1_Click
private void OnSetup(object sender, EventArgs e)
{
this.port = new SerialPort(...);
// TODO: initialize port
Form2 f2 = new Form2(this.port);
f2.Show();
Form3 f3 = new Form3(this.port);
f3.Show();
Form4 f4 = new Form4(this.port);
f4.Show();
}
然后在每个表单构造函数中只订阅serialPort.DataReceived
事件,就是这样。
public Form2(SerialPort port)
{
port.DataReceived += ...
}
一些建议,
form1
,form2
,c
,d
,button2_Click
400
,500
幻数有多处出现,但不清楚它们是什么。Pause Microsoft Visual Studio...
,microsoft visual studio receives data...
的代码的评论中,这是不正确的,您的应用程序(但不是Visual Studio)的执行将在Thread.Sleep()
暂停,您的应用程序将会暂停收到一个收到的串口数据,Visual Studio只是一个开发环境,在这种情况下,dos不直接涉及端口通信。