天天看点

Cypresse+相机+步进电机开发控制背景开发工具流程

背景

之前用赛普拉斯芯片开发的一个自动摄影项目,并控制机器行为. 这里未免遗忘,所以做一下记录.

开发工具

平台: vs2017+Qt,使用C++语言

硬件:cpress芯片+一台相机+一个步进电机.

流程

连接好硬件之后,通过上层软件,控制电机的旋转平移,并在到达指定位置之后,进行数据采集.

原本为了控制,开发了许多独立的小功能,为了傻瓜式调用,所以进行了功能封装.

主要功能代码

cyPressControl.h头文件

class cyPressControl : public QObject
{
	Q_OBJECT

public:

	enum cyPressStatus
	{
		MOTOR_SUCCESS = 0,															//初始化成功.
		MOTOR_WRITESUCCESS = 1,													    //写入成功.
		MOTOR_READSUCCESS = 2,														//读取成功.
		MOTOR_FAILED = -1,															//失败
		MOTOR_NOFOUNDDEVICE = -2,													//找不到设备.
		MOTOR_BULKOUTEPTNULL = -3,													//写入端点异常.
		MOTOR_BULKINEPTNULL = -4,													//读取端点异常.
		MOTOR_WRITEFAILED = -5,														//写入失败.
		MOTOR_READFAILED = -6,														//读取失败
		MOTOR_HANDLEISNULL = -7,													//设备句柄为空
		MOTOR_PARAMSERROR = -8													    //设置的参数异常.
	};

	enum cypressDateControlStyle
	{
		Date_Sync,																	//同步读写
		Date_Async,																    //异步读写
		Date_Thread																	//异步线程读写.
	};

	cyPressControl(QObject *parent = nullptr);

	~cyPressControl();

	bool isDeviceStatus{ false };												   //设备是否初始化成功.

	bool exeCommandFlow();														    //数值测试 执行指令流.

	bool exeCommandFlowHandshake();												    //交互式执行.

	void stopExeCommand();															//停止执行指令.

	int getTotalSteps();														    //获取电机前进总步数.这里式内部维护的一个变量.

	int getTotalStepsByCommand();													//通过读取指令,获取总步数.

	void setTotalSteps(int steps);													//设置总步数.

	bool reSetCommand();															//电机复位(即回退指令)

	inline void LoopTime(int time = 100);

	bool isAbnormal();																//异常


protected:

	cyPressStatus InitCpressDevice();												 //初始化,并设置端点

	bool destroyCpressDevice();														 //销毁设备信息,以及释放资源.

	virtual cyPressStatus writeDate(byte* buffer, long bufferLength,
		byte wEndPtrAddress = 0x02);												 //指定写入端点,写入数据.

	virtual cyPressStatus SyncWriteDate(byte* buffer, long bufferLength,
		byte wEndPtrAddress = 0x02);

	virtual cyPressStatus writeCommand(byte command, UINT16 numberPerStpes = 800);	//写入指令.以及前进的步数. 单位um微米.

	virtual cyPressStatus readCommand(byte &outStatus);								//读取下位机返回值.

	cyPressStatus readDate(byte* outbuffer, long bufferLength,
		byte rEndPtrAddress = 0x86);												//指定读取端点,读取数据.

	virtual cyPressStatus SyncReadDate(byte* outbuffer,
		long bufferLength, byte rEndPtrAddress = 0x86);								 //同步读取数据

	bool cellCommand(int input, int &resullt, int spaceTime = 1000,
		bool isWrite = true, bool isRead = true);

	bool cellCommandHandshake(byte input, byte &result, bool isWrite = true,
		bool isRead = true, int spaceTime = 1000);									 //读写指令

	std::tuple<byte, byte> dec2Towhex(UINT16 number);

	QMutex _mutex;


signals:

	void sigPopStep(QString msg, bool effective);									   //弹射指令序号.

private:

	std::shared_ptr<CCyUSBDevice> _ccyusbDevice{ nullptr };							 	  //内部维护.

	CCyBulkEndPoint *bulkoutEpt = { nullptr };										 	  //写入端点

	CCyBulkEndPoint *bulkInEpt = { nullptr };										 	  //读取端点

	cypressDateControlStyle _syPressaDateStyle = { cypressDateControlStyle::Date_Async };

	bool exeCommandStop{ false };														 //步进电机停止执行迭代.

	int reCordTotalSteps = { 0 };														 //记录电机总步数.

	const int LengthPerStep = { 800 };													 //设置初始步伐常量为800um;
};
           

cyPressControl.cpp

#include "cyPressControl.h"
#include <QEventLoop>
#include <QTimer>
#include <qfuture.h>
#include <QtConcurrent/qtconcurrentmapkernel.h>
#include <QtConcurrent/qtconcurrentrun.h>

cyPressControl::cyPressControl(QObject *parent)
	: QObject(parent)
{
	if (InitCpressDevice() == 0)
	{
		isDeviceStatus = true;
	}
	else
	{
		isDeviceStatus = false;
	}
}

cyPressControl::~cyPressControl()
{
	destroyCpressDevice();
}

cyPressControl::cyPressStatus cyPressControl::InitCpressDevice()
{
	if (_ccyusbDevice = std::make_shared<CCyUSBDevice>())
	{
		//查找目标设备.
		int sourceID = -1;
		for (int i = 0; i < _ccyusbDevice->DeviceCount(); i++)
		{
			if (_ccyusbDevice->Open(i))
			{
				if (_ccyusbDevice->IsOpen() == true) //过滤掉已经打开的设备.
				{
					QString deviceName = _ccyusbDevice->DeviceName;
					if (deviceName.toUpper().contains("EZ-USB"))
					{
						sourceID = i;
						break;
					}
				}
			}
			_ccyusbDevice->Close();
		}

		//和目标设备建立连接.
		if (sourceID != -1)
		{
			_ccyusbDevice->Open(sourceID);

			if (_ccyusbDevice->IsOpen() == false)
			{
				std::cout << "打开设备失败" << std::endl;
				return cyPressStatus::MOTOR_NOFOUNDDEVICE;
			}
			else
			{
				CCyUSBEndPoint *endpt;
				std::cout << "已经找到了设备: " << _ccyusbDevice->DeviceName << std::endl;
				int eptCount = _ccyusbDevice->EndPointCount();
				for (int i = 1; i < eptCount; i++)
				{
					endpt = _ccyusbDevice->EndPoints[i];
					qDebug() << QStringLiteral("当前端点: %1").arg(endpt->Address);
					bool bIn = ((_ccyusbDevice->EndPoints[i]->Address & 0x80) == 0x80);
					bool bBulk = (_ccyusbDevice->EndPoints[i]->Attributes == 2);
					if (bBulk && bIn) bulkInEpt = (CCyBulkEndPoint *)_ccyusbDevice->EndPoints[i];
					if (bBulk && !bIn) bulkoutEpt = (CCyBulkEndPoint *)_ccyusbDevice->EndPoints[i];
				}
			}
		}
		else
		{
			return MOTOR_NOFOUNDDEVICE;
			qDebug() << QStringLiteral("找不到设备");
		}

		if (bulkoutEpt == nullptr || bulkInEpt == nullptr)
		{
			return cyPressStatus::MOTOR_BULKINEPTNULL;
		}

		return cyPressStatus::MOTOR_SUCCESS;
	}
	else
	{
		qDebug() << QStringLiteral("USBDevice is nullptr");
		return cyPressStatus::MOTOR_FAILED;
	}
}

bool cyPressControl::destroyCpressDevice()
{
	if (_ccyusbDevice != nullptr)
	{
		_ccyusbDevice->Close();
		_ccyusbDevice.reset();
	}

	return true;
}

cyPressControl::cyPressStatus cyPressControl::writeDate(byte * buffer, long bufferLength, byte wEndPtrAddress)
{
	qDebug() << QStringLiteral("写入线程ID: %1").arg(GetCurrentThreadId());
	if (_ccyusbDevice != nullptr)
	{
		if (buffer == nullptr || bufferLength < 0)
		{
			return cyPressStatus::MOTOR_PARAMSERROR;
		}

		bulkoutEpt = (CCyBulkEndPoint *)_ccyusbDevice->EndPointOf(wEndPtrAddress);
		if (bulkoutEpt == nullptr)
		{
			return cyPressStatus::MOTOR_HANDLEISNULL;
		}
		OVERLAPPED outOvLap;
		outOvLap.hEvent = CreateEvent(NULL, false, false, L"CYUSB_OUT");
		if (outOvLap.hEvent == nullptr)
		{
			return cyPressStatus::MOTOR_HANDLEISNULL;
		}

		UCHAR *outContext = bulkoutEpt->BeginDataXfer(buffer, bufferLength, &outOvLap);
		if (outContext != nullptr)
		{
			bulkoutEpt->WaitForXfer(&outOvLap, 200);//100ms
			bool success = bulkoutEpt->FinishDataXfer(buffer, bufferLength, &outOvLap, outContext);
			CloseHandle(outOvLap.hEvent);
			if (success == true)
			{
				return cyPressStatus::MOTOR_WRITESUCCESS;
			}
			else
			{
				return cyPressStatus::MOTOR_WRITEFAILED;
			}
		}
		else
		{
			return cyPressStatus::MOTOR_HANDLEISNULL;
		}
	}
	else
	{
		return cyPressStatus::MOTOR_HANDLEISNULL;
	}
}

cyPressControl::cyPressStatus cyPressControl::SyncWriteDate(byte * buffer, long bufferLength, byte wEndPtrAddress)
{
	qDebug() << QStringLiteral("写入线程ID: %1").arg(GetCurrentThreadId());
	if (_ccyusbDevice != nullptr)
	{
		if (buffer == nullptr || bufferLength < 0)
		{
			return cyPressStatus::MOTOR_PARAMSERROR;
		}

		bulkoutEpt = (CCyBulkEndPoint *)_ccyusbDevice->EndPointOf(wEndPtrAddress);
		if (bulkoutEpt == nullptr)
		{
			return cyPressStatus::MOTOR_HANDLEISNULL;
		}

		bool success = bulkoutEpt->XferData(buffer, bufferLength);
		if (success == true)
		{
			return cyPressStatus::MOTOR_WRITESUCCESS;
		}
		else
		{
			return cyPressStatus::MOTOR_WRITEFAILED;
		}
	}
	else
	{
		return cyPressStatus::MOTOR_HANDLEISNULL;
	}
}

cyPressControl::cyPressStatus cyPressControl::writeCommand(byte command, UINT16 numberPerStpes)
{
	cyPressStatus wStatus = cyPressStatus::MOTOR_FAILED;
	byte *writebuffer = new byte[10];
	int length = 10;
	if (writebuffer != nullptr)
	{
		ZeroMemory(writebuffer, 10);
		writebuffer[0] = command; //第一个为指令地址.

		//解析命令numberPerStpes
		std::tuple<byte, byte> getDate = dec2Towhex(numberPerStpes);
		writebuffer[1] = std::get<0>(getDate);
		writebuffer[2] = std::get<1>(getDate);
		qDebug() << QStringLiteral("解析步长: 0x%1  0x%2").arg(writebuffer[1]).arg(writebuffer[2]);

		switch (_syPressaDateStyle)
		{
		case cyPressControl::Date_Sync:
		{
			wStatus = SyncWriteDate(writebuffer, 10); //同步写入数据.
			break;
		}
		case cyPressControl::Date_Async:
		{
			wStatus = writeDate(writebuffer, 10);	  //异步写入数据.
			break;
		}
		case cyPressControl::Date_Thread:
		{
			byte rEndPtrAddress = 0x02;
			QFuture<cyPressStatus> f1 = QtConcurrent::run(this, &cyPressControl::SyncWriteDate, writebuffer, length, rEndPtrAddress);
			f1.waitForFinished();
			break;
		}
		default:
			wStatus = writeDate(writebuffer, 10);
			break;
		}

		delete[]writebuffer;
		writebuffer = nullptr;
	}
	return wStatus;
}

cyPressControl::cyPressStatus cyPressControl::readCommand(byte &outStatus)
{
	cyPressStatus rStatus = cyPressStatus::MOTOR_FAILED;
	long length = 10;
	byte* readbuffer = new byte[10];
	if (readbuffer != nullptr)
	{
		ZeroMemory(readbuffer, length);
		switch (_syPressaDateStyle)
		{
		case cyPressControl::Date_Sync:
		{
			rStatus = SyncReadDate(readbuffer, length); //同步读取数据
			break;
		}
		case cyPressControl::Date_Async:
		{
			rStatus = readDate(readbuffer, length);	   //异步读取数据
			break;
		}
		case cyPressControl::Date_Thread:
		{
			byte rEndPtrAddress = 0x86;
			QFuture<cyPressStatus> f1 = QtConcurrent::run(this, &cyPressControl::SyncReadDate, readbuffer, length, rEndPtrAddress);
			f1.waitForFinished();
			break;
		}
		default:
			rStatus = readDate(readbuffer, length);
			break;
		}

		if (readbuffer != nullptr)
		{
			outStatus = readbuffer[0];
		}

		QString logInfoRead = QStringLiteral("读取数据: %1   读取设备状态: %2   ").arg(outStatus).arg(rStatus);
		qDebug() << logInfoRead;

		if (readbuffer != nullptr)
		{
			delete[] readbuffer;
			readbuffer = nullptr;
		}
	}

	return rStatus;
}

cyPressControl::cyPressStatus cyPressControl::readDate(byte *outbuffer, long bufferLength, byte rEndPtrAddress)
{
	qDebug() << QStringLiteral("读取线程ID: %1").arg(GetCurrentThreadId());
	if (_ccyusbDevice != nullptr)
	{
		if (outbuffer == nullptr)
		{
			return cyPressStatus::MOTOR_PARAMSERROR;
		}

		if (!(bulkInEpt = (CCyBulkEndPoint *)_ccyusbDevice->EndPointOf(rEndPtrAddress)))
		{
			//端点地址失败后,尝试重新获取.
			bulkInEpt = _ccyusbDevice->BulkInEndPt;
		}

		if (bulkInEpt == nullptr)
		{
			qDebug() << QStringLiteral("bulkInEpt is null");
			return  cyPressStatus::MOTOR_HANDLEISNULL;
		}

		OVERLAPPED inOvLap;
		inOvLap.hEvent = CreateEvent(NULL, false, false, L"CYUSB_IN");
		if (inOvLap.hEvent == nullptr)
		{
			qDebug() << QStringLiteral("inOvLap.hEvent is null");
			return  cyPressStatus::MOTOR_HANDLEISNULL;
		}
		UCHAR *inContext = bulkInEpt->BeginDataXfer(outbuffer, bufferLength, &inOvLap);
		if (inContext != nullptr)
		{
			bulkInEpt->WaitForXfer(&inOvLap, 2000); //100mS等待.
			bool success_read = bulkInEpt->FinishDataXfer(outbuffer, bufferLength, &inOvLap, inContext);

			if (success_read == true)
			{
				CloseHandle(inOvLap.hEvent);
				return  cyPressStatus::MOTOR_READSUCCESS;
			}
			else
			{
				CloseHandle(inOvLap.hEvent);
				return cyPressStatus::MOTOR_READFAILED;
			}
		}
		else
		{
			qDebug() << QStringLiteral("_ccyusbDevice is null");
			return  cyPressStatus::MOTOR_HANDLEISNULL;
		}
	}
	else
	{
		return cyPressStatus::MOTOR_READFAILED;
	}
}

cyPressControl::cyPressStatus cyPressControl::SyncReadDate(byte * outbuffer, long bufferLength, byte rEndPtrAddress)
{
	qDebug() << QStringLiteral("读取线程ID: %1").arg(GetCurrentThreadId());
	if (_ccyusbDevice != nullptr)
	{
		if (outbuffer == nullptr)
		{
			return cyPressStatus::MOTOR_PARAMSERROR;
		}

		if (!(bulkInEpt = (CCyBulkEndPoint *)_ccyusbDevice->EndPointOf(rEndPtrAddress)))
		{
			//端点地址失败后,尝试重新获取.
			bulkInEpt = _ccyusbDevice->BulkInEndPt;
		}

		if (bulkInEpt == nullptr)
		{
			qDebug() << QStringLiteral("bulkInEpt is null");
			return  cyPressStatus::MOTOR_HANDLEISNULL;
		}
		else
		{
			//传输数据 同步传输数据.
			bool success_read = bulkInEpt->XferData(outbuffer, bufferLength, nullptr);
			if (success_read == true)
			{
				return  cyPressStatus::MOTOR_READSUCCESS;
			}
			else
			{
				return cyPressStatus::MOTOR_READFAILED;
			}
		}
	}
	else
	{
		return cyPressStatus::MOTOR_READFAILED;
	}
}

std::tuple<byte, byte> cyPressControl::dec2Towhex(UINT16 number)
{
	short int right, left;
	right = number & 0x00ff; // 取右8位
	left = number >> 8;	     // 取左8位
	return std::tuple<byte, byte>(left, right);
}
bool cyPressControl::exeCommandFlow()
{
	qDebug() << QStringLiteral("相机次线程ID: %1").arg(GetCurrentThreadId());
	//执行指令循环.
	int timeOut = 200;
	int input = 2;
	int result[5]{ 0,0,0,0,0 };
	QString sendstr;
	if (cellCommand(input, result[0]) == true)
	{
		sendstr = QStringLiteral("step: %1  %2  %3").arg(1).arg(input).arg(result[0]);
		emit sigPopStep(sendstr, false);
		emit sigPopStep(QStringLiteral("STEP1"), true);
		input = 4;
		LoopTime(1500);
		if (cellCommand(input, result[1]) == true)
		{
			sendstr = QStringLiteral("step: %1  %2  %3").arg(2).arg(input).arg(result[1]);
			emit sigPopStep(sendstr, false);
			emit sigPopStep(QStringLiteral("STEP2"), true);
			input = 6;
			LoopTime(1200);
			if (cellCommand(input, result[2]) == true)
			{
				sendstr = QStringLiteral("step: %1  %2  %3").arg(3).arg(input).arg(result[2]);
				emit sigPopStep(sendstr, false);
				emit sigPopStep(QStringLiteral("STEP3"), true);
				input = 8;
				LoopTime(1200);
				bool eightStatus = false;
				do
				{
					LoopTime(1200);
					eightStatus = cellCommand(input, result[3], 3000, true, true);
					sendstr = QStringLiteral("step: %1  %2  %3").arg(4).arg(input).arg(result[3]);
					emit sigPopStep(sendstr, false);
					emit sigPopStep(QStringLiteral("STEP4"), false);
					emit sigPopStep("ExeEnd", false);
					break;
				} while (1);

				return eightStatus;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

bool cyPressControl::cellCommandHandshake(byte input, byte &result, bool isWrite, bool isRead, int spaceTime)
{
	//测试专用数据.
	byte commanRandom[6] = { 0x01,0x09,0x01,0x06,0x01,0x08 };
	byte GetCommand = commanRandom[(rand() % 4 + 1)];

	if (input > 0x00 && input < 253)
	{
		cyPressStatus wStatus = cyPressStatus::MOTOR_FAILED, rStatus = cyPressStatus::MOTOR_FAILED;
		int iteratorNumber = 0;
		int recordGoNumbers = 0;
		do
		{
			if (isWrite == true)
			{
				wStatus = writeCommand(input, LengthPerStep);
				//wStatus = writeCommand(GetCommand, LengthPerStep); //测试异常指令.
				if (wStatus == cyPressStatus::MOTOR_WRITESUCCESS)
				{
					isWrite = false;
				}

				QString logInfoWrite = QStringLiteral("写入数据: %1   写入数据的状态: %2  ").arg(GetCommand).arg(wStatus);
				emit sigPopStep(logInfoWrite, false);
			}

			LoopTime(spaceTime);
			if ((isRead == true) && (wStatus == cyPressStatus::MOTOR_WRITESUCCESS))
			{
				recordGoNumbers = 0;
				recordGoNumbers = result;
				rStatus = readCommand(result);
				if (rStatus == cyPressStatus::MOTOR_READFAILED)
				{
					reCordTotalSteps = result;
				}

				if (iteratorNumber == 2)
				{
					QString logInfoRead = QStringLiteral("读取状态: %1  记录上次触发数据: %2   读取数据: %3  ").arg(rStatus).arg(recordGoNumbers).arg(result);				//释放内存.
					emit sigPopStep(logInfoRead, false);
				}

				LoopTime(200);
			}

			if ((result - recordGoNumbers) != 1)
			{
				//循环
				if (iteratorNumber >= 6)
				{
					break;
				}
			}
			else
			{
				if (iteratorNumber >= 2)
				{
					break;
				}
			}

			iteratorNumber++;
		} while (iteratorNumber < 6); //(iteratorNumber < 6) && (((result - recordGoNumbers) != 1))

		if ((((result != 255)) || ((result - recordGoNumbers) == 1)) && wStatus == cyPressStatus::MOTOR_WRITESUCCESS && rStatus == cyPressStatus::MOTOR_READSUCCESS)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

bool cyPressControl::exeCommandFlowHandshake()
{
	const int motorGoAheadUnit = LengthPerStep;//前进的单位距离.20个脉冲前进1um
	long motorDistance = 0;					  //前进的距离 单位um
	long motorGoAheadCount = 0;				  //前进步数
	const int IteraterNumber = 50;			  //设置迭代次数
	QString sendstr;
	bool status = false;
	exeCommandStop = true;
	long reconrdIteraterContolNumber = 0;
	do
	{
		QMutexLocker lock(&_mutex);
		if (exeCommandStop == false)
		{
			break;
		}

		byte input = 0x01;
		byte result = 0;
		if (cellCommandHandshake(input, result, true, true, 200) == true)
		{
			//正常执行.发送拍照指令. 进行拍照执行.
			sendstr = QStringLiteral("step: %1  执行指令:%2  电机总步数: %3").arg(++reconrdIteraterContolNumber).arg(input).arg(result);

			emit sigPopStep(sendstr, false);

			if (result != 254 && result != 255 && result >= 0) //获取到的数据不为0,复位成功254 或者 255异常,才可以进行拍照设置.
			{
				emit sigPopStep(QStringLiteral("%1").arg(++motorGoAheadCount), true);
			}

			LoopTime(1200);
			status = true;
		}
		else
		{
			emit sigPopStep(QStringLiteral("电机异常,正在执行复位"), false);
			emit sigPopStep(QStringLiteral("RESET"), true);
			//执行复位指令(电机回退)
			if (reSetCommand() == true)
			{
				emit sigPopStep(QStringLiteral("电机复位成功."), false);
			}

			status = false;
			break;
		}

		motorDistance = motorGoAheadCount * motorGoAheadUnit;


	} while ((motorDistance < 15000) || (motorGoAheadCount < IteraterNumber));

	return status;
}

bool cyPressControl::cellCommand(int input, int &resullt, int spaceTime, bool isWrite, bool isRead)
{
	QStringList logInfoList;
	if (input > 1 && input < 100)
	{
		cyPressStatus wStatus = cyPressStatus::MOTOR_FAILED, rStatus = cyPressStatus::MOTOR_FAILED;
		int iteratorNumber = 0;
		do
		{
			if (isWrite == true)
			{
				//写入.
				byte *writebuffer = new byte[10];
				int length = 10;
				if (writebuffer != nullptr)
				{
					ZeroMemory(writebuffer, 10);
					for (int i = 0; i < 10; i++)
					{
						writebuffer[i] = input;
					}

					switch (_syPressaDateStyle)
					{
					case cyPressControl::Date_Sync:
					{
						wStatus = SyncWriteDate(writebuffer, 10); //同步写入数据.
						break;
					}
					case cyPressControl::Date_Async:
					{
						wStatus = writeDate(writebuffer, 10);	  //异步写入数据.
						break;
					}
					case cyPressControl::Date_Thread:
					{
						byte rEndPtrAddress = 0x02;
						QFuture<cyPressStatus> f1 = QtConcurrent::run(this, &cyPressControl::SyncWriteDate, writebuffer, length, rEndPtrAddress);
						f1.waitForFinished();
						break;
					}
					default:
						break;
					}

					delete[]writebuffer;
					writebuffer = nullptr;

					if (wStatus != cyPressStatus::MOTOR_WRITESUCCESS)
					{
						emit sigPopStep(QStringLiteral("写入命令失败..."), false);
					}
					else
					{
						isWrite = false; //只写一次.
					}
				}

				QString logInfoWrite = QStringLiteral("写入数据: %1   写入数据的状态: %2  ").arg(input).arg(wStatus);
				emit sigPopStep(logInfoWrite, false);
			}

			QEventLoop qloop;
			QTimer::singleShot(spaceTime, &qloop, &QEventLoop::quit);
			qloop.exec();

			if ((isRead == true) && (wStatus == cyPressStatus::MOTOR_WRITESUCCESS))
			{
				//读取.
				long length = 10;
				byte* readbuffer = new byte[10];
				if (readbuffer != nullptr)
				{
					ZeroMemory(readbuffer, length);

					switch (_syPressaDateStyle)
					{
					case cyPressControl::Date_Sync:
					{
						rStatus = SyncReadDate(readbuffer, length); //同步读取数据
						break;
					}
					case cyPressControl::Date_Async:
					{
						rStatus = readDate(readbuffer, length);	   //异步读取数据
						break;
					}
					case cyPressControl::Date_Thread:
					{
						byte rEndPtrAddress = 0x86;
						QFuture<cyPressStatus> f1 = QtConcurrent::run(this, &cyPressControl::SyncReadDate, readbuffer, length, rEndPtrAddress);
						f1.waitForFinished();
						break;
					}
					default:
						break;
					}

					if (readbuffer != nullptr)
					{
						resullt = readbuffer[0];
					}

					QString logInfoRead = QStringLiteral("读取数据: %1   读取数据的状态: %2  ").arg(resullt).arg(rStatus);				//释放内存.
					emit sigPopStep(logInfoRead, false);

					if (readbuffer != nullptr)
					{
						delete[] readbuffer;
						readbuffer = nullptr;
					}
				}

				QEventLoop qloop2;
				QTimer::singleShot(200, &qloop2, &QEventLoop::quit);
				qloop2.exec();
			}

			iteratorNumber++;
			qDebug() << "";
		} while (iteratorNumber < 4 && ((resullt - input) != 1));

		if ((resullt - input) == 1)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}


void cyPressControl::stopExeCommand()
{
	qDebug() << QStringLiteral("停止线程ID: %1").arg(GetCurrentThreadId());
	QMutexLocker lock(&_mutex);
	exeCommandStop = false;
}

int cyPressControl::getTotalSteps()
{
	return reCordTotalSteps;
}

int cyPressControl::getTotalStepsByCommand()
{
	byte ControlSteps = -1;
	cyPressStatus rStatus = readCommand(ControlSteps);
	if (rStatus == cyPressStatus::MOTOR_READSUCCESS)
	{
		if (ControlSteps > 0 && ControlSteps != 254 && ControlSteps != 255)
		{
			return ControlSteps;
		}
		else
		{
			return -1;
		}
	}
	else
	{
		return -1;
	}
}

void cyPressControl::setTotalSteps(int steps)
{
	reCordTotalSteps = steps;
}

bool cyPressControl::reSetCommand()
{
	int TotalSteps = getTotalStepsByCommand();
	//判断回退步数,将非254 以及255 的数据剔除
	if ((TotalSteps == 254 || TotalSteps == 255) && TotalSteps > 0)
	{
		//异常数据,进行软件内部数据的矫正.
		TotalSteps = getTotalSteps();
	}

	emit sigPopStep(QStringLiteral("步进电机回退步数:%1").arg(TotalSteps), false);
	long distance = TotalSteps * LengthPerStep;
	bool write = true;
	bool read = true;
	cyPressStatus wStatus = cyPressStatus::MOTOR_FAILED, rStatus = cyPressStatus::MOTOR_FAILED;
	byte outDate = 0;
	int iteratorCount = 0;
	do
	{
		if (write == true)
		{
			wStatus = writeCommand(0x02, distance);//执行复位指令
			if (wStatus == cyPressStatus::MOTOR_WRITESUCCESS)
			{
				write = false;
			}
		}

		_sleep(2000);

		if ((read == true) && (wStatus == cyPressStatus::MOTOR_WRITESUCCESS))
		{
			rStatus = readCommand(outDate);
			qDebug() << QStringLiteral("复位状态: %1  %2").arg(rStatus).arg(outDate);
		}

		if (((outDate == 254) || (outDate == 255)) && (wStatus == cyPressStatus::MOTOR_WRITESUCCESS) && (rStatus == cyPressStatus::MOTOR_READSUCCESS))
		{
			break;
		}

		iteratorCount++;
	} while (iteratorCount < 5);

	//复位完成.
	if (outDate == 254 && (wStatus == cyPressStatus::MOTOR_WRITESUCCESS) && (rStatus == cyPressStatus::MOTOR_READSUCCESS))
	{
		emit sigPopStep(QStringLiteral("电机复位成功."), false);
		return true;
	}
	else
	{
		emit sigPopStep(QStringLiteral("电机复位失败."), false);
		return false;
	}
}

inline void cyPressControl::LoopTime(int time)
{
	QEventLoop qloop;
	QTimer::singleShot(time, &qloop, &QEventLoop::quit);
	qloop.exec();
}

bool cyPressControl::isAbnormal()
{
	//读取数据,判断其是否为254;
	byte outDate;
	readCommand(outDate);
	if (outDate == 255)
	{
		return true;
	}

	return false;
}
           

封装集成的功能展示

class cyPressControl;
class STEPPINGMOTROSDK_EXPORT StepPingMotroSDK
{
public:

	StepPingMotroSDK();

	/******************************************************/
	// 函数名   : initStepPingMotroSDK
	// 功能描述 : 初始化
	// 参数     : 
	//			: 
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	bool initStepPingMotroSDK();	

	/******************************************************/
	// 函数名   : dstroyStepPingMotroSDK
	// 功能描述 : 销毁
	// 参数     : 
	//			: 
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	void dstroyStepPingMotroSDK();		

	/******************************************************/
	// 函数名   : stopExeCommand
	// 功能描述 : 停止执行指令
	// 参数     : 
	//			:
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	bool stopExeCommand();			


	/******************************************************/
	// 函数名   : startExeCommand
	// 功能描述 : 开始执行指令
	// 参数     : 
	//			:
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	bool startExeCommand();				


	/******************************************************/
	// 函数名   : setTotalSteps
	// 功能描述 : 设置前进步数
	// 参数     :
	//			: 
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	bool setTotalSteps(int steps);		

	/******************************************************/
	// 函数名   : getTotalSteps
	// 功能描述 : 获取电机总步数
	// 参数     : 
	//			: 
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	int getTotalSteps();				


	/******************************************************/
	// 函数名   : reSetCommand
	// 功能描述 : 电机复位
	// 参数     :
	//			:
	//			:
	// 返回值   : 成功返回true  失败返回false
	/******************************************************/
	bool reSetCommand();				


	/******************************************************/
	// 函数名   : isAbnormal
	// 功能描述 : 电机是否运行异常
	// 参数     : 
	//			: 
	//			:
	// 返回值    : 成功返回true  失败返回false
	/******************************************************/
	bool isAbnormal();					

private:

	std::shared_ptr<cyPressControl> _cyPressControl = {nullptr};

};
           

最后,进行调用调试

Cypresse+相机+步进电机开发控制背景开发工具流程

到此,调试完成