背景
之前用賽普拉斯晶片開發的一個自動攝影項目,并控制機器行為. 這裡未免遺忘,是以做一下記錄.
開發工具
平台: 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};
};
最後,進行調用調試
到此,調試完成