plc_data.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // Created by zx on 2019/12/9.
  3. //
  4. #include "plc_data.h"
  5. #include <string.h>
  6. Plc_data *Plc_data::g_ins = 0;
  7. std::mutex Plc_data::g_lock;
  8. /**
  9. * 获取单例句柄
  10. * */
  11. Plc_data *Plc_data::get_instance(std::string ip)
  12. {
  13. if (g_ins == 0)
  14. {
  15. std::lock_guard<std::mutex> lock(g_lock);
  16. if (g_ins == 0)
  17. {
  18. if (ip != "")
  19. {
  20. g_ins = new Plc_data(ip);
  21. LOG(INFO) << "plc data, handle created";
  22. }
  23. else
  24. {
  25. return 0;
  26. }
  27. }
  28. }
  29. return g_ins;
  30. }
  31. // void Plc_data::Release()
  32. // {
  33. // if (g_ins)
  34. // {
  35. // g_ins->m_cond_exit.Notify(true);
  36. // LOG(INFO) << "plc data, try to exit plc send thread";
  37. // g_lock.lock();
  38. // if (g_ins->p_send_thread)
  39. // {
  40. // LOG(INFO) << "plc data, try to join plc send thread";
  41. // // LOG(INFO) << g_ins->p_send_thread->joinable();
  42. // if (g_ins->p_send_thread->joinable())
  43. // g_ins->p_send_thread->join();
  44. // LOG(INFO) << "plc data, try to delete plc send thread";
  45. // delete g_ins->p_send_thread;
  46. // g_ins->p_send_thread = 0;
  47. // LOG(INFO) << "plc data, delete data send thread";
  48. // }
  49. // g_lock.unlock();
  50. // LOG(INFO) << "plc data, start to exit plc handle";
  51. // // if(g_instance->p_plc){
  52. // // LOG(INFO)<<"plc data, try to delete plc handle";
  53. // // delete g_instance->p_plc;
  54. // // g_instance->p_plc = 0;
  55. // // }
  56. // // LOG(INFO)<<"plc data, delete plc handle";
  57. // LOG(INFO) << "plc data, delete instance";
  58. // // delete g_ins;
  59. // // g_ins = 0;
  60. // LOG(INFO) << "plc data, instance deleted";
  61. // }
  62. // else
  63. // {
  64. // LOG(WARNING) << "plc data, cannot find the instance";
  65. // }
  66. // }
  67. /**
  68. * 更新区域状态
  69. * */
  70. void Plc_data::update_data(int state_code, int border_status, int id)
  71. {
  72. // LOG(INFO) << "plc data 更新数据 id: "<<id<<", code: "<<state_code;
  73. if(id<0 || id>=MAX_REGIONS)
  74. return ;
  75. std::lock_guard<std::mutex> lock(g_lock);
  76. m_data[2 * id] = state_code;
  77. m_data[2 * id + 1] = border_status;
  78. }
  79. /**
  80. * plc更新线程,将区域状态写入plc
  81. * */
  82. void Plc_data::plc_update_thread(Plc_data *p)
  83. {
  84. if (p == 0)
  85. {
  86. LOG(ERROR) << "plc update thread null pointer";
  87. return;
  88. }
  89. while (!p->m_cond_exit.wait_for_millisecond(1))
  90. {
  91. // 判断plc状态
  92. if (p->m_plc.getConnection() && p->mb_is_ready)
  93. {
  94. for (int i = 0; i < ELE_FENCE_COUNT; ++i)
  95. {
  96. g_lock.lock();
  97. p->mb_is_ready = p->m_plc.WriteShorts(ELE_FENCE_DB_NUM,
  98. ELE_FENCE_BOUNDARY_START_ADDR + i * ELE_FENCE_OFFSET,
  99. 2,
  100. p->m_data + (i * 2));
  101. memcpy(p->m_last_data + (i * 2), p->m_data + (i * 2), 2 * sizeof(short));
  102. g_lock.unlock();
  103. usleep(10 * 1000);
  104. }
  105. }
  106. else
  107. {
  108. // 重连plc
  109. LOG(WARNING) << "find plc connection error, trying to reconnect.";
  110. g_lock.lock();
  111. p->m_plc.disconnect();
  112. // LOG(WARNING) << "find plc connection error, diconnect first.";
  113. if (p->m_ip_str != "")
  114. {
  115. p->mb_is_ready = p->m_plc.connect(p->m_ip_str);
  116. // LOG(WARNING) << "find plc connection error, trying to connect";
  117. if (p->mb_is_ready)
  118. {
  119. LOG(INFO) << "successfully reconnect.";
  120. }
  121. else
  122. {
  123. LOG(WARNING) << "failed to connect plc.";
  124. }
  125. }
  126. g_lock.unlock();
  127. usleep(p->m_update_interval_milli * 5 * 1000);
  128. }
  129. usleep(p->m_update_interval_milli * 1000);
  130. }
  131. }
  132. /**
  133. * 有参构造
  134. * */
  135. Plc_data::Plc_data(std::string ip) : mp_update_thread(0),
  136. m_ip_str(""),
  137. mb_is_ready(0)
  138. {
  139. m_ip_str = ip;
  140. memset(m_data, 0, MAX_REGIONS*2 * sizeof(short));
  141. memset(m_last_data, 0, MAX_REGIONS*2 * sizeof(short));
  142. // p_plc = new S7PLC();
  143. if (m_ip_str != "")
  144. {
  145. if (m_plc.connect(m_ip_str))
  146. {
  147. mb_is_ready = true;
  148. }
  149. else
  150. {
  151. LOG(ERROR) << "Plc_data instance, connect failed";
  152. }
  153. }
  154. else
  155. {
  156. LOG(ERROR) << "Plc_data instance, empty ip string.";
  157. }
  158. m_cond_exit.notify_all(false);
  159. mp_update_thread = new std::thread(plc_update_thread, this);
  160. mp_update_thread->detach();
  161. }
  162. /**
  163. * 获取plc连接状态
  164. * */
  165. bool Plc_data::get_plc_status()
  166. {
  167. return mb_is_ready;
  168. }