项目场景:
Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。
Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩展性等特点。
工业视觉检测中有时需要使用相机的ForceIP功能,相机使用Force IP可以临时改变相机的IP地址,仅对本次使用有效,当相机掉电重启后会恢复原来的IP,但是这种功能的使用可以是的使得软件设计流程变的更加容易。
技术背景
相机的强制IP地址是指为网络上的相机配置一个固定或静态的IP地址,而不是使用由DHCP服务器分配的动态IP地址。
这可以确保相机总是可以用一个特定的IP地址被访问和识别,从而更容易管理和控制网络上的相机。它通常被推荐用于安全相机和其他在网络中具有固定位置的联网设备。
为了避免相机之间的IP冲突,网络上的每台相机必须有一个唯一的IP地址。
以下是设置IP地址的一些步骤。
1. 确定相机网络所使用的IP地址范围。
2. 选择一个在该范围之外的IP地址。
3. 为每台相机机分配一个独特的IP地址、子网掩码和默认网关。
4. 确保相机的IP地址与使用的计算机或移动设备的网络设置相匹配。
5. 测试每台相机,确保其在网络上正常通信。
此外,可以考虑根据编号方案分配IP地址,或使用DHCP服务器自动分配IP地址给相机。
但是当有很多数量的相机在同一网络的情况下,若使用静态IP的情况下需要繁琐的操作和时间。
此时,自动ForceIP功能就可以自动分配IP地址并保证相互间的通讯。
强制分配IP功能ForceIP实现
Baumer工业相机SDK示例中103_multicast.cpp详细介绍了如何配置相机以及使用ForceIP功能。
软件SDK示例地址如下所示:
Baumer_GAPI_SDK_2.12.0_win_x86_64_cs\examples\src\1_GigE\102_ForceIP\102_ForceIP.cs
代码整体结构相对简单,在Device.open时进行判断是否需要进行ForceIP,部分核心代码如下:
//TEST DEVICE INFORMATION BEFORE DEVICE OPEN
if (dev_pair.Value.TLType == "GEV")
{
System.Console.Write(" Device NodeList Information before opening \r\n");
BGAPI2.NodeMap mDeviceNodeList = dev_pair.Value.NodeList;
System.Console.Write(" Device MAC address (hex): {0:X2}:{1:X2}:{2:X2}:{3:X2}:{4:X2}:{5:X2}\r\n",
((long)mDeviceNodeList["GevDeviceMACAddress"].Value & 0xffffffffffff) >> 40,
((long)mDeviceNodeList["GevDeviceMACAddress"].Value & 0xffffffffff) >> 32,
((long)mDeviceNodeList["GevDeviceMACAddress"].Value & 0xffffffff) >> 24,
((long)mDeviceNodeList["GevDeviceMACAddress"].Value & 0xffffff) >> 16,
((long)mDeviceNodeList["GevDeviceMACAddress"].Value & 0xffff) >> 8,
((long)mDeviceNodeList["GevDeviceMACAddress"].Value & 0xff));
//DEVICE IP ADDRESS
iDeviceIPAddress = (long)mDeviceNodeList["GevDeviceIPAddress"].Value;
System.Console.Write(" Device IP address (hex): 0x{0:X8}\r\n", iDeviceIPAddress);
System.Console.Write(" Device IP address (string): {0}.{1}.{2}.{3}\r\n", (iDeviceIPAddress & 0xff000000) >> 24,
(iDeviceIPAddress & 0x00ff0000) >> 16,
(iDeviceIPAddress & 0x0000ff00) >> 8,
(iDeviceIPAddress & 0x000000ff));
//DEVICE SUBNET MASK
iDeviceSubnetMask = (long)mDeviceNodeList["GevDeviceSubnetMask"].Value;
System.Console.Write(" Device Subnet mask (hex): 0x{0:X8}\r\n", iDeviceSubnetMask);
System.Console.Write(" Device Subnet mask (string): {0}.{1}.{2}.{3}\r\n", (iDeviceSubnetMask & 0xff000000) >> 24,
(iDeviceSubnetMask & 0x00ff0000) >> 16,
(iDeviceSubnetMask & 0x0000ff00) >> 8,
(iDeviceSubnetMask & 0x000000ff));
//CHECK THE SUBNETS ARE MATCHING
System.Console.Write(" Check subnet of device is matching to subnet of interface \r\n");
iDeviceSubnet = iDeviceIPAddress & iDeviceSubnetMask; //bit wise AND
System.Console.Write(" Device Subnet (hex): 0x{0:X8}\r\n", iDeviceSubnet);
System.Console.Write(" Device Subnet (string): {0}.{1}.{2}.{3}\r\n", (iDeviceSubnet & 0xff000000) >> 24,
(iDeviceSubnet & 0x00ff0000) >> 16,
(iDeviceSubnet & 0x0000ff00) >> 8,
(iDeviceSubnet & 0x000000ff));
iInterfaceSubnet = ((long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value) & ((long)mInterface.NodeList["GevInterfaceSubnetMask"].Value); //bit wise AND
System.Console.Write(" Interface Subnet (hex): 0x{0:X8}\r\n", iInterfaceSubnet);
System.Console.Write(" Interface Subnet (string): {0}.{1}.{2}.{3}\r\n", (iInterfaceSubnet & 0xff000000) >> 24,
(iInterfaceSubnet & 0x00ff0000) >> 16,
(iInterfaceSubnet & 0x0000ff00) >> 8,
(iInterfaceSubnet & 0x000000ff));
if (iDeviceSubnet == iInterfaceSubnet)
{
System.Console.Write(" IP address of device matches to IP address of interface \r\n");
}
else
{
System.Console.Write(" IP address of device does not match to IP address of interface \r\n\r\n");
System.Console.Write(" Try ForceIP on camera to get temporary match \r\n");
try
{
//PREPARATION OF FORCE IP - SELECT THE MAC ADDDRESS
long iDeviceMacAddress = (long)mDeviceNodeList["GevDeviceMACAddress"].Value;
mDeviceNodeList["MACAddressNeededToForce"].Value = iDeviceMacAddress;
//PREPARATION OF FORCE IP - CREATE FORCE IP ADDDRESS
long iForceIPAddress = iInterfaceSubnet + 1; // e.g 169.254.0.1
System.Console.Write(" Forced IP Address (hex): 0x{0:X8}\r\n", iForceIPAddress);
System.Console.Write(" Forced IP Address (string): {0}.{1}.{2}.{3}\r\n", (iForceIPAddress & 0xff000000) >> 24,
(iForceIPAddress & 0x00ff0000) >> 16,
(iForceIPAddress & 0x0000ff00) >> 8,
(iForceIPAddress & 0x000000ff));
System.Console.Write(" Interface IP Address (hex): 0x{0:X8}\r\n", (long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value);
System.Console.Write(" Interface IP Address (string): {0}.{1}.{2}.{3}\r\n", ((long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value & 0xff000000) >> 24,
((long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value & 0x00ff0000) >> 16,
((long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value & 0x0000ff00) >> 8,
((long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value & 0x000000ff));
if (iForceIPAddress == (long)mInterface.NodeList["GevInterfaceSubnetIPAddress"].Value)
{
//IF NEW IP ADDRESS IS ALREADY USED BY THE INTERFACE THEN USE NEXT
iForceIPAddress = iForceIPAddress + 1; // e.g. 169.254.0.2
System.Console.Write(" Warning. Created IP address is already used by the interface \r\n");
System.Console.Write(" Try next Forced IP Address \r\n");
System.Console.Write(" Forced IP Address (hex): 0x{0:X8}\r\n", iForceIPAddress);
System.Console.Write(" Forced IP Address (string): {0}.{1}.{2}.{3}\r\n", (iForceIPAddress & 0xff000000) >> 24,
(iForceIPAddress & 0x00ff0000) >> 16,
(iForceIPAddress & 0x0000ff00) >> 8,
(iForceIPAddress & 0x000000ff));
// more checks necessary, like another camera might use that IP address...
}
mDeviceNodeList["ForcedIPAddress"].Value = iForceIPAddress;
//PREPARATION OF FORCE IP - SET FORCE IP SUBNET MASK MATCHING TO INTERFACE SUBNET MASK
long iInterfaceSubnetMask = (long)mInterface.NodeList["GevInterfaceSubnetMask"].Value;
System.Console.Write(" Forced Subnet Mask (hex): 0x{0:X8}\r\n", iInterfaceSubnetMask);
System.Console.Write(" Forced Subnet Mask (string): {0}.{1}.{2}.{3}\r\n", (iInterfaceSubnetMask & 0xff000000) >> 24,
(iInterfaceSubnetMask & 0x00ff0000) >> 16,
(iInterfaceSubnetMask & 0x0000ff00) >> 8,
(iInterfaceSubnetMask & 0x000000ff));
mDeviceNodeList["ForcedSubnetMask"].Value = iInterfaceSubnetMask;
//PREPARATION OF FORCE IP - SET FORCE IP GATEWAY
long iForceIPGateway = 0;
System.Console.Write(" Forced Gateway (hex): 0x{0:X8}\r\n", iForceIPGateway);
System.Console.Write(" Forced Gateway (string): {0}.{1}.{2}.{3}\r\n", (iForceIPGateway & 0xff000000) >> 24,
(iForceIPGateway & 0x00ff0000) >> 16,
(iForceIPGateway & 0x0000ff00) >> 8,
(iForceIPGateway & 0x000000ff));
mDeviceNodeList["ForcedGateway"].Value = iForceIPGateway;
System.Console.Write(" Start of Force IP ... \r\n");
mDeviceNodeList["ForceIP"].Execute();
System.Console.Write(" End of Force IP\r\n");
deviceList.Refresh(100);
System.Console.Write("5.1.6 Detected devices after ForceIP: {0}\r\n", deviceList.Count);
}
catch (BGAPI2.Exceptions.IException ex)
{
returnCode = (0 == returnCode) ? 1 : returnCode;
System.Console.Write("ExceptionType: {0} \r\n", ex.GetType());
System.Console.Write("ErrorDescription: {0} \r\n", ex.GetErrorDescription());
System.Console.Write("in function: {0} \r\n", ex.GetFunctionName());
}
}
}
ForceIP功能优化方法
上面的代码可能由于过于复杂,因此我们这边做了一些优化操作和适当的说明
代码如下所示:
//在获取到相机和相机对应的网口后可使用ForceIP功能
private void ForceIP_Function(BGAPI2.Device CamDevice,BGAPI2.Interface CamInterface)
{
string CameraName = CamDevice.DisplayName;
string CameraSN = CamDevice.SerialNumber;
OnNotifyShowRecieveMsg("相机:" + CameraName + ": " + "无法连接相机,相机IP地址可能设置不正确");
OnNotifyShowRecieveMsg("相机:" + CameraName + ": " + "可以使用ForceIP功能");
BGAPI2.DeviceList CurDeviceList;
CurDeviceList = CamInterface.Devices;
long iDeviceIPAddress = 0;
long iDeviceSubnetMask = 0;
long iDeviceSubnet = 0;
long iInterfaceSubnet = 0;
#region//判断执行相机ForceIP指令
if (CamDevice.TLType == "GEV")//判断当前相机为网口相机
{
BGAPI2.NodeMap mDeviceNodeList = CamDevice.NodeList;
iDeviceIPAddress = (long)mDeviceNodeList["GevDeviceIPAddress"].Value; //获取相机IP地址信息
iDeviceSubnetMask = (long)mDeviceNodeList["GevDeviceSubnetMask"].Value;//获取相机子网掩码地址信息
string CamIPAddres = string.Format("{0}.{1}.{2}.{3}", (iDeviceIPAddress & 0xff000000) >> 24,
(iDeviceIPAddress & 0x00ff0000) >> 16, (iDeviceIPAddress & 0x0000ff00) >> 8, (iDeviceIPAddress & 0x000000ff));
OnNotifyShowRecieveMsg("相机当前IP为:" + CamIPAddres);
iDeviceSubnetMask = (long)mDeviceNodeList["GevDeviceSubnetMask"].Value;
string CamSubAddres2 = string.Format("{0}.{1}.{2}.{3}", (iDeviceSubnetMask & 0xff000000) >> 24,
(iDeviceSubnetMask & 0x00ff0000) >> 16, (iDeviceSubnetMask & 0x0000ff00) >> 8, (iDeviceSubnetMask & 0x000000ff));
OnNotifyShowRecieveMsg("相机当前子网掩码为:" + CamSubAddres2);
//获取相机IP网段信息
iDeviceSubnet = iDeviceIPAddress & iDeviceSubnetMask; //bit wise AND
//相机IP网段信息转换字符串
string iDeviceSubnet2 = string.Format("{0}.{1}.{2}.{3}", (iDeviceSubnet & 0xff000000) >> 24,
(iDeviceSubnet & 0x00ff0000) >> 16, (iDeviceSubnet & 0x0000ff00) >> 8, (iDeviceSubnet & 0x000000ff));
OnNotifyShowRecieveMsg("相机IP网段:" + iDeviceSubnet2);
//获取网口IP网段信息
iInterfaceSubnet = ((long)CamInterface.NodeList["GevInterfaceSubnetIPAddress"].Value) & ((long)CamInterface.NodeList["GevInterfaceSubnetMask"].Value); //bit wise AND
//网口IP网段信息转换字符串
string iInterfaceSubnet2 = string.Format("{0}.{1}.{2}.{3}", (iInterfaceSubnet & 0xff000000) >> 24,
(iInterfaceSubnet & 0x00ff0000) >> 16, (iInterfaceSubnet & 0x0000ff00) >> 8, (iInterfaceSubnet & 0x000000ff));
OnNotifyShowRecieveMsg("网口IP网段:" + iInterfaceSubnet2);
if (iDeviceSubnet != iInterfaceSubnet)
{
MessageBox.Show("检查到相机IP和网口IP不匹配,开始执行ForceIP功能");
long iDeviceMacAddress = (long)mDeviceNodeList["GevDeviceMACAddress"].Value;
mDeviceNodeList["MACAddressNeededToForce"].Value = iDeviceMacAddress;
//为ForceIP做准备,设置一个合适的IP地址
long iForceIPAddress = iInterfaceSubnet + 1; // e.g 169.254.0.1,基于网口的IP加1
string IPAddressNew = string.Format("{0}.{1}.{2}.{3}", (iForceIPAddress & 0xff000000) >> 24,
(iForceIPAddress & 0x00ff0000) >> 16, (iForceIPAddress & 0x0000ff00) >> 8, (iForceIPAddress & 0x000000ff));
OnNotifyShowRecieveMsg("强制相机的IP地址为:" + IPAddressNew);
mDeviceNodeList["ForcedIPAddress"].Value = iForceIPAddress; //设置ForceIP的IP地址
long iInterfaceSubnetMask = (long)CamInterface.NodeList["GevInterfaceSubnetMask"].Value;
mDeviceNodeList["ForcedSubnetMask"].Value = iInterfaceSubnetMask; //设置ForceIP的子网掩码地址
long iForceIPGateway = 0;
mDeviceNodeList["ForcedGateway"].Value = iForceIPGateway; //设置ForceIP的网关地址
OnNotifyShowRecieveMsg("开始执行,请稍后......");
mDeviceNodeList["ForceIP"].Execute(); //强制执行相机IP和网口IP匹配功能命令
CurDeviceList.Refresh(100); //刷新相机设备列表
MessageBox.Show("完成ForceIP功能");
OnNotifyShowRecieveMsg("相机的IP地址已经强制为:" + IPAddressNew);
CamDevice.Open(); //重新执行相机的连接
CamDevice.RemoteNodeList["TriggerMode"].Value = "Off"; //关闭相机的触发模式
}
}
#endregion
}
设置固定IP地址优点
给相机设置固定IP地址有什么好处?
1、稳定性。当一个设备有一个静态的IP地址时,无论它从网络上断开多少次,它都会有相同的IP地址。这确保了相机和网络之间的稳定连接,这对需要不断监控的相机来说非常重要。
2、远程访问。为相机设置一个固定的IP地址,可以方便地使用该IP地址进行远程访问,这对于需要在离开场所时查看相机画面的情况非常有用。
3、易于配置。设置一个固定的IP地址比不断搜索和寻找DHCP分配的IP地址更容易配置。
4、网络安全。为设备分配一个固定的IP地址,可以通过配置防火墙规则和访问控制列表,轻松控制对该设备的访问。
5、综合性。使用固定的IP地址可以提高相机的稳定性和可靠性,因为它消除了与网络上试图使用同一IP地址的其他设备的潜在冲突。
设置DHCP IP地址优点
给相机设置DHCP IP地址有什么好处?
1、简化了网络管理。DHCP使网络管理员能够从一个中央服务器管理所有的IP地址,从而简化了整个网络管理。
2、防止IP地址冲突。通过DHCP分配IP地址,发生IP地址冲突的可能性大大降低,因为DHCP可以自动检测并避免此类问题。
3、提供灵活性。有了DHCP,就可以很容易地在网络上移动相机,而不必手动更新其IP地址。这在管理大量相机时提供了极大的灵活性。
4、简化了安全性。DHCP可与其他安全措施结合使用,如MAC地址过滤,以确保只有经授权的设备能够连接到网络。
5、提高了便捷性。当网络中相机的数量太多时,去一个个设置固定IP是件非常繁琐的事件,使用DHCP可以快速的设置IP,节省了大量的时间成本。