具体现象是d2210_t_pmove,运动50个脉冲,结果直接走到撞机。
相同的程序,在32位的系统下没有问题,但是在x64系统下面有问题。
以前勇哥找过雷塞的人过来看过,当时研究了一天,发现是要把某个硬件信号电平禁用一下。
今天测试设备再现这个问题,一时想不起来究竟是哪个硬件信号。所以写了个小程序排查研究一下。
结果见最后面。

using Samsun.Domain.MotionCard.Common.DMC2210;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int[] card_id = null;
int card_count = 0;
var res = DMC2210SDK.Instance.InitCard(ref card_id, ref card_count);
if (res != 0)
{
label1.Text=("init error");
}
else
{
label1.Text =("OK");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (AxisPEL == 1) but1.BackColor = Color.Red;
else but1.BackColor = Color.Green;
if (AxisMEL == 1) but2.BackColor = Color.Red;
else but2.BackColor = Color.Green;
if (AxisSD == 1) but3.BackColor = Color.Red;
else but3.BackColor = Color.Green;
if (Dmc2210.d2210_read_RDY_PIN(0) == 1) but4.BackColor = Color.Red;
else but4.BackColor = Color.Green;
if (AxisEZ == 1) but5.BackColor = Color.Red;
else but5.BackColor = Color.Green;
if (AxisORG == 1) but6.BackColor = Color.Red;
else but6.BackColor = Color.Green;
//pa
//pb
if (AxisINP == 1) but9.BackColor = Color.Red;
else but9.BackColor = Color.Green;
if (AxisALM == 1) but10.BackColor = Color.Red;
else but10.BackColor = Color.Green;
if (AxisALM == 1) but10.BackColor = Color.Red;
else but10.BackColor = Color.Green;
//LTC
if (AxisEMG == 1) but12.BackColor = Color.Red;
else but12.BackColor = Color.Green;
}
int AxisID = 0;
public int GetAxisCurrentState()
{
uint status = 0;
var res = DMC2210SDK.Instance.GetAxisCardIOStatus(AxisID, ref status);
if (res == 0)
return (int)status;
else
return res;
}
public int GetAxisRsts()
{
uint status = 0;
var res = DMC2210SDK.Instance.GetAxisCardIOStatus(AxisID, ref status);
if (res == 0)
return (int)status;
else
return res;
}
public int AxisStatus
{
get
{
return GetAxisCurrentState();
}
set
{
}
}
/// <summary>
/// 正在加速
/// </summary>
public int AxisFU
{
get
{
return (int)((GetAxisCurrentState() >> 8) % 2);
}
set
{
}
}
/// <summary>
/// 正在减速
/// </summary>
public int AxisFD
{
get
{
return (int)((GetAxisCurrentState() >> 9) % 2);
}
set
{
}
}
/// <summary>
/// 表示在低速运行
/// </summary>
public int AxisFC
{
get
{
return (int)((GetAxisCurrentState() >> 10) % 2);
}
set
{
}
}
/// <summary>
/// 1:表示伺服报警信号 ALM 为 ON
/// </summary>
public int AxisALM
{
get
{
return (int)((GetAxisCurrentState() >> 11) % 2);
}
set
{
}
}
/// <summary>
/// 正极限信号,1表示正限位有效, 0表示无效
/// </summary>
public int AxisPEL
{
get
{
//todo: dmc2210中当el没触发时,读出来就是1,跟官方程序显示的不一样,这个还需要再研究一下为什么
return (int)((GetAxisCurrentState() >> 12) % 2);
}
set
{
}
}
/// <summary>
/// 负极限信号,1表示负限位有效, 0表示无效
/// </summary>
public int AxisMEL
{
get
{
return (int)((GetAxisCurrentState() >> 13) % 2);
}
set
{
}
}
/// <summary>
/// 原点信号,1表示原点有效, 0表示无效
/// </summary>
public int AxisORG
{
get
{
return (int)((GetAxisCurrentState() >> 14) % 2);
}
set
{
}
}
/// <summary>
/// 1:表示 SD 信号为 ON
/// </summary>
public int AxisSD
{
get
{
return (int)((GetAxisCurrentState() >> 15) % 2);
}
set
{
}
}
/// <summary>
/// Index信号,1表示EZ为高电平, 0表示为低电平
/// </summary>
public int AxisEZ
{
get
{
return (int)((GetAxisRsts() >> 10) % 2);
}
set
{
}
}
/// <summary>
/// EMG信号,1表示EMG输入为高, 0表示输入为低;该信号为低电平有效。
/// </summary>
public int AxisEMG
{
get
{
return (int)((GetAxisRsts() >> 7) % 2);
}
set
{
}
}
/// <summary>
/// 当前运动方向,0表示当前运动方向为正向, 1表示当前运动方向为负向。
/// </summary>
public int AxisDIR
{
get
{
return (int)((GetAxisRsts() >> 16) % 2);
}
set
{
}
}
public int AxisINP
{
get
{
return (int)((GetAxisRsts() >> 15) % 2);
}
set
{
}
}
private void button3_Click(object sender, EventArgs e)
{
Dmc2210.d2210_emg_stop();
}
private void timer2_Tick(object sender, EventArgs e)
{
label1.Text= Dmc2210.d2210_get_position(0).ToString();
}
private void button4_Click(object sender, EventArgs e)
{
Dmc2210.d2210_set_position(0, 0);
}
private void button2_Click_1(object sender, EventArgs e)
{
Dmc2210.d2210_set_pulse_outmode(0, 2);
Dmc2210.d2210_counter_config(0, 3);
Dmc2210.d2210_set_HOME_pin_logic(0, 0, 1);
Dmc2210.d2210_config_EL_MODE(0, 2); //
Dmc2210.d2210_config_ALM_PIN(0,0, 1); //
Dmc2210.d2210_config_EZ_PIN(0, 0, 0);
Dmc2210.d2210_config_EMG_PIN(0, 0, 0); //
Dmc2210.d2210_config_SD_PIN(0, 0, 0, 0);
Dmc2210.d2210_config_LTC_PIN(0, 0, 0);
Dmc2210.d2210_config_INP_PIN(0, 0, 0);
Dmc2210.d2210_config_ERC_PIN(0, 0, 0, 0, 1);
Dmc2210.d2210_config_PCS_PIN(0, 0, 0); //注意,就是它了!!!
Dmc2210.d2210_write_SEVON_PIN(0, 0);
//DMC2210SDK.Instance.SetCarsAxisTProfile(0, 100, 1000, 0.5, 0.5);
//DMC2210SDK.Instance.CardAxisPMove(0, 1, 0,0);
Dmc2210.d2210_set_profile(0, 1000, 1000, 0.2, 0.2);
Dmc2210.d2210_t_pmove(0, int.Parse(textBox1.Text), 0);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Dmc2210.d2210_board_close();
}
}
}花了几个小时,找到Dmc2210.d2210_config_PCS_PIN(0, 0, 0);
就是它了,设置为禁用就好了!!!
另外附上全部配置API的摘抄,方便大家查看:
void d2210_config_SD_PIN(WORD axis,WORD enable, WORD sd_logic,WORD sd_mode) 功 能:设置SD 信号有效的逻辑电平及其工作方式 参 数:axis 指定轴号 enable 允许/禁止信号功能:0-无效,1-有效 sd_logic 设置SD 信号的有效逻辑电平:0-低电平有效,1-高电平有效。 sd_mode 设置SD 信号的工作方式: 0-减速到起始速度,如果SD 信号丢失,又开始加速 1-减速到起始速度,并停止,如果在减速过程中,SD 信号丢失,又开始 加速 2-锁存SD 信号,并减速到起始速度 3-锁存SD 信号,并减速到起始速度后停止。 void d2210_config_PCS_PIN(WORD axis,WORD enable,WORD pcs_logic) 功 能:设置允许/禁止PCS 外部信号在运动中改变目标位置 参 数:axis 指定轴号 enable 允许/禁止信号功能:0-无效,1-有效 pcs_logic 设置PCS 信号的有效电平:0-低电平有效,1-高电平有效 返回值:无 void d2210_config_ERC_PIN(WORD axis,WORD enable,WORD erc_logic,WORD erc_width,WORD erc_off_time) 功 能:设置允许/禁止ERC 信号及其有效电平和输出方式 技术支持热线:0755-26417593、26414894 网址:www.szleadtech.com.cn 62 DMC2210 软 件 使 用 手 册 Version 1.3 参 数:axis 指定轴号 enable 范围:0~3: 0-不自动输出ERC 信号 1-接收EL、ALM、CEMG 等信号停止时,自动输出ERC 信号 2-接收ORG 信号时,自动输出ERC 信号 3-满足第1 或2 两项条件时,均会自动输出ERC 信号 erc_logic 设置ERC 信号的有效电平:0-低电平有效,1-高电平有效 erc_width 误差清除信号ERC 有效输出宽度: 0-12us 1-102us 2-409us 3-1.6ms 4-13ms 5-52ms 6-104ms 7-电平输出 erc_off_time ERC 信号的关断时间: 0-0us,1-12us,2-1.6ms,3-104ms 返回值:无 void d2210_config_INP_PIN(WORD axis,WORD enable,WORD inp_logic) 功 能:设置允许/禁止INP 信号及其有效的逻辑电平 参 数:axis 指定轴号 enable 允许/禁止信号功能:0-无效,1-有效 inp_logic 设置INP 信号的有效电平:0-低电平有效,1-高电平有效 返回值:无 void d2210_config_ALM_PIN(WORD axis,WORD alm_logic,WORD alm_action) 功 能:设置ALM 的逻辑电平及其工作方式 参 数:axis 指定轴号 alm_logic ALM 信号的输入电平:0-低电平有效,1-高电平有效 alm_action ALM 信号的制动方式:0-立即停止,1-减速停止 返回值:无 void d2210_config_EZ_PIN(WORD axis,WORD ez_logic, WORD ez_mode) 功 能:设置指定轴的EZ 信号的有效电平及其作用 参 数:axis 指定轴号 ez_logic EZ 信号逻辑电平:0-低有效,1-高有效 ez_mode EZ 信号的工作方式: 0-EZ 信号无效 1-EZ 是计数器复位信号 2-EZ 是原点信号,且不复位计数器 3-EZ 是原点信号,且复位计数器 返回值:无 void d2210_config_LTC_PIN(WORD axis,WORD ltc_logic, WORD ltc_mode) 功 能:设置指定轴锁存信号的有效电平。 参 数:axis 指定轴号 ltc_logic LTC 信号逻辑电平:0-低有效,1-高有效 ltc_mode 保留,可设为任意值 返回值:无 void d2210_config_EL_MODE(WORD axis,WORD el_mode) 功 能:设置EL 信号的有效电平及制动方式 参 数:axis 指定轴号 el_mode EL 有效电平和制动方式: 0-立即停、低有效 1-减速停、低有效 2-立即停、高有效 3-减速停、高有效 void d2210_set_HOME_pin_logic(WORD axis,WORD org_logic,WORD filter) 功 能:设置ORG 信号的有效电平,以及允许/禁止滤波功能 参 数:axis 指定轴号 org_logic ORG 信号的有效电平:0-低电平有效,1-高电平有效 filter 允许/禁止滤波功能:0-禁止,1-允许 返回值:无 int d2210_read_RDY_PIN(WORD axis) 功 能:读取指定运动轴的“伺服准备好”端子的电平状态 参 数:axis 指定轴号 返回值:0-低电平,1-高电平 void d2210_config_EMG_PIN(WORD cardno, WORD enable,WORD emg_logic) 功能描述:EMG 信号设置,急停信号有效后会立即停止所有轴。 输 入: cardno 卡号 Enable 0:无效; 1:有效 emg_logic 0::低有效; 1:高有效 返回值:无
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!
本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:



少有人走的路



















