4

さて、私はあなたが推測したreadSensorと呼ばれる関数を持っています..センサーを読み取ります。

しかし、センサーは通常、応答するのに約 100 ミリ秒かかります。したがって、 readSensor 関数では、基本的にタイマーを開始しています。

時限イベントで、シリアルポートを読み取り、応答を取得します。

ただし、これは、readSensor 関数に入れたいときに、応答が onTimedEvent にあることを意味します。

基本的にメインフォームからこれができるようにしたいです。

値 = readSensor()

現時点で私ができることは readSensor() だけであり、timedEvent が発生すると、応答がメッセージボックスに表示されることで返されていることがわかります。

これが私のコードです。(シリアルポートのセットアップなどをたくさん見逃してしまいましたが、私が抱えている問題を見ていただけると幸いです)

タイマーをポーリングしても、プログラムが遅くなるため、関数で100msだけ待機したくありません..

どうにかして応答を readSensor 関数に戻し、フォームに戻したいと考えています。

    using System;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO.Ports;
    using System.Timers;

    namespace readSensor
    {
      public partial class readSens : UserControl
      {
        public readSens()
        {
          InitializeComponent();
        }

        private System.Timers.Timer rTimer;
        SerialPort sp = new SerialPort();

        private void setupTimer()
        {
          // Create a timer with a 100ms response.
          rTimer = new System.Timers.Timer(100);
          rTimer.SynchronizingObject = this;
          // Hook up the Elapsed event for the timer.
          rTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        }

        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
          string response = getResponse();
        }

        public string getResponse()
        {
          string status = "";
          byte[] readBuffer = new byte[255];
          if (sp.IsOpen)
          {
            if (sp.BytesToRead > 0) //there is data to read
            {
              int length = sp.BytesToRead;

              for (int i = 0; i < length; i++)
              {
                readBuffer[i] = (byte)sp.ReadByte();
                status = "pass";
                return status;
              }
            }
         }

        public void readSensor(byte addr)
        {
          if (!sp.IsOpen)
          {
            openPort();
            readSensor(addr); // calls itself again once port is opened
          }
          else if (sp.IsOpen)
          {
            rTimer.Start();
          }
          else
          {
            MessageBox.Show("Port not opened yet");
          }
        }
      }
    }

メインフォームでは、基本的に言っているだけです

setupTimer();
readSensor(); 

ボタンクリックで。

4

3 に答える 3

1

別のスレッドを開始し、そのスレッドから結果をキューに書き込み、メイン スレッドに戻します。

class Game1
{
    //We declare a queue, which is like an array that we can extract and enter data easily in a FIFO (first in, first out) style list.
    Queue<string> q = new Queue<string>();

    public void threadStart(object obj)
    {
        //We get the result of your function, while our main function is still looping and waiting.
        string result = readInput()
        //We tell C# that the parameter we passed in, is in fact the Game1 class passed from "t.Start"
        Game1 game = (Game1)obj;
        //This puts our "result" into the queue.
        game.q.Enqueue(result);
    }

    public void start()
    {
        //Declares a new thread, which will run "threadStart" function.
        System.Threading.Thread t = new System.Threading.Thread(threadStart);

        //We start the other thread (that will run in parallel) and pass "this" as the parameter.
        t.Start(this);

        //We loop over and over, sleeping, whilst the other function runs at the same time. This is called "multi- threading"
        while (q.Count == 0)
        {
            System.Threading.Thread.Sleep(10);
        }

        //This gets the last-entered (oldest) value from the queue q.
        string result = q.Deque();
    }
}

したがって、これは結果を取得するためにスレッドを開始し、私のバージョンでは、結果が返されるまでしばらくの間キューをポーリングしますが、キューを時々チェックする限り、あなたのものではたくさんのことを行うことができます新しいデータ用。

編集:コメントを追加して、質問の一部を軽減できることを願っています。

于 2013-07-10T09:26:56.167 に答える