lock.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include "lock.h"
  2. #include "config.h"
  3. #include <QtCore>
  4. #include <QDebug>
  5. extern config *pconfig;
  6. lock::lock(QObject *parent) : QThread(parent)
  7. {
  8. QLoggingCategory::setFilterRules("qt.serialport*=true");
  9. }
  10. void lock::slot_set_thread_stop(void)
  11. {
  12. this->threadstatus = false;
  13. }
  14. #define PRESET_VALUE 0xFFFF
  15. #define POLYNOMIAL 0xA001
  16. quint16 lock::uiCrc16Cal(QByteArray &data, quint8 count)
  17. {
  18. quint8 ucI,ucJ;
  19. quint16 uiCrcValue = PRESET_VALUE;
  20. for(ucI = 0; ucI < count; ucI++)
  21. {
  22. uiCrcValue = uiCrcValue ^ (quint8)(data.at(ucI));
  23. for(ucJ = 0; ucJ < 8; ucJ++)
  24. {
  25. if(uiCrcValue & 0x0001)
  26. {
  27. uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL;
  28. }
  29. else
  30. {
  31. uiCrcValue = (uiCrcValue >> 1);
  32. }
  33. }
  34. }
  35. return uiCrcValue;
  36. }
  37. // 发送数据给下位机
  38. void lock::sendData(QByteArray &sendData)
  39. {
  40. // qDebug() << "sendData: " << sendData.toHex();
  41. quint16 crc = uiCrc16Cal(sendData, sendData.size());
  42. // 输出CRC16校验和
  43. // qDebug() << "CRC16:" << QString::number(crc, 16).toUpper();
  44. sendData.append((quint8)crc);
  45. sendData.append((quint8)(crc >> 8));
  46. // qDebug() << "QByteArray: " << sendData.toHex();
  47. // 发送数据帧
  48. // this->devserial->clear(QSerialPort::AllDirections);
  49. qint64 bytesWritten = this->devserial->write(sendData);
  50. if (bytesWritten == -1) {
  51. qWarning() << "Failed to write data:" << this->devserial->errorString();
  52. }
  53. // 等待数据写入完成
  54. if (!this->devserial->waitForBytesWritten(1000)) {
  55. qWarning() << "Timeout: Failed to write data within 5000 milliseconds.";
  56. }
  57. }
  58. // 读取下位机发来数据
  59. bool lock::readData(QByteArray *data, quint16 timeout)
  60. {
  61. if(!this->devserial->waitForReadyRead(timeout))
  62. {
  63. return false;
  64. }
  65. msleep(100);
  66. *data = this->devserial->readAll();
  67. qDebug() << "readData: " << data->toHex();
  68. quint8 addr = data->at(0);
  69. if(addr == ELECTLOCKBOARD_ADDR || addr == 0x90)
  70. {
  71. quint16 crc1 = uiCrc16Cal(*data, data->size() - 2);
  72. quint16 crc2 = quint8(data->at(data->size() - 1));
  73. crc2 <<= 8;
  74. crc2 += quint8(data->at(data->size() - 2));
  75. if(crc1 == crc2)
  76. {
  77. return true;
  78. }
  79. }
  80. return false;
  81. }
  82. bool lock::openSerial(void)
  83. {
  84. this->devserial->setPortName(pconfig->lockPort); // 设定串口名称,根据你的系统修改
  85. this->devserial->setBaudRate(pconfig->lockBaud);
  86. this->devserial->setDataBits(QSerialPort::Data8);
  87. this->devserial->setParity(QSerialPort::NoParity);
  88. this->devserial->setStopBits(QSerialPort::OneStop);
  89. this->devserial->setFlowControl(QSerialPort::NoFlowControl);
  90. // this->devserial->setTextModeEnabled(true);
  91. if (this->devserial->open(QIODevice::ReadWrite)) {
  92. qDebug() << "电磁锁控板串口打开成功";
  93. this->devserial->setReadBufferSize(1024);
  94. //信号与槽函数关联
  95. // connect(devserial, &QSerialPort::readyRead, this, &uart::slot_uartReadData);
  96. return true;
  97. }
  98. return false;
  99. }
  100. void lock::slot_uartinfo_change(void)
  101. {
  102. if(openPort == true)
  103. {
  104. this->devserial->close();
  105. openPort = false;
  106. workstat = lockWorkStat::init;
  107. }
  108. }
  109. bool lock::slot_openLock(void)
  110. {
  111. if(workstat != lockWorkStat::init)
  112. {
  113. workstat = lockWorkStat::controlLock;
  114. return true;
  115. }
  116. else{
  117. return false;
  118. }
  119. }
  120. void lock::getBoardType(void)
  121. {
  122. quint8 dataArray[] = {ELECTLOCKBOARD_ADDR, 0x03, DEVTYPE_REG >> 8, DEVTYPE_REG, 0x00, 0x01};
  123. QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
  124. this->sendData(ba);
  125. QByteArray data;
  126. if(this->devserial->waitForReadyRead(1000))
  127. {
  128. msleep(200);
  129. data = this->devserial->readAll();
  130. int size = data.size();
  131. int idx = 0;
  132. if(size == 7)
  133. {
  134. QByteArray lockData = data.mid(idx, 5);
  135. // qDebug() << "lockData: " << lockData.toHex();
  136. quint16 crc1 = uiCrc16Cal(lockData, 5);
  137. quint16 crc2 = quint8(data.at(6));
  138. crc2 <<= 8;
  139. crc2 += quint8(data.at(5));
  140. if(crc1 != crc2)
  141. {
  142. return;
  143. }
  144. if((quint8)(lockData.at(0)) != ELECTLOCKBOARD_ADDR)
  145. {
  146. return;
  147. }
  148. if(lockData.at(1) != 0x03)
  149. {
  150. return;
  151. }
  152. if(lockData.at(2) != 0x02)
  153. {
  154. return;
  155. }
  156. // quint16 boardtype = 0x00;
  157. // boardtype = lockData.at(3);
  158. // boardtype <<= 8;
  159. // boardtype += lockData.at(4);
  160. // if(boardtype != DEVTYPE_ELECTLOCK)
  161. // {
  162. // break;
  163. // }
  164. workstat = lockWorkStat::readLockStat;
  165. emit signal_lock_run(true);
  166. }
  167. }
  168. else{
  169. qWarning() << "Timeout: No data received within 1000 milliseconds.";
  170. }
  171. }
  172. void lock::openLock(void)
  173. {
  174. // quint8 dataArray[] = {0x90, 0x06, 0x00, 0x08, 0x00, 0x01};
  175. quint8 dataArray[] = {ELECTLOCKBOARD_ADDR, 0x06, LOCKCONTRO_REG >> 8, LOCKCONTRO_REG, 0x03, 0x00};
  176. QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
  177. this->sendData(ba);
  178. QByteArray data;
  179. if(true == this->readData(&data, 1000))
  180. {
  181. workstat = lockWorkStat::readLockStat;
  182. }
  183. }
  184. void lock::openLight(void)
  185. {
  186. quint8 dataArray[] = {ELECTLOCKBOARD_ADDR, 0x06, LIGHTCONTROL_REG >> 8, LIGHTCONTROL_REG, 0x03, 0x00};
  187. if(setRightlightStat == true)
  188. {
  189. dataArray[5] = dataArray[5] | 0x02;
  190. }
  191. if(setLeftlightStat == true)
  192. {
  193. dataArray[5] = dataArray[5] | 0x01;
  194. }
  195. QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
  196. this->sendData(ba);
  197. QByteArray data;
  198. if(true == this->readData(&data, 1000))
  199. {
  200. workstat = lockWorkStat::readLockStat;
  201. }
  202. }
  203. void lock::readLockStat(void)
  204. {
  205. quint8 dataArray[] = {ELECTLOCKBOARD_ADDR, 0x03, LOCKCONTRO_REG >> 8, LOCKCONTRO_REG, 0x00, 0x01};
  206. QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
  207. this->sendData(ba);
  208. QByteArray data;
  209. if(this->devserial->waitForReadyRead(1000))
  210. {
  211. msleep(200);
  212. data = this->devserial->readAll();
  213. int size = data.size();
  214. int idx = 0;
  215. if(size == 7)
  216. {
  217. QByteArray lockData = data.mid(idx, 5);
  218. // qDebug() << "lockData: " << lockData.toHex();
  219. quint16 crc1 = uiCrc16Cal(lockData, 5);
  220. quint16 crc2 = quint8(data.at(6));
  221. crc2 <<= 8;
  222. crc2 += quint8(data.at(5));
  223. if(crc1 != crc2)
  224. {
  225. return;
  226. }
  227. if((quint8)(lockData.at(0)) != ELECTLOCKBOARD_ADDR)
  228. {
  229. return;
  230. }
  231. if(lockData.at(1) != 0x03)
  232. {
  233. return;
  234. }
  235. if(lockData.at(2) != 0x02)
  236. {
  237. return;
  238. }
  239. bool right = false;
  240. bool left = false;
  241. left = ((lockData.at(4) & 0x01) == 0x01)?true:false;
  242. right = ((lockData.at(4) & 0x02) == 0x02)?true:false;
  243. if(left != leftLockStat || right != rightLockStat)
  244. {
  245. leftLockStat = left;
  246. rightLockStat = right;
  247. setLeftlightStat = (leftLockStat == false)?true:false;
  248. setRightlightStat = (rightLockStat == false)?true:false;
  249. workstat = lockWorkStat::controlLight;
  250. emit signal_lockStat(leftLockStat, rightLockStat);
  251. }
  252. }
  253. }
  254. }
  255. void lock::run()
  256. {
  257. this->devserial = new QSerialPort;
  258. while(this->threadstatus)
  259. {
  260. if(pconfig->lockInit == true)
  261. {
  262. if(openPort == false)
  263. {
  264. openPort = this->openSerial();
  265. }
  266. else{
  267. switch(workstat)
  268. {
  269. case lockWorkStat::init:getBoardType();break;
  270. case lockWorkStat::readLockStat:readLockStat();break;
  271. case lockWorkStat::controlLock:openLock();break;
  272. case lockWorkStat::controlLight:openLight();break;
  273. }
  274. }
  275. }
  276. msleep(20);
  277. }
  278. if(openPort == true)
  279. {
  280. this->devserial->close();
  281. }
  282. qDebug() << "lock thread exit!";
  283. }