This commit is contained in:
ChiKyun Kim
2025-12-04 17:10:42 +09:00
parent 34ad1db0e3
commit 8459230053
13 changed files with 540 additions and 1121 deletions

View File

@@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 15 for Windows Desktop # Visual Studio Version 17
VisualStudioVersion = 15.0.36324.19 VisualStudioVersion = 17.14.36310.24
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sub", "Sub", "{C423C39A-44E7-4F09-B2F7-7943975FF948}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sub", "Sub", "{C423C39A-44E7-4F09-B2F7-7943975FF948}"
EndProject EndProject
@@ -9,8 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StateMachine", "StateMachin
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "agvControl", "SubProject\AGVControl\agvControl.csproj", "{8CB883C0-99C3-4DD4-B017-F9B92010A806}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "agvControl", "SubProject\AGVControl\agvControl.csproj", "{8CB883C0-99C3-4DD4-B017-F9B92010A806}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMS", "SubProject\BMS\BMS.csproj", "{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SWPatch", "SubProject\Patch\SWPatch.csproj", "{37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SWPatch", "SubProject\Patch\SWPatch.csproj", "{37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NARUMI", "SubProject\AGV\NARUMI.csproj", "{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NARUMI", "SubProject\AGV\NARUMI.csproj", "{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}"
@@ -38,6 +36,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AGVMapEditor", "AGVLogic\AG
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AGVSimulator", "AGVLogic\AGVSimulator\AGVSimulator.csproj", "{B2C3D4E5-0000-0000-0000-000000000000}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AGVSimulator", "AGVLogic\AGVSimulator\AGVSimulator.csproj", "{B2C3D4E5-0000-0000-0000-000000000000}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{C8D5274F-AC00-46C7-1F8D-E88E81087A52}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_BMS", "TestProject\Test_BMS\Test_BMS.csproj", "{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -72,18 +74,6 @@ Global
{8CB883C0-99C3-4DD4-B017-F9B92010A806}.Release|x64.Build.0 = Release|Any CPU {8CB883C0-99C3-4DD4-B017-F9B92010A806}.Release|x64.Build.0 = Release|Any CPU
{8CB883C0-99C3-4DD4-B017-F9B92010A806}.Release|x86.ActiveCfg = Release|Any CPU {8CB883C0-99C3-4DD4-B017-F9B92010A806}.Release|x86.ActiveCfg = Release|Any CPU
{8CB883C0-99C3-4DD4-B017-F9B92010A806}.Release|x86.Build.0 = Release|Any CPU {8CB883C0-99C3-4DD4-B017-F9B92010A806}.Release|x86.Build.0 = Release|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Debug|x64.ActiveCfg = Debug|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Debug|x64.Build.0 = Debug|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Debug|x86.ActiveCfg = Debug|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Debug|x86.Build.0 = Debug|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Release|Any CPU.Build.0 = Release|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Release|x64.ActiveCfg = Release|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Release|x64.Build.0 = Release|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Release|x86.ActiveCfg = Release|Any CPU
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}.Release|x86.Build.0 = Release|Any CPU
{37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU {37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}.Debug|x64.ActiveCfg = Debug|Any CPU {37DC0BAE-50BF-41E4-BAAB-B0E211467AD1}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -180,19 +170,31 @@ Global
{B2C3D4E5-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|Any CPU {B2C3D4E5-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|Any CPU
{B2C3D4E5-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|Any CPU {B2C3D4E5-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|Any CPU
{B2C3D4E5-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|Any CPU {B2C3D4E5-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|x64.ActiveCfg = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|x64.Build.0 = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|x86.ActiveCfg = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|x86.Build.0 = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|Any CPU.Build.0 = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|x64.ActiveCfg = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|x64.Build.0 = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|x86.ActiveCfg = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{8CB883C0-99C3-4DD4-B017-F9B92010A806} = {C423C39A-44E7-4F09-B2F7-7943975FF948} {8CB883C0-99C3-4DD4-B017-F9B92010A806} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
{7A94C30C-6772-4F71-BF9C-0DF071A1BC70} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7} = {C423C39A-44E7-4F09-B2F7-7943975FF948} {8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
{14E8C9A5-013E-49BA-B435-EFEFC77DD623} = {C423C39A-44E7-4F09-B2F7-7943975FF948} {14E8C9A5-013E-49BA-B435-EFEFC77DD623} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
{9365803B-933D-4237-93C7-B502C855A71C} = {C423C39A-44E7-4F09-B2F7-7943975FF948} {9365803B-933D-4237-93C7-B502C855A71C} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
{C5F7A8B2-8D3E-4A1B-9C6E-7F4D5E2A9B1C} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB} {C5F7A8B2-8D3E-4A1B-9C6E-7F4D5E2A9B1C} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB}
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB} {A1B2C3D4-E5F6-7890-ABCD-EF1234567890} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB}
{B2C3D4E5-0000-0000-0000-000000000000} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB} {B2C3D4E5-0000-0000-0000-000000000000} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB}
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E} = {C8D5274F-AC00-46C7-1F8D-E88E81087A52}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B5B1FD72-356F-4840-83E8-B070AC21C8D9} SolutionGuid = {B5B1FD72-356F-4840-83E8-B070AC21C8D9}

View File

@@ -184,6 +184,8 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>DataSet1.xsd</DependentUpon> <DependentUpon>DataSet1.xsd</DependentUpon>
</Compile> </Compile>
<Compile Include="Device\BMS.cs" />
<Compile Include="Device\BMSInformationEventArgs.cs" />
<Compile Include="Device\CFlag.cs" /> <Compile Include="Device\CFlag.cs" />
<Compile Include="Device\xbee.cs" /> <Compile Include="Device\xbee.cs" />
<Compile Include="Device\Socket.cs" /> <Compile Include="Device\Socket.cs" />
@@ -545,10 +547,6 @@
<Project>{8bae0eac-3d25-402f-9a65-2ba1ecfe28b7}</Project> <Project>{8bae0eac-3d25-402f-9a65-2ba1ecfe28b7}</Project>
<Name>NARUMI</Name> <Name>NARUMI</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\SubProject\BMS\BMS.csproj">
<Project>{7a94c30c-6772-4f71-bf9c-0df071a1bc70}</Project>
<Name>BMS</Name>
</ProjectReference>
<ProjectReference Include="..\SubProject\CommData\CommData.csproj"> <ProjectReference Include="..\SubProject\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project> <Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name> <Name>CommData</Name>

View File

@@ -1,424 +1,426 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.ComponentModel; using System.ComponentModel;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.CodeDom; using System.CodeDom;
namespace arDev namespace arDev
{ {
public class BMS : arRS232 public class BMS : arRS232
{ {
public BMS() public BMS()
{ {
MinRecvLength = 34; MinRecvLength = 34;
} }
/// <summary> /// <summary>
/// 시리얼포트의 핀 상태값이 변경될 때 발생합니다. /// 시리얼포트의 핀 상태값이 변경될 때 발생합니다.
/// </summary> /// </summary>
public event EventHandler<BMSInformationEventArgs> BMSDataReceive; public event EventHandler<BMSInformationEventArgs> BMSDataReceive;
public event EventHandler<BMSCelvoltageEventArgs> BMSCellDataReceive; public event EventHandler<BMSCelvoltageEventArgs> BMSCellDataReceive;
protected override bool CustomParser(byte[] buf, out byte[] remainBuffer) protected override bool CustomParser(byte[] buf, out byte[] remainBuffer)
{ {
List<byte> remain = new List<byte>(); List<byte> remain = new List<byte>();
//데이터는 총 34byt 이며 , DD~77로 구성됨 //데이터는 총 34byt 이며 , DD~77로 구성됨
Boolean bComplete = false; Boolean bComplete = false;
for (int i = 0; i < buf.Length; i++) for (int i = 0; i < buf.Length; i++)
{ {
var incomByte = buf[i]; var incomByte = buf[i];
if (bComplete == true) if (bComplete == true)
{ {
remain.Add(incomByte); remain.Add(incomByte);
} }
else else
{ {
if (findSTX == false) if (findSTX == false)
{ {
if (incomByte != 0xDD) if (incomByte != 0xDD)
{ {
//버리는데이터 //버리는데이터
} }
else else
{ {
findSTX = true; findSTX = true;
tempBuffer.Clear(); tempBuffer.Clear();
tempBuffer.Add(incomByte); tempBuffer.Add(incomByte);
} }
} }
else else
{ {
tempBuffer.Add(incomByte); tempBuffer.Add(incomByte);
var queylen = QueryIndex == 0 ? 34 : 23; var queylen = QueryIndex == 0 ? 34 : 23;
if (tempBuffer.Count == queylen) if (tempBuffer.Count == queylen)
{ {
if (incomByte != 0x77) if (incomByte != 0x77)
{ {
//종단기호가 맞지 않다. 이자료는 폐기한다. //종단기호가 맞지 않다. 이자료는 폐기한다.
tempBuffer.Clear(); var hexstr = string.Join(" ", tempBuffer.Select(t => t.ToString("X2")));
} RaiseMessage(MessageType.Error, $"discard : {hexstr}");
else tempBuffer.Clear();
{ }
//데이터가 맞게 수신됨 else
LastReceiveBuffer = tempBuffer.ToArray(); {
bComplete = true; //데이터가 맞게 수신됨
} LastReceiveBuffer = tempBuffer.ToArray();
findSTX = false; bComplete = true;
} }
else findSTX = false;
{ }
//아직 모자르므로 대기한다 else
} {
} //아직 모자르므로 대기한다
} }
} }
}
remainBuffer = remain.ToArray(); }
return bComplete;
} remainBuffer = remain.ToArray();
return bComplete;
bool Recv0 = false; }
bool Recv1 = false;
public event EventHandler<ChargetDetectArgs> ChargeDetect; bool Recv0 = false;
public override bool ProcessRecvData(byte[] data) bool Recv1 = false;
{ public event EventHandler<ChargetDetectArgs> ChargeDetect;
//LastReceiveBuffer public override bool ProcessRecvData(byte[] data)
if (data == null) {
{ //LastReceiveBuffer
RaiseMessage(MessageType.Error, "수신 데이터가 없습니다"); if (data == null)
return false; {
} RaiseMessage(MessageType.Error, "수신 데이터가 없습니다");
return false;
var datalne = QueryIndex == 0 ? 34 : 23; }
if (data.Length != datalne)
{ var datalne = QueryIndex == 0 ? 34 : 23;
RaiseMessage(MessageType.Error, $"데이터의 길이가 {MinRecvLength}가 아닙니다 길이={data.Length}"); if (data.Length != datalne)
return false; {
} RaiseMessage(MessageType.Error, $"데이터의 길이가 {MinRecvLength}가 아닙니다 길이={data.Length}");
return false;
if (QueryIndex == 0) }
{
return ParseBMSInfo(); if (QueryIndex == 0)
} {
else return ParseBMSInfo();
{ }
return ParseBMSCellVoltage(); else
} {
return ParseBMSCellVoltage();
}
}
bool ParseBMSCellVoltage()
{ }
//var i = 0; bool ParseBMSCellVoltage()
var BatteryCell_Checksum = 0xffff;// - (LastReceiveBuffer[i + 3] + LastReceiveBuffer[i + 4] + LastReceiveBuffer[i + 5] + LastReceiveBuffer[i + 6] + LastReceiveBuffer[i + 7] + LastReceiveBuffer[i + 8] + LastReceiveBuffer[i + 9] + LastReceiveBuffer[i + 10] + LastReceiveBuffer[i + 11] + LastReceiveBuffer[i + 12] + LastReceiveBuffer[i + 13] + LastReceiveBuffer[i + 14] + LastReceiveBuffer[i + 15] + LastReceiveBuffer[i + 16] + LastReceiveBuffer[i + 17] + LastReceiveBuffer[i + 18] + LastReceiveBuffer[i + 19])) + 1; {
for (int i = 3; i < 20; i++) //var i = 0;
{ var BatteryCell_Checksum = 0xffff;// - (LastReceiveBuffer[i + 3] + LastReceiveBuffer[i + 4] + LastReceiveBuffer[i + 5] + LastReceiveBuffer[i + 6] + LastReceiveBuffer[i + 7] + LastReceiveBuffer[i + 8] + LastReceiveBuffer[i + 9] + LastReceiveBuffer[i + 10] + LastReceiveBuffer[i + 11] + LastReceiveBuffer[i + 12] + LastReceiveBuffer[i + 13] + LastReceiveBuffer[i + 14] + LastReceiveBuffer[i + 15] + LastReceiveBuffer[i + 16] + LastReceiveBuffer[i + 17] + LastReceiveBuffer[i + 18] + LastReceiveBuffer[i + 19])) + 1;
BatteryCell_Checksum -= LastReceiveBuffer[i];// + LastReceiveBuffer[i + 4] + LastReceiveBuffer[i + 5] + LastReceiveBuffer[i + 6] + LastReceiveBuffer[i + 7] + LastReceiveBuffer[i + 8] + LastReceiveBuffer[i + 9] + LastReceiveBuffer[i + 10] + LastReceiveBuffer[i + 11] + LastReceiveBuffer[i + 12] + LastReceiveBuffer[i + 13] + LastReceiveBuffer[i + 14] + LastReceiveBuffer[i + 15] + LastReceiveBuffer[i + 16] + LastReceiveBuffer[i + 17] + LastReceiveBuffer[i + 18] + LastReceiveBuffer[i + 19])) + 1; for (int i = 3; i < 20; i++)
} {
BatteryCell_Checksum -= LastReceiveBuffer[i];// + LastReceiveBuffer[i + 4] + LastReceiveBuffer[i + 5] + LastReceiveBuffer[i + 6] + LastReceiveBuffer[i + 7] + LastReceiveBuffer[i + 8] + LastReceiveBuffer[i + 9] + LastReceiveBuffer[i + 10] + LastReceiveBuffer[i + 11] + LastReceiveBuffer[i + 12] + LastReceiveBuffer[i + 13] + LastReceiveBuffer[i + 14] + LastReceiveBuffer[i + 15] + LastReceiveBuffer[i + 16] + LastReceiveBuffer[i + 17] + LastReceiveBuffer[i + 18] + LastReceiveBuffer[i + 19])) + 1;
BatteryCell_Checksum += 1; }
var recvchecksum = BitConverter.ToUInt16(LastReceiveBuffer.Skip(20).Take(2).Reverse().ToArray(), 0);
if (recvchecksum == BatteryCell_Checksum) BatteryCell_Checksum += 1;
{ var recvchecksum = BitConverter.ToUInt16(LastReceiveBuffer.Skip(20).Take(2).Reverse().ToArray(), 0);
var v1 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(4).Take(2).Reverse().ToArray(), 0) / 1000.0; if (recvchecksum == BatteryCell_Checksum)
var v2 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(6).Take(2).Reverse().ToArray(), 0) / 1000.0; {
var v3 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(8).Take(2).Reverse().ToArray(), 0) / 1000.0; var v1 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(4).Take(2).Reverse().ToArray(), 0) / 1000.0;
var v4 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(10).Take(2).Reverse().ToArray(), 0) / 1000.0; var v2 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(6).Take(2).Reverse().ToArray(), 0) / 1000.0;
var v5 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(12).Take(2).Reverse().ToArray(), 0) / 1000.0; var v3 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(8).Take(2).Reverse().ToArray(), 0) / 1000.0;
var v6 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(14).Take(2).Reverse().ToArray(), 0) / 1000.0; var v4 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(10).Take(2).Reverse().ToArray(), 0) / 1000.0;
var v7 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(16).Take(2).Reverse().ToArray(), 0) / 1000.0; var v5 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(12).Take(2).Reverse().ToArray(), 0) / 1000.0;
var v8 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(18).Take(2).Reverse().ToArray(), 0) / 1000.0; var v6 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(14).Take(2).Reverse().ToArray(), 0) / 1000.0;
var v7 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(16).Take(2).Reverse().ToArray(), 0) / 1000.0;
var idx = 0; var v8 = BitConverter.ToUInt16(LastReceiveBuffer.Skip(18).Take(2).Reverse().ToArray(), 0) / 1000.0;
CellVoltage[idx++] = v1;
CellVoltage[idx++] = v2; var idx = 0;
CellVoltage[idx++] = v3; CellVoltage[idx++] = v1;
CellVoltage[idx++] = v4; CellVoltage[idx++] = v2;
CellVoltage[idx++] = v5; CellVoltage[idx++] = v3;
CellVoltage[idx++] = v6; CellVoltage[idx++] = v4;
CellVoltage[idx++] = v7; CellVoltage[idx++] = v5;
CellVoltage[idx++] = v8; CellVoltage[idx++] = v6;
CellVoltage[idx++] = v7;
Recv1 = true; CellVoltage[idx++] = v8;
try Recv1 = true;
{
BMSCellDataReceive?.Invoke(this, new BMSCelvoltageEventArgs(v1, v2, v3, v4, v5, v6, v7, v8)); try
Current_CellTime = DateTime.Now; {
return true; BMSCellDataReceive?.Invoke(this, new BMSCelvoltageEventArgs(v1, v2, v3, v4, v5, v6, v7, v8));
} Current_CellTime = DateTime.Now;
catch (Exception ex) return true;
{ }
RaiseMessage(MessageType.Error, ex.Message); catch (Exception ex)
return false; {
} RaiseMessage(MessageType.Error, ex.Message);
} return false;
else return false; }
}
else return false;
}
bool ParseBMSInfo()
{ }
//전압확인 bool ParseBMSInfo()
UInt16 batH = (UInt16)LastReceiveBuffer[4]; {
UInt16 batL = (UInt16)LastReceiveBuffer[5]; //전압확인
batH = (UInt16)(batH << 8); UInt16 batH = (UInt16)LastReceiveBuffer[4];
batH = (UInt16)(batH | batL); UInt16 batL = (UInt16)LastReceiveBuffer[5];
Current_Volt = (float)(batH / 100.0); batH = (UInt16)(batH << 8);
batH = (UInt16)(batH | batL);
//잔량확인 Current_Volt = (float)(batH / 100.0);
batH = (UInt16)LastReceiveBuffer[8];
batL = (UInt16)LastReceiveBuffer[9]; //잔량확인
batH = (UInt16)(batH << 8); batH = (UInt16)LastReceiveBuffer[8];
batH = (UInt16)(batH | batL); batL = (UInt16)LastReceiveBuffer[9];
var newamp = (int)batH; batH = (UInt16)(batH << 8);
var Changed = newamp != Current_Amp; batH = (UInt16)(batH | batL);
Current_Amp = newamp; var newamp = (int)batH;
var Changed = newamp != Current_Amp;
//총량확인 Current_Amp = newamp;
batH = (UInt16)LastReceiveBuffer[10];
batL = (UInt16)LastReceiveBuffer[11]; //총량확인
batH = (UInt16)(batH << 8); batH = (UInt16)LastReceiveBuffer[10];
batH = (UInt16)(batH | batL); batL = (UInt16)LastReceiveBuffer[11];
Current_MaxAmp = (int)batH; batH = (UInt16)(batH << 8);
batH = (UInt16)(batH | batL);
//남은 % 계산 Current_MaxAmp = (int)batH;
float levraw = (float)(Current_Amp / (Current_MaxAmp * 1.0));
Current_Level = (float)(levraw * 100.0);// (float)(map(remain, 0, total, 0, 100)); //남은 % 계산
Current_LevelA = LastReceiveBuffer[23]; //<- 23번자료는 byte이므로 소수점이잇는 데이터로 직접 계산한다 float levraw = (float)(Current_Amp / (Current_MaxAmp * 1.0));
Current_Level = (float)(levraw * 100.0);// (float)(map(remain, 0, total, 0, 100));
Current_LevelA = LastReceiveBuffer[23]; //<- 23번자료는 byte이므로 소수점이잇는 데이터로 직접 계산한다
//250620 jwlee 추가
int temp1 = (LastReceiveBuffer[27] << 8) | LastReceiveBuffer[28];
int temp2 = (LastReceiveBuffer[29] << 8) | LastReceiveBuffer[30]; //250620 jwlee 추가
int temp1 = (LastReceiveBuffer[27] << 8) | LastReceiveBuffer[28];
Current_temp1 = (temp1 - 2731) / 10f; int temp2 = (LastReceiveBuffer[29] << 8) | LastReceiveBuffer[30];
Current_temp2 = (temp2 - 2731) / 10f;
Current_temp1 = (temp1 - 2731) / 10f;
CheckManualCharge(); Current_temp2 = (temp2 - 2731) / 10f;
Recv0 = true; CheckManualCharge();
try Recv0 = true;
{
BMSDataReceive?.Invoke(this, new BMSInformationEventArgs(Current_Volt, Current_Amp, Current_MaxAmp, Current_Level, Changed)); try
Current_DataTime = DateTime.Now; {
return true; BMSDataReceive?.Invoke(this, new BMSInformationEventArgs(Current_Volt, Current_Amp, Current_MaxAmp, Current_Level, Changed));
} Current_DataTime = DateTime.Now;
catch (Exception ex) return true;
{ }
RaiseMessage(MessageType.Error, ex.Message); catch (Exception ex)
return false; {
} RaiseMessage(MessageType.Error, ex.Message);
} return false;
}
private bool _autocharge = false; }
public Boolean AutoCharge
{ private bool _autocharge = false;
get { return _autocharge; } public Boolean AutoCharge
set { _autocharge = false; } {
} get { return _autocharge; }
set { _autocharge = false; }
//public void ClearManualChargeCheckValue() }
//{
// chk_timee = new DateTime(1982, 11, 23); //public void ClearManualChargeCheckValue()
// chk_times = new DateTime(1982, 11, 23); //{
// chk_valuee = 0f; // chk_timee = new DateTime(1982, 11, 23);
// chk_values = 0f; // chk_times = new DateTime(1982, 11, 23);
//} // chk_valuee = 0f;
// chk_values = 0f;
void CheckManualCharge() //}
{
if (AutoCharge) void CheckManualCharge()
{ {
if (chk_timee.Year != 1982) if (AutoCharge)
{ {
chk_timee = new DateTime(1982, 11, 23); if (chk_timee.Year != 1982)
chk_valuee = 999f; {
} chk_timee = new DateTime(1982, 11, 23);
if (chk_times.Year != 1982) chk_valuee = 999f;
{ }
chk_times = new DateTime(1982, 11, 23); if (chk_times.Year != 1982)
chk_values = 999f; {
} chk_times = new DateTime(1982, 11, 23);
} chk_values = 999f;
if (chk_times.Year == 1982) }
{ }
chk_times = DateTime.Now; if (chk_times.Year == 1982)
chk_values = Current_Level; {
} chk_times = DateTime.Now;
else chk_values = Current_Level;
{ }
if (chk_timee.Year == 1982) else
{ {
if ((Current_Level - chk_values) >= 0.1) if (chk_timee.Year == 1982)
{ {
//충전중이다 if ((Current_Level - chk_values) >= 0.1)
chk_timee = DateTime.Now; {
chk_valuee = Current_Level; //충전중이다
try chk_timee = DateTime.Now;
{ chk_valuee = Current_Level;
ChargeDetect?.Invoke(this, new ChargetDetectArgs(chk_times, chk_values, chk_timee, chk_valuee)); try
} {
catch (Exception ex) { RaiseMessage(MessageType.Error, ex.Message); } ChargeDetect?.Invoke(this, new ChargetDetectArgs(chk_times, chk_values, chk_timee, chk_valuee));
}
} catch (Exception ex) { RaiseMessage(MessageType.Error, ex.Message); }
else if ((Current_Level - chk_values) <= -0.1)
{ }
//방전중이다 else if ((Current_Level - chk_values) <= -0.1)
if (chk_times.Year != 1982) chk_times = new DateTime(1982, 11, 23); {
if (chk_timee.Year != 1982) chk_timee = new DateTime(1982, 11, 23); //방전중이다
} if (chk_times.Year != 1982) chk_times = new DateTime(1982, 11, 23);
else if (chk_timee.Year != 1982) chk_timee = new DateTime(1982, 11, 23);
{ }
//아직 변화가 없으니 종료일을 기록하지 않는다 else
} {
} //아직 변화가 없으니 종료일을 기록하지 않는다
else }
{ }
//이미 종료일이 셋팅된 상태이다 else
if ((Current_Level - chk_valuee) >= 0.1) {
{ //이미 종료일이 셋팅된 상태이다
//종료시간을 시작값에 넣는다 if ((Current_Level - chk_valuee) >= 0.1)
chk_times = chk_timee; {
chk_values = chk_valuee; //종료시간을 시작값에 넣는다
chk_times = chk_timee;
chk_timee = DateTime.Now; chk_values = chk_valuee;
chk_valuee = Current_Level;
try chk_timee = DateTime.Now;
{ chk_valuee = Current_Level;
ChargeDetect?.Invoke(this, new ChargetDetectArgs(chk_times, chk_values, chk_timee, chk_valuee)); try
} {
catch (Exception ex) { RaiseMessage(MessageType.Error, ex.Message); } ChargeDetect?.Invoke(this, new ChargetDetectArgs(chk_times, chk_values, chk_timee, chk_valuee));
} }
else if ((Current_Level - chk_valuee) <= -0.1) catch (Exception ex) { RaiseMessage(MessageType.Error, ex.Message); }
{ }
//방전중이다 else if ((Current_Level - chk_valuee) <= -0.1)
if (chk_times.Year != 1982) chk_times = new DateTime(1982, 11, 23); {
if (chk_timee.Year != 1982) chk_timee = new DateTime(1982, 11, 23); //방전중이다
} if (chk_times.Year != 1982) chk_times = new DateTime(1982, 11, 23);
else if (chk_timee.Year != 1982) chk_timee = new DateTime(1982, 11, 23);
{ }
//아직 변화가 없으니 종료일을 기록하지 않는다 else
} {
} //아직 변화가 없으니 종료일을 기록하지 않는다
}
} }
}
}
}
public DateTime chk_times { get; set; } = new DateTime(1982, 11, 23);
public DateTime chk_timee { get; set; } = new DateTime(1982, 11, 23);
public float chk_values { get; set; } = 0f; public DateTime chk_times { get; set; } = new DateTime(1982, 11, 23);
public float chk_valuee { get; set; } = 0f; public DateTime chk_timee { get; set; } = new DateTime(1982, 11, 23);
public float chk_values { get; set; } = 0f;
/// <summary> public float chk_valuee { get; set; } = 0f;
/// 전압
/// </summary> /// <summary>
public float Current_Volt { get; set; } /// 전압
/// <summary> /// </summary>
/// 남은 잔량(%) public float Current_Volt { get; set; }
/// </summary> /// <summary>
public float Current_Level { get; set; } /// 남은 잔량(%)
public double[] CellVoltage = new double[] { 0, 0, 0, 0, 0, 0, 0, 0 }; /// </summary>
public float Current_Level { get; set; }
public float Current_LevelA { get; set; } public double[] CellVoltage = new double[] { 0, 0, 0, 0, 0, 0, 0, 0 };
/// <summary> public float Current_LevelA { get; set; }
/// 남은 전류량
/// </summary> /// <summary>
public int Current_Amp { get; set; } /// 남은 전류량
/// </summary>
/// <summary> public int Current_Amp { get; set; }
/// BMS 온도값1
/// </summary> /// <summary>
public double Current_temp1 { get; set; } /// BMS 온도값1
/// </summary>
/// <summary> public double Current_temp1 { get; set; }
/// BMS 온도값2
/// </summary> /// <summary>
public double Current_temp2 { get; set; } /// BMS 온도값2
/// </summary>
/// <summary> public double Current_temp2 { get; set; }
/// 총 전류량
/// </summary> /// <summary>
public int Current_MaxAmp { get; set; } /// 총 전류량
/// </summary>
public DateTime Current_DataTime = DateTime.Parse("1982-11-23"); public int Current_MaxAmp { get; set; }
public DateTime Current_CellTime = DateTime.Parse("1982-11-23");
public DateTime Current_DataTime = DateTime.Parse("1982-11-23");
public int QueryIndex { get; set; } = 0; public DateTime Current_CellTime = DateTime.Parse("1982-11-23");
/// <summary> public int QueryIndex { get; set; } = 0;
/// 상태읽기와 전압읽기명령을 반복합니다
/// </summary> /// <summary>
/// <returns></returns> /// 상태읽기와 전압읽기명령을 반복합니다
public Boolean SendQuery() /// </summary>
{ /// <returns></returns>
if (QueryIndex == 0) public Boolean SendQuery()
{ {
if (Recv0 == true) if (QueryIndex == 0)
{ {
QueryIndex = 1; if (Recv0 == true)
Recv1 = false; {
return true; QueryIndex = 1;
} Recv1 = false;
else return true;
{ }
return SendQuery_ReadStatue(); else
} {
} return SendQuery_ReadStatue();
else }
{ }
if (Recv1 == true) else
{ {
QueryIndex = 0; if (Recv1 == true)
Recv0 = false; {
return true; QueryIndex = 0;
} Recv0 = false;
else return true;
{ }
return SendQuery_ReadCellvoltage(); else
} {
} return SendQuery_ReadCellvoltage();
} }
}
public Boolean SendQuery_ReadStatue() }
{
Recv0 = false; public Boolean SendQuery_ReadStatue()
var cmd = new List<byte>(); {
cmd.Add(0xDD); Recv0 = false;
cmd.Add(0xA5); var cmd = new List<byte>();
cmd.Add(0x03); cmd.Add(0xDD);
cmd.Add(0x00); cmd.Add(0xA5);
cmd.Add(0xFF); cmd.Add(0x03);
cmd.Add(0xFD); cmd.Add(0x00);
cmd.Add(0x77); cmd.Add(0xFF);
cmd.Add(0x0D); cmd.Add(0xFD);
return WriteData(cmd.ToArray()); cmd.Add(0x77);
} cmd.Add(0x0D);
return WriteData(cmd.ToArray());
}
public Boolean SendQuery_ReadCellvoltage()
{
Recv1 = false; public Boolean SendQuery_ReadCellvoltage()
var cmd = new List<byte>(); {
cmd.Add(0xDD); Recv1 = false;
cmd.Add(0xA5); var cmd = new List<byte>();
cmd.Add(0x04); cmd.Add(0xDD);
cmd.Add(0x00); cmd.Add(0xA5);
cmd.Add(0xFF); cmd.Add(0x04);
cmd.Add(0xFC); cmd.Add(0x00);
cmd.Add(0x77); cmd.Add(0xFF);
cmd.Add(0x0D); cmd.Add(0xFC);
return WriteData(cmd.ToArray()); cmd.Add(0x77);
} cmd.Add(0x0D);
return WriteData(cmd.ToArray());
} }
}
}
}

View File

@@ -1,44 +1,44 @@
using System; using System;
namespace arDev namespace arDev
{ {
public class ChargetDetectArgs : EventArgs public class ChargetDetectArgs : EventArgs
{ {
public DateTime times { get; set; } public DateTime times { get; set; }
public DateTime timee { get; set; } public DateTime timee { get; set; }
public float values { get; set; } public float values { get; set; }
public float valuee { get; set; } public float valuee { get; set; }
public ChargetDetectArgs(DateTime times, float values, DateTime timee, float valuee) public ChargetDetectArgs(DateTime times, float values, DateTime timee, float valuee)
{ {
this.times = times; this.times = times;
this.times = timee; this.times = timee;
this.values = values; this.values = values;
this.valuee = valuee; this.valuee = valuee;
} }
} }
public class BMSInformationEventArgs : EventArgs public class BMSInformationEventArgs : EventArgs
{ {
public float Volt { get; set; } public float Volt { get; set; }
public int CurAmp { get; set; } public int CurAmp { get; set; }
public int MaxAmp { get; set; } public int MaxAmp { get; set; }
public float Level { get; set; } public float Level { get; set; }
public bool Changed { get; set; } public bool Changed { get; set; }
public BMSInformationEventArgs(float _volt, int _curamp, int _maxamp, float _level, bool _changed) public BMSInformationEventArgs(float _volt, int _curamp, int _maxamp, float _level, bool _changed)
{ {
this.Volt = _volt; this.Volt = _volt;
this.CurAmp = _curamp; this.CurAmp = _curamp;
this.MaxAmp = _maxamp; this.MaxAmp = _maxamp;
this.Level = _level; this.Level = _level;
this.Changed = _changed; this.Changed = _changed;
} }
} }
public class BMSCelvoltageEventArgs : EventArgs public class BMSCelvoltageEventArgs : EventArgs
{ {
public double[] voltage; public double[] voltage;
public BMSCelvoltageEventArgs(double v1, double v2, double v3, double v4, double v5, double v6, double v7, double v8) public BMSCelvoltageEventArgs(double v1, double v2, double v3, double v4, double v5, double v6, double v7, double v8)
{ {
voltage = new double[] { v1, v2, v3, v4, v5, v6, v7, v8 }; voltage = new double[] { v1, v2, v3, v4, v5, v6, v7, v8 };
} }
} }
} }

View File

@@ -53,21 +53,6 @@ namespace Project
// F11: 모든 스레드 상태 덤프 // F11: 모든 스레드 상태 덤프
DumpAllThreadsState(); DumpAllThreadsState();
} }
else if (e1.KeyCode == Keys.F12 && System.Diagnostics.Debugger.IsAttached)
{
// F12: 다음 sm_Running 호출시 디버거 중단
RequestDebugBreak = true;
var lastCall = DateTime.Now - lastSmRunningTime;
PUB.log.Add("DEBUG", $"F12 pressed - 마지막 sm_Running 호출: {lastCall.TotalSeconds:F1}초 전, IsThreadRun: {PUB.sm.IsThreadRun}");
System.Windows.Forms.MessageBox.Show(
$"다음 sm_Running 호출시 디버거가 중단됩니다.\n\n" +
$"마지막 호출: {lastCall.TotalSeconds:F1}초 전\n" +
$"IsThreadRun: {PUB.sm.IsThreadRun}\n" +
$"Current Step: {PUB.sm.Step}",
"디버그 모드",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Information);
}
if (DateTime.Now > PUB.LastInputTime) PUB.LastInputTime = DateTime.Now; if (DateTime.Now > PUB.LastInputTime) PUB.LastInputTime = DateTime.Now;
}; };
@@ -1094,8 +1079,8 @@ namespace Project
var sb = new System.Text.StringBuilder(); var sb = new System.Text.StringBuilder();
sb.AppendLine("===== 스레드 상태 덤프 ====="); sb.AppendLine("===== 스레드 상태 덤프 =====");
sb.AppendLine($"시간: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}"); sb.AppendLine($"시간: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
sb.AppendLine($"마지막 sm_Running 호출: {(DateTime.Now - lastSmRunningTime).TotalSeconds:F1}초 전"); //sb.AppendLine($"마지막 sm_Running 호출: {(DateTime.Now - lastSmRunningTime).TotalSeconds:F1}초 전");
sb.AppendLine($"sm_Running 호출 횟수: {sm_Running_CallCount}"); //sb.AppendLine($"sm_Running 호출 횟수: {sm_Running_CallCount}");
sb.AppendLine($"IsThreadRun: {PUB.sm.IsThreadRun}"); sb.AppendLine($"IsThreadRun: {PUB.sm.IsThreadRun}");
sb.AppendLine($"Current Step: {PUB.sm.Step}"); sb.AppendLine($"Current Step: {PUB.sm.Step}");
sb.AppendLine($"Current RunStep: {PUB.sm.RunStep}"); sb.AppendLine($"Current RunStep: {PUB.sm.RunStep}");
@@ -1123,7 +1108,7 @@ namespace Project
MessageBox.Show( MessageBox.Show(
$"스레드 덤프 완료\n로그 파일에 저장되었습니다.\n\n" + $"스레드 덤프 완료\n로그 파일에 저장되었습니다.\n\n" +
$"마지막 sm_Running: {(DateTime.Now - lastSmRunningTime).TotalSeconds:F1}초 전\n" + //$"마지막 sm_Running: {(DateTime.Now - lastSmRunningTime).TotalSeconds:F1}초 전\n" +
$"IsThreadRun: {PUB.sm.IsThreadRun}", $"IsThreadRun: {PUB.sm.IsThreadRun}",
"스레드 덤프", "스레드 덤프",
MessageBoxButtons.OK, MessageBoxButtons.OK,

View File

@@ -1,12 +0,0 @@
*.suo
*.user
*.pdb
bin
obj
desktop.ini
.vs
.git
packages
*.patch
/Project/SourceSetup.exe
*.zip

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7A94C30C-6772-4F71-BF9C-0DF071A1BC70}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>arDevice</RootNamespace>
<AssemblyName>BMS</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BMSInformationEventArgs.cs" />
<Compile Include="BMS.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("BMS Commnunication Module")]
[assembly: AssemblyDescription("BMS Commnunication Module")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("ATK4")]
[assembly: AssemblyProduct("BMS Commnunication Module")]
[assembly: AssemblyCopyright("Copyright ©ATK4 2020")]
[assembly: AssemblyTrademark("ATK4")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("7a94c30c-6772-4f71-bf9c-0df071a1bc70")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("20.03.09.0000")]
[assembly: AssemblyFileVersion("20.03.09.0000")]

View File

@@ -1,495 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
public abstract partial class arRS232 : IDisposable
{
protected System.IO.Ports.SerialPort _device;
protected ManualResetEvent _mre;
protected byte[] LastReceiveBuffer = new byte[] { };
/// <summary>
/// 최종 전송 메세지
/// </summary>
public byte[] lastSendBuffer = new byte[] { };
//public int ValidCheckTimeMSec { get; set; } = 5000;
protected List<byte> tempBuffer = new List<byte>();
protected Boolean findSTX = false;
public string errorMessage { get; set; }
public DateTime LastConnTime { get; set; }
public DateTime LastConnTryTime { get; set; }
public DateTime lastSendTime;
/// <summary>
/// 메세지 수신시 사용하는 내부버퍼
/// </summary>
protected List<byte> _buffer = new List<byte>();
/// <summary>
/// 데이터조회간격(초)
/// </summary>
public float ScanInterval { get; set; }
// public byte[] LastRecvData;
public string LastRecvString
{
get
{
if (LastReceiveBuffer == null) return String.Empty;
else return System.Text.Encoding.Default.GetString(LastReceiveBuffer);
}
}
/// <summary>
/// 마지막으로 데이터를 받은 시간
/// </summary>
public DateTime lastRecvTime;
public int WriteError = 0;
public string WriteErrorMessage = string.Empty;
public int WaitTimeout { get; set; } = 1000;
public int MinRecvLength { get; set; } = 1;
/// <summary>
/// 포트이름
/// </summary>
[Description("시리얼 포트 이름")]
[Category("설정"), DisplayName("Port Name")]
public string PortName
{
get
{
if (_device == null) return string.Empty;
else return _device.PortName;
}
set
{
if (this.IsOpen)
{
Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 포트이름을 변경할 수 없습니다", true));
}
else if (String.IsNullOrEmpty(value) == false)
_device.PortName = value;
else
{
Message?.Invoke(this, new MessageEventArgs("No PortName", true));
}
}
}
public int BaudRate
{
get
{
if (_device == null) return 0;
else return _device.BaudRate;
}
set
{
if (this.IsOpen)
{
Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 BaudRate(를) 변경할 수 없습니다", true));
}
else if (value != 0)
_device.BaudRate = value;
else Message?.Invoke(this, new MessageEventArgs("No baud rate", true));
}
}
public arRS232()
{
_device = new System.IO.Ports.SerialPort();
this.BaudRate = 9600;
ScanInterval = 10;
_device.DataReceived += barcode_DataReceived;
_device.ErrorReceived += this.barcode_ErrorReceived;
_device.WriteTimeout = 5000;
_device.ReadTimeout = 5000;
// _device.DtrEnable = false;
_device.ReadBufferSize = 8192;
_device.WriteBufferSize = 8192;
errorMessage = string.Empty;
lastRecvTime = DateTime.Parse("1982-11-23");
LastConnTime = DateTime.Parse("1982-11-23");
LastConnTryTime = DateTime.Parse("1982-11-23");
lastRecvTime = DateTime.Parse("1982-11-23");
this._mre = new ManualResetEvent(true);
}
~arRS232()
{
Dispose(false);
}
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
// Free any other managed objects here.
//
}
_device.DataReceived -= barcode_DataReceived;
_device.ErrorReceived -= this.barcode_ErrorReceived;
// Free any unmanaged objects here.
//
disposed = true;
}
public Boolean Open()
{
try
{
_device.Open();
return IsOpen;
}
catch (Exception ex)
{
errorMessage = ex.Message;
Message.Invoke(this, new MessageEventArgs(ex.Message, true));
return false;
}
}
public string GetHexString(Byte[] input)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (byte b in input)
sb.Append(" " + b.ToString("X2"));
return sb.ToString();
}
/// <summary>
/// 포트가 열려있는지 확인
/// </summary>
[Description("현재 시리얼포트가 열려있는지 확인합니다")]
[Category("정보"), DisplayName("Port Open")]
public Boolean IsOpen
{
get
{
if (_device == null) return false;
return _device.IsOpen;
}
}
public virtual void Close(Boolean PortClose = true)
{
if (_device != null && _device.IsOpen)
{
_device.DiscardInBuffer();
_device.DiscardOutBuffer();
if (PortClose) _device.Close(); //dispose에서는 포트를 직접 클리어하지 않게 해뒀다.
}
}
protected Boolean RaiseRecvData()
{
return RaiseRecvData(LastReceiveBuffer.ToArray(), false);
}
/// <summary>
/// 수신받은 메세지를 발생 시킵니다
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual Boolean RaiseRecvData(byte[] Data, bool udpatelastbuffer)
{
//181206 - 최종수신 메세지 기록
lastRecvTime = DateTime.Now;
if (udpatelastbuffer && Data != null)
{
if (LastReceiveBuffer == null || LastReceiveBuffer.Length != Data.Length)
{
LastReceiveBuffer = new byte[Data.Length];
Array.Copy(Data, LastReceiveBuffer, Data.Length);
}
}
try
{
Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
if (ProcessRecvData(Data) == false)
{
//Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
Message?.Invoke(this, new MessageEventArgs(this.errorMessage, true)); //errormessage
return false;
}
else
{
return true;
}
}
catch (Exception ex)
{
this.errorMessage = ex.Message;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
return false;
}
}
/// <summary>
/// 수신받은 자료를 처리한다
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public abstract bool ProcessRecvData(byte[] data);
#region "Internal Events"
void barcode_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
{
Message?.Invoke(this, new MessageEventArgs(e.ToString(), true));
}
byte[] buffer = new byte[] { };
void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
int ReadCount = _device.BytesToRead;
buffer = new byte[ReadCount];
_device.Read(buffer, 0, buffer.Length);
System.Text.StringBuilder LogMsg = new StringBuilder();
byte[] remainBuffer;
Repeat:
if (CustomParser(buffer, out remainBuffer))
{
//분석완료이므로 받은 데이터를 버퍼에 기록한다
if (LastReceiveBuffer == null || (LastReceiveBuffer.Length != tempBuffer.Count))
Array.Resize(ref LastReceiveBuffer, tempBuffer.Count);
Array.Copy(tempBuffer.ToArray(), LastReceiveBuffer, tempBuffer.Count);
tempBuffer.Clear();
//수신메세지발생
RaiseRecvData();
if (remainBuffer != null && remainBuffer.Length > 0)
{
//버퍼를 변경해서 다시 전송을 해준다.
Array.Resize(ref buffer, remainBuffer.Length);
Array.Copy(remainBuffer, buffer, remainBuffer.Length);
goto Repeat; //남은 버퍼가 있다면 진행을 해준다.
}
}
}
catch (Exception ex)
{
//if (IsOpen)
//{
// //_device.DiscardInBuffer();
// //_device.DiscardOutBuffer();
//}
errorMessage = ex.Message;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
}
}
#endregion
#region "External Events"
/// <summary>
/// 오류 및 기타 일반 메세지
/// </summary>
public event EventHandler<MessageEventArgs> Message;
#endregion
#region "Event Args"
/// <summary>
/// 데이터를 수신할떄 사용함(RAW 포함)
/// </summary>
public class ReceiveDataEventArgs : EventArgs
{
private byte[] _buffer = null;
/// <summary>
/// 바이트배열의 버퍼값
/// </summary>
public byte[] Value { get { return _buffer; } }
/// <summary>
/// 버퍼(바이트배열)의 데이터를 문자로 반환합니다.
/// </summary>
public string StrValue
{
get
{
//return string.Empty;
if (_buffer == null || _buffer.Length < 1) return string.Empty;
else return System.Text.Encoding.Default.GetString(_buffer);
}
}
public ReceiveDataEventArgs(byte[] buffer)
{
_buffer = buffer;
}
}
/// <summary>
/// 메세지를 강제 발생
/// </summary>
/// <param name="mt"></param>
/// <param name="message"></param>
protected virtual void RaiseMessage(MessageType mt, string message)
{
this.Message?.Invoke(this, new MessageEventArgs(mt, message));
}
public enum MessageType
{
Normal,
Error,
Send,
Recv,
}
public class MessageEventArgs : EventArgs
{
public MessageType MsgType { get; set; }
private string _message = string.Empty;
/// <summary>
/// Recv,Send,Normal,Error 모두 지원
/// </summary>
public string Message { get { return _message; } }
private byte[] _data = null;
/// <summary>
/// Recv,Send에서만 값이 존재 합니다
/// </summary>
public byte[] Data { get { return _data; } }
public MessageEventArgs(string Message, bool isError = false)
{
if (isError) MsgType = MessageType.Error;
else MsgType = MessageType.Normal;
_message = Message;
}
public MessageEventArgs(MessageType msgtype, string Message)
{
MsgType = msgtype;
_message = Message;
_data = System.Text.Encoding.Default.GetBytes(Message);
}
public MessageEventArgs(byte[] buffer, bool isRecv = true)
{
if (isRecv) MsgType = MessageType.Recv;
else MsgType = MessageType.Send;
_data = new byte[buffer.Length];
Array.Copy(buffer, _data, Data.Length);
_message = System.Text.Encoding.Default.GetString(_data);
}
}
#endregion
protected abstract bool CustomParser(byte[] buf, out byte[] remainBuffer);
/// <summary>
/// 포트가 열려있거나 데이터 수신시간이 없는경우 false를 반환합니다
/// </summary>
public Boolean IsValid
{
get
{
if (IsOpen == false) return false;
if (lastRecvTime.Year == 1982) return false;
var ts = DateTime.Now - lastRecvTime;
if (ts.TotalSeconds > (this.ScanInterval * 2.5)) return false;
return true;
}
}
protected string ByteListToHexString(List<byte> src)
{
return string.Join(" ", src.Select(t => t.ToString("X2")));
}
protected bool WriteData(string cmd)
{
return WriteData(System.Text.Encoding.Default.GetBytes(cmd));
}
/// <summary>
/// 포트에 쓰기(barcode_DataReceived 이벤트로 메세지수신)
/// </summary>
protected Boolean WriteData(byte[] data)
{
Boolean bRet = false;
//171205 : 타임아웃시간추가
if (!_mre.WaitOne(WaitTimeout))
{
errorMessage = $"WriteData:MRE:WaitOne:TimeOut {WaitTimeout}ms";
this.Message?.Invoke(this, new MessageEventArgs(errorMessage, true));
return false;
}
_mre.Reset();
//Array.Resize(ref data, data.Length + 2);
try
{
lastSendTime = DateTime.Now;
if (lastSendBuffer == null) lastSendBuffer = new byte[data.Length]; //171113
else Array.Resize(ref lastSendBuffer, data.Length);
Array.Copy(data, lastSendBuffer, data.Length);
for (int i = 0; i < data.Length; i++)
_device.Write(data, i, 1);
//_device.Write(data, 0, data.Length);
//171113
this.Message?.Invoke(this, new MessageEventArgs(data, false));
bRet = true;
WriteError = 0;
WriteErrorMessage = string.Empty;
}
catch (Exception ex)
{
// this.isinit = false;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
bRet = false;
WriteError += 1; //연속쓰기오류횟수
WriteErrorMessage = ex.Message;
}
finally
{
_mre.Set();
}
return bRet;
}
}

Submodule Cs_HMI/SubProject/EnigProtocol updated: 4f360f33a7...8877cb1a9d

View File

@@ -36,6 +36,8 @@
this.label2 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label();
this.logTextBox1 = new arCtl.LogTextBox(); this.logTextBox1 = new arCtl.LogTextBox();
this.button3 = new System.Windows.Forms.Button(); this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.SuspendLayout(); this.SuspendLayout();
// //
// comboBox1 // comboBox1
@@ -123,17 +125,39 @@
// //
this.button3.Location = new System.Drawing.Point(301, 61); this.button3.Location = new System.Drawing.Point(301, 61);
this.button3.Name = "button3"; this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(220, 20); this.button3.Size = new System.Drawing.Size(140, 20);
this.button3.TabIndex = 5; this.button3.TabIndex = 5;
this.button3.Text = "send query"; this.button3.Text = "send query";
this.button3.UseVisualStyleBackColor = true; this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click); this.button3.Click += new System.EventHandler(this.button3_Click);
// //
// button4
//
this.button4.Location = new System.Drawing.Point(447, 60);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(140, 20);
this.button4.TabIndex = 6;
this.button4.Text = "send query";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// button5
//
this.button5.Location = new System.Drawing.Point(155, 61);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(140, 20);
this.button5.TabIndex = 7;
this.button5.Text = "send query";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// Form1 // Form1
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(574, 450); this.ClientSize = new System.Drawing.Size(574, 450);
this.Controls.Add(this.button5);
this.Controls.Add(this.button4);
this.Controls.Add(this.button3); this.Controls.Add(this.button3);
this.Controls.Add(this.logTextBox1); this.Controls.Add(this.logTextBox1);
this.Controls.Add(this.label2); this.Controls.Add(this.label2);
@@ -161,6 +185,8 @@
private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label2;
private arCtl.LogTextBox logTextBox1; private arCtl.LogTextBox logTextBox1;
private System.Windows.Forms.Button button3; private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
} }
} }

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Diagnostics.Eventing.Reader;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -17,10 +18,10 @@ namespace Test_BMS
InitializeComponent(); InitializeComponent();
bms = new arDev.BMS(); bms = new arDev.BMS();
bms.BMSDataReceive += Bms_BMSDataReceive; bms.BMSDataReceive += Bms_BMSDataReceive;
//bms.Message += Bms_Message; bms.Message += Bms_Message;
} }
private void Bms_Message(object sender, arDev.arRS232.MessageEventArgs e) private void Bms_Message(object sender, arRS232.MessageEventArgs e)
{ {
var sb = new System.Text.StringBuilder(); var sb = new System.Text.StringBuilder();
if (e.Data != null) if (e.Data != null)
@@ -29,7 +30,10 @@ namespace Test_BMS
sb.Append(" " + b.ToString("X2")); sb.Append(" " + b.ToString("X2"));
} }
else sb.Append(e.Message); else sb.Append(e.Message);
addmsg($"{e.MsgType}:{sb}"); if (e.MsgType == arRS232.MessageType.Error)
addmsg(e.Message);
else
addmsg($"{e.MsgType}:{sb}");
} }
private void Bms_BMSDataReceive(object sender, EventArgs e) private void Bms_BMSDataReceive(object sender, EventArgs e)
@@ -54,10 +58,6 @@ namespace Test_BMS
} }
} }
private void Bms_RxData(object sender, arDev.BMS.ReceiveDataEventArgs e)
{
addmsg("Rx:" + e.StrValue);
}
private void Form1_Load(object sender, EventArgs e) private void Form1_Load(object sender, EventArgs e)
{ {
@@ -81,12 +81,22 @@ namespace Test_BMS
private void button3_Click(object sender, EventArgs e) private void button3_Click(object sender, EventArgs e)
{ {
bms.SendQuery(); bms.SendQuery_ReadStatue();
} }
private void label1_Click(object sender, EventArgs e) private void label1_Click(object sender, EventArgs e)
{ {
comboBox1.Text = "COM41"; comboBox1.Text = "COM41";
} }
private void button4_Click(object sender, EventArgs e)
{
bms.SendQuery_ReadCellvoltage();
}
private void button5_Click(object sender, EventArgs e)
{
bms.SendQuery();
}
} }
} }

View File

@@ -83,10 +83,6 @@
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\SubProject\BMS\BMS.csproj">
<Project>{7a94c30c-6772-4f71-bf9c-0df071a1bc70}</Project>
<Name>BMS</Name>
</ProjectReference>
<ProjectReference Include="..\..\SubProject\CommData\CommData.csproj"> <ProjectReference Include="..\..\SubProject\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project> <Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name> <Name>CommData</Name>