实战课思路总结

一、串口通信dmo实现

思路:
首先需要实例化一个SerialPort  对象,
对串口数据进行初始化,写成一个方法
listBox.DataSource = 数组  (有items属性的组件都可以用数组添加数据源)

串口号初始化:SerialPort.GetPortNames(), 字符串数组
波特率初始化:1200, 2400, 4800, 9600, 115200,  整数数组
数据位初始化:6,7,8,  整数数组
校验位初始化:Enum.GetNames(typeof(Parity)),  字符串数组
停止位初始化:Enum.GetNames(typeof(StopBits))  字符串数组

串口通信步骤:配置串口--打开串口--发送数据--接收数据
1、配置串口:c#自带串口类 SerialPort  sp
              
sp.PortName=  str    配置串口号
              
sp.BaudRate=  int     配置波特率
              
sp.DataBits= int        配置数据位
              
sp.Parity=(Parity)Enum.Parse(typeof(Parity), str)     配置校验位
              
sp.StopBits= (StopBits)Enum.Parse(typeof(StopBits),str)    配置停止位
2、打开关闭串口
                        
sp.Open()         打开串口
                        
sp.Close()        关闭串口
3、发送数据(
发送的是字节数组,每个元素两个数  byte[]={01 03 00 00 00 03 05 CB})
                       
 sp.Write()        发送数据
        先进行数据验证(打开串口才能发送,不能发送为空)
        if (textBox.Text.Length==0)
            {
                MessageBox.Show("发送不能为空 ");
                return;
            }
        字符串发送:
将字符串值转字节数组发送
                byte[] sendBuffer = Encoding.Default.GetBytes(str);
                sp.Write(sendBuffer, 0, sendBuffer.Length);
        16进制发送:
将16进制写法字符串值两两分割,转十进制字节数组发送,写成一个方法
                 public byte[] HexStrToByteArray(string hexStr)
                {
                    hexStr = hexStr.Replace(" ", "");  //将字符串的空值替换
                    hexStr = hexStr.Replace("0x", "");  //将字符串的字母替换
                    hexStr = hexStr.Replace("0X", "");
                    byte[] buffer = new byte[hexStr.Length/2];  //两个数一个字节,数组长度减半
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        buffer[i] = Convert.ToByte(hexStr.Substring(i*2,2),16);  //转16位(两个字节)无符号整数
                    }
                    return buffer;
                }

4、开一个子线程循环接收数据(接收字节数组,byte[]={01 03 00 00 00 03 05 CB}

                port.Read()  接收数据
        先创建一个字节数组来存放缓存区数据
        byte[] bys = new byte[lenth];   
新字节长度必须要跟缓存区字节数一致
        int lenth = port.BytesToRead;  //缓存区实际字节数
        port.Read(bys, 0, bys.Length);  //从缓冲区读取数据存入数组
        区分字符串接收和16进制接收
        字符串接收:
将字节数组转字符串值接收显示
         
string str = Encoding.Default.GetString(bys);
        16进制接收:
将接收的十进制字节数组转16进制字符串显示,写一个方法
        public string ByteArrayToHexStr(byte[] buffer)
        {
            string hexStr = "";
            for (int i = 0; i < buffer.Length; i++)
            {
                hexStr+= buffer[i].ToString("X2");
            }
            return hexStr;
        }

子窗体报文解析(接收到数据后直接做报文解析)---显示温度、湿度
用一个类装温度、湿度以及其他参数字段
ModbusRTU协议

读取温湿度值: 01 03 00 00 00 02 c4 0b
发送:按16进制发送(发送区写成16进制发送),(转十进制)发送过去十进制字节值数组  [1,3,0,0,0,2,196,11]
返回值:01 03 04 02 c8 01 0D BA 20
返回数据:返回十进制值,报文解析就需要这个十进制字节值,实际字节数组[1,3,4,2,200,1,13,186,32],转16进制显示后就是  01 03 04 02 c8 01 0D BA 20

(02 c8 为湿度值十六进制转十进制除以十得 71.2,01 0D 为温度值 26.9 )
只要四个字节数值,写一个截取子字节数组的方法
 public byte[]GetChildArrayBytes(byte[]buffer,int indexStart,int len)   参数分别是原始数组、开始截取索引、截取长度
        {
            byte[] childBytes = new byte[len];
            for (int i = 0; i < len; i++)
            {
                //01 03 04 02 c8 01 0D BA 20
                childBytes[i] = buffer[indexStart + i];
            }
            return childBytes;
        }
报文解析先获取数值,再转十进制求数值
                byte[]chidlBytes=GetChildArrayBytes(bufferRec, 3, 4);    //02 c8 01 0D
                Array.Reverse(chidlBytes);    //02 c8 01 0D-->0D 01 c8 02
                short temperature=BitConverter.ToInt16(chidlBytes, 0); // 温度 0D 01
                short humidity = BitConverter.ToInt16(chidlBytes,2);// 湿度 c8 02
                sensorData.temprature = temperature / 10.0;//温度值-浮点型
                sensorData.humidity = humidity / 10.0;//湿度值--浮点型

BitConverter.ToInt16(Bytes, 0)    反着转换的,要先反转数组
BitConverter--将字节数组转换为基数
ToInt16(Bytes, 0)---从数组索引0开始返回16位(2个字节)有符号整数

二、SDK---软件开发包(工程要用X64保存)

C#调用halcon的sdk

1、找dll库和C++库放入C#bin文件夹下       D:\haclon安装\bin\dotnet35\halcondotnet.dll      D:\haclon安装\bin\x64-win64
2、添加引用      halcondotnet.dll
3、添加命名空间      using HalconDotNet;
*在halcon里写好代码,导出C#文件

*采图
用halcon的显示图像组件,组件页面右键--选择项,添加D:\haclon安装\bin\dotnet35\halcondotnet.dll   
//打开文件夹选择图片
OpenFileDialog ofd = new OpenFileDialog();
            ofd.FileName = "图片名";    //选择的图片名
            ofd.InitialDirectory = @"D:\";
            //ofd.Filter = "所有文件(*.*)|*.*";
            ofd.Filter = "图片文件 (*.jpg; *.jpeg; *.png; *.gif; *.bmp;*.tif)|*.jpg; *.jpeg; *.png; *.gif; *.bmp;*.tif";
            ofd.ShowDialog();
            if (ofd.FileName=="")
            {
                return;
            }
HOperatorSet.ReadImage(out ho_Image, ofd.FileName);   // 采集图像
显示
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);  //获得图片大小
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, hv_Height-1, hv_Width-1);  //设置图片大小(注意句柄)
HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);   //显示图像(注意句柄)

*镜像
HOperatorSet.MirrorImage(ho_Image, out ho_ImageMirror, "column");  //镜像
//显示
HOperatorSet.GetImageSize(ho_ImageMirror, out hv_Width, out hv_Height);  //获得图片大小
HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, hv_Height, hv_Width);  //设置图片大小
HOperatorSet.DispObj(ho_ImageMirror, hWindowControl1.HalconWindow);  //显示

C#调用迈德威视dll库

1、找dll库(sdk文件夹)
2、看demo例程 (demo文件夹下c#例程)
3、建工程
拷贝dll库-----把找到的dll库文件拷贝到C#工程文件下bin\X64\debug下
添加引用-----一般不可以直接添加,要找一个.cs文件,在demo文件夹下,添加这个即可
添加命名空间
调用----分4步
        1、枚举设备---搜索enum
        2、初始化(init)---一般是枚举下面的判断
             绑定控件(绑定显示图像的控件名)--- 搜索(init)把初始化代码复制过来,控件的句柄、宽高替换自己的控件
        3、注册回调函数---跟初始化在一个判断里面(有可能被注释,在命名空间外面写一个命令#define USE_CALL_BACK 解除)
        回调函数定义:一个方法,从demo抄过来(方法体内容不用写过来)
        显示预览---写在回调函数方法体里面,图像buffer改成方法传进来的值
        4、开始采集
这时开始出图,如果图片颜色不对,可以增加处理
1、处理写在回调函数方法体里面,处理完后图像buffer改成处理完后的值
2、处理完后的图像需要开辟内存来存,申请内存(相机特性描述)写在初始化方法里面

如果要对图片进行处理,就要把图片转为HObject类型变量显示,然后用halcon的显示方法,获得图片大小,设置图片大小,显示
要把原有绑定的显示控件注释掉,新开一个halcon显示窗口

HOperatorSet.OpenWindow(0, 0, pictureBox1.Width, pictureBox1.Height, pictureBox1.Handle, "visible", "", out hv_WindowHandle);
HDevWindowStack.Push(hv_WindowHandle);


//图片转为HObject类型固定写法
          int bytesByLineRGB= (pFrameHead.iWidth*3+3)/ 4 * 4;//彩色图像每行所占字节数 4 的倍数
          int bytesByLineGray = (pFrameHead.iWidth + 3) / 4 * 4;//灰度图像每行所占字节数 4 的倍数
            byte[] bufferRGB = new byte[bytesByLineRGB* pFrameHead.iHeight];
            byte[] bufferR = new byte[bytesByLineGray * pFrameHead.iHeight];
            byte[] bufferG = new byte[bytesByLineGray * pFrameHead.iHeight];
            byte[] bufferB = new byte[bytesByLineGray * pFrameHead.iHeight];
            byte[] bufferGray = new byte[bytesByLineGray * pFrameHead.iHeight];
            Marshal.Copy(m_ImageBuffer, bufferRGB, 0, bytesByLineRGB * pFrameHead.iHeight); //拷贝原图像字节(
m_ImageBuffer是原图)注意顺序是BGR
            for (int i = 0; i < pFrameHead.iHeight; i++)
            {
                for (int j = 0; j < pFrameHead.iWidth; j++)
                {
                    bufferB[i * bytesByLineGray + j] = bufferRGB[i * bytesByLineRGB + j * 3 + 0];//B分量
                    bufferG[i * bytesByLineGray + j] = bufferRGB[i * bytesByLineRGB + j * 3 + 1];//G分量
                    bufferR[i * bytesByLineGray + j] = bufferRGB[i * bytesByLineRGB + j * 3 + 2];//R分量
                    bufferGray[i * bytesByLineGray + j] =(byte)( 0.11 * bufferR[i * bytesByLineGray + j] + 0.5 * bufferG[i * bytesByLineGray + j] + 0.11 * bufferB[i * bytesByLineGray + j]);
                }
            }


指针操作--需要在项目配置里打开允许危险代码
halcon对应代码是
使用存储管理从像素上的三个指针创建一个三通道图像

gen_image3_extern (Image, 'byte', 512, 512, r, g,b , 0)    
输出图像   图像类型   原图宽   高   R分量   G分量   B分量   内存
unsafe//允许操作指针 
            {
                fixed (byte* r = bufferR,g=bufferG,b=bufferB)//使得内存固定 ---
彩色
                {
                    HOperatorSet.GenImage3Extern(out ho_BImageBGR1, "byte", pFrameHead.iWidth, pFrameHead.iHeight, new IntPtr(r), new IntPtr(g), new IntPtr(b), 0);

                }
            }
fixed (byte* gray = bufferGray)//使得内存固定   ---黑白
                {
                    HOperatorSet.GenImage1Extern(out ho_Image, "byte", pFrameHead.iWidth, pFrameHead.iHeight, new IntPtr(gray), 0);
                }

//显示
HOperatorSet.GetImageSize(ho_BImageBGR1, out hv_Width, out hv_Height);  //获得图片大小
            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height - 1, hv_Width - 1);  //设置图片
            }

            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.DispObj(ho_BImageBGR1, HDevWindowStack.GetActive());  //显示
            }

主动抓取
1、找dll库(sdk文件夹)
2、看demo例程 (demo文件夹下c#例程)
3、建工程
拷贝dll库-----把找到的dll库文件拷贝到C#工程文件下bin\X64\debug下
添加引用-----一般不可以直接添加,要找一个.cs文件,在demo文件夹下,添加这个到bin文件夹下即可
添加命名空间
调用----分4步
        1、枚举设备---搜索enum
        2、初始化(init)---一般是枚举下面的判断
        3、图像需要处理,申请内存(相机特性描述)写在初始化方法里面
        4、主动抓取--开线程
                Task.Factory.StartNew(Grab);
        5、开始采集
                MvApi.CameraPlay(m_hCamera);
        新开线程写成方法Grab(循环抓取)
        延时--图像处理--显示(halcon显示)--释放
        6、想加按钮控制采图暂停,只需在对应按钮点击事件调用暂停代码
        MvApi.CameraPause(m_hCamera);
        7、想添加设置参数
        在初始化配置一下--让SDK来根据相机的型号动态创建该相机的配置窗口
        然后在对应的按钮事件复制代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Flask论坛实战知了传是一门实践性很强的程,旨在帮助学生学习和掌握使用Flask框架开发一个完整、功能完备的论坛应用。 Flask是一个轻量级的Python Web框架,开发人员可以快速构建Web应用程序。知了传采用实战教学的方式,通过一系列的案例和项目,引导学生逐步了解和掌握Flask框架的使用。 在这门程中,学生将学习到如何创建一个Flask应用,包括如何设置路由、处理数据请求和响应、使用模板引擎渲染页面等。同时,学生还将学习到如何处理用户认证和授权、实现用户发表文章和评论、上传图片等功能。 这门程不仅仅注重理论知识的传授,更注重实践操作和项目的实现。学生将通过跟随案例和项目的指导,动手实现一个完整的论坛应用。通过实际操作,他们将了解到如何从零开始搭建一个Flask应用,以及如何解决在开发过程中遇到的各种问题。 此外,这门程还会介绍一些Flask扩展和工具,如数据库ORM框架SQLAlchemy、表单扩展WTForms、测试框架unittest等。学生将学习到如何使用这些工具来提高开发效率和代码质量。 总之,通过Flask论坛实战知了传,学生将能够掌握Flask框架的使用,了解Web应用开发的基本知识,同时也会提升自己的编码能力和项目实践经验。无论是对于想要从事Web开发的初学者,还是对于已有一定开发经验的人来说,这门程都是相当有价值的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值