using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;
using System;
using System.Reflection;
using System.Text;
namespace SHARP_CLAS_UI
{
///
/// Model : RTC4 Scanner Board
/// Home : www.scanlab.de/ko
///
public class Scanner
{
#region Logger
///
/// Exception Log
///
private ILog ExceptionLog = LogManager.GetLogger("Scanner_Exception");
///
/// Exception Log Write
///
/// Method name of exception that occurred
/// exception
public void WriteExceptionLog(string Methodname, Exception ex)
{
if (ExceptionLog != null) ExceptionLog.Debug($"{Methodname}\t{ex.Message}");
}
#endregion
#region Field
bool IsInitialize;
Equipment _equip;
#endregion
#region Construct
public Scanner(Equipment _equip)
{
Create_Exception_Logger();
this._equip = _equip;
}
#endregion
#region Function
///
/// Createt Exception Logger
///
private void Create_Exception_Logger()
{
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
RollingFileAppender rollingAppender = new RollingFileAppender();
PatternLayout layout = new PatternLayout();
hierarchy.Configured = true;
rollingAppender.Name = "ScannerExceptionRollingFile";
rollingAppender.LockingModel = new RollingFileAppender.MinimalLock();
rollingAppender.File = $@"D:\Logger\Scanner\";
rollingAppender.AppendToFile = true;
rollingAppender.DatePattern = "yyyy\\\\'Exception'_MM.dd'.log'";
rollingAppender.RollingStyle = RollingFileAppender.RollingMode.Composite;
rollingAppender.MaxSizeRollBackups = 10;
rollingAppender.MaximumFileSize = "100MB";
rollingAppender.StaticLogFileName = false;
rollingAppender.Encoding = Encoding.UTF8;
rollingAppender.PreserveLogFileNameExtension = true;
layout = new PatternLayout("%d{yyyy/MM/dd HH:mm:ss.fff} %m%n");
layout.ActivateOptions();
rollingAppender.Layout = layout;
rollingAppender.ActivateOptions();
hierarchy.GetLogger("ScannerExceptionRollingFile");
ILog log = LogManager.GetLogger("Scanner_Exception");
Logger l = (Logger)log.Logger;
l.Level = log4net.Core.Level.Debug;
l.AddAppender(rollingAppender);
ExceptionLog = LogManager.GetLogger("Scanner_Exception");
}
///
/// Scanner Initialize.
///
///
public bool Initialize(string file_Path)
{
try
{
short ErrorCode;
ErrorCode = RTC4Wrap.load_correction_file(file_Path,
1, // table; #1 is used by default
1.0, 1.0, // scale factor
0.0, // rotation in degrees, counterclockwise
0.0, 0.0); // offset in bits
if (ErrorCode != 0)
throw new Exception(ErrorMessage(ErrorCode));
ErrorCode = RTC4Wrap.load_program_file("rtc4d2.hex");
if (ErrorCode != 0)
throw new Exception(ErrorMessage(ErrorCode));
RTC4Wrap.set_laser_mode(0);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 5)
throw new Exception("init time out. (5sec)");
}
while (busy);
_equip.Write_Scanner_Log("Scanner Init Success");
IsInitialize = true;
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Scanner Init Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Get Laser on/off status
///
///
public bool Get_Laser_On(out bool laseron)
{
try
{
laseron = false;
if (!IsInitialize) return false;
laseron = RTC4Wrap.get_value((ushort)0) == (short)1;
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
laseron = false;
return false;
}
}
///
/// Set laser on
///
public bool Set_Laser_On()
{
try
{
if (!IsInitialize) return false;
bool isInPosition = false;
if (_equip.Cur_Main_Recipe != null && _equip.Cur_Main_Recipe.process_info != null && _equip.Cur_Main_Recipe.panel_type_info != null)
{
double scannerA1Position = _equip.Cur_Main_Recipe.process_info.Scanner_X_A1 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_X_A1;
double scannerA2Position = _equip.Cur_Main_Recipe.process_info.Scanner_X_A2 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_X_A2;
double scannerB1Position = _equip.Cur_Main_Recipe.process_info.Scanner_X_B1 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_X_B1;
double scannerB2Position = _equip.Cur_Main_Recipe.process_info.Scanner_X_B2 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_X_B2;
double stageA1Position = _equip.Cur_Main_Recipe.process_info.Scanner_Y_A1 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_Y_A1;
double stageA2Position = _equip.Cur_Main_Recipe.process_info.Scanner_Y_A2 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_Y_A2;
double stageB1Position = _equip.Cur_Main_Recipe.process_info.Scanner_Y_B1 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_Y_B1;
double stageB2Position = _equip.Cur_Main_Recipe.process_info.Scanner_Y_B2 + _equip.Cur_Main_Recipe.panel_type_info.Scanner_Offset_Y_B2;
object value;
_equip.sm.Get_Value(RS_Automation_Motor_Address.Ablation_X_Actual_Position, out value);
double scannerPosition = double.Parse($"{value}");
_equip.sm.Get_Value(RS_Automation_Motor_Address.Ablation_Y_1_Actual_Position, out value);
double stageAPosition = double.Parse($"{value}");
_equip.sm.Get_Value(RS_Automation_Motor_Address.Ablation_Y_2_Actual_Position, out value);
double stageBPosition = double.Parse($"{value}");
isInPosition |= (scannerA1Position - 10 <= scannerPosition && scannerPosition <= scannerA1Position + 10) && (stageA1Position - 10 <= stageAPosition && stageAPosition <= stageA1Position + 10);
isInPosition |= (scannerA2Position - 10 <= scannerPosition && scannerPosition <= scannerA2Position + 10) && (stageA2Position - 10 <= stageAPosition && stageAPosition <= stageA2Position + 10);
isInPosition |= (scannerB1Position - 10 <= scannerPosition && scannerPosition <= scannerB1Position + 10) && (stageB1Position - 10 <= stageBPosition && stageBPosition <= stageB1Position + 10);
isInPosition |= (scannerB2Position - 10 <= scannerPosition && scannerPosition <= scannerB2Position + 10) && (stageB2Position - 10 <= stageBPosition && stageBPosition <= stageB2Position + 10);
isInPosition |= _equip.process.ablation.Get_Is_Position_X_Power_Meter() && _equip.process.ablation.Get_Is_Position_Z_Power_Meter();
}
else
{
isInPosition |= _equip.process.ablation.Get_Is_Position_X_Power_Meter() && _equip.process.ablation.Get_Is_Position_Z_Power_Meter();
}
if (isInPosition)
{
RTC4Wrap.laser_signal_on();
_equip.Write_Scanner_Log("Laser On Success");
}
else
{
_equip.Write_Scanner_Log("Laser On fail, not enable position");
return false;
}
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Laser On Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set laser off
///
public bool Set_Laser_Off()
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.laser_signal_off();
_equip.Write_Scanner_Log("Laser Off Success");
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Laser Off Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Get execute list busy
///
/// busy
///
public bool Get_Busy(out bool busy)
{
try
{
busy = false;
if (!IsInitialize) return false;
ushort ubusy, position;
RTC4Wrap.get_status(out ubusy, out position);
busy = ubusy != 0;
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
busy = false;
return false;
}
}
public bool Get_Position(out short position_x, out short position_y)
{
try
{
short x, y;
RTC4Wrap.get_xy_pos(out x, out y);
position_x = x;
position_y = y;
return true;
}
catch(Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
position_x = 0;
position_y = 0;
return false;
}
}
///
/// Set process datas
///
/// jump speed (1ms ~ 50000ms)
/// mark speed (1ms ~ 50000ms)
/// Laser on delay (-8000us ~ 8000us)
/// Laser off delay (2us ~ 8000us)
/// jump delay (us)
/// mark delay (us)
/// ploygon delay (us)
///
public bool Set_Process_Datas(double jump_speed, double mark_speed, short laser_on_delay, short laser_off_delay, ushort jump_delay, ushort mark_delay, ushort polygone_delay = 0)
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.set_start_list((ushort)1);
RTC4Wrap.set_scanner_delays(jump_delay, mark_delay, polygone_delay);
RTC4Wrap.set_laser_delays(laser_on_delay, laser_off_delay);
RTC4Wrap.set_jump_speed(jump_speed);
RTC4Wrap.set_mark_speed(mark_speed / 1.875);// / 1.875
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list((ushort)1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Set Process Datas Delay time out.");
}
while (busy);
_equip.Write_Scanner_Log("Process Data Set Success");
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Process Data Set Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
public bool Set_Power(int frequency, double power)
{
try
{
if (!IsInitialize) return false;
//_Scanner = new RTC4_Scanner();
RTC4Wrap.set_standby(0, // half of the standby period in 1/8 microseconds
0); // pulse width in 1/8 microseconds
double tsetpw;
//_Scanner.SetParameter(Convert.ToInt32(tb_Frequency.Text), Convert.ToInt32(tb_power.Text), 5000, 2000,
// 600, 300, 150, 6, 9);
//scanner.LaserInit(, );
double Fre = (500 / Convert.ToDouble(frequency)) * 8;
double Power = ((1000 / frequency) * (Convert.ToDouble(power) / 100)) * 8;
//double Fre = Convert.ToDouble(frequency);
//double Power = Convert.ToDouble(power);
//tsetpw = (((Fre * 2) * Power) / 100);
//double Pw = tsetpw;
//int Fre = 5000 / Convert.ToInt32(frequency);
//int Power = Convert.ToInt32(power);
//int Pw = (Fre * 2 / 100) * Power;
//double period = 1.0f / frequency * 1000; //us
//double halfPeriod = period / 2.0f;
// Timing, delay and speed preset
RTC4Wrap.set_start_list(1);
RTC4Wrap.set_laser_timing((ushort)Fre, // half of the laser signal period
(ushort)Power, (ushort)Power, // pulse widths of signals LASER1 and LASER2
1); // time base; 0 corresponds to 1 microsecond.
// Otherwise, the time base is 1/8 microseconds.
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list(1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Set Process Datas Delay time out.");
}
while (busy);
_equip.Write_Scanner_Log("Set Power Success");
return true;
}
catch(Exception ex)
{
_equip.Write_Scanner_Log("Set Power Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set jump speed
///
/// jump speed (1ms ~ 50000ms)
///
public bool Set_Jump_Speed(double speed)
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.set_start_list((ushort)1);
RTC4Wrap.set_jump_speed(speed);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list((ushort)1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Set Junp Speed time out.");
}
while (busy);
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set mark speed
///
/// mark speed (1ms ~ 50000ms)
///
public bool Set_Mark_Speed(double speed)
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.set_start_list((ushort)1);
RTC4Wrap.set_mark_speed(speed);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list((ushort)1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Set Mark Speed time out.");
}
while (busy);
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set laser on, off delay
///
/// Laser on delay (-8000us ~ 8000us)
/// Laser off delay (2us ~ 8000us)
///
public bool Set_Laser_Delay(short laserondelay, short laseroffdelay)
{
try
{
if (!IsInitialize) return false;
if (laserondelay > 8000) throw new Exception($"Laser on delay is too high. ({laserondelay}ms)");
else if (laserondelay < -8000) throw new Exception($"Laser on delay is too low. ({laserondelay}ms)");
if (laseroffdelay > 8000) throw new Exception($"Laser off delay is too high. ({laseroffdelay}ms)");
else if (laseroffdelay < 2) throw new Exception($"Laser off delay is too high. ({laseroffdelay}ms)");
RTC4Wrap.set_start_list((ushort)1);
RTC4Wrap.set_laser_delays(laserondelay, laseroffdelay);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list((ushort)1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Set Laser Speed time out.");
}
while (busy);
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set Scanner Delay (jump, mark, ploygon)
///
/// jump delay (us)
/// mark delay (us)
/// ploygon delay (us)
///
public bool Set_Scanner_Delay(ushort jumpdelay, ushort markdelay, ushort polygondelay = 0)
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.set_start_list((ushort)1);
RTC4Wrap.set_scanner_delays(jumpdelay, markdelay, polygondelay);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list((ushort)1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Set Scanner Delay time out.");
}
while (busy);
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set start list
///
/// 1 or 2
///
public bool Set_Start_List(int list_num)
{
try
{
if (!IsInitialize) return false;
if (list_num == 1)
{
_equip.Write_Scanner_Log("Set Start List 1 Success");
RTC4Wrap.set_start_list((ushort)1);
return true;
}
else if (list_num == 2)
{
_equip.Write_Scanner_Log("Set Start List 2 Success");
RTC4Wrap.set_start_list((ushort)2);
return true;
}
else
{
throw new Exception($"list num({list_num}) is error");
}
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Set Start List Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set mark abs, please use after set start list.
///
/// x pos
/// y pos
///
public bool Set_Mark_Abs(short x, short y)
{
try
{
if (!IsInitialize) return false;
_equip.Write_Scanner_Log($"MARK : {x}, {y}");
RTC4Wrap.mark_abs(x, y);
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log($"MARK: {x}, {y} Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set jump abs, please use after set start list.
///
/// x pos
/// y pos
///
public bool Set_Jump_Abs(short x, short y)
{
try
{
if (!IsInitialize) return false;
_equip.Write_Scanner_Log($"JUMP : {x}, {y}");
RTC4Wrap.jump_abs(x, y);
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log($"JUMP : {x}, {y} Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set end of list
///
///
public bool Set_End_Of_List()
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.set_end_of_list();
_equip.Write_Scanner_Log("Set End of List Success");
return true;
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Set End of List Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Set excute list
///
/// 1 or 2
///
public bool Set_Excute_List(int list_num)
{
try
{
if (!IsInitialize) return false;
if (list_num == 1)
{
RTC4Wrap.execute_list((ushort)1);
_equip.Write_Scanner_Log("Set Excute List 1 Success");
return true;
}
else if (list_num == 2)
{
RTC4Wrap.execute_list((ushort)2);
_equip.Write_Scanner_Log("Set Excute List 2 Success");
return true;
}
else
{
throw new Exception($"list num({list_num}) is error");
}
}
catch (Exception ex)
{
_equip.Write_Scanner_Log("Set Excute List Fail");
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
public bool Set_Stop()
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.stop_execution();
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Scanner Home.
///
///
public bool Home()
{
try
{
if (!IsInitialize) return false;
RTC4Wrap.set_start_list((ushort)1);
RTC4Wrap.home_position(0, 0);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list((ushort)1);
DateTime dt = DateTime.Now;
bool busy;
do
{
Get_Busy(out busy);
if ((DateTime.Now - dt).TotalSeconds > 3)
throw new Exception("Home time out.");
}
while (busy);
return true;
}
catch (Exception ex)
{
WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Squire marking test.
///
public void Squire_Marking()
{
if (!IsInitialize) return;
bool moving;
do
{
Get_Busy(out moving);
} while (moving);
// Only, use list 1, which can hold up to 8000 entries
RTC4Wrap.set_start_list(1);
RTC4Wrap.jump_abs((short)-5044, (short)-5044);
RTC4Wrap.mark_abs((short)-5044, (short)5044);
RTC4Wrap.mark_abs((short)5044, (short)5044);
RTC4Wrap.mark_abs((short)5044, (short)-5044);
RTC4Wrap.mark_abs((short)-5044, (short)-5044);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list(1);
}
///
/// Triangle marking test.
///
public void Triangle_Marking()
{
if (!IsInitialize) return;
RTC4Wrap.set_laser_mode(0); // CO2 mode selected
RTC4Wrap.set_standby(100 * 8, // half of the standby period in 1/8 microseconds
8); // pulse width in 1/8 microseconds
// Timing, delay and speed preset
RTC4Wrap.set_start_list(1);
RTC4Wrap.set_laser_timing(100, // half of the laser signal period
50, 50, // pulse widths of signals LASER1 and LASER2
0); // time base; 0 corresponds to 1 microsecond.
// Otherwise, the time base is 1/8 microseconds.
RTC4Wrap.set_scanner_delays(25, // jump delay in 10 microseconds
10, // mark delay in 10 microseconds
5); // polygon delay in 10 microseconds
RTC4Wrap.set_laser_delays(100, // laser on delay in microseconds
100); // laser off delay in microseconds
RTC4Wrap.set_jump_speed(10); // jump speed in bits per milliseconds
RTC4Wrap.set_mark_speed(10.5); // marking speed in bits per milliseconds
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list(1);
bool moving;
do
{
Get_Busy(out moving);
} while (moving);
// Only, use list 1, which can hold up to 8000 entries
RTC4Wrap.set_start_list(1);
RTC4Wrap.jump_abs(-20000, 0);
RTC4Wrap.mark_abs(20000, 0);
RTC4Wrap.mark_abs(0, 20000);
RTC4Wrap.mark_abs(-20000, 0);
RTC4Wrap.set_end_of_list();
RTC4Wrap.execute_list(1);
}
///
/// Error message log.
///
///
string ErrorMessage(short ErrorCode)
{
switch (ErrorCode)
{
case 3:
// File not found, file demaged, and so on
return "cannot read the file.";
case 4:
// The file couldn't be read back from the RTC4
return "cannot verify the file.";
case 6:
return "odd number of bytes in the Intel hex file.";
case 7:
return "checksum error in the Intel hex file.";
case 8:
return "system driver not found. or locked by another application.";
case 9:
return "program file not complete.";
case 10:
return "parameter error.";
case 11:
return "RTC4 not found.";
case 12:
return "trying to load a 3D correction file (the 3D option is not installed).";
case 13:
// Table for the variable polygon delay not found
return "specified table not found.";
default:
return $"default error code {ErrorCode}.";
}
}
#endregion
}
}