Commit c6c852a5 几米阳光

1

1 个父辈 4f4b1190
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
20190114 20190114
增加一维码类型,Barcode 增加一维码类型,Barcode,可与二维码一起配置
20190114 20190114
改为伺服串联兼容模式 改为伺服串联兼容模式
......
using log4net;
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
namespace OnlineStore.DeviceLibrary
{
/// <summary>
/// 硕科控制模块代码
/// </summary>
public class ShuoKeControls
{
public static readonly ILog LOGGER = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static SerialBean bean = null;
public static bool isRun = false;
private static Dictionary<int, ShuoKeInfo> shuokeMap = new Dictionary<int, ShuoKeInfo>();
#region 串口操作
public static bool ResertInitPort(string comPortName, int baudRate, int tparity, int dataBits, StopBits stopBits)
{
if (isRun)
{
ClosePort();
}
return InitPort(comPortName, baudRate, tparity, dataBits, stopBits);
}
public static bool InitPort(string comPortName, int baudRate, int tparity, int dataBits, StopBits stopBits)
{
if (isRun)
{
return true;
}
try
{
Parity parity = (Parity)tparity;
bean = new SerialBean(comPortName, baudRate, parity, 8, stopBits);
bool result = bean.openPort();
if (!result)
{
return false;
}
bean.DataReceived += DataReceived;
isRun = true;
}
catch (Exception ex)
{
isRun = false;
LogUtil.error(LOGGER, "打开步进控制器串口失败:" + ex.ToString());
return false;
}
return true;
}
public static void ClosePort()
{
isRun = false;
bean.closePort();
LogUtil.info(LOGGER, "关闭步进控制器串口完成");
}
public static void SendData(byte[] data)
{
string strSend = "";
for (int i = 0; i < data.Length; i++)
{
strSend += string.Format("{0:X2} ", data[i]);
}
if (strSend.Equals(""))
{
return;
}
if (!isRun)
{
LogUtil.error(LOGGER, "电机发送数据【" + strSend + "】,当前串口未连接上,发送失败!");
return;
}
LogUtil.debug(LOGGER, "电机发送数据【" + strSend + "】");
bean.SendData(data, 0, data.Length);
}
private static void DataReceived(string portName, object sender, SerialDataReceivedEventArgs e, byte[] bits)
{
string strSend = "";
for (int i = 0; i < bits.Length; i++)
{
strSend += string.Format("{0:X2} ", bits[i]);
}
if (strSend.Equals(""))
{
return;
}
//校验
ushort pChecksum = 0;
SerialBean.CalculateCRC(bits, bits.Length - 2, out pChecksum);
string checkStr = Convert.ToString(pChecksum, 16);
byte[] checkByte = SerialBean.StringToByte(checkStr);
if (checkByte.Length == 1)
{
if (!bits[bits.Length - 2].Equals(checkByte[0]))
{
bean.clearInBuffer();
LogUtil.info(LOGGER, "收到数据:端口号 【" + portName + "】 数据【" + strSend + "】,校验错误");
return;
}
}
else
{
if (!bits[bits.Length - 1].Equals(checkByte[0]) || (!bits[bits.Length - 2].Equals(checkByte[1])))
{
bean.clearInBuffer();
LogUtil.info(LOGGER, "收到数据:端口号 【" + portName + "】 数据【" + strSend + "】,校验错误");
return;
}
}
LogUtil.debug(LOGGER, "收到数据:端口号 【" + portName + "】 数据【" + strSend + "】");
int slvAddr = (int)bits[0];
byte cmd = bits[1];
//查询状态
if (cmd.Equals(ShuoKeCMD.SearchMoveStatus))
{
//[数据1]:1表示运动中,0表示停止
//[数据2]:LL-左限位IO状态 1表示有效 0表示无效
//[数据3]:O-原点IO状态 1表示有效 0表示无效,,=1表示原点灭,=0表示当前原点亮
// [数据4]:RL-右限位IO状态 1表示有效 0表示无效
//[数据5]:EN-使能IO状态 1表示有效 0表示无效
int isInMove = bits[3];
int isLLimit = bits[4];
int isOrg = bits[5];
int isRLimit = bits[6];
int isEn = bits[7];
try
{
ShuoKeInfo info = new ShuoKeInfo(isInMove, slvAddr, isLLimit, isOrg, isRLimit, isEn);
if (shuokeMap.ContainsKey(slvAddr))
{
info.LastPosition = shuokeMap[slvAddr].LastPosition;
shuokeMap.Remove(slvAddr);
}
shuokeMap.Add(slvAddr, info);
}
catch (Exception ex)
{
LogUtil.error(LOGGER, "记录状态出错:" + ex.ToString());
}
LogUtil.debug(LOGGER, "收到驱动器【" + slvAddr + "】运动状态:运动【" + isInMove + "】左限位【" + isLLimit + "】右限位【" + isRLimit + "】原点【" + isOrg + "】使能【" + isEn + "】");
}
else if (cmd.Equals(ShuoKeCMD.GetAbsPosition))
{
byte[] positionData = new byte[4];
Array.Copy(bits, 3, positionData, 0, 4);
string a = SerialBean.byteToHexStr(positionData);
int absValue = Convert.ToInt32(a, 16);
LogUtil.info(LOGGER, "收到驱动器【" + slvAddr + "】绝对位置【" + absValue + "】");
if (shuokeMap.ContainsKey(slvAddr))
{
shuokeMap[slvAddr].LastPosition=absValue;
}
else
{
ShuoKeInfo info = new ShuoKeInfo(slvAddr, absValue);
shuokeMap.Add(slvAddr, info);
}
}
}
public static int GetLastPosition(int slvAddr)
{
if (shuokeMap.ContainsKey(slvAddr))
{
ShuoKeInfo info = shuokeMap[slvAddr];
return info.LastPosition;
}
return -1;
}
#endregion
#region 流水线逻辑判断
public static bool IsMoveEnd(int slvAddr,DateTime time, out ShuoKeInfo shuokeInfo)
{
shuokeInfo = null;
if (shuokeMap.ContainsKey(slvAddr))
{
ShuoKeInfo info = shuokeMap[slvAddr];
shuokeInfo = info;
if (info.IsInMove == 0 && info.UpdateTime > time)
{
return true;
}
}
return false;
}
public static bool IsHomeMoveEnd(int slvAddr, DateTime time,out ShuoKeInfo shuokeInfo)
{
shuokeInfo = null;
if (shuokeMap.ContainsKey(slvAddr))
{
ShuoKeInfo info = shuokeMap[slvAddr];
shuokeInfo = info;
if (info.IsInMove == 0 && info.UpdateTime > time&&info.Org==0)
{
return true;
}
}
return false;
}
#endregion
#region 驱动器操作方法
public static void GetStatus(int slvAddr)
{
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.SearchMoveStatus, 0x00, 0);
}
public static void DStoop(int slvAddr)
{
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.DStopMove, 0x00, 0);
}
public static void SuddownStop(int slvAddr)
{
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.SuddownStopMove, 0x00, 0);
}
public static void GetABSPosition(int slvAddr)
{
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.GetAbsPosition, 0x00, 0);
}
/// <summary>
///
/// </summary>
/// <param name="slvAddr"></param>
/// <param name="homeType">0=反方向,1=正方向</param>
public static void HomeMove(int slvAddr, byte homeType)
{
string fangx = homeType.Equals(0) ? "反方向" : "正方向";
LogUtil.info("压紧轴原点返回:" + fangx);
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.HomeMove, 0x01, homeType);
Thread.Sleep(100);
}
public static void VolMove(int slvAddr, int speed)
{
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.VolMove, 0x04, speed);
}
public static void AbsMove(int slvAddr, int TargetPosition)
{
// 47、设置绝对位置并开始运动:不支持广播(开环的32位脉冲统计长度)
//正负数表示绝对位置,如果已经到位置,则不做运动。(M4505S特有命令)
//发送: 应答:
//[设备地址] 0x01 [设备地址] 0x01
//[命令] 0x50 [命令] 0x50
//[数据长度] 4 [数据长度] 0
//[数据] xxxxxxxx [数据] 无
//[CRC校验1] 0xnn [CRC校验1] 0xnn
//[CRC校验2] 0xnn [CRC校验2] 0xnn
//数据:4BYTE,(支持32位有符号脉冲位置)
byte[] sendData = WriteData(slvAddr, ShuoKeCMD.AbsMove, 0x04, TargetPosition);
}
public static void RelativeMove(int slvAddr, int position)
{
//1是正方向
byte fangxiang = 0x01;
if (position < 0)
{
fangxiang = 0x00;
position = Math.Abs(position);
}
byte dataLength = 0x04;
byte[] sendData = new byte[5 + dataLength];
sendData[0] = (byte)slvAddr;
sendData[1] = ShuoKeCMD.RelativeMove;
sendData[2] = dataLength;
sendData[3] = 0x00;
sendData[4] = 0x00;
sendData[5] = 0x00;
sendData[6] = 0x00;
string speed = Convert.ToString(position, 16);
byte[] speedByte = SerialBean.StringToByte(speed);
for (int i = 0; i < speedByte.Length; i++)
{
if (i >= 4)
{
break;
}
sendData[6 - (speedByte.Length - 1 - i)] = speedByte[i];
}
sendData[3] = fangxiang;
sendData = buildCheckData(sendData, 3 + dataLength);
SendData(sendData);
}
public static void PositionClear(int slvAddr, byte setCMD)
{
byte[] sendData = WriteData(slvAddr, setCMD, 0x00, 0);
}
/// <summary>
/// 设置电机的速度
/// </summary>
/// <param name="slvAddr">电机地址</param>
/// <param name="setCMD">设置速度的命令号</param>
/// <param name="speedValue">速度值</param>
public static void SetSpeed(int slvAddr, byte setCMD, int speedValue)
{
byte[] sendData = WriteData(slvAddr, setCMD, 0x04, speedValue);
}
private static byte[] WriteData(int slvAddr, byte cmd, byte dataLength, int dataValue)
{
byte[] sendData = new byte[5 + dataLength];
sendData[0] = (byte)slvAddr;
sendData[1] = cmd;
sendData[2] = dataLength;
if (dataLength.Equals(0x00))
{
}
else if (dataLength.Equals(0x01))
{
sendData[3] = (byte)dataValue;
}
else if (dataLength.Equals(0x04))
{
sendData[3] = 0x00;
sendData[4] = 0x00;
sendData[5] = 0x00;
sendData[6] = 0x00;
string speed = Convert.ToString(dataValue, 16);
byte[] speedByte = SerialBean.StringToByte(speed);
for (int i = 0; i < speedByte.Length; i++)
{
if (i >= 4)
{
break;
}
sendData[6 - (speedByte.Length - 1 - i)] = speedByte[i];
}
}
sendData = buildCheckData(sendData, 3 + dataLength);
SendData(sendData);
return sendData;
}
private static byte[] buildCheckData(byte[] sendData, int length)
{
ushort pChecksum = 0;
SerialBean.CalculateCRC(sendData, length, out pChecksum);
string checkStr = Convert.ToString(pChecksum, 16);
byte[] checkByte = SerialBean.StringToByte(checkStr);
if (checkByte.Length == 1)
{
sendData[length] = checkByte[0];
sendData[length + 1] = 0x00;
}
else
{
sendData[length + 1] = checkByte[0];
sendData[length] = checkByte[1];
}
return sendData;
}
#endregion
}
public class ShuoKeCMD
{
/// <summary>
/// 设置运动初速度://SndHex:01 25 04 00 00 00 64 FC DE
/// </summary>
public static byte SetStartSpeed = 0x25;
/// <summary>
/// 设置运动最大速度://SndHex:01 27 04 00 00 27 10 E6 EB
/// </summary>
public static byte SetMaxSpeed = 0x27;
/// <summary>
/// 设置运动末速度://SndHex:01 29 04 00 00 03 E8 FD 47
/// </summary>
public static byte SetEndSpeed = 0x29;
/// <summary>
/// 设置运动加速度://SndHex:01 2B 04 00 00 13 88 F1 4D
/// </summary>
public static byte SetAddSpeed = 0x2B;
/// <summary>
/// 设置运动减速度://SndHex:01 2D 04 00 00 03 E8 FC C3
/// </summary>
public static byte SetDelSpeed = 0x2D;
/// <summary>
/// 设置归零运动速度://SndHex:01 2F 04 00 00 27 10 E7 A3
/// </summary>
public static byte SetHomeSpeed = 0x2F;
/// <summary>
/// //查找原点命令:
//SndHex:01 3E 01 00 61 84
/// </summary>
public static byte HomeMove = 0x3E;
/// <summary>
/// 绝对位置运动//SndHex:01 50 04 FF FF D8 F0 AC 30
/// </summary>
public static byte AbsMove = 0x50;
/// <summary>
/// 急停命令://SndHex:01 3C 00 31 00
/// </summary>
public static byte SuddownStopMove = 0x3C;
/// <summary>
/// 减速停止命令://SndHex:01 3D 00 30 90
/// </summary>
public static byte DStopMove = 0x3D;
/// <summary>
/// 绝对位置清零: //SndHex:01 38 00 33 C0
/// </summary>
public static byte AbsPositionClear = 0x38;
/// <summary>
/// 相对位置清零: //SndHex:01 3A 00 32 A0
/// </summary>
public static byte RelPositionClear = 0x3A;
/// <summary>
/// 查询运动状态://SndHex:01 3B 00 33 30
/// </summary>
public static byte SearchMoveStatus = 0x3B;
/// <summary>
//查询设备地址://SndHex:00 21 00 69 90
/// </summary>
public static byte SearchSlvAddr = 0x21;
/// <summary>
/// 设置32位运动速度,并恒速运动:SndHex:01 33 04 00 00 27 10 E5 FF
/// </summary>
public static byte VolMove = 0x33;
/// <summary>
/// 查询绝对位置
/// </summary>
public static byte GetAbsPosition = 0x37;
/// <summary>
/// 相对位置运动
/// </summary>
public static byte RelativeMove = 0x32;
}
public class ShuoKeInfo
{
public ShuoKeInfo(int slv,int position)
{
this.IsInMove = 0 ;
this.SlvAddr = slv;
this.LLimit = 0;
this.RLimit = 0;
this.Org = 0;
this.En = 0;
UpdateTime = DateTime.Now;
LastPosition = position;
}
public ShuoKeInfo(int ismove, int slv, int ll, int org, int rl, int en)
{
this.IsInMove = ismove;
this.SlvAddr=slv;
this.LLimit=ll;
this.RLimit=rl;
this.Org=org;
this.En=en;
UpdateTime=DateTime.Now;
LastPosition = 0;
}
public int LastPosition { get; set; }
/// <summary>
/// 驱动器地址
/// </summary>
public int SlvAddr { get; set; }
/// <summary>
/// 是否在运动中
/// </summary>
public int IsInMove { get; set; }
/// <summary>
/// 左极限
/// </summary>
public int LLimit { get; set; }
/// <summary>
/// 右极限
/// </summary>
public int RLimit { get; set; }
/// <summary>
/// 原点信号是否有效
/// </summary>
public int Org { get; set; }
/// <summary>
/// 使能是否有效
/// </summary>
public int En { get; set; }
public DateTime UpdateTime { get; set; }
public string ToShowStr()
{
return "运动[" + IsInMove + "]左限位[" + LLimit + "]右限位[" + RLimit + "]原点[" + Org + "]使能[" + En + "]["+UpdateTime.ToShortTimeString()+"]";
}
}
}
...@@ -1465,7 +1465,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -1465,7 +1465,7 @@ namespace OnlineStore.DeviceLibrary
foreach (string str in codeList) foreach (string str in codeList)
{ {
string code = str; string code = str;
code = "=1+0x0-7x" + height + " =" + code; code = "=1+0x0-7x" + height + "=" + code;
message = message + code + spiltStr; message = message + code + spiltStr;
} }
if (!outMsg.Equals("")) if (!outMsg.Equals(""))
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!