C#从不同的cs文件和串行读取更改变量
C# changing variables from different cs file and serial reading
大家好,我是编程新手,也是 C# 新手。
我想创建第二个文件,让一切看起来更干净一点,但没有成功。
这是一个 RP3 运行 Windows 10 IoT 核心的 UWP 后台项目。
我想制作一个可以被应用程序访问的网络服务器,但显然我还没有制作该代码。
现在我想弄清楚 Arduino 和 RP 之间的联系。它在大多数情况下都能完美运行。
但我想让它看起来更好,所以我想将所有传感器内容放在不同的文件中,但我无法访问或更改任何变量。
比如我想把clState改成true/false,我做不到
我遇到的另一个问题是,当 arduino 通过串口发送单个字符串时,RP 会收到它并且它工作得很好但是如果我发送多个字符串(例如多个 Serial.write)它会收到它但是我的检查它是否正确的代码只适用于一个字符串......我怀疑它与异步的东西有关但我不知道如何修复它。但这并不重要。
rcvdText = dataReaderObject.ReadString(bytesRead);
Debug.WriteLine("Debug: Succesvol gelezen van Arduino");
Debug.WriteLine(rcvdText);
char startMarker = '<';
char endMarker = '>';
if (rcvdText.Contains(startMarker) == true && rcvdText.Contains(endMarker) == true)
{
int startIndex = rcvdText.IndexOf(startMarker) + 1;
int endIndex = rcvdText.IndexOf(endMarker) - 1;
receivedChars = rcvdText.Substring(startIndex, endIndex);
Debug.WriteLine(receivedChars);
CheckNewData();
}
非常感谢所有帮助! :)
抱歉复制时缩进失败...而且我认为我没有遵循命名约定...
这是主文件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;
using Windows.ApplicationModel.Background;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.ApplicationModel.AppService;
using Windows.Storage.Streams;
using System.Runtime.InteropServices.WindowsRuntime;
namespace ArduinoData
{
public sealed class StartupTask : IBackgroundTask
{
//public bool clState;
public ArduinoConnect test2 = new ArduinoConnect();
BackgroundTaskDeferral serviceDeferral;
public void Run(IBackgroundTaskInstance taskInstance)
{
serviceDeferral = taskInstance.GetDeferral();
BackgroundTaskDeferral arduinoDeferral = taskInstance.GetDeferral();
//ArduinoConnect test = new ArduinoConnect();
test2.WatchDevice();
Test();
test2.clState = false;
}
}
}
这是ArduinoConnect.cs
using System;
using System.Linq;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage.Streams;
namespace ArduinoData
{
public sealed class ArduinoConnect
{
DataReader dataReaderObject = null;
private SerialDevice serialPort = null;
private CancellationTokenSource ReadCancellationTokenSource;
private string rcvdText;
private string receivedChars;
//variabelen voor status
private bool clState;
private bool phPlusState;
private bool phMinState;
private bool pompState;
private bool lampenState;
private bool warmteState;
private bool vulState;
private bool waterState;
private byte dekState;
public void WatchDevice()
{
UInt16 vid = 0x2341;
UInt16 pid = 0x0001;
string aqs = SerialDevice.GetDeviceSelectorFromUsbVidPid(vid, pid);
var Watcher = DeviceInformation.CreateWatcher(aqs);
Watcher.Added += new TypedEventHandler<DeviceWatcher, DeviceInformation>(DeviceAdded);
Watcher.Removed += new TypedEventHandler<DeviceWatcher, DeviceInformationUpdate>(OnDeviceRemoved);
Watcher.Start();
}
private async void DeviceAdded(DeviceWatcher watcher, DeviceInformation device)
{
Debug.WriteLine("Debug: Apparaat gevonden! :)");
try
{
serialPort = await SerialDevice.FromIdAsync(device.Id);
Debug.WriteLine("Debug: " + device.Name + " verbonden!!! :D");
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.BaudRate = 9600;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
Debug.WriteLine("Debug: Seriële poort succesvol geconfigureerd! :D");
ReadCancellationTokenSource = new CancellationTokenSource();
}
catch
{
Debug.WriteLine("Debug: Fout bij Seriële poort configureren. :(");
}
Listen();
}
private async void Listen()
{
try
{
Debug.WriteLine("Debug: Listen() function");
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
// keep reading the serial input
while (true)
{
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
catch (TaskCanceledException)
{
Debug.WriteLine("Reading task was cancelled, closing device and cleaning up");
CloseDevice();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
finally
{
// Cleanup once complete
if (dataReaderObject != null)
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
// If task cancellation was requested, comply
cancellationToken.ThrowIfCancellationRequested();
// Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
// Create a task object to wait for data on the serialPort.InputStream
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
// Launch the task and wait
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
rcvdText = dataReaderObject.ReadString(bytesRead);
Debug.WriteLine("Debug: Succesvol gelezen van Arduino");
Debug.WriteLine(rcvdText);
char startMarker = '<';
char endMarker = '>';
if (rcvdText.Contains(startMarker) == true && rcvdText.Contains(endMarker) == true)
{
int startIndex = rcvdText.IndexOf(startMarker) + 1;
int endIndex = rcvdText.IndexOf(endMarker) - 1;
receivedChars = rcvdText.Substring(startIndex, endIndex);
Debug.WriteLine(receivedChars);
CheckNewData();
}
}
}
}
private void CheckNewData()
{
switch (receivedChars)
{
case "CL_STATE=0" :
clState = false;
break;
case "CL_STATE=1" :
clState = true;
break;
case "PHPLUS_STATE=0" :
phPlusState = false;
break;
case "PHPLUS_STATE=1" :
phPlusState = true;
break;
case "POMP_STATE=0" :
pompState = false;
break;
case "POMP_STATE=1" :
pompState = false;
break;
case "LAMPEN_STATE=0" :
lampenState = false;
break;
case "LAMPEN_STATE=1" :
lampenState = true;
break;
case "VUL_STATE=0" :
vulState = false;
break;
case "VUL_STATE=1" :
vulState = true;
break;
case "WATER_STATE=0" :
waterState = false;
break;
case "WATER_STATE=1" :
waterState = true;
break;
case "DEK_STATE=0" :
dekState = 0;
break;
case "DEK_STATE=1" :
dekState = 1;
break;
case "DEK_STATE=2" :
dekState = 2;
break;
case "REFRESH=1" :
Debug.WriteLine("Debug: Refresh uitgevoerd!");
break;
default:
Debug.WriteLine("Debug: Fout commando!");
break;
}
}
private void OnDeviceRemoved(DeviceWatcher sender, DeviceInformationUpdate device)
{
Debug.WriteLine("Debug: Apparaat losgekoppeld.");
try
{
CancelReadTask();
CloseDevice();
}
catch(Exception ex)
{
Debug.WriteLine("Debug: " + ex.Message);
}
}
private void CancelReadTask()
{
if (ReadCancellationTokenSource != null)
{
if (!ReadCancellationTokenSource.IsCancellationRequested)
{
ReadCancellationTokenSource.Cancel();
}
}
}
private void CloseDevice()
{
if (serialPort != null)
{
serialPort.Dispose();
}
serialPort = null;
rcvdText = "";
}
}
}
编辑
我遇到了这个代码的新问题 我上面的旧代码有时也遇到了同样的问题...
错误
抛出异常:System.Private.CoreLib.ni.dll 中的 'System.ArgumentOutOfRangeException'
索引和长度必须引用字符串中的位置。
参数名称:长度
无法正确粘贴,烦人...
if (bytesRead > 0)
{
rcvdText = dataReaderObject.ReadString(bytesRead);
Debug.WriteLine("Debug: Succesvol gelezen van Arduino");
Debug.WriteLine(rcvdText);
//char startMarker = '<';
//char endMarker = '>';
int i = 0;
foreach (var ch in rcvdText)
{
//if (ch != '\u+003C') continue;
if (ch == '\u003C')
{
StartIndex = i + 1;
Debug.WriteLine(StartIndex);
}
if (ch == '\u003E')
{
EndIndex = i - 1;
Debug.WriteLine(EndIndex);
receivedChars = rcvdText.Substring(StartIndex, EndIndex);
Debug.WriteLine(receivedChars);
StartIndex = 0;
EndIndex = 0;
}
i++;
Debug.WriteLine("test");
}
Debug.WriteLine("finished");
}
调试输出:
Debug: Succesvol gelezen van Arduino
<WATER_STATE=1>
<WATER_STATE=0>
1
test
test
test
test
test
test
test
test
test
test
test
test
test
test
13
WATER_STATE=1
test
test
test
18
test
test
test
test
test
test
test
test
test
test
test
test
test
test
30
Exception thrown: 'System.ArgumentOutOfRangeException' in System.Private.CoreLib.ni.dll
test2
Index and length must refer to a location within the string.
Parameter name: length
test2
The program '[2888] backgroundTaskHost.exe' has exited with code -1 (0xffffffff).
EDIT2 我想通了,我是个白痴...
But I wanted to make it look better so I wanted to put all the sensor
stuff in a different file but I can't access or change any variable.
For example, I want to change clState to true/false, I can't do that.
您可以像这样使用自动实现的属性:
public bool clState { get; set; }
更多信息您可以参考here。
大家好,我是编程新手,也是 C# 新手。
我想创建第二个文件,让一切看起来更干净一点,但没有成功。
这是一个 RP3 运行 Windows 10 IoT 核心的 UWP 后台项目。
我想制作一个可以被应用程序访问的网络服务器,但显然我还没有制作该代码。 现在我想弄清楚 Arduino 和 RP 之间的联系。它在大多数情况下都能完美运行。
但我想让它看起来更好,所以我想将所有传感器内容放在不同的文件中,但我无法访问或更改任何变量。 比如我想把clState改成true/false,我做不到
我遇到的另一个问题是,当 arduino 通过串口发送单个字符串时,RP 会收到它并且它工作得很好但是如果我发送多个字符串(例如多个 Serial.write)它会收到它但是我的检查它是否正确的代码只适用于一个字符串......我怀疑它与异步的东西有关但我不知道如何修复它。但这并不重要。
rcvdText = dataReaderObject.ReadString(bytesRead);
Debug.WriteLine("Debug: Succesvol gelezen van Arduino");
Debug.WriteLine(rcvdText);
char startMarker = '<';
char endMarker = '>';
if (rcvdText.Contains(startMarker) == true && rcvdText.Contains(endMarker) == true)
{
int startIndex = rcvdText.IndexOf(startMarker) + 1;
int endIndex = rcvdText.IndexOf(endMarker) - 1;
receivedChars = rcvdText.Substring(startIndex, endIndex);
Debug.WriteLine(receivedChars);
CheckNewData();
}
非常感谢所有帮助! :)
抱歉复制时缩进失败...而且我认为我没有遵循命名约定...
这是主文件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;
using Windows.ApplicationModel.Background;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.ApplicationModel.AppService;
using Windows.Storage.Streams;
using System.Runtime.InteropServices.WindowsRuntime;
namespace ArduinoData
{
public sealed class StartupTask : IBackgroundTask
{
//public bool clState;
public ArduinoConnect test2 = new ArduinoConnect();
BackgroundTaskDeferral serviceDeferral;
public void Run(IBackgroundTaskInstance taskInstance)
{
serviceDeferral = taskInstance.GetDeferral();
BackgroundTaskDeferral arduinoDeferral = taskInstance.GetDeferral();
//ArduinoConnect test = new ArduinoConnect();
test2.WatchDevice();
Test();
test2.clState = false;
}
}
}
这是ArduinoConnect.cs
using System;
using System.Linq;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage.Streams;
namespace ArduinoData
{
public sealed class ArduinoConnect
{
DataReader dataReaderObject = null;
private SerialDevice serialPort = null;
private CancellationTokenSource ReadCancellationTokenSource;
private string rcvdText;
private string receivedChars;
//variabelen voor status
private bool clState;
private bool phPlusState;
private bool phMinState;
private bool pompState;
private bool lampenState;
private bool warmteState;
private bool vulState;
private bool waterState;
private byte dekState;
public void WatchDevice()
{
UInt16 vid = 0x2341;
UInt16 pid = 0x0001;
string aqs = SerialDevice.GetDeviceSelectorFromUsbVidPid(vid, pid);
var Watcher = DeviceInformation.CreateWatcher(aqs);
Watcher.Added += new TypedEventHandler<DeviceWatcher, DeviceInformation>(DeviceAdded);
Watcher.Removed += new TypedEventHandler<DeviceWatcher, DeviceInformationUpdate>(OnDeviceRemoved);
Watcher.Start();
}
private async void DeviceAdded(DeviceWatcher watcher, DeviceInformation device)
{
Debug.WriteLine("Debug: Apparaat gevonden! :)");
try
{
serialPort = await SerialDevice.FromIdAsync(device.Id);
Debug.WriteLine("Debug: " + device.Name + " verbonden!!! :D");
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.BaudRate = 9600;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
Debug.WriteLine("Debug: Seriële poort succesvol geconfigureerd! :D");
ReadCancellationTokenSource = new CancellationTokenSource();
}
catch
{
Debug.WriteLine("Debug: Fout bij Seriële poort configureren. :(");
}
Listen();
}
private async void Listen()
{
try
{
Debug.WriteLine("Debug: Listen() function");
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
// keep reading the serial input
while (true)
{
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
catch (TaskCanceledException)
{
Debug.WriteLine("Reading task was cancelled, closing device and cleaning up");
CloseDevice();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
finally
{
// Cleanup once complete
if (dataReaderObject != null)
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
// If task cancellation was requested, comply
cancellationToken.ThrowIfCancellationRequested();
// Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
// Create a task object to wait for data on the serialPort.InputStream
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
// Launch the task and wait
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
rcvdText = dataReaderObject.ReadString(bytesRead);
Debug.WriteLine("Debug: Succesvol gelezen van Arduino");
Debug.WriteLine(rcvdText);
char startMarker = '<';
char endMarker = '>';
if (rcvdText.Contains(startMarker) == true && rcvdText.Contains(endMarker) == true)
{
int startIndex = rcvdText.IndexOf(startMarker) + 1;
int endIndex = rcvdText.IndexOf(endMarker) - 1;
receivedChars = rcvdText.Substring(startIndex, endIndex);
Debug.WriteLine(receivedChars);
CheckNewData();
}
}
}
}
private void CheckNewData()
{
switch (receivedChars)
{
case "CL_STATE=0" :
clState = false;
break;
case "CL_STATE=1" :
clState = true;
break;
case "PHPLUS_STATE=0" :
phPlusState = false;
break;
case "PHPLUS_STATE=1" :
phPlusState = true;
break;
case "POMP_STATE=0" :
pompState = false;
break;
case "POMP_STATE=1" :
pompState = false;
break;
case "LAMPEN_STATE=0" :
lampenState = false;
break;
case "LAMPEN_STATE=1" :
lampenState = true;
break;
case "VUL_STATE=0" :
vulState = false;
break;
case "VUL_STATE=1" :
vulState = true;
break;
case "WATER_STATE=0" :
waterState = false;
break;
case "WATER_STATE=1" :
waterState = true;
break;
case "DEK_STATE=0" :
dekState = 0;
break;
case "DEK_STATE=1" :
dekState = 1;
break;
case "DEK_STATE=2" :
dekState = 2;
break;
case "REFRESH=1" :
Debug.WriteLine("Debug: Refresh uitgevoerd!");
break;
default:
Debug.WriteLine("Debug: Fout commando!");
break;
}
}
private void OnDeviceRemoved(DeviceWatcher sender, DeviceInformationUpdate device)
{
Debug.WriteLine("Debug: Apparaat losgekoppeld.");
try
{
CancelReadTask();
CloseDevice();
}
catch(Exception ex)
{
Debug.WriteLine("Debug: " + ex.Message);
}
}
private void CancelReadTask()
{
if (ReadCancellationTokenSource != null)
{
if (!ReadCancellationTokenSource.IsCancellationRequested)
{
ReadCancellationTokenSource.Cancel();
}
}
}
private void CloseDevice()
{
if (serialPort != null)
{
serialPort.Dispose();
}
serialPort = null;
rcvdText = "";
}
}
}
编辑
我遇到了这个代码的新问题 我上面的旧代码有时也遇到了同样的问题...
错误 抛出异常:System.Private.CoreLib.ni.dll 中的 'System.ArgumentOutOfRangeException' 索引和长度必须引用字符串中的位置。 参数名称:长度
无法正确粘贴,烦人...
if (bytesRead > 0)
{
rcvdText = dataReaderObject.ReadString(bytesRead);
Debug.WriteLine("Debug: Succesvol gelezen van Arduino");
Debug.WriteLine(rcvdText);
//char startMarker = '<';
//char endMarker = '>';
int i = 0;
foreach (var ch in rcvdText)
{
//if (ch != '\u+003C') continue;
if (ch == '\u003C')
{
StartIndex = i + 1;
Debug.WriteLine(StartIndex);
}
if (ch == '\u003E')
{
EndIndex = i - 1;
Debug.WriteLine(EndIndex);
receivedChars = rcvdText.Substring(StartIndex, EndIndex);
Debug.WriteLine(receivedChars);
StartIndex = 0;
EndIndex = 0;
}
i++;
Debug.WriteLine("test");
}
Debug.WriteLine("finished");
}
调试输出:
Debug: Succesvol gelezen van Arduino
<WATER_STATE=1>
<WATER_STATE=0>
1
test
test
test
test
test
test
test
test
test
test
test
test
test
test
13
WATER_STATE=1
test
test
test
18
test
test
test
test
test
test
test
test
test
test
test
test
test
test
30
Exception thrown: 'System.ArgumentOutOfRangeException' in System.Private.CoreLib.ni.dll
test2
Index and length must refer to a location within the string.
Parameter name: length
test2
The program '[2888] backgroundTaskHost.exe' has exited with code -1 (0xffffffff).
EDIT2 我想通了,我是个白痴...
But I wanted to make it look better so I wanted to put all the sensor stuff in a different file but I can't access or change any variable. For example, I want to change clState to true/false, I can't do that.
您可以像这样使用自动实现的属性:
public bool clState { get; set; }
更多信息您可以参考here。