在 SerialDevice 插件中添加相机增益和光照自动控制功能
以下为实现方式
首先定义串口设备抽象类 ,为该类设置基本属性和构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class SerialDevice { public SerialPort serialPort; public ModbusSerialMaster master; public string portname; public int baunrate; public int databits = 8 ; public Parity parity = Parity.None; public StopBits stopbits = StopBits.One; public string DeviceName; public SerialDevice () { serialPort = new SerialPort(); serialPort.DataBits = databits; serialPort.Parity = parity; serialPort.StopBits = stopbits; } public void close () { serialPort.Close(); } public void open () { if (!serialPort.IsOpen) { serialPort.Open(); } } }
然后继承这个设备抽象类,定义相机控制类 和灯光控制类
1 2 3 4 5 class CameraController : SerialDevice {...}class LightController : SerialDevice {...}
灯光控制类中,加入灯光控制相关指令和操作
相机控制类中,加入相机控制相关串口指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public LightController (string PortName, int Baunrate=38400 ) : base (){ portname = PortName; baunrate = Baunrate; serialPort.PortName = portname; serialPort.BaudRate = baunrate; serialPort.Close(); } public void Intensity (byte port,int intensity ){ ...; } void sendCmd (byte command, byte port, int value ) { ...; } void Check_Dell (ref byte [] buffer ) { ...; }
在 Plugin.cs 中添加 AutoGain 类,并且继承 IPlugin 接口,提供相关接口实现,设置其为周期执行 ,并且执行周期为 5s,周期事件为根据当前图像平均灰度值调节灯光亮度和相机增益。其设置子对象 灯光控制器 light 和相机控制器 camera 并初始化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class AutoGain :IPlugin { ...; public string Name { get { return "自动相机增益和灯光调整插件" ; } } ...; public bool IsLoop { get { return true ; } } public int Interval { get { return 5 ; } } LightController light; CameraController camera; public bool CameraAutoGain = true ; public bool LightAutoAdjust = true ; int Min_threshold_mean = 130 ; int Max_threshold_mean = 170 ; int Min_adjust_mean = 140 ; int Max_adjust_mean = 160 ; int Light_adjust_stride = 4 ; double Camera_adjust_stride = 0.2 ; double gain = 0.5 ; int intensity = 125 ; double mean = 0 ; public EvtHanlder hanlder { get { EvtHanlder h = new EvtHanlder(); h.DefectFoundEvent += DefectFoundHandler; return h; } } }
在 Attributes 列表中添加相应的控制参数,供外部修改相关参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public void Init (Control control = null ){ ...; camera = new CameraController(); light = new LightController("COM3" ); Attributes = new Dictionary<string , object >(); Attributes.Add("Camera" , camera); Attributes.Add("Light" , light); Attributes.Add("Light.COM" , light.serialPort.PortName); Attributes.Add("Light.intensity" , intensity); Attributes.Add("Camera.gain" , gain); Attributes.Add("CameraAutoGain" , CameraAutoGain); Attributes.Add("LightAutoAdjust" , LightAutoAdjust); }
在 AutoGain 类中添加函数,根据当前暂存的平均灰度值调节灯光和相机增益。
1 2 3 4 5 public void AutoGainMain (double mean ){ ...; }
在全局事件定义中添加检测到瑕疵的事件,在主程序流程中添加相应事件触发器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public delegate void DefectFoundHandler (object sender, CustomEventArgs Args ) ;public class EvtHanlder { ...; public event DefectFoundHandler DefectFoundEvent; public void Trigger (object sender, CustomEventArgs Args ) { ...; switch (e) { ...; case CustomEvent.DefectFoundEvent: DefectFoundEvent(sender, Args); break ; ...; } } public EvtHanlder () { ...; DefectFoundEvent += new DefectFoundHandler((object sender, CustomEventArgs Args) => { }); } }
在插件 AutoGain 类中添加事件响应函数,绑定函数实现更新当前平均灰度值,供自动调节过程使用。
1 2 3 4 5 public void DefectFoundHandler (object sender, CustomEventArgs Args ) { mean = (double )PluginToolkits.GetValue(Args.msg, "Mean" ); }
最后添加周期调用函数实现
1 2 3 4 5 6 7 8 9 10 11 public void RunLoop (){ if (camera == null ) return ; if (light == null ) return ; if (mean != 0 ) { Task.Run(() => { AutoGainMain(mean); }); } }
OK,这样就完成了整个功能插件的实现,编译并将插件放入 plugin 目录应该就能实现自动加载和执行了。
未解决的问题:判断对应设备的串口号并连接。
目前没有相应硬件设备,上机调试的问题后续更新。