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