我正在尝试创建一个小应用程序来收集从连接到COM10的外部传感器接收的数据.我已成功创建了一个小型C#控制台对象和应用程序,它使用for循环打开端口并将数据流传输到文件一段固定的时间.
我想转换此应用程序以使用dataReceived事件来代替流.阅读前5个SerialPort提示后,我似乎仍然无法工作,也不知道我缺少什么.我重写了控制台应用程序,以便所有代码都在Main中并粘贴在下面.有人可以帮助启发我,为什么事件处理程序port_OnReceiveDatazz没有被调用,即使我知道硬件有数据被发送到端口?
谢谢
阿齐姆
PS:感谢@Gabe,@ Jason Down和@abatishchev的所有建议.我很难过,似乎无法让事件处理程序工作.也许它与设备有关.我只能在线程中读取端口并将数据直接传输到文件中.
码
namespace serialPortCollection
{ class Program
{
static void Main(string[] args)
{
const int bufSize = 2048;
Byte[] buf = new Byte[bufSize]; //To store the received data.
SerialPort sp = new SerialPort("COM10", 115200);
sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
sp.Open();
sp.WriteLine("$"); //Command to start Data Stream
// Wait for data or user input to continue.
Console.ReadLine();
sp.WriteLine("!"); //Stop Data Stream Command
sp.Close();
}
// My Event Handler Method
private static void port_OnReceiveDatazz(object sender,
SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort) sender;
const int bufSize = 12;
Byte[] buf = new Byte[bufSize];
Console.WriteLine("DATA RECEIVED!");
Console.WriteLine(spL.Read(buf, 0, bufSize));
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jas*_*own 12
我认为你的问题就在于:**
sp.DataReceived + = port_OnReceiveDatazz;
不应该是:
sp.DataReceived + = new SerialDataReceivedEventHandler(port_OnReceiveDatazz);
**没关系,语法很好(当我最初回答这个问题时没有意识到捷径).
我还看到了一些建议,你应该为你的串口打开以下选项:
sp.DtrEnable = true; // Data-terminal-ready
sp.RtsEnable = true; // Request-to-send
Run Code Online (Sandbox Code Playgroud)
您可能还必须将握手设置为RequestToSend(通过握手枚举).
更新:
找到一个建议,说你应该先打开你的端口,然后分配事件处理程序.也许这是一个错误?
所以不是这样的:
sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
sp.Open();
Run Code Online (Sandbox Code Playgroud)
做这个:
sp.Open();
sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
Run Code Online (Sandbox Code Playgroud)
让我知道这是怎么回事.
首先,我建议您使用以下构造函数而不是当前使用的构造函数:
new SerialPort("COM10", 115200, Parity.None, 8, StopBits.One);
Run Code Online (Sandbox Code Playgroud)
接下来,你真的应该删除这段代码:
// Wait 10 Seconds for data...
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(10);
Console.WriteLine(sp.Read(buf,0,bufSize)); //prints data directly to the Console
}
Run Code Online (Sandbox Code Playgroud)
而只是循环直到用户按下一个键或其他东西,如下所示:
namespace serialPortCollection
{ class Program
{
static void Main(string[] args)
{
SerialPort sp = new SerialPort("COM10", 115200);
sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
sp.Open();
sp.WriteLine("$"); //Command to start Data Stream
Console.ReadLine();
sp.WriteLine("!"); //Stop Data Stream Command
sp.Close();
}
// My Event Handler Method
private static void port_OnReceiveDatazz(object sender,
SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort) sender;
byte[] buf = new byte[spL.BytesToRead];
Console.WriteLine("DATA RECEIVED!");
spL.Read(buf, 0, buf.Length);
foreach (Byte b in buf)
{
Console.Write(b.ToString());
}
Console.WriteLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外,请注意对数据接收事件处理程序的修订,它现在应该实际打印缓冲区.
更新1
我刚刚在我的机器上成功运行了以下代码(在COM33和COM34之间使用零调制解调器电缆)
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
Thread writeThread = new Thread(new ThreadStart(WriteThread));
SerialPort sp = new SerialPort("COM33", 115200, Parity.None, 8, StopBits.One);
sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
sp.Open();
sp.WriteLine("$"); //Command to start Data Stream
writeThread.Start();
Console.ReadLine();
sp.WriteLine("!"); //Stop Data Stream Command
sp.Close();
}
private static void port_OnReceiveDatazz(object sender,
SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort) sender;
byte[] buf = new byte[spL.BytesToRead];
Console.WriteLine("DATA RECEIVED!");
spL.Read(buf, 0, buf.Length);
foreach (Byte b in buf)
{
Console.Write(b.ToString() + " ");
}
Console.WriteLine();
}
private static void WriteThread()
{
SerialPort sp2 = new SerialPort("COM34", 115200, Parity.None, 8, StopBits.One);
sp2.Open();
byte[] buf = new byte[100];
for (byte i = 0; i < 100; i++)
{
buf[i] = i;
}
sp2.Write(buf, 0, buf.Length);
sp2.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新2
考虑到最近这个问题的所有流量.我开始怀疑你的串口配置不正确,或设备没有响应.
我强烈建议您尝试使用其他方法与设备通信(我经常使用超级终端).然后,您可以使用所有这些设置(比特率,奇偶校验,数据位,停止位,流量控制),直到找到有效的设置.设备的文档还应指定这些设置.一旦我弄明白了,我会确保我的.NET SerialPort配置正确以使用这些设置.
有关配置串行端口的一些提示:
请注意,当我说你应该使用以下构造函数时,我的意思是使用该函数,不一定是那些参数!您应填写设备的参数,以下设置很常见,但您的设备可能有所不同.
new SerialPort("COM10", 115200, Parity.None, 8, StopBits.One);
Run Code Online (Sandbox Code Playgroud)
设置.NET SerialPort以使用与设备相同的流量控制也很重要(正如其他人之前所说).你可以在这里找到更多信息:
http://www.lammertbies.nl/comm/info/RS-232_flow_control.html
| 归档时间: |
|
| 查看次数: |
109261 次 |
| 最近记录: |