RC.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-05-17 19813 the first version
  9. */
  10. /*********************↓ define ↓************************/
  11. //#define LOG_TAG "RC"
  12. //#define DBG_LVL DBG_LOG
  13. #define Sensor_PWR_ON HAL_GPIO_WritePin(CONTROL_12V_GPIO_Port, CONTROL_12V_Pin, 1)
  14. #define Sensor_PWR_OFF HAL_GPIO_WritePin(CONTROL_12V_GPIO_Port, CONTROL_12V_Pin, 0)
  15. /*********************↑ define ↑************************/
  16. /**
  17. *
  18. *
  19. *
  20. *
  21. * */
  22. /*********************↓ include ↓************************/
  23. //#include <rtdbg.h>
  24. #include "RC.h"
  25. #include "string.h"
  26. #include "modbus_host.h"
  27. /*********************↑ include ↑************************/
  28. /**
  29. *
  30. *
  31. *
  32. *
  33. * */
  34. /*********************↓ extern ↓************************/
  35. extern uint16_t CRC16_Modbus(uint8_t *_pBuf, uint16_t _usLen); // 生成CRC16
  36. extern uint8_t check_link(void); // 检查联网状态
  37. extern void CMD_Find(void); // 执行命令
  38. extern void MQTT_Send_Pub(uint8_t type); // 向pub发送数据
  39. extern void RS485_SendBuf(uint8_t *_ucaBuf, uint16_t _usLen, UART_HandleTypeDef *uart); // 向485发送数据
  40. extern uint8_t Valve_Mode; // 阀控模式
  41. extern uint8_t Expand_Guard_T; // 用于扩容警戒线程的时间
  42. extern uint8_t Wait_Cmd; // 检索命令循环圈数
  43. extern uint8_t cache_buff[]; // 临时缓存
  44. extern uint8_t CMD_Find_Flag;
  45. extern uint16_t CMD_Find_Cnt;
  46. extern uint8_t CMD_Find_Buf[];
  47. extern MODH_T g_tModH;
  48. extern UART_HandleTypeDef huart2;
  49. /*********************↑ extern ↑************************/
  50. /**
  51. *
  52. *
  53. *
  54. *
  55. * */
  56. /********************↓ declaration ↓***********************/
  57. uint8_t DTU_Service(void);
  58. uint8_t str2hex(uint8_t *str, uint8_t *bin);
  59. /********************↑ declaration ↑***********************/
  60. /**
  61. *
  62. *
  63. *
  64. *
  65. * */
  66. /*********************↓ global variables ↓************************/
  67. volatile uint8_t RC_Mode = Zero; // 用于控制远程控制模式得进出
  68. /*********************↑ global variables ↑************************/
  69. /**
  70. *
  71. *
  72. *
  73. *
  74. * */
  75. /**联网上报数据以后,(处理完遗嘱信息后),调用
  76. * @brief 用于执行远程控制模式服务
  77. *
  78. * @return uint8_t 返回值为0 则服务需继续执行 不为0则退出
  79. */
  80. extern void report_update(void);
  81. uint8_t RC_Service(void)
  82. {
  83. uint8_t res = 0;
  84. report_update();
  85. /**
  86. * @brief 前置条件 使能远控模式
  87. *
  88. */
  89. if (RC_Mode != One)
  90. {
  91. return 1;
  92. }
  93. /**
  94. * @brief 前置条件 需要LTE模式
  95. *
  96. */
  97. // if (Node_Type != LTE)
  98. // {
  99. // return 3;
  100. // }
  101. rt_kprintf("RC ^");
  102. Expand_Guard_T = One; // 扩容警戒时间
  103. Sensor_PWR_ON;
  104. rt_kprintf(" \nRC ^Expand_Guard_T =%d\r\n",Expand_Guard_T);
  105. uint16_t CountdownMAX = 90; // 用于倒计时
  106. uint32_t Countdown = 0; // 用于倒计时
  107. uint16_t Base_Secson = 1000;// 计数基准
  108. if (check_link() == 1)
  109. {
  110. rt_sprintf((char *)cache_buff, "RC in");
  111. MQTT_Send_Pub(1);
  112. //check_link_flag = 1;
  113. }
  114. // 等待指令并响应
  115. while ((Countdown < CountdownMAX * Base_Secson) && (RC_Mode == One))
  116. {
  117. if (Countdown % (Base_Secson) == 0) // 隔段时间检查下在线情况
  118. {
  119. rt_kprintf("RC %d/%d\n", Countdown / Base_Secson, CountdownMAX);
  120. if (check_link() != 1) // 确保在线
  121. {
  122. //check_link_flag = 0;
  123. rt_thread_mdelay(10);
  124. if (check_link() != 1)
  125. {
  126. rt_thread_mdelay(10);
  127. Recode_e_code(28, 0);
  128. break;
  129. }
  130. //check_link_flag = 1;
  131. //check_link_oneflag = 1;
  132. }
  133. }
  134. Countdown++;
  135. rt_thread_mdelay(10);
  136. if (CMD_Find_Flag == 1 && CMD_Find_Cnt > 20)
  137. {
  138. Wait_Cmd = 1;
  139. DTU_Service(); //透传指令
  140. CMD_Find(); //在线指令
  141. }
  142. rt_thread_mdelay(10);
  143. }
  144. Sensor_PWR_OFF;
  145. if ((check_link() == 1) && (Countdown >= CountdownMAX * Base_Secson))
  146. {
  147. rt_sprintf((char *)cache_buff, "RC timeout");
  148. MQTT_Send_Pub(1);
  149. }
  150. return res;
  151. }
  152. /**
  153. * @brief 用于对485进行透传
  154. *
  155. * @return uint8_t 1失败 0成功
  156. */
  157. uint8_t DTU_Service(void)
  158. {
  159. if (strstr((const char *)CMD_Find_Buf, "cmd_s") == NULL)
  160. {
  161. return 1;
  162. }
  163. uint8_t cmdhex[15] = {0}; // 存放hex的指令
  164. uint8_t cmdcnt = 0; // hex个数
  165. int i=0;
  166. for(i=70;i<CMD_Find_Cnt;i++)
  167. {
  168. //rt_kprintf("i%d:%c\t",i,CMD_Find_Buf[i]);
  169. if(CMD_Find_Buf[i+0] == 'c' && CMD_Find_Buf[i+1] == 'm' && \
  170. CMD_Find_Buf[i+2] == 'd' && CMD_Find_Buf[i+3] == '_' && \
  171. CMD_Find_Buf[i+4] == 's' && CMD_Find_Buf[i+6] == ':')
  172. {
  173. break;
  174. }
  175. }
  176. cmdcnt = str2hex((uint8_t *)(CMD_Find_Buf + i+8), (uint8_t *)cmdhex);
  177. uint16_t crc = CRC16_Modbus(cmdhex, cmdcnt);
  178. cmdhex[cmdcnt++] = (uint8_t)(crc >> 8);
  179. cmdhex[cmdcnt++] = (uint8_t)(crc & 0xFF);
  180. if (cmdcnt < 3)
  181. {
  182. rt_sprintf((char *)cache_buff, "format ×");
  183. MQTT_Send_Pub(1);
  184. //format_uartbuf(5);
  185. return 1;
  186. }
  187. memset(g_tModH.RxBuf, 0, 64);
  188. g_tModH.RxCount = 0;
  189. RS485_SendBuf((uint8_t *)cmdhex, cmdcnt, &huart2);
  190. uint8_t a_time = 0;
  191. for (a_time = 0; a_time < 200; a_time++)
  192. {
  193. rt_thread_mdelay(10);
  194. if (g_tModH.RxCount > 3)
  195. {
  196. rt_thread_mdelay(30);
  197. break;
  198. }
  199. }
  200. memset(cache_buff, 0, 1024);
  201. if(g_tModH.RxCount == 0)
  202. {
  203. rt_sprintf((char *)cache_buff, "timeout");
  204. }
  205. else
  206. {
  207. for (uint8_t a = 0; a < g_tModH.RxCount; a++)
  208. {
  209. rt_sprintf((char *)cmdhex, "%02X ", g_tModH.RxBuf[a]);
  210. strcat((char *)cache_buff, (const char *)cmdhex);
  211. if((a + 1) == g_tModH.RxCount)
  212. {
  213. if(a_time > 5)
  214. {
  215. a_time -= 5; //时间修正
  216. }
  217. rt_sprintf((char *)cmdhex, "(%dms)", a_time * 10);
  218. strcat((char *)cache_buff, (const char *)cmdhex);
  219. }
  220. }
  221. }
  222. MQTT_Send_Pub(1);
  223. memset(g_tModH.RxBuf, 0, 64);
  224. g_tModH.RxCount = 0;
  225. return 0;
  226. }
  227. // 字符串转hex
  228. uint8_t str2hex(uint8_t *str, uint8_t *bin)
  229. {
  230. uint8_t count = 0;
  231. uint8_t one_byte = 0;
  232. for (uint8_t a = 0; a < strlen((const char *)str); a++)
  233. {
  234. one_byte = 0;
  235. if (str[a] != 0x20 && str[a + 1] != 0x20)
  236. {
  237. if (str[a] >= 0x30 && str[a] <= 0x39)
  238. {
  239. one_byte += (str[a] - 0x30) << 4;
  240. }
  241. else if (str[a] >= 0x41 && str[a] <= 0x46)
  242. {
  243. one_byte += (str[a] - 55) << 4;
  244. }
  245. else
  246. {
  247. return count;
  248. }
  249. if (str[a + 1] >= 0x30 && str[a + 1] <= 0x39)
  250. {
  251. one_byte += (str[a + 1] - 0x30);
  252. }
  253. else if (str[a + 1] >= 0x41 && str[a + 1] <= 0x46)
  254. {
  255. one_byte += (str[a + 1] - 55);
  256. }
  257. else
  258. {
  259. return count;
  260. }
  261. bin[count++] = one_byte;
  262. // rt_kprintf("%d byte : %d\n", count - 1, one_byte);
  263. a++;
  264. }
  265. }
  266. return count;
  267. }