first commit
This commit is contained in:
BIN
ChamChat/.vs/ChamChat/v15/.suo
Normal file
BIN
ChamChat/.vs/ChamChat/v15/.suo
Normal file
Binary file not shown.
0
ChamChat/.vs/ChamChat/v15/Server/sqlite3/db.lock
Normal file
0
ChamChat/.vs/ChamChat/v15/Server/sqlite3/db.lock
Normal file
BIN
ChamChat/.vs/ChamChat/v15/Server/sqlite3/storage.ide
Normal file
BIN
ChamChat/.vs/ChamChat/v15/Server/sqlite3/storage.ide
Normal file
Binary file not shown.
BIN
ChamChat/.vs/ChamChat/v15/Server/sqlite3/storage.ide-shm
Normal file
BIN
ChamChat/.vs/ChamChat/v15/Server/sqlite3/storage.ide-shm
Normal file
Binary file not shown.
BIN
ChamChat/.vs/ChamChat/v15/Server/sqlite3/storage.ide-wal
Normal file
BIN
ChamChat/.vs/ChamChat/v15/Server/sqlite3/storage.ide-wal
Normal file
Binary file not shown.
BIN
ChamChat/.vs/ChamChat/v16/.suo
Normal file
BIN
ChamChat/.vs/ChamChat/v16/.suo
Normal file
Binary file not shown.
BIN
ChamChat/3rd party/C# Change EEPROM values/.vs/EEPROM/v14/.suo
Normal file
BIN
ChamChat/3rd party/C# Change EEPROM values/.vs/EEPROM/v14/.suo
Normal file
Binary file not shown.
@@ -0,0 +1,55 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>EEPROM</RootNamespace>
|
||||
<AssemblyName>EEPROM</AssemblyName>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
</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>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FTD2XX_NET, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\Utils\FTD2XX_NET\FTD2XX_NET\FTD2XX_NET\bin\Release\FTD2XX_NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
341
ChamChat/3rd party/C# Change EEPROM values/Backup/Program.cs
Normal file
341
ChamChat/3rd party/C# Change EEPROM values/Backup/Program.cs
Normal file
@@ -0,0 +1,341 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using FTD2XX_NET;
|
||||
|
||||
|
||||
namespace EEPROM
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Create new instance of the FTDI device class
|
||||
FTDI myFtdiDevice = new FTDI();
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = myFtdiDevice.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
// Check status
|
||||
if (ftStatus == FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
Console.WriteLine("Number of FTDI devices: " + ftdiDeviceCount.ToString());
|
||||
Console.WriteLine("");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
|
||||
|
||||
if (ftStatus == FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
{
|
||||
Console.WriteLine("Device Index: " + i.ToString());
|
||||
Console.WriteLine("Flags: " + String.Format("{0:x}", ftdiDeviceList[i].Flags));
|
||||
Console.WriteLine("Type: " + ftdiDeviceList[i].Type.ToString());
|
||||
Console.WriteLine("ID: " + String.Format("{0:x}", ftdiDeviceList[i].ID));
|
||||
Console.WriteLine("Location ID: " + String.Format("{0:x}", ftdiDeviceList[i].LocId));
|
||||
Console.WriteLine("Serial Number: " + ftdiDeviceList[i].SerialNumber.ToString());
|
||||
Console.WriteLine("Description: " + ftdiDeviceList[i].Description.ToString());
|
||||
Console.WriteLine("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Open first device in our list by serial number
|
||||
ftStatus = myFtdiDevice.OpenBySerialNumber(ftdiDeviceList[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to open device (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create our device EEPROM structure based on the type of device we have open
|
||||
if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_232R)
|
||||
{
|
||||
// We have an FT232R or FT245R so use FT232R EEPROM structure
|
||||
FTDI.FT232R_EEPROM_STRUCTURE myEEData = new FTDI.FT232R_EEPROM_STRUCTURE();
|
||||
// Read the device EEPROM
|
||||
// This can throw an exception if trying to read a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.ReadFT232REEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling ReadFT232REEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to read device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write common EEPROM elements to our console
|
||||
Console.WriteLine("EEPROM Contents for device at index 0:");
|
||||
Console.WriteLine("Vendor ID: " + String.Format("{0:x}", myEEData.VendorID));
|
||||
Console.WriteLine("Product ID: " + String.Format("{0:x}", myEEData.ProductID));
|
||||
Console.WriteLine("Manufacturer: " + myEEData.Manufacturer.ToString());
|
||||
Console.WriteLine("Manufacturer ID: " + myEEData.ManufacturerID.ToString());
|
||||
Console.WriteLine("Description: " + myEEData.Description.ToString());
|
||||
Console.WriteLine("Serial Number: " + myEEData.SerialNumber.ToString());
|
||||
Console.WriteLine("Max Power: " + myEEData.MaxPower.ToString() + "mA");
|
||||
Console.WriteLine("Self Powered: " + myEEData.SelfPowered.ToString());
|
||||
Console.WriteLine("Remote Wakeup Enabled: " + myEEData.RemoteWakeup.ToString());
|
||||
Console.WriteLine("");
|
||||
|
||||
// Change our serial number to write back to device
|
||||
// By setting to an empty string, we allow the FTD2XX DLL
|
||||
// to generate a serial number
|
||||
myEEData.SerialNumber = String.Empty;
|
||||
|
||||
// Write our modified data structure back to the device EEPROM
|
||||
// This can throw an exception if trying to write a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.WriteFT232REEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling WriteFT232REEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to write device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_2232)
|
||||
{
|
||||
// We have an FT2232 so use FT2232 EEPROM structure
|
||||
FTDI.FT2232_EEPROM_STRUCTURE myEEData = new FTDI.FT2232_EEPROM_STRUCTURE();
|
||||
// Read the device EEPROM
|
||||
ftStatus = myFtdiDevice.ReadFT2232EEPROM(myEEData);
|
||||
// This can throw an exception if trying to read a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.ReadFT2232EEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling ReadFT2232EEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to read device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write common EEPROM elements to our console
|
||||
Console.WriteLine("EEPROM Contents for device at index 0:");
|
||||
Console.WriteLine("Vendor ID: " + String.Format("{0:x}", myEEData.VendorID));
|
||||
Console.WriteLine("Product ID: " + String.Format("{0:x}", myEEData.ProductID));
|
||||
Console.WriteLine("Manufacturer: " + myEEData.Manufacturer.ToString());
|
||||
Console.WriteLine("Manufacturer ID: " + myEEData.ManufacturerID.ToString());
|
||||
Console.WriteLine("Description: " + myEEData.Description.ToString());
|
||||
Console.WriteLine("Serial Number: " + myEEData.SerialNumber.ToString());
|
||||
Console.WriteLine("Max Power: " + myEEData.MaxPower.ToString() + "mA");
|
||||
Console.WriteLine("Self Powered: " + myEEData.SelfPowered.ToString());
|
||||
Console.WriteLine("Remote Wakeup Enabled: " + myEEData.RemoteWakeup.ToString());
|
||||
Console.WriteLine("");
|
||||
|
||||
// Change our serial number to write back to device
|
||||
// By setting to an empty string, we allow the FTD2XX DLL
|
||||
// to generate a serial number
|
||||
myEEData.SerialNumber = String.Empty;
|
||||
|
||||
// Write our modified data structure back to the device EEPROM
|
||||
// This can throw an exception if trying to write a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.WriteFT2232EEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling WriteFT2232EEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to write device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_BM)
|
||||
{
|
||||
// We have an FT232B or FT245B so use FT232B EEPROM structure
|
||||
FTDI.FT232B_EEPROM_STRUCTURE myEEData = new FTDI.FT232B_EEPROM_STRUCTURE();
|
||||
// Read the device EEPROM
|
||||
ftStatus = myFtdiDevice.ReadFT232BEEPROM(myEEData);
|
||||
// This can throw an exception if trying to read a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.ReadFT232BEEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling ReadFT232BEEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to read device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write common EEPROM elements to our console
|
||||
Console.WriteLine("EEPROM Contents for device at index 0:");
|
||||
Console.WriteLine("Vendor ID: " + String.Format("{0:x}", myEEData.VendorID));
|
||||
Console.WriteLine("Product ID: " + String.Format("{0:x}", myEEData.ProductID));
|
||||
Console.WriteLine("Manufacturer: " + myEEData.Manufacturer.ToString());
|
||||
Console.WriteLine("Manufacturer ID: " + myEEData.ManufacturerID.ToString());
|
||||
Console.WriteLine("Description: " + myEEData.Description.ToString());
|
||||
Console.WriteLine("Serial Number: " + myEEData.SerialNumber.ToString());
|
||||
Console.WriteLine("Max Power: " + myEEData.MaxPower.ToString() + "mA");
|
||||
Console.WriteLine("Self Powered: " + myEEData.SelfPowered.ToString());
|
||||
Console.WriteLine("Remote Wakeup Enabled: " + myEEData.RemoteWakeup.ToString());
|
||||
Console.WriteLine("");
|
||||
|
||||
// Change our serial number to write back to device
|
||||
// By setting to an empty string, we allow the FTD2XX DLL
|
||||
// to generate a serial number
|
||||
myEEData.SerialNumber = String.Empty;
|
||||
|
||||
// Write our modified data structure back to the device EEPROM
|
||||
// This can throw an exception if trying to write a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.WriteFT232BEEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling WriteFT232BEEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to write device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use cycle port to force a re-enumeration of the device.
|
||||
// In the FTD2XX_NET class library, the cycle port method also
|
||||
// closes the open handle so no need to call the Close method separately.
|
||||
ftStatus = myFtdiDevice.CyclePort();
|
||||
|
||||
UInt32 newFtdiDeviceCount = 0;
|
||||
do
|
||||
{
|
||||
// Wait for device to be re-enumerated
|
||||
// The device will have the same location since it has not been
|
||||
// physically unplugged, so we will keep trying to open it until it succeeds
|
||||
ftStatus = myFtdiDevice.OpenByLocation(ftdiDeviceList[0].LocId);
|
||||
Thread.Sleep(1000);
|
||||
} while (ftStatus != FTDI.FT_STATUS.FT_OK);
|
||||
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
|
||||
// Re-create our device list
|
||||
ftStatus = myFtdiDevice.GetNumberOfDevices(ref newFtdiDeviceCount);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-populate our device list
|
||||
ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
|
||||
|
||||
if (ftStatus == FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
{
|
||||
Console.WriteLine("Device Index: " + i.ToString());
|
||||
Console.WriteLine("Flags: " + String.Format("{0:x}", ftdiDeviceList[i].Flags));
|
||||
Console.WriteLine("Type: " + ftdiDeviceList[i].Type.ToString());
|
||||
Console.WriteLine("ID: " + String.Format("{0:x}", ftdiDeviceList[i].ID));
|
||||
Console.WriteLine("Location ID: " + String.Format("{0:x}", ftdiDeviceList[i].LocId));
|
||||
Console.WriteLine("Serial Number: " + ftdiDeviceList[i].SerialNumber.ToString());
|
||||
Console.WriteLine("Description: " + ftdiDeviceList[i].Description.ToString());
|
||||
Console.WriteLine("");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Press any key to continue.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("EEPROM")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("FTDI")]
|
||||
[assembly: AssemblyProduct("EEPROM")]
|
||||
[assembly: AssemblyCopyright("Copyright © FTDI 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4276d0d9-348e-4699-ba99-1b72708463d2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
84
ChamChat/3rd party/C# Change EEPROM values/EEPROM.csproj
Normal file
84
ChamChat/3rd party/C# Change EEPROM values/EEPROM.csproj
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>EEPROM</RootNamespace>
|
||||
<AssemblyName>EEPROM</AssemblyName>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</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>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FTD2XX_NET, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>.\FTD2XX_NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishUrlHistory />
|
||||
<InstallUrlHistory />
|
||||
<SupportUrlHistory />
|
||||
<UpdateUrlHistory />
|
||||
<BootstrapperUrlHistory />
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>en-US</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
22
ChamChat/3rd party/C# Change EEPROM values/EEPROM.sln
Normal file
22
ChamChat/3rd party/C# Change EEPROM values/EEPROM.sln
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EEPROM", "EEPROM.csproj", "{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2256AEA0-6A5A-4506-9F4B-99AB11C0ECA0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
1600
ChamChat/3rd party/C# Change EEPROM values/FTD2XX_NET.XML
Normal file
1600
ChamChat/3rd party/C# Change EEPROM values/FTD2XX_NET.XML
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ChamChat/3rd party/C# Change EEPROM values/FTD2XX_NET.dll
Normal file
BIN
ChamChat/3rd party/C# Change EEPROM values/FTD2XX_NET.dll
Normal file
Binary file not shown.
347
ChamChat/3rd party/C# Change EEPROM values/Program.cs
Normal file
347
ChamChat/3rd party/C# Change EEPROM values/Program.cs
Normal file
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using FTD2XX_NET;
|
||||
|
||||
|
||||
namespace EEPROM
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Create new instance of the FTDI device class
|
||||
FTDI myFtdiDevice = new FTDI();
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = myFtdiDevice.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
// Check status
|
||||
if (ftStatus == FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
Console.WriteLine("Number of FTDI devices: " + ftdiDeviceCount.ToString());
|
||||
Console.WriteLine("");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
|
||||
|
||||
if (ftStatus == FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
{
|
||||
Console.WriteLine("Device Index: " + i.ToString());
|
||||
Console.WriteLine("Flags: " + String.Format("{0:x}", ftdiDeviceList[i].Flags));
|
||||
Console.WriteLine("Type: " + ftdiDeviceList[i].Type.ToString());
|
||||
Console.WriteLine("ID: " + String.Format("{0:x}", ftdiDeviceList[i].ID));
|
||||
Console.WriteLine("Location ID: " + String.Format("{0:x}", ftdiDeviceList[i].LocId));
|
||||
Console.WriteLine("Serial Number: " + ftdiDeviceList[i].SerialNumber.ToString());
|
||||
Console.WriteLine("Description: " + ftdiDeviceList[i].Description.ToString());
|
||||
Console.WriteLine("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Open first device in our list by serial number
|
||||
ftStatus = myFtdiDevice.OpenBySerialNumber(ftdiDeviceList[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to open device (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create our device EEPROM structure based on the type of device we have open
|
||||
if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_232R)
|
||||
{
|
||||
// We have an FT232R or FT245R so use FT232R EEPROM structure
|
||||
FTDI.FT232R_EEPROM_STRUCTURE myEEData = new FTDI.FT232R_EEPROM_STRUCTURE();
|
||||
// Read the device EEPROM
|
||||
// This can throw an exception if trying to read a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.ReadFT232REEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling ReadFT232REEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to read device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write common EEPROM elements to our console
|
||||
Console.WriteLine("EEPROM Contents for device at index 0:");
|
||||
Console.WriteLine("Vendor ID: " + String.Format("{0:x}", myEEData.VendorID));
|
||||
Console.WriteLine("Product ID: " + String.Format("{0:x}", myEEData.ProductID));
|
||||
Console.WriteLine("Manufacturer: " + myEEData.Manufacturer.ToString());
|
||||
Console.WriteLine("Manufacturer ID: " + myEEData.ManufacturerID.ToString());
|
||||
Console.WriteLine("Description: " + myEEData.Description.ToString());
|
||||
Console.WriteLine("Serial Number: " + myEEData.SerialNumber.ToString());
|
||||
Console.WriteLine("Max Power: " + myEEData.MaxPower.ToString() + "mA");
|
||||
Console.WriteLine("Self Powered: " + myEEData.SelfPowered.ToString());
|
||||
Console.WriteLine("Remote Wakeup Enabled: " + myEEData.RemoteWakeup.ToString());
|
||||
Console.WriteLine("");
|
||||
|
||||
// Change our serial number to write back to device
|
||||
// By setting to an empty string, we allow the FTD2XX DLL
|
||||
// to generate a serial number
|
||||
//myEEData.SerialNumber = String.Empty;
|
||||
|
||||
// Wim: Set to defined string
|
||||
myEEData.SerialNumber ="ChamChat_01";
|
||||
myEEData.Description = "FDTI_USB_COM422_WE";
|
||||
|
||||
// Write our modified data structure back to the device EEPROM
|
||||
// This can throw an exception if trying to write a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.WriteFT232REEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling WriteFT232REEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to write device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_2232)
|
||||
{
|
||||
// We have an FT2232 so use FT2232 EEPROM structure
|
||||
FTDI.FT2232_EEPROM_STRUCTURE myEEData = new FTDI.FT2232_EEPROM_STRUCTURE();
|
||||
// Read the device EEPROM
|
||||
ftStatus = myFtdiDevice.ReadFT2232EEPROM(myEEData);
|
||||
// This can throw an exception if trying to read a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.ReadFT2232EEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling ReadFT2232EEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to read device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write common EEPROM elements to our console
|
||||
Console.WriteLine("EEPROM Contents for device at index 0:");
|
||||
Console.WriteLine("Vendor ID: " + String.Format("{0:x}", myEEData.VendorID));
|
||||
Console.WriteLine("Product ID: " + String.Format("{0:x}", myEEData.ProductID));
|
||||
Console.WriteLine("Manufacturer: " + myEEData.Manufacturer.ToString());
|
||||
Console.WriteLine("Manufacturer ID: " + myEEData.ManufacturerID.ToString());
|
||||
Console.WriteLine("Description: " + myEEData.Description.ToString());
|
||||
Console.WriteLine("Serial Number: " + myEEData.SerialNumber.ToString());
|
||||
Console.WriteLine("Max Power: " + myEEData.MaxPower.ToString() + "mA");
|
||||
Console.WriteLine("Self Powered: " + myEEData.SelfPowered.ToString());
|
||||
Console.WriteLine("Remote Wakeup Enabled: " + myEEData.RemoteWakeup.ToString());
|
||||
Console.WriteLine("");
|
||||
|
||||
|
||||
|
||||
// Change our serial number to write back to device
|
||||
// By setting to an empty string, we allow the FTD2XX DLL
|
||||
// to generate a serial number
|
||||
myEEData.SerialNumber = String.Empty;
|
||||
|
||||
// Write our modified data structure back to the device EEPROM
|
||||
// This can throw an exception if trying to write a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.WriteFT2232EEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling WriteFT2232EEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to write device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_BM)
|
||||
{
|
||||
// We have an FT232B or FT245B so use FT232B EEPROM structure
|
||||
FTDI.FT232B_EEPROM_STRUCTURE myEEData = new FTDI.FT232B_EEPROM_STRUCTURE();
|
||||
// Read the device EEPROM
|
||||
ftStatus = myFtdiDevice.ReadFT232BEEPROM(myEEData);
|
||||
// This can throw an exception if trying to read a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.ReadFT232BEEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling ReadFT232BEEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to read device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write common EEPROM elements to our console
|
||||
Console.WriteLine("EEPROM Contents for device at index 0:");
|
||||
Console.WriteLine("Vendor ID: " + String.Format("{0:x}", myEEData.VendorID));
|
||||
Console.WriteLine("Product ID: " + String.Format("{0:x}", myEEData.ProductID));
|
||||
Console.WriteLine("Manufacturer: " + myEEData.Manufacturer.ToString());
|
||||
Console.WriteLine("Manufacturer ID: " + myEEData.ManufacturerID.ToString());
|
||||
Console.WriteLine("Description: " + myEEData.Description.ToString());
|
||||
Console.WriteLine("Serial Number: " + myEEData.SerialNumber.ToString());
|
||||
Console.WriteLine("Max Power: " + myEEData.MaxPower.ToString() + "mA");
|
||||
Console.WriteLine("Self Powered: " + myEEData.SelfPowered.ToString());
|
||||
Console.WriteLine("Remote Wakeup Enabled: " + myEEData.RemoteWakeup.ToString());
|
||||
Console.WriteLine("");
|
||||
|
||||
// Change our serial number to write back to device
|
||||
// By setting to an empty string, we allow the FTD2XX DLL
|
||||
// to generate a serial number
|
||||
myEEData.SerialNumber = String.Empty;
|
||||
|
||||
// Write our modified data structure back to the device EEPROM
|
||||
// This can throw an exception if trying to write a device type that does not
|
||||
// match the EEPROM structure being used, so should always use a
|
||||
// try - catch block when calling
|
||||
try
|
||||
{
|
||||
ftStatus = myFtdiDevice.WriteFT232BEEPROM(myEEData);
|
||||
}
|
||||
catch (FTDI.FT_EXCEPTION)
|
||||
{
|
||||
Console.WriteLine("Exception thrown when calling WriteFT232BEEPROM");
|
||||
}
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to write device EEPROM (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use cycle port to force a re-enumeration of the device.
|
||||
// In the FTD2XX_NET class library, the cycle port method also
|
||||
// closes the open handle so no need to call the Close method separately.
|
||||
ftStatus = myFtdiDevice.CyclePort();
|
||||
|
||||
UInt32 newFtdiDeviceCount = 0;
|
||||
do
|
||||
{
|
||||
// Wait for device to be re-enumerated
|
||||
// The device will have the same location since it has not been
|
||||
// physically unplugged, so we will keep trying to open it until it succeeds
|
||||
ftStatus = myFtdiDevice.OpenByLocation(ftdiDeviceList[0].LocId);
|
||||
Thread.Sleep(1000);
|
||||
} while (ftStatus != FTDI.FT_STATUS.FT_OK);
|
||||
|
||||
// Close the device
|
||||
myFtdiDevice.Close();
|
||||
|
||||
// Re-create our device list
|
||||
ftStatus = myFtdiDevice.GetNumberOfDevices(ref newFtdiDeviceCount);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-populate our device list
|
||||
ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
|
||||
|
||||
if (ftStatus == FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
{
|
||||
Console.WriteLine("Device Index: " + i.ToString());
|
||||
Console.WriteLine("Flags: " + String.Format("{0:x}", ftdiDeviceList[i].Flags));
|
||||
Console.WriteLine("Type: " + ftdiDeviceList[i].Type.ToString());
|
||||
Console.WriteLine("ID: " + String.Format("{0:x}", ftdiDeviceList[i].ID));
|
||||
Console.WriteLine("Location ID: " + String.Format("{0:x}", ftdiDeviceList[i].LocId));
|
||||
Console.WriteLine("Serial Number: " + ftdiDeviceList[i].SerialNumber.ToString());
|
||||
Console.WriteLine("Description: " + ftdiDeviceList[i].Description.ToString());
|
||||
Console.WriteLine("");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for a key press
|
||||
Console.WriteLine("Press any key to continue.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("EEPROM")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("FTDI")]
|
||||
[assembly: AssemblyProduct("EEPROM")]
|
||||
[assembly: AssemblyCopyright("Copyright © FTDI 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4276d0d9-348e-4699-ba99-1b72708463d2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
BIN
ChamChat/3rd party/C# Change EEPROM values/UpgradeLog.htm
Normal file
BIN
ChamChat/3rd party/C# Change EEPROM values/UpgradeLog.htm
Normal file
Binary file not shown.
BIN
ChamChat/3rd party/FTDI_EEPROM.sln.lnk
Normal file
BIN
ChamChat/3rd party/FTDI_EEPROM.sln.lnk
Normal file
Binary file not shown.
102
ChamChat/ChamChat.sln
Normal file
102
ChamChat/ChamChat.sln
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C# Express 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChamChat", "ChamChat\ChamChat.csproj", "{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "Models\Models.csproj", "{09375A4A-28B8-427B-853D-75C03A070728}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client_HTS7057", "Client_HTS7057\Client_HTS7057.csproj", "{B03537FE-EF64-42E3-A8C0-25C79BB818A7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client_LHL113", "Client_LHL113\Client_LHL113.csproj", "{162E2D74-E197-4188-A3B2-B33B827CC519}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client_TSx", "Client_TSx\Client_TSx.csproj", "{A863C309-E15C-4EA1-82F2-BDFE83C96D15}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client_PLxKPH", "Client_PLxKPH\Client_PLxKPH.csproj", "{1FB70C9C-6F0B-4580-9682-A85B40C90B38}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client_Watlow988U", "Client_Watlow988U\Client_Watlow988U.csproj", "{5698A508-3CFD-4570-AC10-86B9B40F0C23}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Debug|x86.Build.0 = Debug|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Release|x86.ActiveCfg = Release|x86
|
||||
{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}.Release|x86.Build.0 = Release|x86
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{09375A4A-28B8-427B-853D-75C03A070728}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{B03537FE-EF64-42E3-A8C0-25C79BB818A7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{162E2D74-E197-4188-A3B2-B33B827CC519}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{A863C309-E15C-4EA1-82F2-BDFE83C96D15}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{5698A508-3CFD-4570-AC10-86B9B40F0C23}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
BIN
ChamChat/ChamChat.suo
Normal file
BIN
ChamChat/ChamChat.suo
Normal file
Binary file not shown.
1566
ChamChat/ChamChat/ChamChat.Designer.cs
generated
Normal file
1566
ChamChat/ChamChat/ChamChat.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
2127
ChamChat/ChamChat/ChamChat.cs
Normal file
2127
ChamChat/ChamChat/ChamChat.cs
Normal file
File diff suppressed because it is too large
Load Diff
137
ChamChat/ChamChat/ChamChat.csproj
Normal file
137
ChamChat/ChamChat/ChamChat.csproj
Normal file
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{CB29FF5C-CB83-48A3-96EC-E7D08DDEFF58}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ChamChat</RootNamespace>
|
||||
<AssemblyName>ChamChat</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FTD2XX_NET">
|
||||
<HintPath>..\Lib\FTD2XX_NET.dll</HintPath>
|
||||
</Reference>
|
||||
<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.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Clients.cs" />
|
||||
<Compile Include="Interface.FDTI_USB_RS232.cs" />
|
||||
<Compile Include="Interface.FDTI_USB_RS485.cs" />
|
||||
<Compile Include="Graph.cs" />
|
||||
<Compile Include="Interfaces.cs" />
|
||||
<Compile Include="Layouts.cs" />
|
||||
<Compile Include="Interface.FDTI_USB_RS422.cs" />
|
||||
<Compile Include="PromptProgramNo.cs" />
|
||||
<Compile Include="ChamChat.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ChamChat.Designer.cs">
|
||||
<DependentUpon>ChamChat.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="ChamChat.resx">
|
||||
<DependentUpon>ChamChat.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Client_HTS7057\Client_HTS7057.csproj">
|
||||
<Project>{B03537FE-EF64-42E3-A8C0-25C79BB818A7}</Project>
|
||||
<Name>Client_HTS7057</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Client_LHL113\Client_LHL113.csproj">
|
||||
<Project>{162E2D74-E197-4188-A3B2-B33B827CC519}</Project>
|
||||
<Name>Client_LHL113</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Client_PLxKPH\Client_PLxKPH.csproj">
|
||||
<Project>{1FB70C9C-6F0B-4580-9682-A85B40C90B38}</Project>
|
||||
<Name>Client_PLxKPH</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Client_TSx\Client_TSx.csproj">
|
||||
<Project>{A863C309-E15C-4EA1-82F2-BDFE83C96D15}</Project>
|
||||
<Name>Client_TSx</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Client_Watlow988U\Client_Watlow988U.csproj">
|
||||
<Project>{5698A508-3CFD-4570-AC10-86B9B40F0C23}</Project>
|
||||
<Name>Client_Watlow988U</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Models\Models.csproj">
|
||||
<Project>{09375A4A-28B8-427B-853D-75C03A070728}</Project>
|
||||
<Name>Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
3
ChamChat/ChamChat/ChamChat.csproj.user
Normal file
3
ChamChat/ChamChat/ChamChat.csproj.user
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
||||
615
ChamChat/ChamChat/ChamChat.resx
Normal file
615
ChamChat/ChamChat/ChamChat.resx
Normal file
@@ -0,0 +1,615 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>577, 17</value>
|
||||
</metadata>
|
||||
<metadata name="dgvLoopsColumnFirst.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvLoopsColumnLast.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvLoopsColumnN.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridViewTextBoxColumn1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnStep.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnT.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnRH.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnRampCtrlT.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnRampCtrlRH.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnPreT.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnLimit.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnDurationHr.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvProfileColumnDurationMin.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvTasksColumnDescription.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dgvTasksColumnDescription.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="timerUpdateTask.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>157, 17</value>
|
||||
</metadata>
|
||||
<metadata name="sfdSave.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>301, 17</value>
|
||||
</metadata>
|
||||
<metadata name="menu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>494, 17</value>
|
||||
</metadata>
|
||||
<metadata name="ofdOpen.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>394, 17</value>
|
||||
</metadata>
|
||||
<metadata name="bgworkerImport.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="bgworkerExport.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>724, 14</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>51</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
eSwoJRBCQhAl3Kp5dFdXlUZLpGpqAAAAAAAAAAAAAAAAAAAAAAAAACBDl5eXNjY9UQFLK71CQr1MIn2R
|
||||
UXAgAURLqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASciXAwO0tEMgRGp4eKgBcEN+UV7JAQFEAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAA2Nja0AwMDQwggIOsPPTZ+UXDOiwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAFg2tAMDAwMDNjY2NjaAxvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD+HwMDAwMDNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA//////////////AAD///////gAAAf/////wAAAAf////8AAAAA/////g
|
||||
AAAAB////4AAAAAD////AAAAAAP///4AAAAAA////AAAAAAH///8AAAAAAf///gAAAAAD///8AAAAAAP
|
||||
///wAAAAAA///+AAAAAAB///4AAAAAAH///AAAAAAAf//8AAAAAAA///wAAAAAAD///AAAAAAAP//4AA
|
||||
AAAAA///gAAAAAAB//+AAAAAAAH//4AAAAAAAf//gAAAAAAB//+AAAAAAAH//4AAAAAAAf//gAAAAAAD
|
||||
///AAAAAAAP//8AAAAAAA///wAAAAAAD///AAAAAAAf//+AAAAAAB///4AAAAAAH///wAAAAAA////AA
|
||||
AAAAD///+AAAAAAf///4AAAAAD////wAAAAAP////gAAAAB/////AAAAAP////+AAAAB/////8AAAAf/
|
||||
////8AAAD//////8AAA///////8AAP////////AP////////////////KAAAACAAAABAAAAAAQAIAAAA
|
||||
AACABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAkFRoANRsnAEY0OQApa7oAEhptACU5iQBmV2cAdmVvABky
|
||||
eQBDNEQAJ0iVABkaRwAXNocANShFACojOABDN1YAIyllACskJwApM2cAOEl4ADQ0VQBTSWYAFCqFAHZZ
|
||||
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
|
||||
Mv8yKDT/KSYk/z0vINiViYAyvrSuAaCUmgF0Y20tIAgb0xgCG/8gAh7/JQom/zIeP/8/Nlz/SUh1/1dW
|
||||
gf9qXXH/hHJw/4Jvbv9aUGX/Njlm/y00bv8yP3//L0WJ/y1Dgv8+Tob/SlSM/0NNlf9FV6L/PFiU/0Vr
|
||||
qv8wX63/DSyH/xkpif8cMo//HjiQ/wwwiv8ZSaL/KlGr/xw0hv8nNXD/Lz9w/yQ7bf8pPG7/MjVg/zov
|
||||
TP9TQlP/QTA+/yYaK/8yKjf/MiYi/llHNLCViHsWAAAAAAAAAABtW2QSNBsqoh0EGv0mCCL/Nhcv/0Qo
|
||||
QP9VPVj/Z1Ry/3xhef+ScXL/mH1x/3xoZv9PQlb/My1T/ygqXP8vPHb/PVKL/0pakP9JU43/RkqF/0dE
|
||||
h/9FRY7/MkaK/0ZxvP8YQ6D/DRuB/x0tk/8YNaH/HT6s/xNArf8eWbz/KFm1/yFBlf8zRIP/NEBy/yo/
|
||||
a/85TnP/RUxp/1VKXv9YQ07/MiAs/yMZKv8zLDf/Oy4n925gUHh/cF4IAAAAAAAAAABfS1QGTTZDYiEF
|
||||
HO4sEir/PyIy/1AuOv92VmD/jG11/5lzdv+jfXT/iXBq/1pIV/88L0z/NDZY/z1Nef9IY5r/VG6l/1hn
|
||||
o/9LU5v/O0KK/zIyd/83NYH/L0GP/0hswP8TMZL/Fh99/xgug/8ONY//Hkap/ydXwf8wZsn/NmC2/zNN
|
||||
mv9DT4r/Skp4/0dFbP9LSmn/VlBm/2FQXf9MMzv/KxUd/yYZJP81Ky7/TD0w2Il8bj+uo5gDAAAAAAAA
|
||||
AACOfYIBWEFOKScLIb0rESn+Ox0q/2A+Qf+WdG//o4J5/518eP+NdXP/XlNg/zQwUv8rLlj/Ok54/1Bs
|
||||
of9YdLP/X3Wz/1ZwtP9LbLz/Nlmq/yM2hP8kK37/Kj2T/ydBm/8RJ4D/Iix5/x8ud/8TNX7/LlOd/zVh
|
||||
r/8oVKH/MEuR/z1Niv9QVYX/WU5z/1xMaP9nV27/ZFRl/1Q/Sf87Iif/JQ8V/yocIf89LyX6Z1RAmpKB
|
||||
bxcAAAAAAAAAAAAAAAAAAAAAUkFQCzonOXEkCyLtQyIw/3xWU/+mfnX/o354/4xvc/91ZXP/VlBt/zk8
|
||||
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
|
||||
DAIFCBAENDw+C1BTVBZOSk0lTExRLUtJUi5IRFElRTtMFS8kNwgPBxYEEgcRAhQHBgEAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
|
||||
AAAAAf////4AAAAB////+AAAAAD////gAAAAAP///4AAAAAA////AAAAAAD///4AAAAAAP///AAAAAAA
|
||||
///4AAAAAAD///AAAAAAAP//8AAAAAAA///gAAAAAAD//8AAAAAAAP//wAAAAAAB//+AAAAAAAH//4AA
|
||||
AAAAAf//gAAAAAAB//+AAAAAAAH//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
|
||||
//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
|
||||
AAAAAf//gAAAAAAB//+AAAAAAAH//4AAAAAAA///wAAAAAAD///AAAAAAAP//+AAAAAAB///4AAAAAAP
|
||||
///wAAAAAA////gAAAAAH////AAAAAA////+AAAAAH////8AAAAA/////4AAAAH/////wAAAB//////w
|
||||
AAAP//////wAAD///////4AB/////ygAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE1LTwhBPUUeODM/OzQt
|
||||
Olc1LTtpOTA+dTw4QXdFREh2TExOdFFRUnRTU1JzUlJScFJSUmpSUlJiUlJSVVNTU0dSUlI2UVFRJFJS
|
||||
UhNVVVUGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAEYAREFGgwdECA1HQ8iexUK
|
||||
IrQQCCHUDwUb5BAFHOoSBR7sEQgf6RYPJeMfGivXLCo1xkFBRbROTk+qUlJSolJSUppSUlKNUlJSfVJS
|
||||
UmdRUVFNUVFRMFJSUhJHR0cCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH1tewokDSREGwshrCUV
|
||||
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
|
||||
///AA///4Af///AP//8=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
106
ChamChat/ChamChat/Clients.cs
Normal file
106
ChamChat/ChamChat/Clients.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public static class Clients
|
||||
{
|
||||
public static List<Client> GetAll()
|
||||
{
|
||||
List<Client> result = new List<Client>();
|
||||
|
||||
Client client00018 = new HTS7057_Client(18, Models.ClientType.HTS7057);
|
||||
client00018.Address = 1;
|
||||
result.Add(client00018);
|
||||
|
||||
Client client00847 = new TSx_Client(847, Models.ClientType.TSE11A);
|
||||
client00847.Address = 1;
|
||||
result.Add(client00847);
|
||||
|
||||
Client client00947 = new TSx_Client(947, Models.ClientType.TSE11A);
|
||||
client00947.Address = 2;
|
||||
result.Add(client00947);
|
||||
|
||||
Client client00987 = new TSx_Client(987, Models.ClientType.TSE11A);
|
||||
client00987.Address = 3;
|
||||
result.Add(client00987);
|
||||
|
||||
Client client01728 = new TSx_Client(1728, Models.ClientType.TSD100);
|
||||
client01728.Address = 4;
|
||||
result.Add(client01728);
|
||||
|
||||
Client client01880 = new TSx_Client(1880, Models.ClientType.TSE11A);
|
||||
client01880.Address = 5;
|
||||
result.Add(client01880);
|
||||
|
||||
Client client00781 = new LHL113_Client(781, Models.ClientType.LHL113);
|
||||
client00781.Address = 6;
|
||||
result.Add(client00781);
|
||||
|
||||
Client client00782 = new LHL113_Client(782, Models.ClientType.LHL113);
|
||||
client00782.Address = 7;
|
||||
result.Add(client00782);
|
||||
|
||||
Client client00986 = new PLxKPH_Client(986, Models.ClientType.PL3KPH);
|
||||
client00986.Address = 8;
|
||||
result.Add(client00986);
|
||||
|
||||
Client client01056 = new PLxKPH_Client(1056, Models.ClientType.PL2KPH);
|
||||
client01056.Address = 9;
|
||||
result.Add(client01056);
|
||||
|
||||
Client client01120 = new PLxKPH_Client(1120, Models.ClientType.PL3KPH);
|
||||
client01120.Address = 10;
|
||||
result.Add(client01120);
|
||||
|
||||
|
||||
//Client client00995 = new Client(995, null);
|
||||
//client00995.Address = 11;
|
||||
//result.Add(client00995);
|
||||
|
||||
//Client client01238 = new Client(1238, null);
|
||||
//client01238.Address = 12;
|
||||
//result.Add(client01238);
|
||||
|
||||
//Client client02183 = new Client(2183, null);
|
||||
//client02183.Address = 13;
|
||||
//result.Add(client02183);
|
||||
|
||||
Client client02222 = new TSx_Client(2222, Models.ClientType.TSD100S);
|
||||
client02222.Address = 14;
|
||||
result.Add(client02222);
|
||||
|
||||
|
||||
Client client00038 = new Watlow988U_Client(38, Models.ClientType.Despatch_Watlow988U);
|
||||
client00038.Address = 1;
|
||||
result.Add(client00038);
|
||||
|
||||
|
||||
|
||||
return OrderByMIDS(result);
|
||||
}
|
||||
|
||||
|
||||
private static List<Client> OrderByMIDS(List<Client> list)
|
||||
{
|
||||
List<Client> result = new List<Client>();
|
||||
|
||||
|
||||
while (list.Count > 0)
|
||||
{
|
||||
int k = 0;
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (list[i].MIDS < list[k].MIDS)
|
||||
k = i;
|
||||
}
|
||||
result.Add(list[k]);
|
||||
list.RemoveAt(k);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
327
ChamChat/ChamChat/Graph.cs
Normal file
327
ChamChat/ChamChat/Graph.cs
Normal file
@@ -0,0 +1,327 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using ChamChat.Models;
|
||||
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public class Graph
|
||||
{
|
||||
// Rule: Max size of image is limietd by Control.Location as 2^15 = 32768 pix.
|
||||
private const float _MaxSizeOfImage = 32768F;
|
||||
|
||||
public Int32 MaxSizeOfImage { get { return (int)Math.Round(_MaxSizeOfImage); } }
|
||||
|
||||
public Graph(Profile Profile, Size SizeOfView, Client Client)
|
||||
{
|
||||
_Profile = Profile;
|
||||
_SizeOfView = SizeOfView;
|
||||
_Client = Client;
|
||||
_Width = _SizeOfView.Width;
|
||||
_Height = _SizeOfView.Height;
|
||||
_HrsInView = 24;
|
||||
|
||||
// Pens
|
||||
_Pen = new Pen(Color.Black, 3); ;
|
||||
_PenTemp = new Pen(Color.Red, 3); ;
|
||||
_PenRH = new Pen(Color.Blue, 3); ;
|
||||
_PenPreTemp = new Pen(Color.Tomato, 1);
|
||||
_PenPreTemp.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
|
||||
_PenLoopBox = new Pen(Color.Green, 2);
|
||||
_PenLoopBox.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
|
||||
|
||||
_PenStepBorder = new Pen(Color.LightGray, 1); ;
|
||||
_PenStepBorder.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
|
||||
_Font = new Font("Arial", 8);
|
||||
_MarginY = (float)Math.Round(_Height * 0.07);
|
||||
_MarginX = Math.Min(20,(float)Math.Round(_Width * 0.05));
|
||||
}
|
||||
|
||||
|
||||
private float _MarginY = 20;
|
||||
private float _MarginX = 20;
|
||||
private Size _SizeOfView;
|
||||
private Font _Font;
|
||||
private Pen _PenStepBorder;
|
||||
private Pen _PenPreTemp;
|
||||
private Pen _PenTemp;
|
||||
private Pen _PenRH;
|
||||
private Pen _Pen;
|
||||
private Pen _PenLoopBox;
|
||||
|
||||
private Client _Client; public Client Client { get { return _Client; } }
|
||||
private Profile _Profile; public Profile Profile { get { return _Profile; } }
|
||||
private Bitmap _Image;
|
||||
|
||||
private double _maxY = double.MinValue;
|
||||
private double _minY = double.MaxValue;
|
||||
private float _HrsInView = 24; public float HrsInView { get { return _HrsInView; } set { _HrsInView = value; } }
|
||||
private double _maxX = 6; // in minutes
|
||||
private float _Height; public Int32 Height { get { return (int)Math.Round(_Height); } set { _Height = value; } }
|
||||
private float _Width; public Int32 Width { get { return (int)Math.Round(_Width); } }
|
||||
private float _maxStepDisplayDuration = 240; public Double MaxStepDisplayDuration { set { _maxStepDisplayDuration = (float)value; } }
|
||||
float[,] _StepBorders; // Set while drawing
|
||||
|
||||
|
||||
|
||||
private void SetScale()
|
||||
{
|
||||
_Width = _SizeOfView.Width;
|
||||
_minY = Double.MaxValue;
|
||||
_maxY = Double.MinValue;
|
||||
_maxX = 0;
|
||||
|
||||
foreach (Step s in _Profile.Steps)
|
||||
{
|
||||
// Temperature
|
||||
_minY = Math.Min(_minY, s.T);
|
||||
_maxY = Math.Max(_maxY, s.T);
|
||||
|
||||
if (_Client.Parameters.Contains(Parameter.PreTemp))
|
||||
{
|
||||
_maxY = Math.Max(_maxY, s.PreTemp);
|
||||
_minY = Math.Min(_minY, s.PreTemp);
|
||||
}
|
||||
|
||||
// Shorten if steps are displayed cropped
|
||||
if (s.DurationMin > _maxStepDisplayDuration)
|
||||
_maxX += _maxStepDisplayDuration;
|
||||
else
|
||||
_maxX += s.DurationMin;
|
||||
}
|
||||
|
||||
// Take a margin
|
||||
_maxY += Math.Abs(0.15 * _maxY);
|
||||
_minY -= Math.Abs(0.07 * _minY);
|
||||
|
||||
|
||||
// Max number of hours in 1 view
|
||||
float pixelsPerMinute = _SizeOfView.Width / (60 * _HrsInView);
|
||||
|
||||
|
||||
_Width = (float)Math.Round(pixelsPerMinute * (float)_maxX);
|
||||
_Width = Math.Min(_MaxSizeOfImage, _Width);
|
||||
_Width = Math.Max(_SizeOfView.Width, _Width);
|
||||
|
||||
_maxY = Math.Max(100, _maxY); // Scale is 100 minimum (for RH)
|
||||
}
|
||||
|
||||
|
||||
private float YtoCanvas(Double y)
|
||||
{
|
||||
float a = (_Height - 2 * _MarginY) / ((float)_minY - (float)_maxY);
|
||||
float b = _MarginY - a * (float)_maxY;
|
||||
return a * (float)y + b;
|
||||
}
|
||||
private float XtoCanvas(Double x)
|
||||
{
|
||||
float a = ((float)_Width - 2 * _MarginX) / (float)_maxX;
|
||||
float b = _MarginX;
|
||||
return a * (float)x + b;
|
||||
}
|
||||
|
||||
|
||||
private void Create()
|
||||
{
|
||||
_Image = new Bitmap((int)_Width, (int)_Height);
|
||||
Graphics g = Graphics.FromImage(_Image);
|
||||
g.Clear(Color.White);
|
||||
|
||||
// Horizontal axis
|
||||
g.DrawLine(_Pen, 0, YtoCanvas(0), _Width, YtoCanvas(0));
|
||||
|
||||
// Temperature
|
||||
float X1 = 0;
|
||||
float X2 = 0;
|
||||
double T1 = 25;
|
||||
double T2 = 0;
|
||||
double RH1 = 50;
|
||||
double RH2 = 50;
|
||||
_StepBorders = new float[_Profile.Steps.Count, 2];
|
||||
|
||||
g.DrawLine(_PenStepBorder, XtoCanvas(X1), 0, XtoCanvas(X1), _Height);
|
||||
|
||||
// Draw from room temperature of 25 °C to first start
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1), YtoCanvas(T1), XtoCanvas(X2), YtoCanvas(_Profile.Steps[0].T));
|
||||
|
||||
|
||||
for (int i = 0; i < _Profile.Steps.Count; i++)
|
||||
{
|
||||
Step s = _Profile.Steps[i];
|
||||
|
||||
|
||||
T2 = s.T;
|
||||
RH2 = s.RH;
|
||||
X2 = X1 + (float)s.DurationMin;
|
||||
|
||||
// Draw the connecting vertical line (infinite ramp)
|
||||
if (!s.RampCtrlT)
|
||||
{
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1), YtoCanvas(T1), XtoCanvas(X1), YtoCanvas(T2));
|
||||
T1 = s.T;
|
||||
}
|
||||
if (!s.RampCtrlRH && s.RH > 0)
|
||||
{
|
||||
g.DrawLine(_PenRH, XtoCanvas(X1), YtoCanvas(RH1), XtoCanvas(X1), YtoCanvas(RH2));
|
||||
RH1 = s.RH;
|
||||
}
|
||||
|
||||
// Draw the profile line
|
||||
if (s.DurationMin > _maxStepDisplayDuration)
|
||||
{
|
||||
// Shrink period with dotted line
|
||||
X2 = X1 + _maxStepDisplayDuration;
|
||||
|
||||
if (RH2 > 0)
|
||||
{
|
||||
if (s.RampCtrlRH) // Draw RH ramp with dots in the middle
|
||||
{
|
||||
float x1 = XtoCanvas(X1); float x2 = XtoCanvas(X2);
|
||||
float y1 = YtoCanvas(RH1); float y2 = YtoCanvas(RH2);
|
||||
PointF P1 = new PointF(x1, y1);
|
||||
PointF P2 = new PointF(x1 + 0.25F * (x2 - x1), y1 + 0.25F * (y2 - y1));
|
||||
PointF P3 = new PointF(x1 + 0.75F * (x2 - x1), y1 + 0.75F * (y2 - y1));
|
||||
PointF P4 = new PointF(x2, y2);
|
||||
g.DrawLine(_PenRH, P1, P2);
|
||||
_PenRH.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
|
||||
g.DrawLine(_PenRH, P2, P3);
|
||||
_PenRH.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
|
||||
g.DrawLine(_PenRH, P3, P4);
|
||||
}
|
||||
else // Draw straight RH line with dots in the middle
|
||||
{
|
||||
g.DrawLine(_PenRH, XtoCanvas(X1), YtoCanvas(RH1), XtoCanvas(X1 + 0.25 * _maxStepDisplayDuration), YtoCanvas(RH2));
|
||||
_PenRH.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
|
||||
g.DrawLine(_PenRH, XtoCanvas(X1 + 0.25 * _maxStepDisplayDuration), YtoCanvas(RH1), XtoCanvas(X1 + 0.75 * _maxStepDisplayDuration), YtoCanvas(RH2));
|
||||
_PenRH.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
|
||||
g.DrawLine(_PenRH, XtoCanvas(X1 + 0.75 * _maxStepDisplayDuration), YtoCanvas(RH1), XtoCanvas(X2), YtoCanvas(RH2));
|
||||
}
|
||||
}
|
||||
|
||||
if (s.RampCtrlT) // Draw T ramp with dots in the middle
|
||||
{
|
||||
float x1 = XtoCanvas(X1); float x2 = XtoCanvas(X2);
|
||||
float y1 = YtoCanvas(T1); float y2 = YtoCanvas(T2);
|
||||
PointF P1 = new PointF(x1, y1);
|
||||
PointF P2 = new PointF(x1 + 0.25F * (x2 - x1), y1 + 0.25F * (y2 - y1));
|
||||
PointF P3 = new PointF(x1 + 0.75F * (x2 - x1), y1 + 0.75F * (y2 - y1));
|
||||
PointF P4 = new PointF(x2, y2);
|
||||
g.DrawLine(_PenTemp, P1, P2);
|
||||
_PenTemp.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
|
||||
g.DrawLine(_PenTemp, P2, P3);
|
||||
_PenTemp.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
|
||||
g.DrawLine(_PenTemp, P3, P4);
|
||||
}
|
||||
else // Draw straight T line with dots in the middle
|
||||
{
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1), YtoCanvas(T1), XtoCanvas(X1 + 0.25 * _maxStepDisplayDuration), YtoCanvas(T2));
|
||||
_PenTemp.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1 + 0.25 * _maxStepDisplayDuration), YtoCanvas(T1), XtoCanvas(X1 + 0.75 * _maxStepDisplayDuration), YtoCanvas(T2));
|
||||
_PenTemp.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1 + 0.75 * _maxStepDisplayDuration), YtoCanvas(T1), XtoCanvas(X2), YtoCanvas(T2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else // Period is shorter than _maxStepDisplayDuration
|
||||
{
|
||||
if (RH2 > 0)
|
||||
{
|
||||
if (RH2 == T2)
|
||||
g.DrawLine(_PenRH, XtoCanvas(X1), YtoCanvas(RH1) + _PenRH.Width / 2, XtoCanvas(X2), YtoCanvas(RH2) + _PenRH.Width / 2);
|
||||
else
|
||||
g.DrawLine(_PenRH, XtoCanvas(X1), YtoCanvas(RH1), XtoCanvas(X2), YtoCanvas(RH2));
|
||||
}
|
||||
|
||||
if (T2 == RH2)
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1), YtoCanvas(T1) - _PenTemp.Width / 2, XtoCanvas(X2), YtoCanvas(T2) - _PenTemp.Width / 2);
|
||||
else
|
||||
g.DrawLine(_PenTemp, XtoCanvas(X1), YtoCanvas(T1), XtoCanvas(X2), YtoCanvas(T2));
|
||||
}
|
||||
|
||||
|
||||
// Draw temperature text (below if RH > T or if T < 0)
|
||||
if (!s.RampCtrlT)
|
||||
{
|
||||
string sTemp = String.Format("{0:0}", s.T);
|
||||
if (s.T <= 0 || RH2 > T2)
|
||||
g.DrawString(sTemp, _Font, new SolidBrush(_PenTemp.Color), new PointF(XtoCanvas(X1) + 2, YtoCanvas(s.T) + 2));
|
||||
else
|
||||
g.DrawString(sTemp, _Font, new SolidBrush(_PenTemp.Color), new PointF(XtoCanvas(X1) + 2, YtoCanvas(s.T) - g.MeasureString(sTemp, _Font).Height - 2));
|
||||
|
||||
}
|
||||
|
||||
// Draw RH text (always below line)
|
||||
if (!s.RampCtrlRH && s.RH > 0)
|
||||
{
|
||||
string sRH = String.Format("{0:0}", s.RH);
|
||||
g.DrawString(sRH, _Font, new SolidBrush(_PenRH.Color), new PointF(XtoCanvas(X1) + 2, YtoCanvas(s.RH) + 2));
|
||||
}
|
||||
|
||||
|
||||
// Draw pre-temp
|
||||
if (_Client.Parameters.Contains(Parameter.PreTemp))
|
||||
g.DrawLine(_PenPreTemp, XtoCanvas(X1), YtoCanvas(s.PreTemp), XtoCanvas(X2), YtoCanvas(s.PreTemp));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Draw step border
|
||||
string stepInfo = String.Format("{0:00}", s.PK + 1);
|
||||
g.DrawLine(_PenStepBorder, XtoCanvas(X2), 0, XtoCanvas(X2), _Height);
|
||||
float h = g.MeasureString(stepInfo, _Font).Height;
|
||||
float w = g.MeasureString(stepInfo, _Font).Width;
|
||||
if (w < XtoCanvas(X2) - XtoCanvas(X1))
|
||||
g.DrawString(stepInfo, _Font, Brushes.Black, new PointF(XtoCanvas(X1) + 2, _Height - h - 2));
|
||||
|
||||
// Add to stepBorders
|
||||
_StepBorders[i, 0] = X1;
|
||||
_StepBorders[i, 1] = X2;
|
||||
|
||||
|
||||
T1 = T2;
|
||||
RH1 = RH2;
|
||||
X1 = X2;
|
||||
}
|
||||
|
||||
|
||||
// Loops boxes
|
||||
foreach (Loop loop in _Profile.Loops)
|
||||
{
|
||||
float xLeft = _StepBorders[loop.First, 0];
|
||||
float xRight = _StepBorders[loop.Last, 1];
|
||||
g.DrawRectangle(_PenLoopBox, XtoCanvas(xLeft) + 3, _MarginY, XtoCanvas(xRight) - XtoCanvas(xLeft) - 6, _Height - 2 * _MarginY);
|
||||
string l = string.Format("{0:0}X", loop.N);
|
||||
g.DrawString(l, _Font, new SolidBrush(_PenLoopBox.Color), new PointF(XtoCanvas(xLeft) + 6, _MarginY));
|
||||
}
|
||||
|
||||
//g.DrawString(_Width.ToString(), _Font, Brushes.Black, new PointF(0, 0));
|
||||
|
||||
g.Dispose();
|
||||
}
|
||||
|
||||
|
||||
public Bitmap GetImage()
|
||||
{
|
||||
SetScale();
|
||||
Create();
|
||||
return _Image;
|
||||
}
|
||||
|
||||
public Int32 StepAtMousePosition(Int32 X)
|
||||
{
|
||||
for (int i = 0; i < _StepBorders.GetLength(0); i++)
|
||||
if (X > XtoCanvas(_StepBorders[i, 0]) && X < XtoCanvas(_StepBorders[i, 1]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
375
ChamChat/ChamChat/Interface.FDTI_USB_RS232.cs
Normal file
375
ChamChat/ChamChat/Interface.FDTI_USB_RS232.cs
Normal file
@@ -0,0 +1,375 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FTD2XX_NET;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
// Communication with FDTI USB-COM422 Plus 1 or WE
|
||||
public class FDTI_USB_RS232 : Interface
|
||||
{
|
||||
public FDTI_USB_RS232(String ID) : base(ID)
|
||||
{
|
||||
_Type = InterfaceType.FDTI_USB_RS232;
|
||||
}
|
||||
|
||||
public FDTI_USB_RS232()
|
||||
: base()
|
||||
{
|
||||
_Type = InterfaceType.FDTI_USB_RS232;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Properties and fields
|
||||
private static FTDI _RS232COM = new FTDI();
|
||||
private static uint _Baudrate = 9600;
|
||||
private static FlowControl _FlowControl = FlowControl.FT_FLOW_NONE;
|
||||
private System.Object lockDataTransfer = new System.Object();
|
||||
private bool _Connected = false; public Boolean Connected { get { return _Connected; } }
|
||||
|
||||
|
||||
|
||||
public override Boolean Open()
|
||||
{
|
||||
bool result;
|
||||
|
||||
if (_ID != null)
|
||||
result = OpenByID();
|
||||
else
|
||||
result = OpenSingleConnected();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override Boolean Close()
|
||||
{
|
||||
_RS232COM.Close();
|
||||
_Connected = false;
|
||||
_RS232COM = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Boolean OpenByID()
|
||||
{
|
||||
_InterfaceStatus = null;
|
||||
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = _RS232COM.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
|
||||
// Check status
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No FTDI devices found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = _RS232COM.GetDeviceList(ftdiDeviceList);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Find all USB-COM422 devices
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> ftdiDevices = new List<FTDI.FT_DEVICE_INFO_NODE>();
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
ftdiDevices.Add(ftdiDeviceList[i]);
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> USBCOM232List = ftdiDevices.FindAll(delegate(FTDI.FT_DEVICE_INFO_NODE node) { return node.SerialNumber == _ID; });
|
||||
|
||||
|
||||
if (USBCOM232List.Count > 1)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("More than one USB-COM232 devices with given serial number found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (USBCOM232List.Count == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No USB-COM232 device found with given serial number");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open device by serial number
|
||||
ftStatus = _RS232COM.OpenBySerialNumber(USBCOM232List[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to open USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_ID = USBCOM232List[0].SerialNumber;
|
||||
|
||||
|
||||
// Set up device data parameters
|
||||
// Set Baud rate
|
||||
ftStatus = _RS232COM.SetBaudRate(_Baudrate);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set baud rate in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set data characteristics - Data bits, Stop bits, Parity
|
||||
ftStatus = _RS232COM.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set data characteristics in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flow control - set Xon/Xoff control OFF
|
||||
ushort flowCtrl = (ushort)_FlowControl;
|
||||
|
||||
|
||||
ftStatus = _RS232COM.SetFlowControl(flowCtrl, 0x11, 0x13);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set flow control in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set read timeout to 5 seconds, write timeout to infinite
|
||||
ftStatus = _RS232COM.SetTimeouts(5000, 0);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set timeouts in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
_Connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Boolean OpenSingleConnected()
|
||||
{
|
||||
_InterfaceStatus = null;
|
||||
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = _RS232COM.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
|
||||
// Check status
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of FTDI devices",ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No FTDI devices found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = _RS232COM.GetDeviceList(ftdiDeviceList);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Find all USB-COM422 devices
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> ftdiDevices = new List<FTDI.FT_DEVICE_INFO_NODE>();
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
ftdiDevices.Add(ftdiDeviceList[i]);
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> USBCOM232List = ftdiDevices.FindAll(delegate(FTDI.FT_DEVICE_INFO_NODE node) { return (node.Description.ToString().Contains("FTDI_USB_RS232")); });
|
||||
|
||||
|
||||
if (USBCOM232List.Count > 1)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("More than one USB-COM232 device found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (USBCOM232List.Count == 0 )
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No USB-COM232 device found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Open device by serial number
|
||||
ftStatus = _RS232COM.OpenBySerialNumber(USBCOM232List[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to open USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_ID = USBCOM232List[0].SerialNumber;
|
||||
|
||||
|
||||
// Set up device data parameters
|
||||
// Set Baud rate
|
||||
ftStatus = _RS232COM.SetBaudRate(_Baudrate);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set baud rate in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set data characteristics - Data bits, Stop bits, Parity
|
||||
ftStatus = _RS232COM.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set data characteristics in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flow control - set Xon/Xoff control OFF
|
||||
ushort flowCtrl = (ushort)_FlowControl;
|
||||
|
||||
|
||||
ftStatus = _RS232COM.SetFlowControl(flowCtrl, 0x11, 0x13);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set flow control in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set read timeout to 5 seconds, write timeout to infinite
|
||||
ftStatus = _RS232COM.SetTimeouts(5000, 0);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set timeouts in USB-COM232 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
_Connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string ReplaceDelimeters(string cmd)
|
||||
{
|
||||
string result = cmd;
|
||||
result = result.Replace(((char)13).ToString(), "<CR>");
|
||||
result = result.Replace(((char)10).ToString(), "<LF>");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override DataTransferLog DataTransfer(String Command, out String _ReturnData, Int32 ReturnDataWaitms)
|
||||
{
|
||||
lock (lockDataTransfer) // Calling threads will wait for the current thread to finish executing the locked section.
|
||||
{
|
||||
DataTransferLog dataTransferLog = new DataTransferLog(ReplaceDelimeters(Command), "", this);
|
||||
|
||||
_ReturnData = "";
|
||||
_InterfaceStatus = null;
|
||||
|
||||
|
||||
// Construct string to send
|
||||
string dataToSend = Command.Replace(" ", "");
|
||||
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
UInt32 numBytesWritten = 0;
|
||||
ftStatus = _RS232COM.Write(dataToSend, dataToSend.Length, ref numBytesWritten);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to write to USB-COM232 device", ftStatus.ToString());
|
||||
_ReturnData = "Failed to write to USB-COM232 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
|
||||
|
||||
// Read from devices
|
||||
if (ReturnDataWaitms > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(ReturnDataWaitms);
|
||||
|
||||
UInt32 numBytesAvailable = 0;
|
||||
ftStatus = _RS232COM.GetRxBytesAvailable(ref numBytesAvailable);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of bytes available to read from USB-COM232 device", ftStatus.ToString());
|
||||
dataTransferLog.ReturnData = "Failed to get number of bytes available to read from USB-COM232 device | " + ftStatus.ToString();
|
||||
return dataTransferLog;
|
||||
}
|
||||
|
||||
// Now that we have the amount of data we want available, read it
|
||||
string readData;
|
||||
UInt32 numBytesRead = 0;
|
||||
|
||||
// Note that the Read method is overloaded, so can read string or byte array data
|
||||
ftStatus = _RS232COM.Read(out readData, numBytesAvailable, ref numBytesRead);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to read data from USB-COM232 device", ftStatus.ToString());
|
||||
dataTransferLog.ReturnData = "Failed to read data from USB-COM232 device | " + ftStatus.ToString();
|
||||
return dataTransferLog;
|
||||
}
|
||||
_ReturnData = readData.Trim();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ReturnData += "not requested";
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
}
|
||||
|
||||
return dataTransferLog;
|
||||
} // End lock
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}.{1}: Baud {2:0}, Flowcontrol {3}", _Type, _ID, _Baudrate, _FlowControl.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
378
ChamChat/ChamChat/Interface.FDTI_USB_RS422.cs
Normal file
378
ChamChat/ChamChat/Interface.FDTI_USB_RS422.cs
Normal file
@@ -0,0 +1,378 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FTD2XX_NET;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
// Communication with FDTI USB-COM422 Plus 1 or WE
|
||||
public class FDTI_USB_COM422 : Interface
|
||||
{
|
||||
public FDTI_USB_COM422(String ID) : base(ID)
|
||||
{
|
||||
_Type = InterfaceType.FDTI_USB_COM422;
|
||||
}
|
||||
|
||||
public FDTI_USB_COM422()
|
||||
: base()
|
||||
{
|
||||
_Type = InterfaceType.FDTI_USB_COM422;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Properties and fields
|
||||
private static FTDI _RS422COM = new FTDI();
|
||||
private static uint _Baudrate = 9600;
|
||||
private static FlowControl _FlowControl = FlowControl.FT_FLOW_NONE;
|
||||
private System.Object lockDataTransfer = new System.Object();
|
||||
private bool _Connected = false; public Boolean Connected { get { return _Connected; } }
|
||||
|
||||
|
||||
|
||||
public override Boolean Open()
|
||||
{
|
||||
bool result;
|
||||
|
||||
if (_ID != null)
|
||||
result = OpenByID();
|
||||
else
|
||||
result = OpenSingleConnected();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override Boolean Close()
|
||||
{
|
||||
_RS422COM.Close();
|
||||
_Connected = false;
|
||||
_RS422COM = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Boolean OpenByID()
|
||||
{
|
||||
_InterfaceStatus = null;
|
||||
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = _RS422COM.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
|
||||
// Check status
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No FTDI devices found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = _RS422COM.GetDeviceList(ftdiDeviceList);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Find all USB-COM422 devices
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> ftdiDevices = new List<FTDI.FT_DEVICE_INFO_NODE>();
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
ftdiDevices.Add(ftdiDeviceList[i]);
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> USBCOM422List = ftdiDevices.FindAll(delegate(FTDI.FT_DEVICE_INFO_NODE node) { return node.SerialNumber == _ID; });
|
||||
|
||||
|
||||
if (USBCOM422List.Count > 1)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("More than one USB-COM422 devices with given serial number found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (USBCOM422List.Count == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No USB-COM422 device found with given serial number");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open device by serial number
|
||||
ftStatus = _RS422COM.OpenBySerialNumber(USBCOM422List[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to open USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_ID = USBCOM422List[0].SerialNumber;
|
||||
|
||||
|
||||
// Set up device data parameters
|
||||
// Set Baud rate
|
||||
ftStatus = _RS422COM.SetBaudRate(_Baudrate);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set baud rate in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set data characteristics - Data bits, Stop bits, Parity
|
||||
ftStatus = _RS422COM.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set data characteristics in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flow control - set Xon/Xoff control OFF
|
||||
ushort flowCtrl = (ushort)_FlowControl;
|
||||
|
||||
|
||||
ftStatus = _RS422COM.SetFlowControl(flowCtrl, 0x11, 0x13);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set flow control in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set read timeout to 5 seconds, write timeout to infinite
|
||||
ftStatus = _RS422COM.SetTimeouts(5000, 0);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set timeouts in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
_Connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Boolean OpenSingleConnected()
|
||||
{
|
||||
_InterfaceStatus = null;
|
||||
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = _RS422COM.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
|
||||
// Check status
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of FTDI devices",ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No FTDI devices found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = _RS422COM.GetDeviceList(ftdiDeviceList);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Find all USB-COM422 devices
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> ftdiDevices = new List<FTDI.FT_DEVICE_INFO_NODE>();
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
ftdiDevices.Add(ftdiDeviceList[i]);
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> USBCOM422List = ftdiDevices.FindAll(delegate(FTDI.FT_DEVICE_INFO_NODE node) { return (node.Description.ToString().Contains("FTDI_USB_RS422")); });
|
||||
|
||||
|
||||
if (USBCOM422List.Count > 1)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("More than one USB-COM422 device found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (USBCOM422List.Count == 0 )
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No USB-COM422 device found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Open device by serial number
|
||||
ftStatus = _RS422COM.OpenBySerialNumber(USBCOM422List[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to open USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_ID = USBCOM422List[0].SerialNumber;
|
||||
|
||||
|
||||
// Set up device data parameters
|
||||
// Set Baud rate
|
||||
ftStatus = _RS422COM.SetBaudRate(_Baudrate);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set baud rate in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set data characteristics - Data bits, Stop bits, Parity
|
||||
ftStatus = _RS422COM.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set data characteristics in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flow control - set Xon/Xoff control OFF
|
||||
ushort flowCtrl = (ushort)_FlowControl;
|
||||
|
||||
|
||||
ftStatus = _RS422COM.SetFlowControl(flowCtrl, 0x11, 0x13);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set flow control in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set read timeout to 5 seconds, write timeout to infinite
|
||||
ftStatus = _RS422COM.SetTimeouts(5000, 0);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set timeouts in USB-COM422 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
_Connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string ReplaceDelimeters(string cmd)
|
||||
{
|
||||
string result = cmd;
|
||||
result = result.Replace(((char)13).ToString(), "<CR>");
|
||||
result = result.Replace(((char)10).ToString(), "<LF>");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override DataTransferLog DataTransfer(String Command, out String _ReturnData, Int32 ReturnDataWaitms)
|
||||
{
|
||||
lock (lockDataTransfer) // Calling threads will wait for the current thread to finish executing the locked section.
|
||||
{
|
||||
DataTransferLog dataTransferLog = new DataTransferLog(ReplaceDelimeters(Command), "", this);
|
||||
|
||||
_ReturnData = "";
|
||||
_InterfaceStatus = null;
|
||||
|
||||
|
||||
// Construct string to send
|
||||
string dataToSend = Command.Replace(" ", "");
|
||||
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
UInt32 numBytesWritten = 0;
|
||||
ftStatus = _RS422COM.Write(dataToSend, dataToSend.Length, ref numBytesWritten);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to write to USB-COM422 device", ftStatus.ToString());
|
||||
_ReturnData = "Failed to write to USB-COM422 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
|
||||
|
||||
// Read from devices
|
||||
if (ReturnDataWaitms > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(ReturnDataWaitms);
|
||||
|
||||
UInt32 numBytesAvailable = 0;
|
||||
ftStatus = _RS422COM.GetRxBytesAvailable(ref numBytesAvailable);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of bytes available to read from USB-COM422 device", ftStatus.ToString());
|
||||
_ReturnData = "Failed to get number of bytes available to read from USB-COM422 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
|
||||
// Now that we have the amount of data we want available, read it
|
||||
string readData;
|
||||
UInt32 numBytesRead = 0;
|
||||
|
||||
// Note that the Read method is overloaded, so can read string or byte array data
|
||||
ftStatus = _RS422COM.Read(out readData, numBytesAvailable, ref numBytesRead);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to read data from USB-COM422 device", ftStatus.ToString());
|
||||
|
||||
_ReturnData = "Failed to read data from USB-COM422 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
_ReturnData = readData.Trim();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ReturnData = "not requested";
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
}
|
||||
|
||||
return dataTransferLog;
|
||||
} // End lock
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}.{1}: Baud {2:0}, Flowcontrol {3}", _Type, _ID, _Baudrate, _FlowControl.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
407
ChamChat/ChamChat/Interface.FDTI_USB_RS485.cs
Normal file
407
ChamChat/ChamChat/Interface.FDTI_USB_RS485.cs
Normal file
@@ -0,0 +1,407 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FTD2XX_NET;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
// Communication with FDTI USB-COM485-Plus1
|
||||
public class FDTI_USB_COM485 : Interface
|
||||
{
|
||||
public FDTI_USB_COM485(String ID)
|
||||
: base(ID)
|
||||
{
|
||||
_Type = InterfaceType.FDTI_USB_COM485;
|
||||
}
|
||||
|
||||
public FDTI_USB_COM485()
|
||||
: base()
|
||||
{
|
||||
_Type = InterfaceType.FDTI_USB_COM485;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Properties and fields
|
||||
private static FTDI _RS485COM = new FTDI();
|
||||
private static uint _Baudrate = 9600;
|
||||
private static FlowControl _FlowControl = FlowControl.FT_FLOW_NONE;
|
||||
|
||||
|
||||
|
||||
private System.Object lockDataTransfer = new System.Object();
|
||||
private bool _Connected = false; public Boolean Connected { get { return _Connected; } }
|
||||
|
||||
|
||||
|
||||
public override Boolean Open()
|
||||
{
|
||||
bool result;
|
||||
|
||||
if (_ID != null)
|
||||
result = OpenByID();
|
||||
else
|
||||
result = OpenSingleConnected();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Close()
|
||||
{
|
||||
_RS485COM.Close();
|
||||
_Connected = false;
|
||||
_RS485COM = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Boolean OpenByID()
|
||||
{
|
||||
_InterfaceStatus = null;
|
||||
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = _RS485COM.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
|
||||
// Check status
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No FTDI devices found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = _RS485COM.GetDeviceList(ftdiDeviceList);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Find all USB-COM485 devices
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> ftdiDevices = new List<FTDI.FT_DEVICE_INFO_NODE>();
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
ftdiDevices.Add(ftdiDeviceList[i]);
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> USBCOM485List = ftdiDevices.FindAll(delegate(FTDI.FT_DEVICE_INFO_NODE node) { return node.SerialNumber == _ID; });
|
||||
|
||||
|
||||
|
||||
|
||||
if (USBCOM485List.Count > 1)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("More than one USB-COM485 devices with given serial number found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (USBCOM485List.Count == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No USB-COM485 device found with given serial number");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open device by serial number
|
||||
ftStatus = _RS485COM.OpenBySerialNumber(USBCOM485List[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to open USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_ID = USBCOM485List[0].SerialNumber;
|
||||
|
||||
|
||||
// Set up device data parameters
|
||||
// Set Baud rate
|
||||
ftStatus = _RS485COM.SetBaudRate(_Baudrate);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set baud rate in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Set data characteristics - Data bits, Stop bits, Parity
|
||||
ftStatus = _RS485COM.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set data characteristics in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flow control - set Xon/Xoff control OFF
|
||||
ushort flowCtrl = (ushort)_FlowControl;
|
||||
|
||||
|
||||
ftStatus = _RS485COM.SetFlowControl(flowCtrl, 0x11, 0x13);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set flow control in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set read timeout to 5 seconds, write timeout to infinite
|
||||
ftStatus = _RS485COM.SetTimeouts(5000, 0);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set timeouts in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
_Connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Boolean OpenSingleConnected()
|
||||
{
|
||||
_InterfaceStatus = null;
|
||||
|
||||
UInt32 ftdiDeviceCount = 0;
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
// Determine the number of FTDI devices connected to the machine
|
||||
ftStatus = _RS485COM.GetNumberOfDevices(ref ftdiDeviceCount);
|
||||
|
||||
// Check status
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of FTDI devices",ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no devices available, return
|
||||
if (ftdiDeviceCount == 0)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No FTDI devices found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Allocate storage for device info list
|
||||
FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
|
||||
|
||||
|
||||
// Populate our device list
|
||||
ftStatus = _RS485COM.GetDeviceList(ftdiDeviceList);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get FTDI devices", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Find all USB-COM485 devices
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> ftdiDevices = new List<FTDI.FT_DEVICE_INFO_NODE>();
|
||||
for (UInt32 i = 0; i < ftdiDeviceCount; i++)
|
||||
ftdiDevices.Add(ftdiDeviceList[i]);
|
||||
List<FTDI.FT_DEVICE_INFO_NODE> USBCOM485List = ftdiDevices.FindAll(delegate(FTDI.FT_DEVICE_INFO_NODE node) { return (node.Description.ToString().Contains("FTDI_USB_RS485")); });
|
||||
|
||||
|
||||
if (USBCOM485List.Count > 1)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("More than one USB-COM485 device found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (USBCOM485List.Count == 0 )
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("No USB-COM485 device found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Open device by serial number
|
||||
ftStatus = _RS485COM.OpenBySerialNumber(USBCOM485List[0].SerialNumber);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to open USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_ID = USBCOM485List[0].SerialNumber;
|
||||
|
||||
|
||||
// Set up device data parameters
|
||||
// Set Baud rate
|
||||
ftStatus = _RS485COM.SetBaudRate(_Baudrate);
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set baud rate in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set data characteristics - Data bits, Stop bits, Parity
|
||||
ftStatus = _RS485COM.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set data characteristics in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flow control - set Xon/Xoff control OFF
|
||||
ushort flowCtrl = (ushort)_FlowControl;
|
||||
|
||||
|
||||
ftStatus = _RS485COM.SetFlowControl(flowCtrl, 0x11, 0x13);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set flow control in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Set read timeout to 5 seconds, write timeout to infinite
|
||||
ftStatus = _RS485COM.SetTimeouts(5000, 0);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to set timeouts in USB-COM485 device", ftStatus.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
_Connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string NOTINUSE_ReplaceDelimeters(string cmd)
|
||||
{
|
||||
string result = cmd;
|
||||
result = result.Replace(((char)13).ToString(), "<CR>");
|
||||
result = result.Replace(((char)10).ToString(), "<LF>");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override DataTransferLog DataTransfer(String Command, out String _ReturnData, Int32 ReturnDataWaitms)
|
||||
{
|
||||
lock (lockDataTransfer) // Calling threads will wait for the current thread to finish executing the locked section.
|
||||
{
|
||||
DataTransferLog dataTransferLog = new DataTransferLog(ANSI_X328.ToANSI(Command), "", this);
|
||||
|
||||
_ReturnData = "";
|
||||
_InterfaceStatus = null;
|
||||
|
||||
|
||||
// Construct string to send
|
||||
string dataToSend = Command.Replace(" ", "");
|
||||
|
||||
FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
|
||||
|
||||
UInt32 numBytesWritten = 0;
|
||||
ftStatus = _RS485COM.Write(dataToSend, dataToSend.Length, ref numBytesWritten);
|
||||
|
||||
|
||||
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to write to USB-COM485 device", ftStatus.ToString());
|
||||
_ReturnData = "Failed to write to USB-COM485 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
|
||||
|
||||
// Read from devices
|
||||
if (ReturnDataWaitms > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(ReturnDataWaitms);
|
||||
|
||||
UInt32 numBytesAvailable = 0;
|
||||
ftStatus = _RS485COM.GetRxBytesAvailable(ref numBytesAvailable);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to get number of bytes available to read from USB-COM485 device", ftStatus.ToString());
|
||||
_ReturnData = "Failed to get number of bytes available to read from USB-COM485 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
|
||||
// Now that we have the amount of data we want available, read it
|
||||
string readData;
|
||||
UInt32 numBytesRead = 0;
|
||||
|
||||
|
||||
// Note that the Read method is overloaded, so can read string or byte array data
|
||||
ftStatus = _RS485COM.Read(out readData, numBytesAvailable, ref numBytesRead);
|
||||
if (ftStatus != FTDI.FT_STATUS.FT_OK)
|
||||
{
|
||||
_InterfaceStatus = new InterfaceStatus("Failed to read data from USB-COM485 device", ftStatus.ToString());
|
||||
|
||||
_ReturnData = "Failed to read data from USB-COM485 device | " + ftStatus.ToString();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
return dataTransferLog;
|
||||
}
|
||||
_ReturnData = readData.Trim();
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ReturnData = "not requested";
|
||||
dataTransferLog.ReturnData = _ReturnData;
|
||||
}
|
||||
|
||||
return dataTransferLog;
|
||||
} // End lock
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string comPortName = "COM N/A";
|
||||
try
|
||||
{
|
||||
_RS485COM.GetCOMPort(out comPortName);
|
||||
}
|
||||
catch { }
|
||||
|
||||
byte latency = 0;
|
||||
try
|
||||
{
|
||||
_RS485COM.GetLatency(ref latency);
|
||||
}
|
||||
catch { }
|
||||
|
||||
|
||||
return string.Format("{0}.{1} on {2}: Baud {3:0}, Flowcontrol {4}, Latency {5}", _Type, _ID,comPortName, _Baudrate, _FlowControl.ToString(), latency.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
51
ChamChat/ChamChat/Interfaces.cs
Normal file
51
ChamChat/ChamChat/Interfaces.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
// Hard coded system properties.
|
||||
|
||||
|
||||
public static class Interfaces
|
||||
{
|
||||
public static List<Interface> GetAll()
|
||||
{
|
||||
List<Interface> result = new List<Interface>();
|
||||
|
||||
|
||||
Interface intFace;
|
||||
|
||||
// Add known device
|
||||
intFace = new FDTI_USB_COM422("USB_RS422_MOD_1");
|
||||
if (intFace.Open())
|
||||
result.Add(intFace);
|
||||
|
||||
|
||||
// Add known device
|
||||
intFace = new FDTI_USB_COM422("USB_RS422_MOD_2");
|
||||
if (intFace.Open())
|
||||
result.Add(intFace);
|
||||
|
||||
|
||||
// Add known device
|
||||
intFace = new FDTI_USB_COM422("USB_RS422_WE_1");
|
||||
if (intFace.Open())
|
||||
result.Add(intFace);
|
||||
|
||||
|
||||
// Add known device
|
||||
intFace = new FDTI_USB_COM485("USB_RS485_MOD_1");
|
||||
if (intFace.Open())
|
||||
result.Add(intFace);
|
||||
|
||||
// Add known device
|
||||
intFace = new FDTI_USB_RS232("USB_RS232_WE_1");
|
||||
if (intFace.Open())
|
||||
result.Add(intFace);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
ChamChat/ChamChat/Layouts.cs
Normal file
44
ChamChat/ChamChat/Layouts.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public static class Layouts
|
||||
{
|
||||
|
||||
public static void Buttons(Control control)
|
||||
{
|
||||
FlatStyle flatStyle = FlatStyle.Flat;
|
||||
|
||||
|
||||
if (control.GetType() == typeof(Button))
|
||||
{
|
||||
Button b = (Button)control;
|
||||
b.FlatStyle = flatStyle;
|
||||
}
|
||||
foreach (Control child in control.Controls)
|
||||
{
|
||||
Buttons(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void DataGridViewNotSortable(DataGridView dgv)
|
||||
{
|
||||
foreach (DataGridViewColumn column in dgv.Columns)
|
||||
column.SortMode = DataGridViewColumnSortMode.NotSortable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
21
ChamChat/ChamChat/Program.cs
Normal file
21
ChamChat/ChamChat/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new ChamChat());
|
||||
}
|
||||
}
|
||||
}
|
||||
50
ChamChat/ChamChat/PromptProgramNo.cs
Normal file
50
ChamChat/ChamChat/PromptProgramNo.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public static class PromptProgramNo
|
||||
{
|
||||
public static int Value = 0;
|
||||
private static bool valueSet;
|
||||
|
||||
|
||||
|
||||
public static bool ShowDialog(int Minimum, int Maximum)
|
||||
{
|
||||
Form prompt = new Form();
|
||||
prompt.Width = 235;
|
||||
prompt.Height = 130;
|
||||
prompt.Text = "Import program form client";
|
||||
//prompt.TopMost = true;
|
||||
prompt.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
prompt.ControlBox = false;
|
||||
prompt.StartPosition = FormStartPosition.CenterParent;
|
||||
Label textLabel = new Label() { Left = 16, Top = 16, Text = "Select the program to import!" };
|
||||
textLabel.AutoSize = true;
|
||||
|
||||
NumericUpDown inputBox = new NumericUpDown() { Left = 163, Top = 14, Width = 43, Height = 20 };
|
||||
inputBox.Minimum = Minimum;
|
||||
inputBox.Maximum = Maximum;
|
||||
inputBox.Value = Minimum;
|
||||
Value = Minimum;
|
||||
inputBox.ValueChanged += (sender, e) => { Value = (int)inputBox.Value; };
|
||||
|
||||
Button confirmation = new Button() { Text = "OK", Left = 131, Top = 54, Width = 75, Height = 23 };
|
||||
confirmation.Click += (sender, e) => { valueSet = true; prompt.Close(); };
|
||||
|
||||
Button cancel = new Button() { Text = "Cancel", Left = 19, Top = 54, Width = 75, Height = 23 };
|
||||
cancel.Click += (sender, e) => { valueSet= false; prompt.Close(); };
|
||||
|
||||
prompt.Controls.Add(confirmation);
|
||||
prompt.Controls.Add(cancel);
|
||||
prompt.Controls.Add(textLabel);
|
||||
prompt.Controls.Add(inputBox);
|
||||
prompt.ShowDialog();
|
||||
return valueSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
ChamChat/ChamChat/Properties/AssemblyInfo.cs
Normal file
36
ChamChat/ChamChat/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SPeak")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("SPeak")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a0d149fe-a1b8-4ffd-8901-5459f33b770a")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
63
ChamChat/ChamChat/Properties/Resources.Designer.cs
generated
Normal file
63
ChamChat/ChamChat/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ChamChat.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChamChat.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
ChamChat/ChamChat/Properties/Resources.resx
Normal file
117
ChamChat/ChamChat/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
50
ChamChat/ChamChat/Properties/Settings.Designer.cs
generated
Normal file
50
ChamChat/ChamChat/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,50 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ChamChat.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public int Client {
|
||||
get {
|
||||
return ((int)(this["Client"]));
|
||||
}
|
||||
set {
|
||||
this["Client"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string ProfileFilename {
|
||||
get {
|
||||
return ((string)(this["ProfileFilename"]));
|
||||
}
|
||||
set {
|
||||
this["ProfileFilename"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
ChamChat/ChamChat/Properties/Settings.settings
Normal file
12
ChamChat/ChamChat/Properties/Settings.settings
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SPeak.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="Client" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="ProfileFilename" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
18
ChamChat/ChamChat/app.config
Normal file
18
ChamChat/ChamChat/app.config
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="SPeak.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><userSettings>
|
||||
<SPeak.Properties.Settings>
|
||||
<setting name="Client" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="ProfileFilename" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
</SPeak.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
BIN
ChamChat/ChamChat/icon.ico
Normal file
BIN
ChamChat/ChamChat/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
|
||||
BIN
ChamChat/ChamChat/obj/x86/Release/ChamChat.ChamChat.resources
Normal file
BIN
ChamChat/ChamChat/obj/x86/Release/ChamChat.ChamChat.resources
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
48272d1c474abd70b671bd09b41ba43c29c5bc67
|
||||
@@ -0,0 +1,5 @@
|
||||
\\silicium\software\MASER software\Source\ChamChat\ChamChat\obj\x86\Release\ChamChat.csproj.AssemblyReference.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\ChamChat\obj\x86\Release\ChamChat.ChamChat.resources
|
||||
\\silicium\software\MASER software\Source\ChamChat\ChamChat\obj\x86\Release\ChamChat.Properties.Resources.resources
|
||||
\\silicium\software\MASER software\Source\ChamChat\ChamChat\obj\x86\Release\ChamChat.csproj.GenerateResource.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\ChamChat\obj\x86\Release\ChamChat.csproj.CoreCompileInputs.cache
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
308
ChamChat/Client_HTS7057/Client.HTS7057.cs
Normal file
308
ChamChat/Client_HTS7057/Client.HTS7057.cs
Normal file
@@ -0,0 +1,308 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public partial class HTS7057_Client : Client
|
||||
{
|
||||
private const Int32 _OptionRange = 4000;
|
||||
private const Int32 _DataTransferTimeOut = 1000;
|
||||
private DateTime _ReadyToSend = DateTime.Now; // Timestamp when client is ready to communicate
|
||||
private DateTime _dtTestStart = DateTime.Now;
|
||||
|
||||
|
||||
public HTS7057_Client(Int32 MIDS, ClientType Type)
|
||||
: base(MIDS, Type)
|
||||
{
|
||||
// Set options available in client
|
||||
_Parameters = new List<Parameter>();
|
||||
_Parameters.Add(Parameter.T);
|
||||
//_Parameters.Add(Parameter.RampT);
|
||||
|
||||
// Add option range
|
||||
_ClientOptions = new List<ProfileOption>();
|
||||
foreach (ProfileOption o in Enum.GetValues(typeof(ProfileOption)))
|
||||
if ((int)o >= _OptionRange && (int)o < _OptionRange+999)
|
||||
_ClientOptions.Add(o);
|
||||
|
||||
_InterfaceType = InterfaceType.FDTI_USB_COM422;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public override Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw)
|
||||
{
|
||||
String title = string.Format("{0:00000} {1}", _MIDS, _Type.ToStr());
|
||||
List<Step> steps = new List<Step>();
|
||||
Step step = new Step(365 * 24 * 60);
|
||||
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = string.Format("${0:00}I", _Address);
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
if (read.Length >= 6)
|
||||
{
|
||||
double sw = 0;
|
||||
if (double.TryParse(read.Substring(0, 6), out sw))
|
||||
{
|
||||
step.T = sw;
|
||||
}
|
||||
}
|
||||
steps.Add(step);
|
||||
return new Profile(title, steps, new List<Loop>(), new List<ProfileOption>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Boolean WriteProfile(Profile profile)
|
||||
{
|
||||
return WriteProfile(profile, -1);
|
||||
}
|
||||
|
||||
public override Boolean WriteProfile(Profile profile, int RAM)
|
||||
{
|
||||
// Only stand alone profiles allowed!
|
||||
if (!IsProgrammable(profile))
|
||||
return false;
|
||||
_Profile = profile;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override Boolean IsProgrammable(Profile profile)
|
||||
{
|
||||
// Profile is programmable if all below applies
|
||||
|
||||
// Profile contains just 1 step
|
||||
if (profile.SerializedStepList.Count != 1)
|
||||
{
|
||||
_ClientMessages.Add(new ClientMessage("Temperature range is -70 to 200 °C"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Step step = profile.SerializedStepList[0];
|
||||
|
||||
// Temperature is limited between -70 & 200 °C
|
||||
if (step.T < -70 || step.T > 200)
|
||||
{
|
||||
_ClientMessages.Add(new ClientMessage("Temperature range is -70 to 200 °C"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// To do
|
||||
public override Boolean HasAlarm(out List<Alarm> alarms)
|
||||
{
|
||||
alarms = new List<Alarm>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Boolean IsIdle()
|
||||
{
|
||||
// Chamber is idle if return value's last 16 chars are 0
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = string.Format("${0:00}I", _Address);
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
try
|
||||
{
|
||||
if (read.Substring(15,1) == "0")
|
||||
return true;
|
||||
}
|
||||
catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Start()
|
||||
{
|
||||
// Command consists of $01E xXxx.x bbbbbbbb
|
||||
// The minus sign for temperature must be on location of X
|
||||
// Bit 3 is on/off bit of chamber (return as bit 1 in 16-bit output)
|
||||
// Bit 5 is on/off bit of heater/cooler (return as bit 3 in 16-bit output)
|
||||
|
||||
if (_Profile == null)
|
||||
return false;
|
||||
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
double t = _Profile.Steps[0].T;
|
||||
if( t< 0)
|
||||
cmd = string.Format("${0:00}E 0-{1:00.0} 00010100", _Address, Math.Abs(t));
|
||||
else
|
||||
cmd = string.Format("${0:00}E {1:0000.0} 00010100", _Address, t);
|
||||
|
||||
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
_dtTestStart = DateTime.Now;
|
||||
|
||||
return TxRxSucces(cmd, read);
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsFinished()
|
||||
{
|
||||
// Chambers does not finish on its own
|
||||
return IsIdle();
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Stop()
|
||||
{
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = string.Format("${0:00}E 0023.0 00000000", _Address);
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
return TxRxSucces(cmd, read);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Boolean IsOnline()
|
||||
{
|
||||
// Chamber is online if Sollwert in °C is returned
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = string.Format("${0:00}I", _Address);
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
if (read.Length < 6)
|
||||
return false;
|
||||
|
||||
double sw = 0;
|
||||
if (double.TryParse(read.Substring(0, 6), out sw))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override String Progress()
|
||||
{
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = string.Format("${0:00}I", _Address);
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
if (read.Length < 13)
|
||||
return "n/a";
|
||||
|
||||
string progress = "";
|
||||
|
||||
double sw = 0;
|
||||
if (double.TryParse(read.Substring(0, 6), out sw))
|
||||
progress += string.Format("Setting is {0:0.0} °C", sw);
|
||||
|
||||
double iw = 0;
|
||||
if (double.TryParse(read.Substring(7, 6), out iw))
|
||||
progress += string.Format(", current temperature is {0:0.0} °C",iw);
|
||||
|
||||
if (progress.Length == 0)
|
||||
progress += "n/a";
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
|
||||
private bool TxRxSucces(string cmd, string read)
|
||||
{
|
||||
if (cmd.Contains("I"))
|
||||
if (read.Length == 30)
|
||||
if (read.Substring(4, 1) == "." && read.Substring(11, 1) == ".")
|
||||
return true;
|
||||
|
||||
if (cmd.Contains("E"))
|
||||
return read == "0";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Performs transfer and adds interface logs to list in Client parent class
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms)
|
||||
{
|
||||
// If no maximum number of attempts is given, it defaults to 3.
|
||||
return DataTransfer(cmd, out read, ReturnDataWaitms, 3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Performs transfer and adds interface logs to list in Client parent class
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms, int MaxNumOfAttempts)
|
||||
{
|
||||
// Construct command to send
|
||||
cmd += (char)13; // CR
|
||||
cmd = cmd.Replace(" ", "");
|
||||
|
||||
|
||||
// Wait for _ReadyToSend or max 1 seconds
|
||||
DateTime go = DateTime.Now.AddSeconds(1);
|
||||
while (DateTime.Now < _ReadyToSend && DateTime.Now < go)
|
||||
System.Threading.Thread.Sleep(50);
|
||||
|
||||
read = "";
|
||||
bool success = false;
|
||||
int attempts = 0;
|
||||
while (!success && attempts <= MaxNumOfAttempts)
|
||||
{
|
||||
DataTransferLog log = _Interface.DataTransfer(cmd, out read, ReturnDataWaitms);
|
||||
success = TxRxSucces(cmd, read);
|
||||
attempts++;
|
||||
|
||||
// Mask for showing in GUI
|
||||
if (cmd.Contains("I"))
|
||||
log.ShowInGUI = false;
|
||||
|
||||
// Notify user via GUI of failed attempts
|
||||
if (attempts > 1)
|
||||
log.Command += string.Format(" [Attempt {0:0}]", attempts);
|
||||
|
||||
// Add to logs
|
||||
AppendDataTransferLog(log);
|
||||
|
||||
|
||||
// Set _ReadyToSend acc. manual specs
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(2000);
|
||||
|
||||
|
||||
// Sleeps
|
||||
if (!success)
|
||||
System.Threading.Thread.Sleep(3000); // Sleep 3 seconds before resending if failed
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
61
ChamChat/Client_HTS7057/Client_HTS7057.csproj
Normal file
61
ChamChat/Client_HTS7057/Client_HTS7057.csproj
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{B03537FE-EF64-42E3-A8C0-25C79BB818A7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Speak</RootNamespace>
|
||||
<AssemblyName>HTS7057</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</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>
|
||||
</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>
|
||||
</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="Client.HTS7057.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Task.HTS7057.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj">
|
||||
<Project>{09375A4A-28B8-427B-853D-75C03A070728}</Project>
|
||||
<Name>Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
36
ChamChat/Client_HTS7057/Properties/AssemblyInfo.cs
Normal file
36
ChamChat/Client_HTS7057/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Client_HTS7057")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Client_HTS7057")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3e41095f-2a04-41f7-989a-d2705d89e835")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
226
ChamChat/Client_HTS7057/Task.HTS7057.cs
Normal file
226
ChamChat/Client_HTS7057/Task.HTS7057.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public class HTS7057_Task : Task
|
||||
{
|
||||
// Each step is separately programmed to the TSE11.
|
||||
// Steps are programmed at 110% of required step duration.
|
||||
// End of program is always of shutdown type to avoid stressing to much. (Excluding last step)
|
||||
// If next step is of different type (tA or tB), then the next temperature is prepared in other chamber.
|
||||
// Default temperatures are 0 °C for tA and 85 °C for tB.
|
||||
|
||||
public HTS7057_Task(Client Client, Profile Profile)
|
||||
: base(Client, Profile)
|
||||
{
|
||||
_Profile = Profile;
|
||||
_Client = Client;
|
||||
_SerSteps = _Profile.SerializedStepList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Needs to be overriden, because chamber is never stand alone programmable
|
||||
public override Boolean IsStandAloneProgrammable(Profile profile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private const Int32 PollingIntervalSeconds = 10;
|
||||
private List<Step> _SerSteps;
|
||||
|
||||
|
||||
public override Boolean IsControlledProgrammable(Profile profile)
|
||||
{
|
||||
foreach (Step step in profile.SerializedStepList)
|
||||
{
|
||||
List<Step> steps = new List<Step>();
|
||||
steps.Add(step);
|
||||
Profile p = new Profile(_Client.Type.ToStr(), steps, new List<Loop>(), profile.Options);
|
||||
if (!_Client.IsProgrammable(p))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected override void ThreadStandAlone()
|
||||
{
|
||||
_Status = TaskStatus.Aborted;
|
||||
_TaskProgress = "Client cannot operate in standaline mode";
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void ThreadControlled()
|
||||
{
|
||||
|
||||
|
||||
Int32 iCurrentSerialStep = -1;
|
||||
DateTime startOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
DateTime endOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
Step currentStep = _SerSteps[0];
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning)
|
||||
{
|
||||
if (DateTime.Now > endOfCurrentProgram)
|
||||
{
|
||||
iCurrentSerialStep += 1;
|
||||
|
||||
// Last step has been performed?
|
||||
if (iCurrentSerialStep > _SerSteps.Count - 1)
|
||||
{
|
||||
// Do not stop client, but leave running if option given
|
||||
if (_Profile.Options.Contains(ProfileOption.HTS7057_EndModeHold))
|
||||
{
|
||||
_Status = TaskStatus.Finished;
|
||||
AddEventLog(ProfileOption.HTS7057_EndModeHold.ToStr());
|
||||
_TaskProgress = ProfileOption.HTS7057_EndModeOff.ToStr();
|
||||
_TaskProgress += string.Format(" (setting is {0:0.0} °C)", _SerSteps[_SerSteps.Count - 1].T);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Client.Stop();
|
||||
_Status = TaskStatus.Finished;
|
||||
AddEventLog(ProfileOption.HTS7057_EndModeOff.ToStr());
|
||||
_TaskProgress = ProfileOption.HTS7057_EndModeOff.ToStr();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Profile newProfile = GetProfile(iCurrentSerialStep);
|
||||
|
||||
currentStep = _SerSteps[iCurrentSerialStep];
|
||||
AddEventLog(string.Format("{0} minutes @ {1:0.0} °C", _SerSteps[iCurrentSerialStep].DurationMin, _SerSteps[iCurrentSerialStep].T));
|
||||
|
||||
RestartClient(newProfile);
|
||||
|
||||
if (_Status != TaskStatus.IsRunning) // Might be altered in RestartClient()
|
||||
continue;
|
||||
|
||||
// Update variables
|
||||
startOfCurrentProgram = DateTime.Now;
|
||||
endOfCurrentProgram = startOfCurrentProgram.AddMinutes(newProfile.DurationMin);
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted; // Profile did not finish, client did
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
double taskRunTimeMin = (DateTime.Now - _startThread).TotalMinutes;
|
||||
double pTest = Math.Max(0,Math.Min(100, Math.Floor(taskRunTimeMin / _Profile.DurationMin * 100)));
|
||||
double stepRuntime = (DateTime.Now - startOfCurrentProgram).TotalMinutes;
|
||||
double pStep = Math.Max(0,Math.Min(100, Math.Floor(stepRuntime / _SerSteps[iCurrentSerialStep].DurationMin * 100)));
|
||||
double taskTimeRemain = Math.Max(0, _Profile.DurationMin - taskRunTimeMin);
|
||||
double taskTimeRemainHrs = Math.Floor(taskTimeRemain / 60);
|
||||
double taskTimeRemainMin = Math.Floor(taskTimeRemain - 60 * taskTimeRemainHrs);
|
||||
_TaskProgress = String.Format("Step #{0:00}/{1:00} progress {2:0}%, test progress {3:0}%, remaining test time {4:0}h{5:00}m", iCurrentSerialStep + 1, _Profile.SerializedStepList.Count, pStep, pTest, taskTimeRemainHrs, taskTimeRemainMin);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_TaskProgress = "Progress could not be calculated.";
|
||||
}
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
System.Threading.Thread.Sleep(200);
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
private void RestartClient(Profile newProfile)
|
||||
{
|
||||
// Write profile
|
||||
try
|
||||
{
|
||||
if (!_Client.WriteProfile(newProfile))
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
//AddEventLog("RestartClient.Start");
|
||||
if (!_Client.Start())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Profile GetProfile(int iStep)
|
||||
{
|
||||
// Stepslist
|
||||
List<Step> steps = new List<Step>();
|
||||
steps.Add(_SerSteps[iStep].DeepClone());
|
||||
|
||||
// Loops
|
||||
List<Loop> loops = new List<Loop>();
|
||||
|
||||
// Options
|
||||
List<ProfileOption> options = new List<ProfileOption>();
|
||||
|
||||
// Create profile
|
||||
return new Profile(_Profile.Title, steps, loops, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
78ce0a1107047916b3702a482dea8e66722a26e2
|
||||
@@ -0,0 +1,2 @@
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_HTS7057\obj\Release\Client_HTS7057.csproj.AssemblyReference.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_HTS7057\obj\Release\Client_HTS7057.csproj.CoreCompileInputs.cache
|
||||
Binary file not shown.
428
ChamChat/Client_LHL113/Client.LHL113.cs
Normal file
428
ChamChat/Client_LHL113/Client.LHL113.cs
Normal file
@@ -0,0 +1,428 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public partial class LHL113_Client : Client
|
||||
{
|
||||
private const Int32 _OptionRange = 3000;
|
||||
private const Int32 _DataTransferTimeOut = 1000;
|
||||
private DateTime _ReadyToSend = DateTime.Now; // Timestamp when client is ready to communicate
|
||||
private const int _RAM = 1;
|
||||
private DateTime _dtTestStart = DateTime.Now;
|
||||
|
||||
|
||||
// To do
|
||||
public LHL113_Client(Int32 MIDS, ClientType Type)
|
||||
: base(MIDS, Type)
|
||||
{
|
||||
// Set options available in client
|
||||
_Parameters = new List<Parameter>();
|
||||
_Parameters.Add(Parameter.T);
|
||||
_Parameters.Add(Parameter.RH);
|
||||
_Parameters.Add(Parameter.RampT);
|
||||
_Parameters.Add(Parameter.RampRH);
|
||||
|
||||
// Add option range
|
||||
_ClientOptions = new List<ProfileOption>();
|
||||
foreach (ProfileOption o in Enum.GetValues(typeof(ProfileOption)))
|
||||
if ((int)o >= _OptionRange && (int)o < _OptionRange+999)
|
||||
_ClientOptions.Add(o);
|
||||
|
||||
// Set availabel addresses for programming
|
||||
_AvailableRAMs = new List<int>();
|
||||
for (int i = 1; i < 31; i++)
|
||||
_AvailableRAMs.Add(i);
|
||||
|
||||
|
||||
_InterfaceType = InterfaceType.FDTI_USB_COM422;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// To do
|
||||
public override Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw)
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
Profile profile = new Profile();
|
||||
|
||||
try
|
||||
{
|
||||
// Communicate with client
|
||||
cmd = sAddr + ",PRGMREAD,";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
|
||||
List<Step> steps = new List<Step>();
|
||||
List<Loop> loops = new List<Loop>();
|
||||
List<ProfileOption> options = new List<ProfileOption>();
|
||||
String name = "LHL113_Client";
|
||||
|
||||
// Create profile
|
||||
profile = new Profile(name, steps, loops, options);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean WriteProfile(Profile profile)
|
||||
{
|
||||
return WriteProfile(profile, _RAM);
|
||||
}
|
||||
|
||||
public override Boolean WriteProfile(Profile profile, int RAM)
|
||||
{
|
||||
// Only stand alone profiles allowed!
|
||||
if (!IsProgrammable(profile))
|
||||
return false;
|
||||
|
||||
|
||||
string sRAM = String.Format("{0:0}", RAM);
|
||||
|
||||
string sCmdStart = _Address.ToString() + ", PRGM DATA WRITE, PGM:" + sRAM + ", ";
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
|
||||
// Set to STANDBY if OFF
|
||||
cmd = _Address.ToString() + ", MODE?";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
if (read.Contains("OFF"))
|
||||
{
|
||||
cmd = _Address.ToString() + ", MODE, STANDBY";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Communicate with client (page 49)
|
||||
cmd = sCmdStart + "EDIT START";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
for (int i = 0; i < profile.SerializedStepList.Count; i++)
|
||||
{
|
||||
Step step = profile.SerializedStepList[i];
|
||||
cmd = sCmdStart;
|
||||
cmd += string.Format("STEP{0:0}, ", i + 1);
|
||||
cmd += string.Format("TEMP{0:00.0}, ", step.T);
|
||||
if (step.RampCtrlT) cmd += "TRAMPON,"; else cmd += "TRAMPOFF,";
|
||||
cmd += string.Format("HUMI{0:00}, ", step.RH);
|
||||
if (step.RampCtrlRH) cmd += "HRAMPON,"; else cmd += "HRAMPOFF,";
|
||||
|
||||
if (step.Hours < 100)
|
||||
cmd += string.Format("TIME{0:00}:{1:00}, ", step.Hours, step.Minutes);
|
||||
else
|
||||
cmd += string.Format("TIME{0:00}:00, ", step.Hours);
|
||||
cmd += "GRANTY OFF, ";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
|
||||
// End options (off is default)
|
||||
if (profile.Options.Contains(ProfileOption.LHL113_EndModeHold))
|
||||
cmd = sCmdStart + "END, HOLD";
|
||||
else
|
||||
cmd = sCmdStart + "END, OFF";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
|
||||
|
||||
// Loop (see page 50)
|
||||
if (profile.Loops.Count == 1)
|
||||
{
|
||||
Loop l = profile.Loops[0];
|
||||
cmd = sCmdStart + String.Format("COUNT, ({0:0}. {1:0}. {2:0})", l.First, l.Last, l.N);
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
}
|
||||
|
||||
cmd = sCmdStart + "EDIT END";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
|
||||
Boolean result = false;
|
||||
if (_Interface.InterfaceStatus == null)
|
||||
result = true;
|
||||
|
||||
_Profile = profile;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsProgrammable(Profile profile)
|
||||
{
|
||||
// Profile is programmable if all below applies
|
||||
|
||||
// Step is at least 3 minutes
|
||||
foreach (Step step in profile.Steps)
|
||||
if (step.DurationMin < 3)
|
||||
return false;
|
||||
|
||||
// Temperature is limited between 30 & 90 °C
|
||||
foreach (Step step in profile.Steps)
|
||||
if (step.T < 30 || step.T > 90)
|
||||
return false;
|
||||
|
||||
// RH is limited between 60 & 95 °C
|
||||
foreach (Step step in profile.Steps)
|
||||
if (step.RH < 60 || step.RH > 95)
|
||||
return false;
|
||||
|
||||
// Only one program of a max of 9 steps and a maximum of 99 repeated steps can be stored at a time (page 44 of user's manual).
|
||||
if (profile.Steps.Count > 9)
|
||||
return false;
|
||||
|
||||
if (profile.Loops.Count == 1)
|
||||
{
|
||||
if (profile.Loops[0].N > 99)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (profile.SerializedStepList.Count > 9)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// To do
|
||||
public override Boolean HasAlarm(out List<Alarm> alarms)
|
||||
{
|
||||
alarms = new List<Alarm>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsIdle()
|
||||
{
|
||||
// IsIdle() returns true if status of chamber is 'Standby'. See page 31 MODE?.
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE?";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
if (read.Contains("STANDBY") || read.Contains("OFF"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Boolean Start()
|
||||
{
|
||||
if (_Profile == null)
|
||||
return false;
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE, RUN "+_RAM; // See page 47.
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
_dtTestStart = DateTime.Now;
|
||||
|
||||
return TxRxSucces(cmd, read);
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsFinished()
|
||||
{
|
||||
// Finished() returns true if chamber is not running. See page 34 MODE?.
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE?";
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
if (read.Contains("OFF") || read.Contains("STANDBY"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Boolean Stop()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE, STANDBY"; // Pg. 47
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
return TxRxSucces(cmd, read);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Boolean IsOnline()
|
||||
{
|
||||
try
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = sAddr + ", ROM?"; // Pg. 27
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
return read.ToLower().Contains("jlc");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override String Progress()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
//cmd = sAddr + ", MON?"; // See page 31
|
||||
//DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
//Double T = Double.Parse(read.Split(',')[0]);
|
||||
//Double RH = Double.Parse(read.Split(',')[1]);
|
||||
|
||||
cmd = sAddr + ", PRGM MON?"; // See page 35
|
||||
DataTransfer(cmd, out read, _DataTransferTimeOut);
|
||||
|
||||
int step = Int32.Parse(read.Split(',')[1]) - 1;
|
||||
Double Tset = Double.Parse(read.Split(',')[2]);
|
||||
Double RHset = Double.Parse(read.Split(',')[3]);
|
||||
string time = read.Split(',')[4];
|
||||
int hrs = Int32.Parse(time.Split(':')[0]);
|
||||
int min = Int32.Parse(time.Split(':')[1]);
|
||||
int cyclesLeft = Int32.Parse(read.Split(',')[5]);
|
||||
|
||||
double stepTimeLeft = hrs * 60 + min;
|
||||
double stepDuration = _Profile.SerializedStepList[step].DurationMin;
|
||||
double stepRuntime = stepDuration - stepTimeLeft;
|
||||
double pStep = Math.Min(100, Math.Floor(stepRuntime / stepDuration * 100));
|
||||
|
||||
double testRunTime = (_dtTestStart - DateTime.Now).TotalMinutes;
|
||||
double pTest = Math.Min(100, Math.Floor(testRunTime / _Profile.DurationMin * 100));
|
||||
|
||||
double testTimeRemain = _Profile.DurationMin - testRunTime;
|
||||
double testTimeRemainHrs = Math.Floor(testTimeRemain / 60);
|
||||
double testTimeRemainMin = Math.Floor(testTimeRemain - 60 * testTimeRemainHrs);
|
||||
|
||||
string progress = String.Format("Step #{0:00}/{1:00} progress {2:0}%, ", step + 1, _Profile.SerializedStepList.Count, pStep);
|
||||
progress += String.Format("remaining step time {0:0}h{1:00}m, remaining cycles {2:0}, ",hrs,min, cyclesLeft);
|
||||
progress += String.Format("test progress {0:0}%, remaining test time {1:0}h{2:00}m", pTest, testTimeRemainHrs,testTimeRemainMin);
|
||||
return progress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool TxRxSucces(string cmd, string read)
|
||||
{
|
||||
// Command not correctly processed
|
||||
if (read.StartsWith("NA:"))
|
||||
return false;
|
||||
|
||||
// No response received
|
||||
if (read.Trim().Length < 1)
|
||||
return false;
|
||||
|
||||
// Handle monitoring commands
|
||||
if (cmd.Trim().Contains("?"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(read.Trim().Contains("OK:"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Performs transfer and adds interface logs to list in Client parent class
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms)
|
||||
{
|
||||
// If no maximum number of attempts is given, it defaults to 3.
|
||||
return DataTransfer(cmd, out read, ReturnDataWaitms, 3);
|
||||
}
|
||||
|
||||
|
||||
// Performs transfer and adds interface logs to list in Client parent class
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms, int MaxNumOfAttempts)
|
||||
{
|
||||
// Construct command to send
|
||||
cmd += (char)13; // CR
|
||||
cmd += (char)10; // LF
|
||||
cmd = cmd.Replace(" ", "");
|
||||
|
||||
|
||||
// Wait for _ReadyToSend or max 2 seconds
|
||||
DateTime go = DateTime.Now.AddSeconds(2);
|
||||
while (DateTime.Now < _ReadyToSend && DateTime.Now < go)
|
||||
System.Threading.Thread.Sleep(10);
|
||||
|
||||
read = "";
|
||||
bool success = false;
|
||||
int attempts = 0;
|
||||
while (!success && attempts <= MaxNumOfAttempts)
|
||||
{
|
||||
DataTransferLog log = _Interface.DataTransfer(cmd, out read, ReturnDataWaitms);
|
||||
success = TxRxSucces(cmd, read);
|
||||
attempts++;
|
||||
|
||||
// Mask for showing in GUI
|
||||
if (cmd.Contains("MODE?") || cmd.Contains("MON?"))
|
||||
log.ShowInGUI = false;
|
||||
|
||||
// Notify user via GUI of failed attempts
|
||||
if (attempts > 1)
|
||||
log.Command += string.Format(" [Attempt {0:0}]", attempts);
|
||||
|
||||
// Add to logs
|
||||
AppendDataTransferLog(log);
|
||||
|
||||
|
||||
// Set _ReadyToSend acc. manual specs
|
||||
if (cmd.Contains("?"))
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(300);
|
||||
else
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(1000);
|
||||
|
||||
|
||||
// Sleeps
|
||||
if (!success)
|
||||
System.Threading.Thread.Sleep(3000); // Sleep 3 seconds before resending if failed
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
61
ChamChat/Client_LHL113/Client_LHL113.csproj
Normal file
61
ChamChat/Client_LHL113/Client_LHL113.csproj
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{162E2D74-E197-4188-A3B2-B33B827CC519}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>LHL113</RootNamespace>
|
||||
<AssemblyName>LHL113</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</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>
|
||||
</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>
|
||||
</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="Client.LHL113.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Task.LHL113.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj">
|
||||
<Project>{09375A4A-28B8-427B-853D-75C03A070728}</Project>
|
||||
<Name>Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
36
ChamChat/Client_LHL113/Properties/AssemblyInfo.cs
Normal file
36
ChamChat/Client_LHL113/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("LHL113")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("LHL113")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("8354967d-1852-4e51-81c6-2cb820268198")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
388
ChamChat/Client_LHL113/Task.LHL113.cs
Normal file
388
ChamChat/Client_LHL113/Task.LHL113.cs
Normal file
@@ -0,0 +1,388 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public class LHL113_Task : Task
|
||||
{
|
||||
public LHL113_Task(Client Client, Profile Profile)
|
||||
: base(Client, Profile)
|
||||
{
|
||||
_Profile = Profile;
|
||||
_Client = Client;
|
||||
_SerSteps = _Profile.SerializedStepList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private const Int32 PollingIntervalSeconds = 10;
|
||||
private List<Step> _SerSteps;
|
||||
|
||||
|
||||
|
||||
// To do
|
||||
public override Boolean IsControlledProgrammable(Profile profile)
|
||||
{
|
||||
#warning LHL113_Task to implement: IsControlledProgrammable(Profile profile)
|
||||
return true;
|
||||
|
||||
|
||||
_NewProfileDuration = 0;
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
|
||||
List<Profile> profiles = new List<Profile>();
|
||||
int k = 0;
|
||||
while( k < _SerSteps.Count)
|
||||
{
|
||||
Profile p = GetProfile(k);
|
||||
profiles.Add(p);
|
||||
k += _ProfileNumOfSerialSteps;
|
||||
}
|
||||
|
||||
// for (int i = 0; i < _SerSteps.Count; i++)
|
||||
//profiles.Add(GetProfile(i));
|
||||
|
||||
foreach (Profile p in profiles)
|
||||
if (!_Client.IsProgrammable(p))
|
||||
return false;
|
||||
|
||||
// In cases below, overheat/overcool alarm will sound immediately.
|
||||
// Limits can be set to 50 °C from temperature.
|
||||
for (int i = 1; i < _SerSteps.Count; i++)
|
||||
{
|
||||
Step step1 = _SerSteps[i - 1];
|
||||
Step step2 = _SerSteps[i];
|
||||
|
||||
if (step1.T < 40 && step2.T < 40)
|
||||
if (step2.T > step1.T + 50)
|
||||
return false;
|
||||
|
||||
if (step1.T > 40 && step2.T > 40)
|
||||
if (step2.T < step1.T - 50)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void ThreadStandAlone()
|
||||
{
|
||||
// Write profile
|
||||
try
|
||||
{
|
||||
if (!_Client.WriteProfile(_Profile))
|
||||
{
|
||||
_Status = TaskStatus.Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
if (!_Client.Start())
|
||||
{
|
||||
_Status = TaskStatus.Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning)
|
||||
{
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
_Status = TaskStatus.Finished;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
_TaskProgress = _Client.Progress();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_TaskProgress = "Progress could not be retrieved from client.";
|
||||
}
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(100);
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private Double _NewProfileDuration = 0; // Duration of new profile in minutes
|
||||
private int _ProfileNumOfSerialSteps = 1; // Number of steps from serial step list performed in new profile.
|
||||
|
||||
|
||||
protected override void ThreadControlled()
|
||||
{
|
||||
Int32 iCurrentSerialStep = -1;
|
||||
DateTime startOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
DateTime endOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
Step currentStep = _SerSteps[0];
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
_NewProfileDuration = 0;
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning)
|
||||
{
|
||||
if (DateTime.Now > endOfCurrentProgram)
|
||||
{
|
||||
iCurrentSerialStep += _ProfileNumOfSerialSteps;
|
||||
|
||||
// Last step has been performed?
|
||||
if (iCurrentSerialStep > _SerSteps.Count - 1)
|
||||
{
|
||||
_Client.Stop();
|
||||
_Status = TaskStatus.Finished;
|
||||
AddEventLog("Last step performed");
|
||||
continue;
|
||||
}
|
||||
|
||||
currentStep = _SerSteps[iCurrentSerialStep];
|
||||
|
||||
Profile newProfile = GetProfile(iCurrentSerialStep);
|
||||
|
||||
|
||||
if (_ProfileNumOfSerialSteps > 1)
|
||||
{
|
||||
if(newProfile.Loops.Count == 1 )
|
||||
AddEventLog("Program : " + string.Format("{0:0} serial steps, loop {1}", _ProfileNumOfSerialSteps, newProfile.Loops[0].ToString()));
|
||||
else
|
||||
AddEventLog("Program : " + string.Format("{0:0} serial steps, no loops", _ProfileNumOfSerialSteps));
|
||||
}
|
||||
else
|
||||
AddEventLog("Single step : " + currentStep.ToString());
|
||||
|
||||
|
||||
|
||||
RestartClient(newProfile);
|
||||
|
||||
|
||||
|
||||
if (_Status != TaskStatus.IsRunning)
|
||||
continue;
|
||||
|
||||
// Update variables
|
||||
startOfCurrentProgram = DateTime.Now;
|
||||
endOfCurrentProgram = DateTime.Now.AddMinutes(_NewProfileDuration);
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted; // Profile did not finish, client did
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
double taskRunTime = (DateTime.Now - _startThread).TotalMinutes;
|
||||
double pTest = Math.Min(100, Math.Floor(taskRunTime / _Profile.DurationMin * 100));
|
||||
|
||||
double stepRuntime = (DateTime.Now - startOfCurrentProgram).TotalMinutes;
|
||||
double pStep = Math.Min(100,Math.Floor(stepRuntime / _NewProfileDuration * 100));
|
||||
|
||||
double taskTimeRemain = _Profile.DurationMin - taskRunTime;
|
||||
double taskTimeRemainHrs = Math.Floor(taskTimeRemain / 60);
|
||||
double taskTimeRemainMin = Math.Floor(taskTimeRemain - 60 * taskTimeRemainHrs);
|
||||
|
||||
_TaskProgress = String.Format("Step #{0:00}/{1:00} progress {2:0}%, test progress {3:0}%, remaining test time {4:0}h{5:00}m", iCurrentSerialStep + 1, _Profile.SerializedStepList.Count, pStep, pTest, taskTimeRemainHrs, taskTimeRemainMin);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_TaskProgress = "Progress could not be calculated.";
|
||||
}
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
System.Threading.Thread.Sleep(200);
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void RestartClient(Profile newProfile)
|
||||
{
|
||||
// Stop client
|
||||
try
|
||||
{
|
||||
if (!_Client.Stop())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Stop() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
|
||||
// Wait to finish
|
||||
try
|
||||
{
|
||||
Boolean timedOut = true;
|
||||
|
||||
DateTime startWait = DateTime.Now;
|
||||
while (DateTime.Now < startWait.AddSeconds(60))
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
timedOut = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timedOut)
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Time out (60 s) in RestartClient.WaitForFinish");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WaitForFinish exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Write profile
|
||||
try
|
||||
{
|
||||
if (!_Client.WriteProfile(newProfile))
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
//AddEventLog("RestartClient.Start");
|
||||
if (!_Client.Start())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Profile GetProfile(int iStep)
|
||||
{
|
||||
Step step = _SerSteps[iStep].DeepClone();
|
||||
// Duration of programmed step is 15 minutes longer than profile
|
||||
step.DurationMin += 15;
|
||||
|
||||
_NewProfileDuration = _SerSteps[iStep].DurationMin;
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
|
||||
List<Step> steps = new List<Step>();
|
||||
steps.Add(step);
|
||||
|
||||
|
||||
// Loops
|
||||
List<Loop> loops = new List<Loop>();
|
||||
|
||||
// Options
|
||||
List<ProfileOption> options = new List<ProfileOption>();
|
||||
options.Add(ProfileOption.LHL113_EndModeOff); // Shut down client for safety
|
||||
|
||||
// Create profile
|
||||
return new Profile(_Profile.Title, steps, loops, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
ae4a20f7096bc6f8a600f5bcf410b2ab95b95f6c
|
||||
@@ -0,0 +1,2 @@
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_LHL113\obj\Release\Client_LHL113.csproj.AssemblyReference.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_LHL113\obj\Release\Client_LHL113.csproj.CoreCompileInputs.cache
|
||||
Binary file not shown.
45
ChamChat/Client_PLxKPH/Client.PLxKPH.Specific.cs
Normal file
45
ChamChat/Client_PLxKPH/Client.PLxKPH.Specific.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public partial class PLxKPH_Client : Client
|
||||
{
|
||||
// Run a single step.
|
||||
// The last setting is held when the program ends.
|
||||
// See page 60.
|
||||
public Boolean Start(Double DurationMin, Double StartT, Double TargetT, Double StartRH, Double TargetRH )
|
||||
{
|
||||
|
||||
// Example: RUN PRGM, TEMP10.0 GOTEMP23.0 HUMI85 GOHUMI100 TIME1:00
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", RUN PRGM, ";
|
||||
|
||||
cmd += string.Format("TEMP{0:0.0} ", StartT);
|
||||
if (StartT != TargetT) // Ramping required
|
||||
cmd += string.Format("GOTEMP{0:0.0} ", TargetT);
|
||||
|
||||
if (TargetRH > 0)
|
||||
{
|
||||
cmd += string.Format("HUMI{0:0} ", StartRH);
|
||||
if (StartRH != TargetRH) // Ramping required
|
||||
cmd += string.Format("GOHUMI{0:0} ", TargetRH);
|
||||
}
|
||||
else cmd += "HUMI OFF "; // No RH set
|
||||
|
||||
double hrs = Math.Floor(DurationMin/60);
|
||||
double min = Math.Floor(DurationMin - hrs * 60);
|
||||
cmd += String.Format("TIME{0:0}:{1:0}", hrs, min);
|
||||
|
||||
return DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
384
ChamChat/Client_PLxKPH/Client.PLxKPH.cs
Normal file
384
ChamChat/Client_PLxKPH/Client.PLxKPH.cs
Normal file
@@ -0,0 +1,384 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public partial class PLxKPH_Client : Client
|
||||
{
|
||||
private const Int32 _OptionRange = 2000;
|
||||
private const int _RAM = 1;
|
||||
private const Int32 _ReturnDataWaitms = 300; // Time out for client to prepare and return data
|
||||
private DateTime _ReadyToSend = DateTime.Now; // Timestamp when client is ready to communicate
|
||||
|
||||
|
||||
public PLxKPH_Client(Int32 MIDS, ClientType Type)
|
||||
: base(MIDS, Type)
|
||||
{
|
||||
|
||||
// Set options available in client
|
||||
_Parameters = new List<Parameter>();
|
||||
_Parameters.Add(Parameter.T);
|
||||
_Parameters.Add(Parameter.RH);
|
||||
_Parameters.Add(Parameter.RampT);
|
||||
_Parameters.Add(Parameter.RampRH);
|
||||
|
||||
|
||||
// Add option range
|
||||
_ClientOptions = new List<ProfileOption>();
|
||||
foreach (ProfileOption o in Enum.GetValues(typeof(ProfileOption)))
|
||||
if ((int)o >= _OptionRange && (int)o < _OptionRange + 999)
|
||||
_ClientOptions.Add(o);
|
||||
|
||||
// Set availabel addresses for programming
|
||||
_AvailableRAMs = new List<int>();
|
||||
for (int i = 1; i < 21; i++)
|
||||
_AvailableRAMs.Add(i);
|
||||
|
||||
_InterfaceType = InterfaceType.FDTI_USB_COM422;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// To do
|
||||
public override Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw)
|
||||
{
|
||||
Profile profile = new Profile();
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean WriteProfile(Profile profile)
|
||||
{
|
||||
return WriteProfile(profile, _RAM);
|
||||
}
|
||||
|
||||
public override Boolean WriteProfile(Profile profile, int RAM)
|
||||
{
|
||||
// Only stand alone profiles allowed!
|
||||
if( !IsProgrammable(profile))
|
||||
return false;
|
||||
|
||||
string title = profile.Title.Substring(0, (int)Math.Min(14, profile.Title.Length)).Trim();
|
||||
|
||||
string sRAM = string.Format("{0:0}", RAM);
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
string cmd_pre = sAddr + ", PRGM DATA WRITE, PGM" + sRAM + ", ";
|
||||
|
||||
|
||||
|
||||
// Cancel RAM program editing
|
||||
cmd = cmd_pre + "EDIT CANCEL";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms,1);
|
||||
if( !read.Contains("ERR-3"))
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 3);
|
||||
|
||||
|
||||
|
||||
// Open RAM program
|
||||
cmd = cmd_pre + "EDIT START";
|
||||
DataTransfer(cmd,out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Steps
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < profile.Steps.Count; i++)
|
||||
{
|
||||
Step step = profile.Steps[i];
|
||||
cmd = cmd_pre;
|
||||
cmd += String.Format("STEP{0:0}, ", i + 1);
|
||||
cmd += String.Format("TEMP{0:0.0}, ", step.T);
|
||||
cmd += step.RampCtrlT ? "TRAMPON, " : "TRAMPOFF, ";
|
||||
cmd += step.HasRH ? String.Format("HUMI{0:0}, ", step.RH) : "HUMI OFF, ";
|
||||
cmd += step.RampCtrlRH ? "HRAMPON, " : "HRAMPOFF, ";
|
||||
cmd += String.Format("TIME{0:00}:{1:00}, ", step.Hours, step.Minutes);
|
||||
cmd += "GRANTY OFF, ";
|
||||
cmd += "PAUSE OFF";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { throw new Exception("writing steps - " + ex.Message); }
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Loops
|
||||
if (profile.Loops.Count > 0)
|
||||
{
|
||||
Loop loop = profile.Loops[0];
|
||||
cmd = cmd_pre;
|
||||
cmd += String.Format("COUNT, A({0}.{1}.{2})", loop.N - 1, loop.Last + 1, loop.First + 1);
|
||||
|
||||
if (profile.Loops.Count > 1)
|
||||
{
|
||||
loop = profile.Loops[1];
|
||||
cmd += String.Format(", B({0}.{1}.{2})", loop.N - 1, loop.Last + 1, loop.First + 1);
|
||||
}
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { throw new Exception("writing loops - " + ex.Message); }
|
||||
|
||||
|
||||
|
||||
// End mode
|
||||
try
|
||||
{
|
||||
cmd = profile.Options.Contains(ProfileOption.PLxKPH_EndModeHold) ? cmd_pre + "END, HOLD" : cmd_pre + "END, OFF";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
}
|
||||
catch (Exception ex) { throw new Exception("writing end mode - " + ex.Message); }
|
||||
|
||||
|
||||
|
||||
// Name of program
|
||||
cmd = cmd_pre + "NAME, " + title;
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Close and save RAM program
|
||||
cmd = cmd_pre + "EDIT END";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
// Wait 3 seconds to close program
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
|
||||
Boolean result = false;
|
||||
if (_Interface.InterfaceStatus == null)
|
||||
result = true;
|
||||
|
||||
_Profile = profile;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsProgrammable(Profile profile)
|
||||
{
|
||||
// Profile is programmable if all below applies
|
||||
// number of profile steps 99
|
||||
// number of loops < 3
|
||||
// -40 < t < 150
|
||||
|
||||
if(profile.Steps.Count > 99)
|
||||
return false;
|
||||
|
||||
if (profile.Loops.Count > 2)
|
||||
return false;
|
||||
|
||||
foreach (Loop loop in profile.Loops)
|
||||
if (loop.N > 99 || loop.N < 2)
|
||||
return false;
|
||||
|
||||
foreach (Step step in profile.Steps)
|
||||
{
|
||||
if (step.T < -40 || step.T > 150)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean HasAlarm(out List<Alarm> alarms)
|
||||
{
|
||||
alarms = new List<Alarm>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsIdle()
|
||||
{
|
||||
// IsIdle() returns true if status of chamber is 'Standby'. See page 36 MODE?.
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE?";
|
||||
DataTransfer(cmd,out read, _ReturnDataWaitms);
|
||||
|
||||
if (read.Contains("STANDBY"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Start()
|
||||
{
|
||||
if (_Profile == null)
|
||||
return false;
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", PRGM, RUN, RAM:" + _RAM+", STEP1"; // See page 56
|
||||
|
||||
return DataTransfer(cmd,out read, _ReturnDataWaitms);
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsFinished()
|
||||
{
|
||||
// Finished() returns true if chamber is not running. See page 36 MODE?.
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MON?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
try
|
||||
{
|
||||
double t = Double.Parse(read.Split(',')[0]);
|
||||
double RH = Double.Parse(read.Split(',')[1]);
|
||||
_Progress = String.Format("Current conditions are {0:0.0} °C and {1:0} %rh", t, RH);
|
||||
_LastProgressUpdate = DateTime.Now;
|
||||
}
|
||||
catch { _Progress = DateTime.Now.ToString("yyyy-MM-dd @ hh:mm"); }
|
||||
|
||||
|
||||
if (read.Contains("STANDBY"))
|
||||
return true;
|
||||
|
||||
if (read.Contains("OFF"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Stop()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = sAddr + ", MODE, STANDBY";
|
||||
return DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsOnline()
|
||||
{
|
||||
try
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = sAddr + ", TYPE?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
return (read.ToLower().Contains("scp220") );
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string _Progress = "";
|
||||
private DateTime _LastProgressUpdate = DateTime.Now;
|
||||
public override String Progress()
|
||||
{
|
||||
if(_LastProgressUpdate.AddMinutes(3) < DateTime.Now)
|
||||
IsFinished();
|
||||
return _Progress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool TxRxSucces(string cmd, string read)
|
||||
{
|
||||
// Command not correctly processed
|
||||
if (read.StartsWith("NA:"))
|
||||
return false;
|
||||
|
||||
// No response received
|
||||
if (read.Trim().Length < 1)
|
||||
return false;
|
||||
|
||||
// Handle monitoring commands
|
||||
if (cmd.Trim().Contains("?"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read.Trim().StartsWith("OK:"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms)
|
||||
{
|
||||
// If no maximum number of attempts is given, it defaults to 4.
|
||||
return DataTransfer(cmd, out read, ReturnDataWaitms,4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Performs transfer and adds interface logs to list in Client parent class
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms, int MaxNumOfAttempts)
|
||||
{
|
||||
// Construct command to send
|
||||
cmd += (char)13; // CR
|
||||
cmd += (char)10; // LF
|
||||
cmd = cmd.Replace(" ", "");
|
||||
|
||||
|
||||
// Wait for _ReadyToSend or max 1 seconds
|
||||
DateTime go = DateTime.Now.AddSeconds(1);
|
||||
while (DateTime.Now < _ReadyToSend && DateTime.Now < go)
|
||||
System.Threading.Thread.Sleep(10);
|
||||
|
||||
read = "";
|
||||
bool success = false;
|
||||
int attempt = 0;
|
||||
while (!success && attempt < MaxNumOfAttempts)
|
||||
{
|
||||
DataTransferLog log = _Interface.DataTransfer(cmd, out read, ReturnDataWaitms);
|
||||
success = TxRxSucces(cmd, read);
|
||||
attempt++;
|
||||
|
||||
// Mask for showing in GUI
|
||||
if (cmd.Contains("MON?") || cmd.Contains("EDIT CANCEL") || cmd.Contains("EDITCANCEL"))
|
||||
log.ShowInGUI = false;
|
||||
|
||||
|
||||
// Notify user via GUI of failed attempts
|
||||
if (attempt > 1)
|
||||
log.Command += string.Format(" [Attempt {0:0}]", attempt);
|
||||
|
||||
// Add to logs
|
||||
AppendDataTransferLog(log);
|
||||
|
||||
|
||||
// Set _ReadyToSend acc. manual specs
|
||||
if (cmd.Contains("?"))
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(500);
|
||||
else
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(1200);
|
||||
|
||||
|
||||
// Sleeps
|
||||
if (!success)
|
||||
System.Threading.Thread.Sleep(5000); // Sleep 5 seconds before resending if failed
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
63
ChamChat/Client_PLxKPH/Client_PLxKPH.csproj
Normal file
63
ChamChat/Client_PLxKPH/Client_PLxKPH.csproj
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{1FB70C9C-6F0B-4580-9682-A85B40C90B38}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ChamChat</RootNamespace>
|
||||
<AssemblyName>PLxKPH</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</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>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<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="Client.PLxKPH.cs" />
|
||||
<Compile Include="Client.PLxKPH.Specific.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Task.PLxKPH.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj">
|
||||
<Project>{09375A4A-28B8-427B-853D-75C03A070728}</Project>
|
||||
<Name>Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
20
ChamChat/Client_PLxKPH/Client_PLxKPH.sln
Normal file
20
ChamChat/Client_PLxKPH/Client_PLxKPH.sln
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C# Express 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client_PLxKPH", "Client_PLxKPH.csproj", "{1FB70C9C-6F0B-4580-9682-A85B40C90B38}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FB70C9C-6F0B-4580-9682-A85B40C90B38}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
BIN
ChamChat/Client_PLxKPH/Client_PLxKPH.suo
Normal file
BIN
ChamChat/Client_PLxKPH/Client_PLxKPH.suo
Normal file
Binary file not shown.
36
ChamChat/Client_PLxKPH/Properties/AssemblyInfo.cs
Normal file
36
ChamChat/Client_PLxKPH/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TSD100S")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("TSD100S")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2fc0fe7d-2c1d-4983-a44a-6c1fd33288e3")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
347
ChamChat/Client_PLxKPH/Task.PLxKPH.cs
Normal file
347
ChamChat/Client_PLxKPH/Task.PLxKPH.cs
Normal file
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public class PLxKPH_Task : Task
|
||||
{
|
||||
public PLxKPH_Task(Client Client, Profile Profile)
|
||||
: base(Client, Profile)
|
||||
{
|
||||
_Profile = Profile;
|
||||
_Client = Client;
|
||||
_SerSteps = _Profile.SerializedStepList;
|
||||
}
|
||||
|
||||
private const Int32 PollingIntervalSeconds = 10;
|
||||
|
||||
private List<Step> _SerSteps;
|
||||
|
||||
|
||||
public override Boolean IsControlledProgrammable(Profile profile)
|
||||
{
|
||||
ClientMessage msg = new ClientMessage(String.Format("The {0} can only operate in stand alone mode.", _Client.TypeDescription));
|
||||
_Client.ClientMessages = new List<ClientMessage>();
|
||||
_Client.ClientMessages.Add(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override void ThreadStandAlone()
|
||||
{
|
||||
// Write profile
|
||||
try
|
||||
{
|
||||
if (!_Client.WriteProfile(_Profile))
|
||||
{
|
||||
_Status = TaskStatus.Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
if (!_Client.Start())
|
||||
{
|
||||
_Status = TaskStatus.Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning)
|
||||
{
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
_Status = TaskStatus.Finished;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
// Client return "Current conditions are x °C and x %rh"
|
||||
_TaskProgress = _Client.Progress();
|
||||
double runTimeMin = (DateTime.Now - StartOfTask).TotalMinutes;
|
||||
double p = runTimeMin / _Profile.DurationMin * 100;
|
||||
double remainTimeMin = Math.Max(0,_Profile.DurationMin - runTimeMin);
|
||||
double hrs = Math.Floor(remainTimeMin /60);
|
||||
double min = Math.Floor(remainTimeMin - 60 * hrs);
|
||||
_TaskProgress += String.Format(", {0:0.0}% completed, {1:0}h{2:00} remaining",p, hrs,min );
|
||||
|
||||
}
|
||||
catch { }
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(100);
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void ThreadControlled()
|
||||
{
|
||||
Int32 iCurrentSerialStep = -1;
|
||||
DateTime startOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
DateTime endOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
Step currentStep = _SerSteps[0];
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning)
|
||||
{
|
||||
if (DateTime.Now > endOfCurrentProgram)
|
||||
{
|
||||
iCurrentSerialStep++;
|
||||
|
||||
// Last step has been performed?
|
||||
if (iCurrentSerialStep > _SerSteps.Count - 1)
|
||||
{
|
||||
_Client.Stop();
|
||||
_Status = TaskStatus.Finished;
|
||||
AddEventLog("Last step performed");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get step details
|
||||
currentStep = _SerSteps[iCurrentSerialStep];
|
||||
double TargetT = currentStep.T;
|
||||
double TargetRH = currentStep.RH;
|
||||
double DurationMin = currentStep.DurationMin;
|
||||
|
||||
double StartT = currentStep.T; // Set start to be target, but change to value of previous step if ramped.
|
||||
if (currentStep.RampCtrlT)
|
||||
{
|
||||
if (iCurrentSerialStep == 0)
|
||||
StartT = 23;
|
||||
else
|
||||
StartT = _SerSteps[iCurrentSerialStep - 1].T;
|
||||
}
|
||||
|
||||
double StartRH = currentStep.RH; // Set start to be target, but change to value of previous step if ramped.
|
||||
if (currentStep.RampCtrlRH)
|
||||
{
|
||||
if (iCurrentSerialStep == 0)
|
||||
StartRH = 60;
|
||||
else
|
||||
StartRH = _SerSteps[iCurrentSerialStep - 1].RH;
|
||||
}
|
||||
|
||||
RestartClient(DurationMin, StartT, TargetT, StartRH, TargetRH);
|
||||
|
||||
if (_Status != TaskStatus.IsRunning)
|
||||
continue;
|
||||
|
||||
|
||||
// Update variables
|
||||
startOfCurrentProgram = DateTime.Now;
|
||||
endOfCurrentProgram = DateTime.Now.AddMinutes(DurationMin);
|
||||
lastPolled = DateTime.Now;
|
||||
|
||||
|
||||
#region Update events
|
||||
try
|
||||
{
|
||||
string s = "Set conditions: ";
|
||||
if (currentStep.RampCtrlT)
|
||||
s += String.Format("to {0:0.0} °C ({1:0.00} ˜°C/min), ", TargetT, (TargetT - StartT) / DurationMin);
|
||||
else
|
||||
s += String.Format("{0:0.0} °C, ", TargetT);
|
||||
if (currentStep.RampCtrlRH)
|
||||
s += String.Format("to {0:0.0} %rh ({1:0.00} ˜%rh/min), ", TargetRH, (TargetRH - StartRH) / DurationMin);
|
||||
else
|
||||
s += String.Format("{0:0.0} %rh, ", TargetRH);
|
||||
|
||||
s += string.Format("{0:0}h{1:00}", currentStep.Hours, currentStep.Minutes);
|
||||
|
||||
AddEventLog(s);
|
||||
s = string.Format("Partial profile end is {0:00}-{1:00} @ {2:00}:{3:00}:{4:00}", endOfCurrentProgram.Day, endOfCurrentProgram.Month, endOfCurrentProgram.Hour, endOfCurrentProgram.Minute, endOfCurrentProgram.Second);
|
||||
AddEventLog(s);
|
||||
}
|
||||
catch (Exception ex) { AddEventLog("Update events: " + ex.Message); }
|
||||
#endregion Update events
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
// Last step is held (page 61) when program ends. Client will never finish by itself.
|
||||
AddEventLog("Client finished, but task did not!");
|
||||
_Status = TaskStatus.Interrupted; // Profile did not finish, client did
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch { } // Always continue and keep trying
|
||||
|
||||
|
||||
#region Taskprogress
|
||||
try
|
||||
{
|
||||
double taskRunTime = (DateTime.Now - _startThread).TotalMinutes;
|
||||
double pTest = Math.Min(100, Math.Floor(taskRunTime / _Profile.DurationMin * 100));
|
||||
double taskTimeRemain = _Profile.DurationMin - taskRunTime;
|
||||
double taskTimeRemainHrs = Math.Floor(taskTimeRemain / 60);
|
||||
double taskTimeRemainMin = Math.Floor(taskTimeRemain - 60 * taskTimeRemainHrs);
|
||||
double currentStepRuntime = (DateTime.Now - startOfCurrentProgram).TotalMinutes;
|
||||
double pStep = Math.Min(100, Math.Floor(currentStepRuntime / currentStep.DurationMin * 100));
|
||||
_TaskProgress = String.Format("Step #{0:0}/{1:0} progress {2:0}%, test progress {3:0}%, remaining test time {4:0}h{5:00}m", iCurrentSerialStep + 1,_SerSteps.Count, pStep, pTest, taskTimeRemainHrs, taskTimeRemainMin);
|
||||
if (iCurrentSerialStep + 1 == _SerSteps.Count && pTest > 99.99)
|
||||
_TaskProgress = "Profile executed";
|
||||
}
|
||||
catch { _TaskProgress = "n/a"; }
|
||||
#endregion Taskprogress
|
||||
|
||||
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(200);
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
private void RestartClient(Double DurationMin, Double StartT, Double TargetT, Double StartRH, Double TargetRH)
|
||||
{
|
||||
// Stop client
|
||||
try
|
||||
{
|
||||
AddEventLog("Info: Stopping client");
|
||||
if (!_Client.Stop())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Task interrupted while trying to stop client!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Stop() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait to finish
|
||||
try
|
||||
{
|
||||
Boolean timedOut = true;
|
||||
|
||||
DateTime startWait = DateTime.Now;
|
||||
while (DateTime.Now < startWait.AddSeconds(60))
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
timedOut = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timedOut)
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Time out (60 s) in RestartClient.WaitForFinish");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WaitForFinish exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
AddEventLog("Info: Client stopped");
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
AddEventLog("Info: Starting client");
|
||||
|
||||
if (!((PLxKPH_Client)_Client).Start(DurationMin, StartT, TargetT, StartRH, TargetRH))
|
||||
{
|
||||
// Try to start again after 10 sec
|
||||
AddEventLog("First attempt to start client failed!");
|
||||
System.Threading.Thread.Sleep(10000);
|
||||
|
||||
if (!((PLxKPH_Client)_Client).Start(DurationMin, StartT, TargetT, StartRH, TargetRH))
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Task interrupted while trying to start client!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
AddEventLog("Info: Client started");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
030d805dcba3c63f1b65d4f63d5ddc35bc93310a
|
||||
@@ -0,0 +1,2 @@
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_PLxKPH\obj\Release\Client_PLxKPH.csproj.AssemblyReference.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_PLxKPH\obj\Release\Client_PLxKPH.csproj.CoreCompileInputs.cache
|
||||
Binary file not shown.
151
ChamChat/Client_TSx/Client.TSx.Specific.cs
Normal file
151
ChamChat/Client_TSx/Client.TSx.Specific.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public partial class TSx_Client : Client
|
||||
{
|
||||
public bool ShiftToA()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", TAREA?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
// If moving, wait to finish
|
||||
if (read.Contains("MOVE"))
|
||||
{
|
||||
bool moving = true;
|
||||
while (moving)
|
||||
{
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
if (!read.Contains("MOVE"))
|
||||
moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Already in Cold
|
||||
if (read.Contains("C"))
|
||||
return true;
|
||||
|
||||
|
||||
cmd = sAddr + ", MODE, TAREAMOVE";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
System.Threading.Thread.Sleep(5000); // Wait for move to finish
|
||||
|
||||
cmd = sAddr + ", TAREA?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
// If moving, wait to finish
|
||||
if (read.Contains("MOVE"))
|
||||
{
|
||||
bool moving = true;
|
||||
while (moving)
|
||||
{
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
if (!read.Contains("MOVE"))
|
||||
moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Already in Cold
|
||||
if (read.Contains("C"))
|
||||
return true;
|
||||
|
||||
// Not in Cold, not moving towards cold
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ShiftToB()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", TAREA?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
// If moving, wait to finish
|
||||
if (read.Contains("MOVE"))
|
||||
{
|
||||
bool moving = true;
|
||||
while (moving)
|
||||
{
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
if (!read.Contains("MOVE"))
|
||||
moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Already in Hot
|
||||
if (read.Contains("H"))
|
||||
return true;
|
||||
|
||||
|
||||
cmd = sAddr + ", MODE, TAREAMOVE";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
System.Threading.Thread.Sleep(5000); // Wait for move to finish
|
||||
|
||||
cmd = sAddr + ", TAREA?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
// If moving, wait to finish
|
||||
if (read.Contains("MOVE"))
|
||||
{
|
||||
bool moving = true;
|
||||
while (moving)
|
||||
{
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
if (!read.Contains("MOVE"))
|
||||
moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
// In Hot
|
||||
if (read.Contains("H"))
|
||||
return true;
|
||||
|
||||
// Not in Hot, not moving towards Hot
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean AwaitMoving(Int32 timeOutSec)
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd = sAddr + ", TAREA?";;
|
||||
string read;
|
||||
|
||||
DateTime dtTimeOut = DateTime.Now.AddSeconds(timeOutSec);
|
||||
while (DateTime.Now < dtTimeOut)
|
||||
{
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
if (!read.Contains("MOVE"))
|
||||
return true;
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Double CurrentTemperature()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", TEMP?"; // See page 36
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms,1);
|
||||
return Double.Parse(read.Split(',')[6]);
|
||||
}
|
||||
}
|
||||
}
|
||||
724
ChamChat/Client_TSx/Client.TSx.cs
Normal file
724
ChamChat/Client_TSx/Client.TSx.cs
Normal file
@@ -0,0 +1,724 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public partial class TSx_Client : Client
|
||||
{
|
||||
private const Int32 _OptionRange = 1000;
|
||||
//private const string _RAM = "RAM:20";
|
||||
private const int _RAM = 20;
|
||||
private const Int32 _ReturnDataWaitms = 300; // Time out for client to prepare and return data
|
||||
private DateTime _ReadyToSend = DateTime.Now; // Timestamp when client is ready to communicate
|
||||
|
||||
|
||||
|
||||
|
||||
public TSx_Client(Int32 MIDS, ClientType Type)
|
||||
: base(MIDS, Type)
|
||||
{
|
||||
|
||||
// Set options available in client
|
||||
_Parameters = new List<Parameter>();
|
||||
_Parameters.Add(Parameter.T);
|
||||
_Parameters.Add(Parameter.PreTemp);
|
||||
_Parameters.Add(Parameter.Tlimit);
|
||||
_Parameters.Add(Parameter.ProceedWithNextStep);
|
||||
|
||||
|
||||
// Add option range
|
||||
_ClientOptions = new List<ProfileOption>();
|
||||
foreach (ProfileOption o in Enum.GetValues(typeof(ProfileOption)))
|
||||
if ((int)o >= _OptionRange && (int)o < _OptionRange + 999)
|
||||
_ClientOptions.Add(o);
|
||||
|
||||
// Set availabel addresses for programming
|
||||
_AvailableRAMs = new List<int>();
|
||||
for (int i = 1; i < 31; i++)
|
||||
_AvailableRAMs.Add(i);
|
||||
|
||||
_InterfaceType = InterfaceType.FDTI_USB_COM422;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw)
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
string ram = string.Format("RAM:{0:00}", RAM);
|
||||
|
||||
|
||||
|
||||
// Communicate with client
|
||||
cmd = sAddr + ",PRGMREAD," + ram;
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
bgw.ReportProgress(8);
|
||||
|
||||
cmd = sAddr + ",LISTTEMP?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTTEMP = read;
|
||||
bgw.ReportProgress(16);
|
||||
|
||||
cmd = sAddr + ",LISTPREAI?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTPREAI = read;
|
||||
bgw.ReportProgress(24);
|
||||
|
||||
cmd = sAddr + ",LISTPRE?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTPRE = read;
|
||||
bgw.ReportProgress(32);
|
||||
|
||||
cmd = sAddr + ",LISTTIME?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTTIME = read;
|
||||
bgw.ReportProgress(40);
|
||||
|
||||
cmd = sAddr + ",LISTCYCLE?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTCYCLE = read;
|
||||
bgw.ReportProgress(48);
|
||||
|
||||
cmd = sAddr + ",LISTSTARTPOSITION?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTSTARTPOSITION = read;
|
||||
bgw.ReportProgress(56);
|
||||
|
||||
cmd = sAddr + ",LISTEND?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTEND = read;
|
||||
bgw.ReportProgress(64);
|
||||
|
||||
cmd = sAddr + ",LISTNAME?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTNAME = read;
|
||||
bgw.ReportProgress(72);
|
||||
|
||||
cmd = sAddr + ",LISTSENSOR?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1); // Not used in software.
|
||||
string LISTSENSOR = read;
|
||||
bgw.ReportProgress(80);
|
||||
|
||||
cmd = sAddr + ",LISTTEMPLIMIT?";
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
string LISTTEMPLIMIT = read;
|
||||
bgw.ReportProgress(88);
|
||||
|
||||
// 01728 test
|
||||
// 4,PRGMREAD,RAM:20
|
||||
// 4,LISTTEMPLIMIT?
|
||||
// 4,PRGMREADEND
|
||||
|
||||
cmd = sAddr + ",PRGMREADEND";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms, 1);
|
||||
bgw.ReportProgress(96);
|
||||
|
||||
|
||||
Profile profile = new Profile();
|
||||
|
||||
// Cancel read out
|
||||
if (bgw.CancellationPending)
|
||||
{
|
||||
profile.Title = "Cancelled";
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// High temperature
|
||||
double TB = Double.Parse(LISTTEMP.Split(',')[0]);
|
||||
string tB = LISTTIME.Split(',')[1].Trim();
|
||||
double hrsB = Double.Parse(tB.Split(':')[0]);
|
||||
double minB = Double.Parse(tB.Split(':')[1]);
|
||||
double preTB = Double.Parse(LISTPRE.Split(',')[0]);
|
||||
double HL = Double.Parse(LISTTEMPLIMIT.Split(',')[0]);
|
||||
|
||||
|
||||
// Low temperature
|
||||
double TA = Double.Parse(LISTTEMP.Split(',')[1]);
|
||||
string tA = LISTTIME.Split(',')[2].Trim();
|
||||
double hrsA = Double.Parse(tA.Split(':')[0]);
|
||||
double minA = Double.Parse(tA.Split(':')[1]);
|
||||
double preTA = Double.Parse(LISTPRE.Split(',')[1]);
|
||||
double LL = Double.Parse(LISTTEMPLIMIT.Split(',')[1]);
|
||||
|
||||
// Number of cycles
|
||||
Int32 numOfCycles = Int32.Parse(LISTCYCLE);
|
||||
|
||||
// Name
|
||||
String name = LISTNAME;
|
||||
|
||||
// Options: page 44 & 72
|
||||
List<ProfileOption> options = new List<ProfileOption>();
|
||||
if (LISTPREAI == "ON")
|
||||
options.Add(ProfileOption.TSx_PreTempAuto);
|
||||
else
|
||||
options.Add(ProfileOption.TSx_PreTempManual);
|
||||
|
||||
|
||||
switch (LISTEND)
|
||||
{
|
||||
case "HEATRETURN":
|
||||
options.Add(ProfileOption.TSx_EndModeHeatReturn);
|
||||
break;
|
||||
case "SETUP":
|
||||
options.Add(ProfileOption.TSx_EndModeSetup);
|
||||
break;
|
||||
case "DEFROST":
|
||||
options.Add(ProfileOption.TSx_EndModeDefrost);
|
||||
break;
|
||||
case "DRY":
|
||||
options.Add(ProfileOption.TSx_EndModeDry);
|
||||
break;
|
||||
default:
|
||||
options.Add(ProfileOption.TSx_EndModeOff);
|
||||
break;
|
||||
}
|
||||
|
||||
Step B = new Step(hrsB * 60 + minB);
|
||||
B.T = TB;
|
||||
B.PreTemp = preTB;
|
||||
B.LimitT = HL;
|
||||
|
||||
Step A = new Step(hrsA * 60 + minA);
|
||||
A.T = TA;
|
||||
A.PreTemp = preTA;
|
||||
A.LimitT = LL;
|
||||
|
||||
List<Step> steps = new List<Step>();
|
||||
|
||||
|
||||
// If test should start in high, then start with B
|
||||
if (LISTSTARTPOSITION == "H")
|
||||
{
|
||||
steps.Add(B);
|
||||
steps.Add(A);
|
||||
}
|
||||
else
|
||||
{
|
||||
steps.Add(A);
|
||||
steps.Add(B);
|
||||
}
|
||||
|
||||
Loop loop = new Loop(numOfCycles, 0, 1);
|
||||
List<Loop> loops = new List<Loop>();
|
||||
loops.Add(loop);
|
||||
|
||||
// Create profile
|
||||
profile = new Profile(name, steps, loops, options);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean WriteProfile(Profile profile)
|
||||
{
|
||||
// Pass a dummy bacckgroundworker and the default RAM
|
||||
return WriteProfile(profile, _RAM);
|
||||
}
|
||||
|
||||
public override Boolean WriteProfile(Profile profile, int RAM)
|
||||
{
|
||||
// Pass a dummy bacckgroundworker with no event subscriptions
|
||||
System.ComponentModel.BackgroundWorker bgw = new System.ComponentModel.BackgroundWorker();
|
||||
return WriteProfile(profile, _RAM, ref bgw);
|
||||
}
|
||||
|
||||
public override Boolean WriteProfile(Profile profile, int RAM, ref System.ComponentModel.BackgroundWorker bgw)
|
||||
{
|
||||
|
||||
|
||||
// Only stand alone profiles allowed!
|
||||
if (!IsProgrammable(profile))
|
||||
return false;
|
||||
|
||||
string title = profile.Title.Substring(0, (int)Math.Min(14, profile.Title.Length)).Trim();
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
string ram = string.Format("RAM:{0:00}", RAM);
|
||||
|
||||
|
||||
Step A, B; // A is low temperature step, B is high temperature step
|
||||
string startPosition;
|
||||
if (profile.Steps[0].T < profile.Steps[1].T)
|
||||
{
|
||||
A = profile.Steps[0];
|
||||
B = profile.Steps[1];
|
||||
startPosition = "L";
|
||||
}
|
||||
else
|
||||
{
|
||||
A = profile.Steps[1];
|
||||
B = profile.Steps[0];
|
||||
startPosition = "H";
|
||||
}
|
||||
|
||||
|
||||
#warning report Progress to bgw
|
||||
bgw.ReportProgress(8);
|
||||
|
||||
|
||||
|
||||
|
||||
// Communicate with client
|
||||
cmd = sAddr + ", PRGMWRITE," + ram;
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
|
||||
|
||||
// Name of program
|
||||
cmd = sAddr + ", NAME, " + title;
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Temperatures
|
||||
cmd = sAddr + ", TEMP, " + string.Format("S{0:000},{1:+#;-#00}", B.T, A.T);
|
||||
if (A.T == 0)
|
||||
cmd = sAddr + ", TEMP, " + string.Format("S{0:000}, 000", B.T);
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Preheat and precool
|
||||
cmd = sAddr + ", PRE, " + string.Format("{0:000},{1:+#;-#00}", B.PreTemp, A.PreTemp);
|
||||
if (A.PreTemp == 0)
|
||||
cmd = sAddr + ", PRE, " + string.Format("{0:000}, 000", B.PreTemp);
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Dwell times
|
||||
int hrsA = (int)Math.Floor(A.DurationMin / 60);
|
||||
int minA = (int)Math.Floor(A.DurationMin - 60 * hrsA);
|
||||
int hrsB = (int)Math.Floor(B.DurationMin / 60);
|
||||
int minB = (int)Math.Floor(B.DurationMin - 60 * hrsB);
|
||||
cmd = sAddr + ", TIME, " + string.Format("00:00, {0:00}:{1:00}, {2:00}:{3:00}", hrsB, minB, hrsA, minA);
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Start position
|
||||
cmd = sAddr + ", STARTPOSITION, " + startPosition;
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Auto preheat/precool (default is manual): page 44 & 72
|
||||
string preai = "OFF";
|
||||
if (profile.Options.Contains(ProfileOption.TSx_PreTempAuto))
|
||||
preai = "ON";
|
||||
cmd = sAddr + ", PREAI, " + preai;
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Number of cycles
|
||||
int numOfCycles = 1;
|
||||
if (profile.Loops.Count > 0)
|
||||
numOfCycles = profile.Loops[0].N;
|
||||
cmd = sAddr + ", CYCLE, " + string.Format("{0:0000}", numOfCycles);
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// End mode (default is off)
|
||||
string end = "OFF";
|
||||
if (profile.Options.Contains(ProfileOption.TSx_EndModeHeatReturn))
|
||||
end = "HEATRETURN";
|
||||
if (profile.Options.Contains(ProfileOption.TSx_EndModeSetup))
|
||||
end = "SETUP";
|
||||
if (profile.Options.Contains(ProfileOption.TSx_EndModeDefrost))
|
||||
end = "DEFROST";
|
||||
if (profile.Options.Contains(ProfileOption.TSx_EndModeDry))
|
||||
end = "DRY";
|
||||
cmd = sAddr + ", END, " + end;
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
|
||||
// Overheat/Overcool protection
|
||||
cmd = sAddr + ", TEMPLIMIT, " + string.Format("{0:000},{1:+#;-#00}", B.LimitT, A.LimitT);
|
||||
if (A.LimitT == 0)
|
||||
cmd = sAddr + ", TEMPLIMIT, " + string.Format("{0:000}, 000", B.LimitT);
|
||||
|
||||
if (!bgw.CancellationPending)
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
// Always perform PRGMWRITEEND, also if bgw.CancellationPending
|
||||
cmd = sAddr + ", PRGMWRITEEND," + ram;
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
Boolean result = false;
|
||||
if (_Interface.InterfaceStatus == null)
|
||||
result = true;
|
||||
|
||||
_Profile = profile;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsProgrammable(Profile profile)
|
||||
{
|
||||
// Profile is programmable if all below applies
|
||||
// number of steps 2
|
||||
// number of loops < 2
|
||||
// number of cycles < 9999
|
||||
// -77 < tA < 0
|
||||
// 60 < tB < 205
|
||||
// -77 < Pre-tA < 0
|
||||
// 60 <Pre-tB < 205
|
||||
// Limit overcool is 0..50 °C below tA
|
||||
// Limit overheat is 0..50 °C above tB
|
||||
// Ramp control not used
|
||||
|
||||
double[] preH = new double[2]{60,205};
|
||||
double[] preC = new double[2] { -77, 0 };
|
||||
double[] tB = new double[2] { 60, 205 };
|
||||
double[] tA = new double[2] { -77, 0 };
|
||||
|
||||
|
||||
// Specifics
|
||||
if (_Type == ClientType.TSD100S)
|
||||
{
|
||||
preH[1] = 305;
|
||||
tB[1] = 305;
|
||||
}
|
||||
if (_Type == ClientType.TSD100 && _MIDS == 1728)
|
||||
{
|
||||
preH[0] = 30;
|
||||
tB[0] = 30;
|
||||
}
|
||||
if (_Type == ClientType.TSE11A)
|
||||
{
|
||||
preC[0] = -82;
|
||||
}
|
||||
|
||||
|
||||
foreach (Step step in profile.Steps)
|
||||
if (step.RampCtrlT)
|
||||
{
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: ramp control must be off"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (profile.Steps.Count != 2)
|
||||
{
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: there must be 2 steps"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (profile.Loops.Count > 1)
|
||||
return false;
|
||||
|
||||
if(profile.Loops.Count == 1)
|
||||
if(profile.Loops[0].N > 9999)
|
||||
{
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: number of repeats must ben smaller than 9999"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Step A, B; // A is low temperature step, B is high temperature step
|
||||
if (profile.Steps[0].T < profile.Steps[1].T)
|
||||
{
|
||||
A = profile.Steps[0];
|
||||
B = profile.Steps[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
A = profile.Steps[1];
|
||||
B = profile.Steps[0];
|
||||
}
|
||||
|
||||
// Step A
|
||||
if (A.PreTemp < preC[0] || A.PreTemp > preC[1])
|
||||
{
|
||||
string msg = string.Format("pre-cool must be in range {0:0} to {1:0} °C", preC[0] , preC[1]);
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: "+msg));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (A.T < tA[0] || A.T > tA[1])
|
||||
{
|
||||
string msg = string.Format("cold temperature must be in range {0:0} to {1:0} °C", tA[0], tA[1]);
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (A.LimitT > A.T || A.LimitT < A.T-50)
|
||||
{
|
||||
string msg = string.Format("cold limit must be in range {0:0} to {1:0} °C", A.T - 50, A.T);
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Step B
|
||||
if (B.PreTemp < preH[0] || B.PreTemp > preH[1])
|
||||
{
|
||||
string msg = string.Format("pre-heat must be in range {0:0} to {1:0} °C", preH[0], preH[1]);
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
if (B.T < tB[0] || B.T > tB[1])
|
||||
{
|
||||
string msg = string.Format("hot temperature must be in range {0:0} to {1:0} °C", tB[0], tB[1]);
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (B.LimitT < B.T || B.LimitT > B.T +50)
|
||||
{
|
||||
string msg = string.Format("hot limit must be in range {0:0} to {1:0} °C", B.T, B.T + 50);
|
||||
_ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean HasAlarm(out List<Alarm> alarms)
|
||||
{
|
||||
alarms = new List<Alarm>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsIdle()
|
||||
{
|
||||
// IsIdle() returns true if status of chamber is 'Standby'. See page 34 MODE?.
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE?";
|
||||
DataTransfer(cmd,out read, _ReturnDataWaitms);
|
||||
|
||||
if (read.Contains("STANDBY"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Start()
|
||||
{
|
||||
if (_Profile == null)
|
||||
return false;
|
||||
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
// Clear number of remaining cycles
|
||||
cmd = sAddr + ", OPECYCLERESET"; // See ASSIGN page 63
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms,1);
|
||||
|
||||
string ram = string.Format("RAM:{0:00}", _RAM);
|
||||
|
||||
// Assign the profile
|
||||
cmd = sAddr + ", ASSIGN, " + ram; // See ASSIGN page 66
|
||||
if(!DataTransfer(cmd,out read, _ReturnDataWaitms))
|
||||
return false;
|
||||
|
||||
if (_Profile.Options.Contains(ProfileOption.TSx_StartNoSetup))
|
||||
cmd = sAddr + ", OPETEST"; // See page 61
|
||||
else
|
||||
cmd = sAddr + ", OPESETUPEND"; // See page 61
|
||||
|
||||
return DataTransfer(cmd,out read, _ReturnDataWaitms);
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsFinished()
|
||||
{
|
||||
// Finished() returns true if chamber is not running. See page 34 MODE?.
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
|
||||
cmd = sAddr + ", MODE?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
|
||||
if (read.Contains("POWER-OFF"))
|
||||
return true;
|
||||
|
||||
if (read.Contains("STANDBY"))
|
||||
return true;
|
||||
|
||||
if (read.Contains("END-SETUP"))
|
||||
return true;
|
||||
|
||||
if (read.Contains("END-READY"))
|
||||
return true;
|
||||
|
||||
if (read.Contains("END-OFF"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override Boolean Stop()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = sAddr + ", OPESTANDBY";
|
||||
return DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
}
|
||||
|
||||
|
||||
public override Boolean IsOnline()
|
||||
{
|
||||
try
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = sAddr + ", MODEL?";
|
||||
DataTransfer(cmd, out read, _ReturnDataWaitms);
|
||||
return (read.ToLower().Contains("tsd") || read.ToLower().Contains("tse"));
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override String Progress()
|
||||
{
|
||||
string sAddr = _Address.ToString();
|
||||
string cmd;
|
||||
string read;
|
||||
cmd = sAddr + ", CYCLE?"; // See page 38
|
||||
DataTransfer(cmd,out read, _ReturnDataWaitms,1);
|
||||
Int32 n = Int32.Parse(read.Split(',')[0]);
|
||||
Int32 N = Int32.Parse(read.Split(',')[1]);
|
||||
double t = CurrentTemperature();
|
||||
return String.Format("{0:0}/{1:0} cycles executed. Temperature is {2:0} °C", n, N, t);
|
||||
}
|
||||
|
||||
|
||||
private bool TxRxSucces(string cmd, string read)
|
||||
{
|
||||
// Command not correctly processed
|
||||
if (read.StartsWith("NA:"))
|
||||
return false;
|
||||
|
||||
// No response received
|
||||
if (read.Trim().Length < 1)
|
||||
return false;
|
||||
|
||||
// Handle monitoring commands
|
||||
if (cmd.Trim().Contains("?"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read.Trim().StartsWith("OK:"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms)
|
||||
{
|
||||
// If no maximum number of attempts is given, it defaults to 3.
|
||||
return DataTransfer(cmd, out read, ReturnDataWaitms,3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Performs transfer and adds interface logs to list in Client parent class
|
||||
private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms, int MaxNumOfAttempts)
|
||||
{
|
||||
// Construct command to send
|
||||
cmd += (char)13; // CR
|
||||
cmd += (char)10; // LF
|
||||
cmd = cmd.Replace(" ", "");
|
||||
|
||||
|
||||
// Wait for _ReadyToSend or max 1 seconds
|
||||
DateTime go = DateTime.Now.AddSeconds(1);
|
||||
while (DateTime.Now < _ReadyToSend && DateTime.Now < go)
|
||||
System.Threading.Thread.Sleep(10);
|
||||
|
||||
read = "";
|
||||
bool success = false;
|
||||
int attempts = 0;
|
||||
while (!success && attempts <= MaxNumOfAttempts)
|
||||
{
|
||||
DataTransferLog log = _Interface.DataTransfer(cmd, out read, ReturnDataWaitms);
|
||||
success = TxRxSucces(cmd, read);
|
||||
attempts++;
|
||||
|
||||
// Mask for showing in GUI
|
||||
if (cmd.Contains("MODE?") || cmd.Contains("CYCLE?"))
|
||||
log.ShowInGUI = false;
|
||||
|
||||
// Notify user via GUI of failed attempts
|
||||
if (attempts > 1)
|
||||
log.Command += string.Format(" [Attempt {0:0}]", attempts);
|
||||
|
||||
// Add to logs
|
||||
AppendDataTransferLog(log);
|
||||
|
||||
|
||||
// Set _ReadyToSend acc. manual specs
|
||||
if (cmd.Contains("?"))
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(300);
|
||||
else
|
||||
_ReadyToSend = DateTime.Now.AddMilliseconds(1000);
|
||||
|
||||
|
||||
// Sleeps
|
||||
if (!success)
|
||||
System.Threading.Thread.Sleep(3000); // Sleep 3 seconds before resending if failed
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
63
ChamChat/Client_TSx/Client_TSx.csproj
Normal file
63
ChamChat/Client_TSx/Client_TSx.csproj
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A863C309-E15C-4EA1-82F2-BDFE83C96D15}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ChamChat</RootNamespace>
|
||||
<AssemblyName>TSx</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</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>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<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="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Task.TSx.cs" />
|
||||
<Compile Include="Client.TSx.cs" />
|
||||
<Compile Include="Client.TSx.Specific.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Models\Models.csproj">
|
||||
<Project>{09375A4A-28B8-427B-853D-75C03A070728}</Project>
|
||||
<Name>Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
36
ChamChat/Client_TSx/Properties/AssemblyInfo.cs
Normal file
36
ChamChat/Client_TSx/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TSD100S")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("TSD100S")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2fc0fe7d-2c1d-4983-a44a-6c1fd33288e3")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
657
ChamChat/Client_TSx/Task.TSx.cs
Normal file
657
ChamChat/Client_TSx/Task.TSx.cs
Normal file
@@ -0,0 +1,657 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ChamChat.Models;
|
||||
|
||||
namespace ChamChat
|
||||
{
|
||||
public class TSx_Task : Task
|
||||
{
|
||||
// Each step is separately programmed to the TSE11.
|
||||
// Steps are programmed at 110% of required step duration.
|
||||
// End of program is always of shutdown type to avoid stressing to much. (Excluding last step)
|
||||
// If next step is of different type (tA or tB), then the next temperature is prepared in other chamber.
|
||||
// Default temperatures are 0 °C for tA and 85 °C for tB.
|
||||
|
||||
public TSx_Task(Client Client, Profile Profile)
|
||||
: base(Client, Profile)
|
||||
{
|
||||
_Profile = Profile;
|
||||
_Client = Client;
|
||||
_SerSteps = _Profile.SerializedStepList;
|
||||
|
||||
// Limit tA is overall limit
|
||||
_tAProfileLimit = 0;
|
||||
foreach (Step s in _SerSteps)
|
||||
if (s.LimitT < _tAProfileLimit)
|
||||
_tAProfileLimit = s.LimitT;
|
||||
|
||||
// Limit tB is overall limit
|
||||
_tBProfileLimit = 60;
|
||||
foreach (Step s in _SerSteps)
|
||||
if (s.LimitT > _tBProfileLimit)
|
||||
_tBProfileLimit = s.LimitT;
|
||||
}
|
||||
|
||||
private DateTime _dtIdlingStart = DateTime.Now.AddYears(10);
|
||||
|
||||
private const Int32 PollingIntervalSeconds = 10; // Interval in seconds for updating task progress
|
||||
private const Int32 maxIdlingTimeSec = 60;
|
||||
|
||||
private List<Step> _SerSteps;
|
||||
private double _tAProfileLimit = 0;
|
||||
private double _tBProfileLimit = 0;
|
||||
|
||||
|
||||
public override Boolean IsControlledProgrammable(Profile profile)
|
||||
{
|
||||
// Clear existing ClientMessages
|
||||
_Client.ClientMessages = new List<ClientMessage>();
|
||||
|
||||
|
||||
_NewProfileDuration = 0;
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
|
||||
List<Profile> profiles = new List<Profile>();
|
||||
int k = 0;
|
||||
while (k < _SerSteps.Count)
|
||||
{
|
||||
Profile p = GetProfile(k);
|
||||
profiles.Add(p);
|
||||
k += _ProfileNumOfSerialSteps;
|
||||
}
|
||||
|
||||
|
||||
foreach (Profile p in profiles)
|
||||
if (!_Client.IsProgrammable(p))
|
||||
return false;
|
||||
|
||||
|
||||
// If subsequent tA resp. tB steps differ more than 50 °C, overheat/overcool alarm will sound immediately.
|
||||
// Limits can be set to 50 °C from temperature.
|
||||
|
||||
List<Step> tASteps = new List<Step>();
|
||||
List<Step> tBSteps = new List<Step>();
|
||||
|
||||
// Create list of all tA steps resp. tB steps
|
||||
foreach (Step s in _SerSteps)
|
||||
if (s.T > 25)
|
||||
tBSteps.Add(s);
|
||||
else
|
||||
tASteps.Add(s);
|
||||
|
||||
// Compare subsequent tA steps
|
||||
for (int i = 1; i < tASteps.Count; i++)
|
||||
{
|
||||
double t1 = tASteps[i - 1].T;
|
||||
double t2 = tASteps[i].T;
|
||||
|
||||
if (Math.Abs(t1 - t2) > 50)
|
||||
{
|
||||
string msg = string.Format("stepping from {0:0} to {1:0} will cause overcool alarm", t1, t2);
|
||||
_Client.ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare subsequent tB steps
|
||||
for (int i = 1; i < tBSteps.Count; i++)
|
||||
{
|
||||
double t1 = tBSteps[i - 1].T;
|
||||
double t2 = tBSteps[i].T;
|
||||
|
||||
if (Math.Abs(t1 - t2) > 50)
|
||||
{
|
||||
string msg = string.Format("stepping from {0:0} to {1:0} will cause overheat alarm", t1, t2);
|
||||
_Client.ClientMessages.Add(new ClientMessage("Program cannot be written to client: " + msg));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void ThreadStandAlone()
|
||||
{
|
||||
// Write profile
|
||||
try
|
||||
{
|
||||
if (!_Client.WriteProfile(_Profile))
|
||||
{
|
||||
_Status = TaskStatus.Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
if (!_Client.Start())
|
||||
{
|
||||
_Status = TaskStatus.Stopped;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning)
|
||||
{
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
_Status = TaskStatus.Finished;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
_TaskProgress = _Client.Progress();
|
||||
}
|
||||
catch { }
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(100);
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
private Double _NewProfileDuration = 0; // Duration of new profile in minutes
|
||||
private int _ProfileNumOfSerialSteps = 1; // Number of steps from serial step list performed in new profile.
|
||||
|
||||
|
||||
protected override void ThreadControlled()
|
||||
{
|
||||
Int32 iCurrentSerialStep = -1;
|
||||
DateTime startOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
DateTime endOfCurrentProgram = new DateTime(1900, 1, 1);
|
||||
Step currentStep = _SerSteps[0];
|
||||
DateTime lastPolled = DateTime.Now;
|
||||
_NewProfileDuration = 0;
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
Profile newProfile;
|
||||
|
||||
while (_Status == TaskStatus.IsRunning || _Status == TaskStatus.NextStepRequested)
|
||||
{
|
||||
|
||||
#warning Update 02/05/2016
|
||||
// Proceed with next step if it is not the last one.
|
||||
if (_Status == TaskStatus.NextStepRequested && iCurrentSerialStep < _SerSteps.Count - 1)
|
||||
{
|
||||
endOfCurrentProgram = DateTime.Now.AddYears(1);
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
}
|
||||
|
||||
|
||||
if (DateTime.Now > endOfCurrentProgram)
|
||||
{
|
||||
iCurrentSerialStep += _ProfileNumOfSerialSteps; // Is starting step of newProfile to be executed
|
||||
|
||||
// Last step has been performed?
|
||||
if (iCurrentSerialStep > _SerSteps.Count - 1)
|
||||
{
|
||||
_Client.Stop();
|
||||
_Status = TaskStatus.Finished;
|
||||
AddEventLog("Last step performed");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
newProfile = new Profile();
|
||||
try
|
||||
{
|
||||
//AddEventLog("Debugging: Getting profile for iCurrentSerialStep=" + iCurrentSerialStep.ToString());
|
||||
newProfile = GetProfile(iCurrentSerialStep);
|
||||
//AddEventLog("Debugging: Profile for iCurrentSerialStep: " + newProfile.ToString());
|
||||
}
|
||||
catch (Exception ex) { AddEventLog("GetProfile() error: " + ex.Message); }
|
||||
|
||||
|
||||
RestartClient(newProfile); // RestartClient sets TaskStatus to IsRunning if succesfull.
|
||||
|
||||
|
||||
if (_Status != TaskStatus.IsRunning)
|
||||
continue;
|
||||
|
||||
|
||||
// Update variables
|
||||
startOfCurrentProgram = DateTime.Now;
|
||||
endOfCurrentProgram = DateTime.Now.AddMinutes(_NewProfileDuration);
|
||||
lastPolled = DateTime.Now;
|
||||
|
||||
|
||||
// Update events
|
||||
try
|
||||
{
|
||||
Step s1 = newProfile.Steps[0];
|
||||
Step s2 = newProfile.Steps[1];
|
||||
//AddEventLog("Profile in client: " + newProfile.ToString());
|
||||
if (newProfile.Loops.Count == 1)
|
||||
AddEventLog(string.Format("Set conditions: {0:0}h{1:00} @ {2:0} °C, {3:0}h{4:00} @ {5:0} °C, {6:0} cycles", s1.Hours, s1.Minutes, s1.T, s2.Hours, s2.Minutes, s2.T, newProfile.Loops[0].N));
|
||||
else
|
||||
AddEventLog(string.Format("Set conditions: {0:0}h{1:00} @ {2:0} °C, {3:0}h{4:00} @ {5:0} °C", s1.Hours, s1.Minutes, s1.T, s2.Hours, s2.Minutes, s2.T));
|
||||
string s = string.Format("Partial profile end is {0:00}-{1:00} @ {2:00}:{3:00}:{4:00}", endOfCurrentProgram.Day, endOfCurrentProgram.Month, endOfCurrentProgram.Hour, endOfCurrentProgram.Minute, endOfCurrentProgram.Second);
|
||||
AddEventLog(s);
|
||||
}
|
||||
catch (Exception ex) { AddEventLog("Update events: " + ex.Message); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Poll only every 'PollingIntervalSeconds' seconds
|
||||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||||
{
|
||||
// Is finished?
|
||||
try
|
||||
{
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
AddEventLog("Client finished, but task did not!");
|
||||
if (_dtIdlingStart < DateTime.Now.AddSeconds(-maxIdlingTimeSec))
|
||||
{
|
||||
AddEventLog("Debugging: _dtIdlingStart < DateTime.Now.AddSeconds(-maxIdlingTimeSec)");
|
||||
// _Status = TaskStatus.Interrupted; // Profile did not finish, client did
|
||||
//continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dtIdlingStart = DateTime.Now;
|
||||
AddEventLog("Debugging: _dtIdlingStart set to "+_dtIdlingStart.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
_dtIdlingStart = DateTime.Now.AddYears(10);
|
||||
}
|
||||
catch { _dtIdlingStart = DateTime.Now.AddYears(10); } // Always continue and keep trying
|
||||
|
||||
|
||||
|
||||
#region Taskprogress
|
||||
try
|
||||
{
|
||||
double taskRunTime = (DateTime.Now - _startThread).TotalMinutes;
|
||||
double pTest = Math.Min(100, Math.Floor(taskRunTime / _Profile.DurationMin * 100));
|
||||
double taskTimeRemain = _Profile.DurationMin - taskRunTime;
|
||||
double taskTimeRemainHrs = Math.Floor(taskTimeRemain / 60);
|
||||
double taskTimeRemainMin = Math.Floor(taskTimeRemain - 60 * taskTimeRemainHrs);
|
||||
|
||||
double newProfileRuntime = (DateTime.Now - startOfCurrentProgram).TotalMinutes;
|
||||
double pNewProfile = Math.Min(100, Math.Floor(newProfileRuntime / _NewProfileDuration * 100));
|
||||
|
||||
|
||||
double profileTimeExecutedSoFar = newProfileRuntime;
|
||||
for (int i = 0; i < iCurrentSerialStep; i++)
|
||||
profileTimeExecutedSoFar += _SerSteps[i].DurationMin;
|
||||
|
||||
int serialStepNo = iCurrentSerialStep;
|
||||
double min = 0;
|
||||
for (int i = 0; i < _SerSteps.Count; i++)
|
||||
{
|
||||
min += _SerSteps[i].DurationMin;
|
||||
if (min > profileTimeExecutedSoFar)
|
||||
{
|
||||
serialStepNo = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_TaskProgress = String.Format("Step #{0:00}/{1:00} progress {2:0}%, test progress {3:0}%, remaining test time {4:0}h{5:00}m", serialStepNo + 1, _Profile.SerializedStepList.Count, pNewProfile, pTest, taskTimeRemainHrs, taskTimeRemainMin);
|
||||
if (serialStepNo + 1 == _Profile.SerializedStepList.Count && pTest > 99.99)
|
||||
_TaskProgress = "Profile executed";
|
||||
}
|
||||
catch { _TaskProgress = "n/a"; }
|
||||
#endregion Taskprogress
|
||||
|
||||
|
||||
lastPolled = DateTime.Now;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(200);
|
||||
|
||||
_isKicking = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (_Status == TaskStatus.AbortRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Client.Stop())
|
||||
_Status = TaskStatus.Aborted;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_isKicking = false;
|
||||
}
|
||||
|
||||
|
||||
private void RestartClient(Profile newProfile)
|
||||
{
|
||||
// Stop client
|
||||
try
|
||||
{
|
||||
AddEventLog("Info: Stopping client");
|
||||
|
||||
|
||||
#warning Do not stop if this is the first parital profile
|
||||
|
||||
|
||||
if (!_Client.Stop())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Task interrupted while trying to stop client!");
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Stop() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait to finish
|
||||
try
|
||||
{
|
||||
Boolean timedOut = true;
|
||||
|
||||
DateTime startWait = DateTime.Now;
|
||||
while (DateTime.Now < startWait.AddSeconds(60))
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
if (_Client.IsFinished())
|
||||
{
|
||||
timedOut = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timedOut)
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Time out (60 s) in RestartClient.WaitForFinish");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WaitForFinish exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
AddEventLog("Info: Client stopped");
|
||||
|
||||
|
||||
|
||||
// Wait for move to end
|
||||
try
|
||||
{
|
||||
if (!((TSx_Client)_Client).AwaitMoving(60))
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Time out (60 s) in RestartClient.AwaitMoving");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client AwaitMoving() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
// AddEventLog("Debugging: Client AwaitMoving done");
|
||||
|
||||
|
||||
|
||||
// Write profile
|
||||
try
|
||||
{
|
||||
AddEventLog("Info: Writing to client");
|
||||
if (!_Client.WriteProfile(newProfile))
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Task interrupted while trying to write new profile to client!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
AddEventLog("Info: Profile written to client");
|
||||
|
||||
|
||||
// Start client
|
||||
try
|
||||
{
|
||||
AddEventLog("Info: Starting client");
|
||||
if (!_Client.Start())
|
||||
{
|
||||
// Try to start again after 10 sec
|
||||
AddEventLog("First attempt to start client failed!");
|
||||
System.Threading.Thread.Sleep(10000);
|
||||
|
||||
if (!_Client.Start())
|
||||
{
|
||||
_Status = TaskStatus.Interrupted;
|
||||
AddEventLog("Task interrupted while trying to start client!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Status = TaskStatus.ExceptionOccured;
|
||||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||||
AddEventLog(_TaskProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
AddEventLog("Info: Client started");
|
||||
|
||||
|
||||
#warning Update 02/05/2016
|
||||
_Status = TaskStatus.IsRunning;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Profile GetProfile(int iStep)
|
||||
{
|
||||
Step nextStep = null;
|
||||
if (iStep + 1 < _SerSteps.Count)
|
||||
nextStep = _SerSteps[iStep + 1].DeepClone();
|
||||
|
||||
// Last tA set to client
|
||||
double tALastSet = 0;
|
||||
for (int i = 0; i < iStep; i++)
|
||||
if (_SerSteps[i].T < 40)
|
||||
tALastSet = _SerSteps[i].T;
|
||||
double tAsetting = Math.Min(0, tALastSet + 40); // As high as possible without exceeding limits of prev step
|
||||
|
||||
// Last tB set to client
|
||||
double tBLastSet = 0;
|
||||
for (int i = 0; i < iStep; i++)
|
||||
if (_SerSteps[i].T > 40)
|
||||
tBLastSet = _SerSteps[i].T;
|
||||
double tBsetting = Math.Max(60, tBLastSet - 40); // As low as possible without exceeding limits of prev step
|
||||
|
||||
|
||||
// Create standard steps with 1 min duration
|
||||
Step stdA = new Step(1);
|
||||
stdA.T = tAsetting;
|
||||
stdA.LimitT = tAsetting - 50; // Reset later
|
||||
stdA.PreTemp = tAsetting;
|
||||
Step stdB = new Step(1);
|
||||
stdB.T = tBsetting;
|
||||
stdB.LimitT = tBsetting + 50; // Reset later
|
||||
stdB.PreTemp = tBsetting;
|
||||
|
||||
Step step1 = _SerSteps[iStep].DeepClone();
|
||||
Step step2 = new Step(15);
|
||||
|
||||
// Programmed step is minimum 10 minutes, maxmimum 1.5 times the required step duration.
|
||||
// If multiple steps can be performed without restart, the duration is altered below.
|
||||
step1.DurationMin = Math.Max(10, Math.Round(1.5 * step1.DurationMin));
|
||||
|
||||
// Set time of restart to end of current step.
|
||||
// If multiple steps can be performed without restart, the duration is altered below.
|
||||
_NewProfileDuration = _SerSteps[iStep].DurationMin;
|
||||
_ProfileNumOfSerialSteps = 1;
|
||||
|
||||
// Remark: Area to start in is defined by client based on step order.
|
||||
if (step1.T > 40)
|
||||
{
|
||||
// Current step is tB, step 2 programmed to client must be tA
|
||||
step2 = stdA;
|
||||
if (nextStep != null)
|
||||
if (nextStep.T < 40)
|
||||
{
|
||||
// If next step is tA, then program it as is.
|
||||
step2 = nextStep.DeepClone();
|
||||
|
||||
//// The two steps can be run by client without restarting.
|
||||
//// If no restarting takes place, then the next opposite step is not being prepared. The previous retains.
|
||||
//step2.DurationMin = Math.Max(30, Math.Round(1.5 * step2.DurationMin));
|
||||
//step1.DurationMin = _SerSteps[iStep].DurationMin;
|
||||
//_NewProfileDuration = step1.DurationMin + step2.DurationMin;
|
||||
//_ProfileNumOfSerialSteps = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current step is tA, step 2 programmed to client must be tB
|
||||
step2 = stdB;
|
||||
if (nextStep != null)
|
||||
if (nextStep.T > 40)
|
||||
{
|
||||
// If next step is tB, then program it as is.
|
||||
step2 = nextStep.DeepClone();
|
||||
|
||||
//// The two steps can be run by client without restarting.
|
||||
//// If no restarting takes place, then the next opposite step is not being prepared. The previous retains.
|
||||
//step2.DurationMin = Math.Max(30, Math.Round(1.5 * step2.DurationMin));
|
||||
//step1.DurationMin = _SerSteps[iStep].DurationMin;
|
||||
//_NewProfileDuration = step1.DurationMin + step2.DurationMin;
|
||||
//_ProfileNumOfSerialSteps = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set PK
|
||||
step1.PK = _SerSteps[iStep].PK; // Set for Loop.ToString()
|
||||
step2.PK = _SerSteps[iStep].PK + 1;
|
||||
|
||||
|
||||
// If current step is start of a loop comprising 2 opposite steps, then create loop in newProfile and set end time of newProfile
|
||||
List<Loop> loops = new List<Loop>();
|
||||
int N = 0;
|
||||
foreach (Loop loop in _Profile.Loops)
|
||||
{
|
||||
if (loop.First == _SerSteps[iStep].PK && loop.Last == _SerSteps[iStep].PK + 1)
|
||||
{
|
||||
if ((step1.T < 40 && step2.T > 40) || (step1.T > 40 && step2.T < 40))
|
||||
{
|
||||
// Steps are in different chambers of client.
|
||||
N = loop.N;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (N != 0)
|
||||
{
|
||||
loops.Add(new Loop(N, 0, 1)); // Loop is always from 1st to 2nd step
|
||||
step1.DurationMin = _SerSteps[iStep].DurationMin;
|
||||
step2.DurationMin = nextStep.DurationMin;
|
||||
_NewProfileDuration = N * (step1.DurationMin + step2.DurationMin);
|
||||
_ProfileNumOfSerialSteps = 2 * N;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Set limits to max, but do not exceed profile limits
|
||||
if (step1.T < 40)
|
||||
{
|
||||
step1.LimitT = Math.Max(step1.T - 50, _tAProfileLimit);
|
||||
step2.LimitT = Math.Min(step2.T + 50, _tBProfileLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
step1.LimitT = Math.Min(step1.T + 50, _tBProfileLimit);
|
||||
step2.LimitT = Math.Max(step2.T - 50, _tAProfileLimit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<Step> steps = new List<Step>();
|
||||
steps.Add(step1);
|
||||
steps.Add(step2);
|
||||
|
||||
|
||||
|
||||
List<ProfileOption> options = new List<ProfileOption>();
|
||||
options.Add(ProfileOption.TSx_EndModeOff); // Shut down client
|
||||
|
||||
|
||||
// NOTE: It is impossible to wait for setup, unless endofCurrentProgram is moved forwards.
|
||||
options.Add(ProfileOption.TSx_StartNoSetup); // Do not wait for setup
|
||||
//if (iStep == 0 && _Profile.Options.Contains(ProfileOption.TSE11A_StartSetupTest))
|
||||
// options.Add(ProfileOption.TSE11A_StartSetupTest); // Wait for setup in first step
|
||||
//else
|
||||
// options.Add(ProfileOption.TSE11A_StartNoSetup); // Do not wait for setup
|
||||
|
||||
|
||||
Profile newProfile = new Profile(_Profile.Title, steps, loops, options);
|
||||
return newProfile;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
BIN
ChamChat/Client_TSx/bin/Release/ChamChat.Models.dll
Normal file
BIN
ChamChat/Client_TSx/bin/Release/ChamChat.Models.dll
Normal file
Binary file not shown.
BIN
ChamChat/Client_TSx/bin/Release/ChamChat.Models.pdb
Normal file
BIN
ChamChat/Client_TSx/bin/Release/ChamChat.Models.pdb
Normal file
Binary file not shown.
BIN
ChamChat/Client_TSx/bin/Release/TSx.dll
Normal file
BIN
ChamChat/Client_TSx/bin/Release/TSx.dll
Normal file
Binary file not shown.
BIN
ChamChat/Client_TSx/bin/Release/TSx.pdb
Normal file
BIN
ChamChat/Client_TSx/bin/Release/TSx.pdb
Normal file
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
0d605b8d358746cb8dedaee3da21912cbaeec1bd
|
||||
@@ -0,0 +1,9 @@
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\bin\Release\TSx.dll
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\bin\Release\TSx.pdb
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\bin\Release\ChamChat.Models.dll
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\bin\Release\ChamChat.Models.pdb
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\obj\Release\Client_TSx.csproj.AssemblyReference.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\obj\Release\Client_TSx.csproj.CoreCompileInputs.cache
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\obj\Release\Client_TSx.csproj.CopyComplete
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\obj\Release\TSx.dll
|
||||
\\silicium\software\MASER software\Source\ChamChat\Client_TSx\obj\Release\TSx.pdb
|
||||
Binary file not shown.
BIN
ChamChat/Client_TSx/obj/Release/TSx.dll
Normal file
BIN
ChamChat/Client_TSx/obj/Release/TSx.dll
Normal file
Binary file not shown.
BIN
ChamChat/Client_TSx/obj/Release/TSx.pdb
Normal file
BIN
ChamChat/Client_TSx/obj/Release/TSx.pdb
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user