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.rhkb.cn/news/373837.html

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

相关文章

idea中打开静态网页端口是63342而不是8080

问题&#xff1a; 安装了tomcat 并且也配置了环境&#xff0c;但是在tomcat下运行&#xff0c;总是在63342下面显示。这也就意味着&#xff0c;并没有运行到tomcat环境下。 找了好几个教程&#xff08;中间还去学习了maven&#xff0c;因为跟的教程里面&#xff0c;没有maven,但…

C++ STL IO流介绍

目录 一&#xff1a;IO流的继承关系&#xff1a; 二&#xff1a;输入输出功能 1. 基本用法 2. 格式化输入 3.非格式化输入 4. 格式化输出 三&#xff1a;流 1. 字符流 2. 向字符流中写入数据 3. 从字符流中读出数据 4. 清空字符流 5.完整的例子 四&#xff1a;文件…

php快速入门

前言 php是一门脚本语言&#xff0c;可以访问服务器&#xff0c;对数据库增删查改&#xff08;后台/后端语言&#xff09; 后台语言&#xff1a;php&#xff0c;java&#xff0c;c&#xff0c;c&#xff0c;python等等 注意&#xff1a;php是操作服务器&#xff0c;不能直接在…

数据结构(3.8)——栈的应用

栈在括号匹配中的应用 流程图 代码 #include <stdio.h> #include <stdlib.h> #define MaxSize 10typedef struct {char data[MaxSize];int top; } SqStack;// 初始化栈 void InitStack(SqStack* S) {S->top -1; // 初始化栈顶指针 }// 判空 bool StackEmpty(…

设计模式探索:观察者模式

1. 观察者模式 1.1 什么是观察者模式 观察者模式用于建立一种对象与对象之间的依赖关系&#xff0c;当一个对象发生改变时将自动通知其他对象&#xff0c;其他对象会相应地作出反应。 在观察者模式中有如下角色&#xff1a; Subject&#xff08;抽象主题/被观察者&#xf…

C++第四弹 -- 类与对象(中上) (构造函数 析构函数 拷贝构造函数)

目录 前言构造函数1. 概念2. 特征 析构函数1. 概念2. 特征 拷贝构造函数1. 概念2. 特征 总结 前言 让我们一起揭开 C 对象生命周期管理的神秘面纱&#xff0c;掌握构造函数、析构函数和拷贝构造函数的精髓&#xff01; 博客主页: 酷酷学!!! 期待更多好文, 点击关注~ 构造函…

【Neo4j】实战 (数据库技术丛书)学习笔记

Neo4j实战 (数据库技术丛书) 第1章演示了应用Neo4j作为图形数据库对改进性能和扩展性的可能性, 也讨论了对图形建模的数据如何正好适应于Neo4j数据模型,现在到了该动 手实践的时间了。第一章 概述 Neo4j将数据作为顶点和边存储(或者用Neo4j术语,节点和关系存 储)。用户被定…

外卖商城平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;骑手管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;订单信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&#…

深入了解java锁升级可以应对各种疑难问题

对于java锁升级&#xff0c;很多人都停留在比较浅层的表面理解&#xff0c;一定程度下也许够用&#xff0c;但如果学习其中的细节&#xff0c;我们更好地理解多线程并发时各种疑难问题的应对方式&#xff01; 因此我将锁升级过程中可能涉及的大部分细节或者疑问都整合成了一篇…

后端之路——文件本地上传

一、基础原理 文件上传是一个很基础的知识点&#xff0c;尤其是本地上传&#xff0c;在现实开发基本都是云上传&#xff0c;但是作为一个基础要简单了解一下 首先前端我就不多讲解了&#xff0c;网页开发里用<form>表单可以上传文件&#xff0c;只需要加上这三属性&…

防火墙基础实验配置

一&#xff0c;实验拓扑 二&#xff0c;实验需求&#xff1a; 1.DMZ区内的服务器&#xff0c;办公区仅能在办公时间内&#xff08;9&#xff1a;00 - 18&#xff1a;00&#xff09;可以访问&#xff0c;生产区的设备全天可以访问 2.生产区不允许访问互联网&#xff0c;办公区…

如何批量更改很多个文件夹里的文件名中包含文件夹名?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

共生与变革:AI在开发者世界的角色深度剖析

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是遥不可及的概念&#xff0c;而是逐步渗透到我们工作与生活的每一个角落。对于开发者这一群体而言&#xff0c;AI的崛起既带来了前所未有的机遇&#xff0c;也引发了关于其角色定位的深刻讨论——AI…

STM32-Unix时间戳和BKP备份寄存器以及RTC实时时钟

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. Unix时间戳1.1 Unix时间戳简介1.2 UTC/GMT1.3 时间戳转换 2. BKP备份寄存器2.1 BKP简介2.2 BKP基本结构2.3 BKP库函数 3. RTC实时时钟3.1 RTC简介3.2 RTC框图3.3 RTC基本结构3.4 硬件电路3.5 RTC操作注意事项3.6 R…

修改服务器挂载目录

由于我们的项目通常需要挂载一个大容量的数据盘来存储文件数据&#xff0c;所以我们每台服务器都需要一个默认的挂载目录来存放这些数据&#xff0c;但是由于我们的误操作&#xff0c;导致挂载目录名字建错了&#xff0c;这时候后端就读不到挂载目录了&#xff0c;那我们我们的…

在mysql中delete和truncated的相同点和区别点

相同点 删除数据&#xff1a;两者都会删除表中的数据。影响数据&#xff1a;两者都不删除表结构&#xff0c;只影响表中的数据。 区别点 操作方式&#xff1a; DELETE&#xff1a;逐行删除数据&#xff0c;可以使用 WHERE 子句来指定删除的条件。如果不加 WHERE 子句&#…

NI 5G大规模MIMO测试台:将理论变为现实

目录 概览引言MIMO原型验证系统MIMO原型验证系统硬件LabVIEW通信系统设计套件&#xff08;简称LabVIEW Communications&#xff09;CPU开发代码FPGA代码开发硬件和软件紧密集成 LabVIEW Communications MIMO应用框架MIMO应用框架特性单用户MIMO和多用户MIMO基站和移动站天线数量…

Hive 高可用分布式部署详细步骤

目录 系统版本说明 hive安装包下载及解压 上传mysql-connector-java的jar包 配置环境变量 进入conf配置文件中&#xff0c;将文件重命名 在hadoop集群上创建文件夹 创建本地目录 修改hive-site.xml文件 同步到其他的节点服务器 修改node02中的配置 hive-site.xml 修改…

如何在多个服务器上安装WordPress分布式部署

许多网络主机现在保证其服务的正常运行时间为 99.9%&#xff0c;但这仍然每年最多有 8.7 小时的停机时间。 许多公司不能够承担这种风险。例如。在超级碗比赛中失败的体育新闻网站可能会失去忠实的追随者。 我们通过设置维护高可用性 WordPress分布式部署配置来帮助 WordPres…

C基础day8

一、思维导图 二、课后习题 #include<myhead.h> #define Max_Stu 100 //函数声明 //学生信息录入函数 void Enter_stu(int *Num_Stu,char Stu_name[][50],int Stu_score[]); //查看学生信息 void Print_stu(int Num_Stu,char Stu_name[][50],int Stu_score[]); //求出成绩…