2.5 C#视觉程序开发实例1----IO_Manager实现脉冲输出控制

2.5 C#视觉程序开发实例1----IO_Manager实现脉冲输出控制

1 目标效果视频

目标效果展示

IO_Manager

2 信号输出流程说明

为了防止线程不同步导致输出信号没有被输出, 尽量使用一个输出队列来进行输出的管理
在这里插入图片描述

3 IO_Manager中添加内容

3.0 添加两个类

1 Out_State :输出状态标志

public enum Out_State : int{State_Out = 1,// 输出状态State_Reset = 2,// 复位状态State_Wait = 0,//wait}

2 Task_Out_Server 输出管理类,实现了输出请求队列的管理

/// <summary>
/// Task_IO_Out_Server
/// </summary>
public class Task_Out_Server
{// 最大缓存 buffer个数static int max_buffer = 16;public Out_State state;public List<bool> out_requests;private int index_ok;private int index_ng;private int index_sto;private int out_pulse_width;// 输出脉冲宽度private int reset_pulse_width;// 输出复位脉冲宽度private DateTime cur_starttime;// 当前task 开始时间public object mutex;private int count_output;private int count_reset;private int count_wait;private int output_mode = 0;//0: pulse  1: 开关亮输出public int Tasks_Count{get { return out_requests.Count; }}public string Task_Info{get{return "outcount=" + count_output.ToString() + ",resetcount=" + count_reset.ToString() + ",waitcount=" + count_wait.ToString();}}public Task_Out_Server(){state = Out_State.State_Wait;out_requests = new List<bool>();index_ok = -1;index_ng = -1;index_sto = -1;out_pulse_width = 100;reset_pulse_width = 10;mutex = new object();cur_starttime = DateTime.Now;}public void init_Task(int _index_ok, int _index_ng, int _index_sto, int out_pulse, int reset_pusle){index_ok = _index_ok;index_ng = _index_ng;index_sto = _index_sto;out_pulse_width = out_pulse;reset_pulse_width = reset_pusle;count_output = count_reset = count_reset = 0;}public void Add_One_Task(bool status){lock (mutex){if (out_requests.Count < max_buffer)out_requests.Add(status);// 增加一个任务}}public void Update_Task_State(DateTime cur_time, ref bool[] outstates){if (outstates == null) return;lock (mutex){switch (state){default://waitif (out_requests.Count > 0){bool _status = out_requests[0];out_requests.RemoveAt(0);state = Out_State.State_Out;if (index_ok != -1)outstates[index_ok] = _status;if (index_ng != -1)outstates[index_ng] = !_status;if (index_sto != -1)outstates[index_sto] = true;cur_starttime = cur_time;count_output++;}break;case Out_State.State_Out:// 输出if (cur_time.Subtract(cur_starttime).TotalMilliseconds >= out_pulse_width){//sto 复位if (index_sto != -1)outstates[index_sto] = false; if (output_mode == 0)// pulse输出{if (index_ok != -1)outstates[index_ok] = false;if (index_ng != -1)outstates[index_ng] = false;}state = Out_State.State_Reset;count_reset++;}break;case Out_State.State_Reset://resetif (cur_time.Subtract(cur_starttime).TotalMilliseconds >= out_pulse_width + reset_pulse_width){state = Out_State.State_Wait;count_wait++;}break;}}}
}
3.1 增加代码 初始化Task_Out_Server

增加Task_Out_Server 实例

#region  Task_IO_Server 用来管理STO|OK|NG 输出public Task_Out_Server task_out_server_thread0 =new Task_Out_Server();private int pulse_width = 300;// 脉冲输出时长private int pulse_reset_width = 100;// 脉冲复位时长#endregion

IO_Manager()初始化函数中增加Init_Task()
目的: 绑定输出STO|OK|NG pin角,然后脉冲输出宽度和复位宽度

//初始化 task_out_server_thread0,
task_out_server_thread0.init_Task(index_ok,index_ng,index_sto, pulse_width, pulse_reset_width);
3.2 Write()函数更新

//更新STO |OK|NG输出 status
task_out_server_thread0.Update_Task_State(cur,ref Outputs);

public int Write()
{int nRet = 0;DateTime cur = DateTime.Now;try{// DM8  WritePInvoker.SetDM8(array_dm8_out, count_DM8, count_DM8);for (int i = 0; i < count_DM8; i++){if (Outputs[i]) array_dm8_out[i] = 1;else array_dm8_out[i] = 0;} //更新STO |OK|NG输出 statustask_out_server_thread0.Update_Task_State(cur,ref Outputs);GC.KeepAlive(array_dm8_out);}catch (Exception ex){nRet = -2;}return nRet;
}

4 Form_vision中增加代码

4.1 添加一个线程统计的类

实现线程结果的统计,和保存

/// <summary>
/// thread_statistics
/// 线程结果统计
/// </summary>
public class Thread_Statistics
{public int count_ok;//当前线程ok 计数public int count_ng;//当前线程ng 计数public int count_total;//当前线程Total 计数public bool status;// 当前线程状态public Thread_Statistics(){count_ok = 0; count_ng = 0; count_total = 0;status = true;}public void Reset(){count_ok = 0; count_ng = 0; count_total = 0;status = true;}public string  toString(){string str = "";str = "总数:" + count_total.ToString() + ",OK:" + count_ok.ToString() + ",NG:" + count_ng.ToString();return str; }/// <summary>/// Update_Statistics/// </summary>/// <param name="status"></param>public void  Update_Statistics(bool status){if (status) count_ok += 1;else count_ng += 1;count_total += 1;}
}
4.2 mgAcqRunCCD0 中增加采集事件

触发事件发生后,通知Img_Process现成, newImgEvent_thread.Set()

// 通过判断上升沿进行 相机采集n_trig0_cur =Convert.ToInt32( ContextManager.get_IOCtx().get_Trig0());if (n_trig0_cur > 0 && n_trig0_last == 0)  //判断上升沿触发{//相机采集int nRet = 0; if(nRet==0){newImgEvent_thread.Set();}}
4.3 Img_Process线程增加相应的功能代码

1.Create_Thread()中 创建线程 ImgProcess

//创建ImgProcess 现成0
threadProcessCCD=new Task(() => ImgProcessCCD(), TaskCreationOptions.LongRunning);threadProcessCCD.Start();
  1. ImgProcessCCD(int n_thread_index = 0) 函数增加统计代码
// 添加线程统计信息thead0_summary.Update_Statistics(status);
  1. ImgProcessCCD(int n_thread_index = 0) 函数增加显示统计结果
bdDisplay_Runsets1.Update_Cam_Text(status, thead0_summary.toString());
  1. ImgProcessCCD(int n_thread_index = 0) 函数增加输出STO|OK|NG
// 输出脉冲     
ContextManager.get_IOCtx().task_out_server_thread0.Add_One_Task(status);

ImgProcessCCD()汇总

private void ImgProcessCCD(int n_thread_index = 0)
{ListViewItem DATA = new ListViewItem();DateTime ts3 = DateTime.Now; bool[] flag = new bool[100];  DateTime current = DateTime.Now;bool status = true;while ( newImgEvent_thread.WaitOne())   //相机1&2都已经已拍照{// 添加线程统计信息thead0_summary.Update_Statistics(status);bdDisplay_Runsets1.Update_Cam_Text(status, thead0_summary.toString());// 输出脉冲ContextManager.get_IOCtx().task_out_server_thread0.Add_One_Task(status);// img  process if (StopProgramEvent.WaitOne(0, true)) break;} //end while return;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VSCode推荐插件:Copy Class Name快速复制html中的类名

插件地址&#xff1a;https://marketplace.visualstudio.com/items?itemNamemouday.copy-class-name 复制Vue和React中HTML代码的类名&#xff0c;实现快速复制 使用方式&#xff1a; 选中代码&#xff0c;右键复制类名&#xff0c;再粘贴到文件中即可 示例 <div clas…

Flink SQL kafka连接器

版本说明 Flink和kafka的版本号有一定的匹配关系&#xff0c;操作成功的版本&#xff1a; Flink1.17.1kafka_2.12-3.3.1 添加kafka连接器依赖 将flink-sql-connector-kafka-1.17.1.jar上传到flink的lib目录下 下载flink-sql-connector-kafka连接器jar包 https://mvnreposi…

最新整理的机器人相关数据合集(1993-2022年不等 具体看数据类型)

机器人安装数据是指记录全球或特定区域内工业机器人新安装数量的信息&#xff0c;这一数据由国际机器人联合会(IFR)等权威机构定期发布。这些数据不仅揭示了机器人技术的市场需求趋势&#xff0c;还反映了各国和地区自动化水平及产业升级的步伐。例如&#xff0c;数据显示中国在…

数据库测试|Elasticsearch和ClickHouse的对决

前言 数据库作为产品架构的重要组成部分&#xff0c;一直是技术人员做产品选型的考虑因素之一。 ClkLog会经常遇到小伙伴问支持兼容哪几种数据库&#xff1f;为什么是选择ClickHouse而不是这个或那个。 由于目前市场上主流的数据库有许多&#xff0c;这次我们选择其中一个比较典…

深度学习3 基于规则的决策树模型

1.决策树是一种归纳学习算法&#xff0c;从一些没有规则、没有顺序、杂乱无章的数据中&#xff0c;推理出决 策模型。不管是什么算法的决策树&#xff0c;都是一种对实例进行分类的树形结构。决策树有三个要素&#xff1a;节点(Node)、分支(Branches)和结果(Leaf)。 训练决策树…

算法010:无重复字符的最长子串

无重复字符的最长子串. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/longest-substring-without-repeating-characters/ 使用的算法&#xff1a;滑动窗口 在这个…

干货 | 2024大模型增强下的图智能在金融场景的应用(免费下载)

如需下载本方案PPT/WORD原格式&#xff0c;诚挚邀请您微信扫描以下二维码加入方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&#xff01;&#xff01;&#xff01;感谢支持&#xff01;&#xff01;&#xff01;

SSM高校教师教学质量评估系统-计算机毕业设计源码03344

摘要 在高等教育中&#xff0c;教学质量是培养优秀人才的关键。为了提高教学质量&#xff0c;高校需要建立一套科学、有效的教师教学质量评估系统。本研究采用 SSM技术框架&#xff0c;旨在开发一款高校教师教学质量评估系统。 SSM框架作为一种成熟的Java开发框架&#xff0c;具…

Mysql5.7并发插入死锁问题

死锁的产生条件 互斥、请求和保持、不可剥夺、循环等待 MySQL锁类型 死锁复现 环境&#xff1a;Mysql 5.7版本&#xff0c;Innodb引擎&#xff0c;可重复度隔离级别 并发场景下使用duplicate key update插入或更新数据可能会造成死锁&#xff0c;下面就产生死锁的条件进行模…

七大排序-冒泡排序,插入排序,希尔排序(一)

目录 排序冒泡排序插入排序冒泡排序和插入排序的对比希尔排序 排序 先写单趟&#xff0c;再写多趟&#xff0c;这样比较好写 排序可以理解为对商品价格的排序&#xff0c;对数字大小的排序&#xff0c;排序再生活中随处可见 冒泡排序 冒泡排序就是两个相邻的数交换&#xff…

GD32 MCU ADC采样率如何计算?

大家在使用ADC采样的时候是否计算过ADC的采样率&#xff0c;这个问题非常关键&#xff01; 以下为GD32F303系列MCU中有关ADC的参数&#xff0c;其中ADC时钟最大值为40MHz&#xff0c;12位分辨率下最大采样率为2.86MSPS.如果ADC时钟超频的话&#xff0c;可能会造成ADC采样异常&…

工作两年后,我如何看待设计模式

在软件工程中&#xff0c;设计模式是经过反复验证的最佳实践&#xff0c;用于解决在软件设计中经常遇到的一类问题。它们为开发者提供了一种通用的解决方案和语言&#xff0c;使得复杂的编程问题得以简化&#xff0c;代码结构更加清晰&#xff0c;可维护性大大提高。简而言之&a…

阶段三:项目开发---大数据开发运行环境搭建:任务6:安装配置HBase

任务描述 知识点&#xff1a;安装配置HBase 重 点&#xff1a; 安装配置HBase 难 点&#xff1a;无 内 容&#xff1a; 本阶段任务是安装配置HBase&#xff0c;实时飞行数据是保存在HBase中的&#xff0c;因为HBase具有高效的读写能力&#xff0c;在当前项目中我们是…

矢量绘图设计Sketch中文 Sketch直装安装包

Sketch是一款专为UI设计师和UX专家打造的矢量图形设计软件&#xff0c;以其简洁的界面、强大的功能和高效的协作能力而闻名。Sketch支持快速创建高质量的UI界面、图标、图形和插画&#xff0c;其矢量绘图工具让设计细节更加精准。同时&#xff0c;Sketch内置丰富的插件和组件库…

基于vue的3D高德地图的引入

在引入高德地图的时候需要先注册一个账号 登录下面的网站 账号认证 | 高德控制台 (amap.com) 打开首页应用管理&#xff0c;我的应用 创建新的应用 根据自己的需求进行选择 创建完成之后&#xff0c;点击添加key 不同的服务平台对应不同的可使用服务&#xff0c;选择自己适…

LeetCode刷题之HOT100之完全平方数

2024 7/7 转眼间就到周日啦&#xff01;昨天下午开组会&#xff0c;开了三个半小时。如坐针毡&#xff0c;会后跑了个步、洗了个澡、洗了衣服、躺床上看了会《罪与罚》&#xff0c;睡着了。早上起来&#xff0c;去拿我昨晚充电的车&#xff0c;当我看到车没有停在昨天的位置&am…

《算法笔记》总结No.3——排序

基础算法之一&#xff0c;相当重要。在普通的机试中如果没有数据类型和时空限制&#xff0c;基本上选择自己最熟悉的就好。本篇只总结选择排序和插入排序&#xff0c;侧重应用&#xff0c;408中要求的种类更加繁多&#xff0c;此处先不扩展难度~总结最常用的两种排序。 一.选择…

14-24 剑和侠客 – 预训练模型三部曲1 - 文本

在这个三部曲中&#xff0c;我们旨在从三个部分深入研究预训练模型&#xff1a;文本、图像和机器人。 我们旨在探索它们的概念、出现以及这些模型的工作原理。还将研究预训练模型的不同架构和类型。 探索哪些是最强大的&#xff0c;以及预训练模型和 Transformers 是否是 LLM…

常用SQL语句(基础篇)

前言 查询的sql的结构是 select...from...where...group by...having...order by...limit... 写查询sql的时候需要按照如下顺序写 from&#xff0c;where&#xff08;and&#xff0c;or&#xff0c;&#xff01;&#xff09;&#xff0c;group by&#xff0c;select&#xf…

文章解读与仿真程序复现思路——太阳能学报EI\CSCD\北大核心《计及电-热-氢负荷与动态重构的主动配电网优化调度》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…