Newer
Older
ISCamRecorder / ISCamRecorder / SensorData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Management;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

namespace ISCamRecorder {

    /// <summary>
    /// センサーデータクラス
    /// </summary>
    internal class SensorData {

        readonly string SERIAL_PORT_NAME = "USB シリアル";  // デバイス名
        SerialPort _Serial = null;                          // シリアル通信オブジェクト
        Queue<int> ValuesB = new Queue<int>();               // センサー値
        Queue<int> ValuesR = new Queue<int>();               // センサー値
        Queue<int> ValuesG = new Queue<int>();               // センサー値
        Queue<DateTime> Times = new Queue<DateTime>();      // サンプル時間
        int _QueueLength;                                   // グラフ表示するサンプル数
        StreamWriter _CsvWriter = null;                     // ファイル保存オブジェクト
        FrameRateCounter _Fps = new FrameRateCounter(10);   // FPS計測
        int _LastButtonState = 0;                      // ボタンの前の状態
        MainForm _MainForm = null;                          // メインフォームインスタンス

        public float FrameRate { get { return _Fps.FrameRate; } }   // FPS値

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="mf"></param>
        public SensorData(MainForm mf, int queueLength) {
            _MainForm = mf;
            _QueueLength = queueLength;
        }

        /// <summary>
        /// 接続
        /// </summary>
        /// <returns></returns>
        public bool Connect() {

            // シリアルポート接続 
            var portname = GetSerialPort();
            if (portname.Length < 1) {
                MessageBox.Show("シリアルデバイスに接続できません", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            _Serial = new SerialPort {
                PortName = portname,
                BaudRate = 115200,
                DataBits = 8,
                Parity = Parity.None,
                StopBits = StopBits.One,
                Handshake = Handshake.None,
                Encoding = Encoding.ASCII,
                WriteTimeout = 1000,
                ReadTimeout = 1000,
                RtsEnable = true,
            };
            try {
                _Serial.Open();
            } catch (Exception ex) {
                Debug.WriteLine(ex.Message);
                return false;
            }
            Debug.WriteLine($"Serial Connect {portname}");
            return true;
        }

        /// <summary>
        /// 受信ループ
        /// </summary>
        public void Loop() {
            while (_MainForm.State != STATE.Exit) {

                // データ受信
                var str = _Serial.ReadLine();
                var strs = str.Split(',');
                if (strs.Length < 5) continue;
                var values = strs.Select(s => int.Parse(s)).ToArray();

                // ボタン状態
                var buttonState = (1 - values[4]);
                if (_LastButtonState == 0 && buttonState == 1 && _MainForm.SwitchEnabled) {
                    _MainForm.StartRecoding();
                }
                _LastButtonState = buttonState;

                // センサー値
                //var photoSensor = int.Parse(values[1]);
                var dt = DateTime.Now;
                var elapsed = (dt - _MainForm.RecodingTime).TotalMilliseconds;

                // CSV保存
                if (_MainForm.State == STATE.Recoding) {
                    if (_CsvWriter == null) {
                        var sensorFile = Path.Combine(_MainForm.OutputDir, $"Sensor_{_MainForm.RecodingTimeStr}.csv");
                        _CsvWriter = new StreamWriter(sensorFile);
                        if (_CsvWriter != null) {
                            _CsvWriter.WriteLine($"Date,Time,elapsed,B,R,G,IR,switch");
                        }
                    }
                    if (_CsvWriter != null) {
                        _CsvWriter.WriteLine(
                            $"{dt.ToString("yyyy/MM/dd,HH:mm:ss.fff")},{elapsed:0.00}" + 
                            $",{values[0]},{values[1]},{values[2]},{values[3]},{buttonState}");
                    }
                } else {
                    if (_CsvWriter != null) {
                        _CsvWriter.Close();
                        _CsvWriter = null;
                    }
                }

                // データ追加
                ValuesB.Enqueue(values[0]);
                ValuesR.Enqueue(values[1]);
                ValuesG.Enqueue(values[2]);
                Times.Enqueue(dt);
                if (ValuesB.Count > _QueueLength) {
                    ValuesB.Dequeue();
                    ValuesR.Dequeue();
                    ValuesG.Dequeue();
                    Times.Dequeue();
                }

                // 表示
                if (_MainForm.State != STATE.Exit) {
                    _MainForm.SensorChart.Invoke((MethodInvoker)delegate {
                        _MainForm.SensorChart.Series[0].Points.Clear();
                        _MainForm.SensorChart.Series[0].Points.DataBindXY(Times, ValuesB);
                        _MainForm.SensorChart.Series[1].Points.Clear();
                        _MainForm.SensorChart.Series[1].Points.DataBindXY(Times, ValuesR);
                        _MainForm.SensorChart.Series[2].Points.Clear();
                        _MainForm.SensorChart.Series[2].Points.DataBindXY(Times, ValuesG);
                    });
                }

                _Fps.Shot();
            }

            _Serial?.Close();
            _Serial = null;
        }

        /// <summary>
        /// シリアルポート取得
        /// </summary>
        /// <returns></returns>
        private string GetSerialPort() {
            var portname = "";
            var mcW32SerPort = new ManagementClass("Win32_SerialPort");
            foreach (var port in mcW32SerPort.GetInstances()) {
                if (port.GetPropertyValue("Caption").ToString().Contains(SERIAL_PORT_NAME)) {
                    portname = port.GetPropertyValue("DeviceID").ToString();
                }
            }
            return portname;
        }
    }
}