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;
}
}
}