led_protocol.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. //
  2. // Created by huli on 2021/12/23.
  3. //
  4. #include "led_protocol.h"
  5. Led_protocol::Led_protocol()
  6. {
  7. }
  8. Led_protocol::~Led_protocol()
  9. {
  10. led_protocol_uninit();
  11. }
  12. //led通信协议初始化, area_size必须为1~5
  13. Error_manager Led_protocol::led_protocol_init(int area_size)
  14. {
  15. led_communication_msg_init(area_size);
  16. m_encapsulate_flag = false;
  17. return Error_code::SUCCESS;
  18. }
  19. Error_manager Led_protocol::led_protocol_uninit()
  20. {
  21. return Error_code::SUCCESS;
  22. }
  23. Error_manager Led_protocol::led_protocol_reset()
  24. {
  25. m_encapsulate_flag = false;
  26. //清除缓存后, 直接初始化可以重置所有...
  27. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.clear();
  28. led_protocol_init();
  29. return Error_code::SUCCESS;
  30. }
  31. Error_manager Led_protocol::led_protocol_delete(int area_index)
  32. {
  33. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) !=
  34. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end())
  35. {
  36. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.erase(area_index);
  37. }
  38. return Error_code::SUCCESS;
  39. }
  40. //创建led消息, 参数输入需要显示的字符串即可
  41. std::string Led_protocol::create_led_message(int area_index, std::string show_string, unsigned short x, unsigned short y, unsigned short width, unsigned short heigth)
  42. {
  43. led_communication_area_create(area_index);
  44. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_show_string = show_string;
  45. unsigned short t_area_x = 0x8000+x; //区域 X 坐标,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位
  46. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[3] = t_area_x;
  47. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[4] = t_area_x>>8;
  48. unsigned short t_area_y = y; //区域 Y 坐标,以像素点为单位
  49. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[5] = t_area_y;
  50. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[6] = t_area_y>>8;
  51. unsigned short t_area_width = 0x8000+width; //区域宽度,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位
  52. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[7] = t_area_width;
  53. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[8] = t_area_width>>8;
  54. unsigned short t_area_height = heigth; //区域高度,以像素点为单位
  55. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[9] = t_area_height;
  56. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[10] = t_area_height>>8;
  57. return get_led_msg_total_string();
  58. }
  59. //获取led协议封装后的最终消息, 这个结果就可以直接tcp发送了
  60. std::string Led_protocol::get_led_msg_total_string()
  61. {
  62. led_communication_total_encapsulate();
  63. return m_led_communication_msg.m_total_string;
  64. }
  65. //获取led协议封装后的最终消息, 这个结果就可以直接tcp发送了
  66. std::string Led_protocol::get_led_msg_total_string(int area_index)
  67. {
  68. led_communication_total_encapsulate(area_index);
  69. return m_led_communication_msg.m_total_string;
  70. }
  71. //设置显示的内容
  72. Error_manager Led_protocol::set_show_string(int area_index, std::string show_string)
  73. {
  74. led_communication_area_create(area_index);
  75. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_show_string = show_string;
  76. return Error_code::SUCCESS;
  77. }
  78. //设置显示的矩形框, 单位像素点, (注:一个汉字为16*16像素)
  79. Error_manager Led_protocol::set_show_rectangle(int area_index, unsigned short x, unsigned short y, unsigned short width, unsigned short heigth)
  80. {
  81. led_communication_area_create(area_index);
  82. unsigned short t_area_x = 0x8000+x; //区域 X 坐标,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位
  83. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[3] = t_area_x;
  84. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[4] = t_area_x>>8;
  85. unsigned short t_area_y = y; //区域 Y 坐标,以像素点为单位
  86. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[5] = t_area_y;
  87. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[6] = t_area_y>>8;
  88. unsigned short t_area_width = 0x8000+width; //区域宽度,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位
  89. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[7] = t_area_width;
  90. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[8] = t_area_width>>8;
  91. unsigned short t_area_height = heigth; //区域高度,以像素点为单位
  92. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[9] = t_area_height;
  93. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[10] = t_area_height>>8;
  94. return Error_code::SUCCESS;
  95. }
  96. //设置显示的行间距
  97. Error_manager Led_protocol::set_lines_sizes(int area_index, unsigned char lines_sizes)
  98. {
  99. led_communication_area_create(area_index);
  100. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[12] = lines_sizes;
  101. return Error_code::SUCCESS;
  102. }
  103. //设置显示动态区运行模式
  104. Error_manager Led_protocol::set_run_mode(int area_index, unsigned char run_mode, unsigned short time_out)
  105. {
  106. led_communication_area_create(area_index);
  107. /*动态区运行模式
  108. 0—动态区数据循环显示。
  109. 1—动态区数据显示完成后静止显示最后一页数
  110. 据。
  111. 2—动态区数据循环显示,超过设定时间后数据仍
  112. 未更新时不再显示
  113. 3—动态区数据循环显示,超过设定时间后数据仍
  114. 未更新时显示 Logo 信息,Logo 信息即为动态区域
  115. 的最后一页信息
  116. 4—动态区数据顺序显示,显示完最后一页后就不
  117. 再显示
  118. 5—动态区数据顺序显示,超过设定次数后数据仍
  119. 未更新时不再显示*/
  120. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[13] = run_mode;
  121. //动态区数据超时时间,单位为 秒/次数 (若RunMode=5,则表示更新次数), , 默认0x0002
  122. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[14] = time_out;
  123. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[15] = time_out>>8;
  124. return Error_code::SUCCESS;
  125. }
  126. //设置显示的排版方式
  127. Error_manager Led_protocol::set_type_setting(int area_index, unsigned char type_setting)
  128. {
  129. led_communication_area_create(area_index);
  130. /* 排 版 方 式 ( 上 下 左 右 有 优 先 级 )
  131. 当 ExtendParaLen > 0,才发送该字节,否则不发送
  132. 0:表示先从左往右,再从上往下
  133. 1:表示先从右往左,再从上往下
  134. 2:表示先从上往下,再从左往右
  135. 3:表示先从上往下,再从右往左*/
  136. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[17] = type_setting;
  137. return Error_code::SUCCESS;
  138. }
  139. //设置显示的对齐方式
  140. Error_manager Led_protocol::set_text_alignment(int area_index, unsigned char text_alignment)
  141. {
  142. led_communication_area_create(area_index);
  143. /* 行(上下左右)字对齐方式
  144. Bit1 Bit0
  145. 0 0 ----左对齐(左右 默认)
  146. 0 1 ----右对齐(左右)
  147. 1 0 ----居中对齐(左右)
  148. Bit3 Bit2
  149. 0 0 ----上对齐(上下 默认)
  150. 0 1 ----下对齐(上下)
  151. 1 0 ----居中对齐(上下)*/
  152. unsigned char t_text_alignment = text_alignment;
  153. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[18] = t_text_alignment;
  154. return Error_code::SUCCESS;
  155. }
  156. //设置显示 是否单行显示 是否自动换行
  157. Error_manager Led_protocol::set_line_mode(int area_index, unsigned char single_line, unsigned char new_line)
  158. {
  159. led_communication_area_create(area_index);
  160. /*是否单行显示
  161. 0x01——单行显示
  162. 0x02——多行显示*/
  163. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[19] = single_line;
  164. /*是否自动换行
  165. 0x01——不自动换行,显示数据在换行时必须插入
  166. 换行符
  167. 0x02——自动换行,显示内容不需要换行符,但是
  168. 只能使用统一的中文字体和英文字体*/
  169. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[20] = new_line;
  170. return Error_code::SUCCESS;
  171. }
  172. //设置显示方式, 文字移动的方式
  173. Error_manager Led_protocol::set_display_mode(int area_index, unsigned char display_mode)
  174. {
  175. led_communication_area_create(area_index);
  176. /*显示方式,其定义如下:
  177. 0x01——静止显示
  178. 0x02——快速打出
  179. 0x03——向左移动
  180. 0x04——向右移动
  181. 0x05——向上移动
  182. 0x06——向下移动*/
  183. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[21] = display_mode;
  184. return Error_code::SUCCESS;
  185. }
  186. //设置显示速度 显示特技停留时间
  187. Error_manager Led_protocol::set_speed(int area_index, unsigned char speed, unsigned char stay_time)
  188. {
  189. led_communication_area_create(area_index);
  190. //显示速度, 默认0x00, 从0x00~0x18 数字越小速度越快
  191. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[23] = speed;
  192. //显示特技停留时间,单位为 0.5s, 默认0x0a, 如:0x0A,则停留5秒
  193. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[24] = stay_time;
  194. return Error_code::SUCCESS;
  195. }
  196. //led通信的区域数据, 新建, area_size为更新区域的索引编号//map里面没有就新建一个, 有就什么都不做.
  197. Error_manager Led_protocol::led_communication_area_create(int area_index)
  198. {
  199. //map里面没有就新建一个, 有就什么都不做.
  200. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) ==
  201. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end() )
  202. {
  203. unsigned short t_area_data_len = 0x0000; //区域的数据长度,就是 29-2+m_show_string.length(), 后面再赋值
  204. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[0] = t_area_data_len;
  205. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[1] = t_area_data_len>>8;
  206. unsigned char t_area_type = 0x00; //区域类型, 默认0x00
  207. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[2] = t_area_type;
  208. unsigned short t_area_x = 0x8000; //区域 X 坐标,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位
  209. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[3] = t_area_x;
  210. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[4] = t_area_x>>8;
  211. unsigned short t_area_y = 0x0000; //区域 Y 坐标,以像素点为单位
  212. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[5] = t_area_y;
  213. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[6] = t_area_y>>8;
  214. unsigned short t_area_width = 0x8020; //区域宽度,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位
  215. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[7] = t_area_width;
  216. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[8] = t_area_width>>8;
  217. unsigned short t_area_height = 0x0020; //区域高度,以像素点为单位
  218. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[9] = t_area_height;
  219. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[10] = t_area_height>>8;
  220. //这里的宽高默认为0x20和0x20, 即为32*32, 可以显示4个汉字.(每个汉字为16*16, 字母为8*16)
  221. unsigned char t_area_index = area_index; //动态区域编号
  222. //注意:该参数只对动态区有效,其他区域为默认值,动态区必须统一编号,编号从 0 开始递增。
  223. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[11] = t_area_index;
  224. unsigned char t_lines_sizes = 0x00; //行间距, 默认0x00
  225. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[12] = t_lines_sizes;
  226. unsigned char t_run_mode = 0x00; //动态区运行模式, 默认0x00
  227. /*动态区运行模式
  228. 0—动态区数据循环显示。
  229. 1—动态区数据显示完成后静止显示最后一页数
  230. 据。
  231. 2—动态区数据循环显示,超过设定时间后数据仍
  232. 未更新时不再显示
  233. 3—动态区数据循环显示,超过设定时间后数据仍
  234. 未更新时显示 Logo 信息,Logo 信息即为动态区域
  235. 的最后一页信息
  236. 4—动态区数据顺序显示,显示完最后一页后就不
  237. 再显示
  238. 5—动态区数据顺序显示,超过设定次数后数据仍
  239. 未更新时不再显示*/
  240. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[13] = t_run_mode;
  241. unsigned short t_timeout = 0x0002; //动态区数据超时时间,单位为 秒/次数 (若RunMode=5,则表示更新次数), , 默认0x0002
  242. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[14] = t_timeout;
  243. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[15] = t_timeout>>8;
  244. unsigned char t_extend_para_len = 0x00; //拓展位个数, 默认0x00, 如:0x0A,则拓展位为 10 位,
  245. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[16] = t_extend_para_len;
  246. unsigned char t_type_setting = 0x00; //排 版 方 式, 默认0x00,
  247. /* 排 版 方 式 ( 上 下 左 右 有 优 先 级 )
  248. 当 ExtendParaLen > 0,才发送该字节,否则不发送
  249. 0:表示先从左往右,再从上往下
  250. 1:表示先从右往左,再从上往下
  251. 2:表示先从上往下,再从左往右
  252. 3:表示先从上往下,再从右往左*/
  253. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[17] = t_type_setting;
  254. unsigned char t_text_alignment = 0x00; //字体对齐方式/区域数据排版, 默认0x00, 如:0x00, 左对齐 , 上对齐
  255. /* 行(上下左右)字对齐方式
  256. Bit1 Bit0
  257. 0 0 ----左对齐(左右 默认)
  258. 0 1 ----右对齐(左右)
  259. 1 0 ----居中对齐(左右)
  260. Bit3 Bit2
  261. 0 0 ----上对齐(上下 默认)
  262. 0 1 ----下对齐(上下)
  263. 1 0 ----居中对齐(上下)*/
  264. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[18] = t_text_alignment;
  265. unsigned char t_single_line = 0x02; //是否单行显示, 默认0x02, 0x01——单行显示 0x02——多行显示
  266. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[19] = t_single_line;
  267. unsigned char t_new_line = 0x01; //是否自动换行, 默认0x01,
  268. /*是否自动换行
  269. 0x01——不自动换行,显示数据在换行时必须插入
  270. 换行符
  271. 0x02——自动换行,显示内容不需要换行符,但是
  272. 只能使用统一的中文字体和英文字体*/
  273. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[20] = t_new_line;
  274. unsigned char t_display_mode = 0x01; //显示方式, 默认0x01, 如果显示内容较多, 就需要滚动显示, 就设为向上移动0x05
  275. /*显示方式,其定义如下:
  276. 0x01——静止显示
  277. 0x02——快速打出
  278. 0x03——向左移动
  279. 0x04——向右移动
  280. 0x05——向上移动
  281. 0x06——向下移动*/
  282. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[21] = t_display_mode;
  283. unsigned char t_exit_mode = 0x00; //退出方式, 默认0x00,
  284. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[22] = t_exit_mode;
  285. unsigned char t_speed = 0x00; //显示速度, 默认0x00, 从0x00~0x18 数字越小速度越快
  286. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[23] = t_speed;
  287. unsigned char t_stay_time = 0x0a; //显示特技停留时间,单位为 0.5s, 默认0x0a, 如:0x0A,则停留5秒
  288. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[24] = t_stay_time;
  289. unsigned int t_show_string_len = 0x00000000; //数据长度(包括换行,颜色等转义参数), 就是 m_show_string.length(), 后面再赋值
  290. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[25] = t_show_string_len;
  291. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[26] = t_show_string_len>>8;
  292. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[27] = t_show_string_len>>16;
  293. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[28] = t_show_string_len>>24;
  294. }
  295. return Error_code::SUCCESS;
  296. }
  297. //led通信的控制指令, 初始化, area_size为更新区域的数量, 默认为0
  298. Error_manager Led_protocol::led_communication_cmd_init(int area_size)
  299. {
  300. //led通信的区域数据, 在修改里面具体参数的时候初始化
  301. //多次修改也只初始化一次
  302. //初始化 led通信的控制指令, 结构体
  303. //0xA3 0x06 表示 发送实时显示区域数据
  304. unsigned char t_cmd_group = 0xA3; //命令分组编号
  305. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[0] = t_cmd_group;
  306. unsigned char t_cmd = 0x06; //命令编号
  307. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[1] = t_cmd;
  308. unsigned char t_response = 0x01; //是否要求控制器回复, 默认0x01
  309. /* 是否要求控制器回复。
  310. 0x01——控制器必须回复
  311. 0x02——控制器不必回复*/
  312. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[2] = t_response;
  313. unsigned char t_process_mode = 0x00; //处理模式, 默认0x00
  314. /* 当该字节为 0 时,收到动态信息后不再进行清区域
  315. 和初始化区域的操作,当该字节为 1 时,收到动态
  316. 信息后需要进行清区域和初始化区域的操作。*/
  317. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[3] = t_process_mode;
  318. unsigned char t_reserved = 0x00; //此处保留1个byte
  319. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[4] = t_reserved;
  320. unsigned char t_delete_area_num = 0x00; //要删除的区域个数, 默认0x00
  321. /* 要删除的区域个数。
  322. 注意:如果该值为 0xFF,则删除所有动态区数据。
  323. 如果该值为 0x00,则不删除区域。*/
  324. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[5] = t_delete_area_num;
  325. unsigned char t_updata_area_num = area_size; //要更新的区域个数, 默认0x00
  326. /* 要删除的区域个数。
  327. 注意:如果该值为 0xFF,则删除所有动态区数据。
  328. 如果该值为 0x00,则不删除区域。*/
  329. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[6] = t_updata_area_num;
  330. return Error_code::SUCCESS;
  331. }
  332. //led通信的物理传输层, 初始化, area_size为更新区域的数量, 默认为0
  333. Error_manager Led_protocol::led_communication_msg_init(int area_size)
  334. {
  335. led_communication_cmd_init(area_size);
  336. //初始化 led通信的物理传输层, 结构体
  337. memset(m_led_communication_msg.m_frame_head, 0xA5, 8); //帧头, 默认8个0xA5
  338. unsigned short t_dst_addr = 0xFFFE; //屏地址, 默认0xFFFE
  339. /* 屏地址。
  340. 在 PHY 层,广播地址定义如下:
  341. 0xFFFF 为广播地址 1,此种模式下,控制器不返回
  342. 数据,其可用于广播校时等命令。
  343. 0xFFFE 为广播地址 2,此种模式主要用于广播设置
  344. 屏参,控制器需返回数据。在返回的数据帧中,地
  345. 址也应为 0XFFFE。
  346. 0x8000~0xDFFF 地址为保留地址,对于物理层类型
  347. 为 TCP/IP 或 GPRS 这种不需要处理 DstAddr 的,可
  348. 将其目标地址设置为这个范围中的一个,默认设置
  349. 地址为 0x8000。*/
  350. m_led_communication_msg.m_frame_configuration[0] = t_dst_addr;
  351. m_led_communication_msg.m_frame_configuration[1] = t_dst_addr>>8;
  352. unsigned short t_src_addr = 0x8000; //屏地址, 默认0x8000
  353. /* 源地址,几个特殊地址定义如下:
  354. PC 客户端软件从 0x8000 开始,范围为
  355. 0x8000~0xDFFF,用来代表不同客户端软件;
  356. 0xE000~0xFFFE 为保留地址*/
  357. m_led_communication_msg.m_frame_configuration[2] = t_src_addr;
  358. m_led_communication_msg.m_frame_configuration[3] = t_src_addr>>8;
  359. unsigned char t_reserved = 0x00; //此处保留3个byte
  360. m_led_communication_msg.m_frame_configuration[4] = t_reserved;
  361. m_led_communication_msg.m_frame_configuration[5] = t_reserved;
  362. m_led_communication_msg.m_frame_configuration[6] = t_reserved;
  363. unsigned char t_option = 0x00; //选项, 默认0x00
  364. /* 当该字节的 BIT0 为 1 时,需要发送接下来的 16 字
  365. 节 BarCode,这么做是为了便于在线设置控制器 IP.
  366. 反之,当该字节的 BIT0 为 0 时,不需要发送接下来
  367. 的 16 字节 BarCode.
  368. 注意:
  369. 1. 只有设置 IP 命令需要将该字节的 BIT0 设置为 1
  370. 2. 上位机需要通过网络搜索命令来获取当前局域网
  371. 内所有控制卡的 BarCode*/
  372. m_led_communication_msg.m_frame_configuration[7] = t_option;
  373. unsigned char t_check_mode = 0x00; //校验模式, 默认0x00
  374. /* 校验值共两个字节
  375. 当该字节为 0 时,采用 CRC16 方式
  376. 当该字节为 1 时,采用和校验的方式,仅保留最低
  377. 位两个字节,采用小端模式
  378. 当该字节为 2 时,无校验,校验字节可以为任意值*/
  379. m_led_communication_msg.m_frame_configuration[8] = t_check_mode;
  380. unsigned char t_display_mode = 0x00; //显示模式, 默认0x00
  381. /* 0x00:普通模式,动态区与节目可同时显示,但各
  382. 区域不可重叠。
  383. 0x01:动态模式,优先显示动态区,无动态区则显
  384. 示节目,动态区与节目区可重叠。
  385. 注:特殊动态区不支持动态模式。*/
  386. m_led_communication_msg.m_frame_configuration[9] = t_display_mode;
  387. unsigned char t_device_type = LED_DEVICE_TYPE; //设备类型, 默认0x63
  388. /* 用于区分网络中不同的设备类型,定义如下:
  389. 0x51——BX-5K1
  390. 0x58——BX-5K2
  391. 0x53——BX-5MK2
  392. 0x54——BX-5MK1
  393. 0x61——BX-6K1
  394. 与 5K1 (0x51)兼容
  395. 0x62——BX-6K2
  396. 与 5MK1 (0x54) 兼容
  397. 0x63——BX-6K3
  398. 与 5K2,5MK2 (0x53/0x58)兼容
  399. 0x64——BX-6K1-YY
  400. 0x65——BX-6K2-YY
  401. 0x66——BX-6K3-YY*/
  402. m_led_communication_msg.m_frame_configuration[10] = t_device_type;
  403. unsigned char t_protocol_version = 0x02; //协议版本号, 默认0x02
  404. //协议版本号,用于区分控制卡使用的协议
  405. m_led_communication_msg.m_frame_configuration[11] = t_protocol_version;
  406. unsigned short t_data_len = 0; //数据域长度(不包括帧头、帧尾、帧校验和包头), 这里指通信指令, 后面再赋值
  407. m_led_communication_msg.m_frame_configuration[12] = t_data_len;
  408. m_led_communication_msg.m_frame_configuration[13] = t_data_len>>8;
  409. unsigned short t_crc = 0; //crc校验码, 包校验为包头数据和数据域的校验值, 后面再赋值
  410. m_led_communication_msg.m_frame_crc[0] = t_crc;
  411. m_led_communication_msg.m_frame_crc[1] = t_crc>>8;
  412. memset(m_led_communication_msg.m_frame_tail, 0x5A, 1); //帧尾, 默认1个0x5A
  413. return Error_code::SUCCESS;
  414. }
  415. //led通信的区域数据, 通过协议转化, m_led_communication_area 封装成 m_total_string
  416. Error_manager Led_protocol::led_communication_area_encapsulate()
  417. {
  418. for (auto iter = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.begin();
  419. iter != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end(); ++iter)
  420. {
  421. //1.填写区域数据长度, 后面的27byte加显示字符串
  422. unsigned short t_area_data_len = 29-2+iter->second.m_show_string.length();
  423. iter->second.m_area_head[0] = t_area_data_len;
  424. iter->second.m_area_head[1] = t_area_data_len>>8;
  425. //2.填写显示字符串长度
  426. unsigned int t_show_string_len = iter->second.m_show_string.length();
  427. iter->second.m_area_head[25] = t_show_string_len;
  428. iter->second.m_area_head[26] = t_show_string_len>>8;
  429. iter->second.m_area_head[27] = t_show_string_len>>16;
  430. iter->second.m_area_head[28] = t_show_string_len>>24;
  431. //3.汇总字符串
  432. iter->second.m_total_string = std::string( (char*)iter->second.m_area_head, 29);
  433. iter->second.m_total_string += iter->second.m_show_string;
  434. }
  435. return Error_code::SUCCESS;
  436. }
  437. //led通信的区域数据, 通过协议转化, m_led_communication_area 封装成 m_total_string
  438. Error_manager Led_protocol::led_communication_area_encapsulate(int area_index)
  439. {
  440. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) !=
  441. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end())
  442. {
  443. auto & second = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index];
  444. //1.填写区域数据长度, 后面的27byte加显示字符串
  445. unsigned short t_area_data_len = 29-2+second.m_show_string.length();
  446. second.m_area_head[0] = t_area_data_len;
  447. second.m_area_head[1] = t_area_data_len>>8;
  448. //2.填写显示字符串长度
  449. unsigned int t_show_string_len = second.m_show_string.length();
  450. second.m_area_head[25] = t_show_string_len;
  451. second.m_area_head[26] = t_show_string_len>>8;
  452. second.m_area_head[27] = t_show_string_len>>16;
  453. second.m_area_head[28] = t_show_string_len>>24;
  454. //3.汇总字符串
  455. second.m_total_string = std::string( (char*)second.m_area_head, 29);
  456. second.m_total_string += second.m_show_string;
  457. }
  458. return Error_code::SUCCESS;
  459. }
  460. //led通信的控制指令, 通过协议转化, m_led_communication_cmd 封装成 m_total_string
  461. Error_manager Led_protocol::led_communication_cmd_encapsulate()
  462. {
  463. //1.填写更新区域的个数
  464. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[6] =
  465. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.size();
  466. //2.汇总字符串
  467. m_led_communication_msg.m_led_communication_cmd.m_total_string =
  468. std::string( (char*)m_led_communication_msg.m_led_communication_cmd.m_cmd_head, 7);
  469. for (auto iter = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.begin();
  470. iter != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end(); ++iter)
  471. {
  472. m_led_communication_msg.m_led_communication_cmd.m_total_string += iter->second.m_total_string;
  473. }
  474. return Error_code::SUCCESS;
  475. }
  476. //led通信的控制指令, 通过协议转化, m_led_communication_cmd 封装成 m_total_string
  477. Error_manager Led_protocol::led_communication_cmd_encapsulate(int area_index)
  478. {
  479. //1.填写更新区域的个数
  480. m_led_communication_msg.m_led_communication_cmd.m_cmd_head[6] = 1;
  481. //2.汇总字符串
  482. m_led_communication_msg.m_led_communication_cmd.m_total_string =
  483. std::string( (char*)m_led_communication_msg.m_led_communication_cmd.m_cmd_head, 7);
  484. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) !=
  485. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end())
  486. {
  487. m_led_communication_msg.m_led_communication_cmd.m_total_string +=
  488. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_total_string;
  489. }
  490. return Error_code::SUCCESS;
  491. }
  492. //led通信的物理传输层, 通过协议转化, m_led_communication_msg 封装成 m_total_string
  493. Error_manager Led_protocol::led_communication_msg_encapsulate()
  494. {
  495. //1.填写指令的长度
  496. unsigned short t_data_len = m_led_communication_msg.m_led_communication_cmd.m_total_string.length();
  497. m_led_communication_msg.m_frame_configuration[12] = t_data_len;
  498. m_led_communication_msg.m_frame_configuration[13] = t_data_len>>8;
  499. //2.计算crc校验码, 需要使用包头和指令
  500. std::string t_result_src = std::string((char*)m_led_communication_msg.m_frame_configuration, 14);
  501. t_result_src += m_led_communication_msg.m_led_communication_cmd.m_total_string;
  502. unsigned short t_crc = crc16((unsigned char *)t_result_src.c_str(), t_result_src.length());
  503. m_led_communication_msg.m_frame_crc[0] = t_crc;
  504. m_led_communication_msg.m_frame_crc[1] = t_crc>>8;
  505. //3.字符转义, 需要使用包头和指令和crc校验码
  506. t_result_src += std::string( (char*)m_led_communication_msg.m_frame_crc, 2);
  507. int t_result_src_length=t_result_src.length();
  508. unsigned char t_result_dst[1024] = {0};//转义后的临时缓存, 长度上限1024
  509. int t_result_dst_length=0;
  510. character_escape(t_result_dst, &t_result_dst_length, (unsigned char *)t_result_src.c_str(), &t_result_src_length);
  511. //4.汇总字符串
  512. std::string str1 = std::string((char*)m_led_communication_msg.m_frame_head, 8);
  513. std::string str2 = std::string((char*)t_result_dst, t_result_dst_length);
  514. std::string str3 = std::string((char*)m_led_communication_msg.m_frame_tail, 1);
  515. m_led_communication_msg.m_total_string = str1 + str2 + str3;
  516. return Error_code::SUCCESS;
  517. }
  518. //led通信的物理传输层, 通过协议转化, m_led_communication_msg 封装成 m_total_string
  519. Error_manager Led_protocol::led_communication_msg_encapsulate(int area_index)
  520. {
  521. return led_communication_msg_encapsulate();
  522. }
  523. //led通信协议的整体封装
  524. Error_manager Led_protocol::led_communication_total_encapsulate()
  525. {
  526. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.size() <=0 )
  527. {
  528. m_encapsulate_flag = false;
  529. m_led_communication_msg.m_total_string.clear();
  530. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  531. " fun error m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.size() <=0");
  532. }
  533. led_communication_area_encapsulate();
  534. led_communication_cmd_encapsulate();
  535. led_communication_msg_encapsulate();
  536. m_encapsulate_flag = true;
  537. return Error_code::SUCCESS;
  538. }
  539. //led通信协议的整体封装
  540. Error_manager Led_protocol::led_communication_total_encapsulate(int area_index)
  541. {
  542. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) ==
  543. m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end() )
  544. {
  545. m_encapsulate_flag = false;
  546. m_led_communication_msg.m_total_string.clear();
  547. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  548. " fun error m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find() error ");
  549. }
  550. led_communication_area_encapsulate(area_index);
  551. led_communication_cmd_encapsulate(area_index);
  552. led_communication_msg_encapsulate(area_index);
  553. m_encapsulate_flag = true;
  554. return Error_code::SUCCESS;
  555. }
  556. //crc校验码
  557. unsigned short Led_protocol::crc16(unsigned char * data,int size)
  558. {
  559. unsigned char data_t ;
  560. unsigned short crc,i,j;
  561. crc = i = j = 0;
  562. if(data == NULL)
  563. {
  564. return 0;
  565. }
  566. for(j=0;j<size;j++)
  567. {
  568. data_t = data[j];
  569. crc = (data_t ^ crc);
  570. for(i=0;i<8;i++)
  571. {
  572. if((crc&0x1)==1)
  573. {
  574. crc = (crc >> 1) ^ 0xA001;
  575. }
  576. else
  577. {
  578. crc >>= 1;
  579. }
  580. }
  581. }
  582. return crc;
  583. }
  584. //字符转义
  585. void Led_protocol::character_escape(unsigned char * p_dst, int * p_dst_length, unsigned char * p_src, int * p_src_length)
  586. {
  587. /* 字符转义
  588. ◆ 封帧中遇到 0xA5,则将之转义为 0xA6,0x02;如遇到 0xA6,则将之转义为 0xA6,0x01 。
  589. ◆ 封帧中遇到 0x5A,则将之转义为 0x5B,0x02;如遇到 0x5B,则将之转义为 0x5B,0x01 。
  590. ◆ 解帧过程如果遇到连续两个字节为 0xA6, 0x02 ,则反转义为 0xA5 。
  591. ◆ 解帧过程如果遇到连续两个字节为 0xA6, 0x01 ,则反转义为 0xA6 。
  592. ◆ 解帧过程如果遇到连续两个字节为 0x5B, 0x02 ,则反转义为 0x5A。
  593. ◆ 解帧过程如果遇到连续两个字节为 0x5B, 0x01 ,则反转义为 0x5B。
  594. 注意:封帧过程中,所涉及校验的数据皆是转义之前的数据,所涉及的数据长度皆是转义之前的数据
  595. 长度。
  596. */
  597. if ( p_dst == NULL || p_src == NULL)
  598. {
  599. return;
  600. }
  601. int i=0;
  602. int j=0;
  603. for (i = 0; i < *p_src_length; ++i)
  604. {
  605. if ( p_src[i] == 0xA5 )
  606. {
  607. p_dst[j] = 0xA6;
  608. p_dst[j+1] = 0x02;
  609. j+=2;
  610. }
  611. else if ( p_src[i] == 0xA6 )
  612. {
  613. p_dst[j] = 0xA6;
  614. p_dst[j+1] = 0x01;
  615. j+=2;
  616. }
  617. else if ( p_src[i] == 0x5A )
  618. {
  619. p_dst[j] = 0x5B;
  620. p_dst[j+1] = 0x02;
  621. j+=2;
  622. }
  623. else if ( p_src[i] == 0x5B )
  624. {
  625. p_dst[j] = 0x5B;
  626. p_dst[j+1] = 0x01;
  627. j+=2;
  628. }
  629. else
  630. {
  631. p_dst[j] = p_src[i];
  632. j++;
  633. }
  634. }
  635. *p_dst_length = j;
  636. return;
  637. }
  638. //
  639. ////led通信的物理传输层, 通过协议转化, m_led_communication_msg -->> m_led_communication_string
  640. //Error_manager Led_protocol::led_communication_encapsulate()
  641. //{
  642. // unsigned char t_result_src[1024] = {0};//转义前的临时缓存, 长度上限1024
  643. // unsigned char t_result_dst[1024] = {0};//转义后的临时缓存, 长度上限1024
  644. // int t_result_src_length=0;
  645. // int t_result_dst_length=0;
  646. // memcpy(t_result_src+t_result_src_length, m_led_communication_msg.m_frame_configuration, 14);
  647. // t_result_src_length += 14;
  648. // memcpy(t_result_src+t_result_src_length, m_led_communication_msg.m_led_communication_cmd.m_total_string.c_str(), m_led_communication_msg.m_led_communication_cmd.m_total_string.length());
  649. // t_result_src_length += m_led_communication_msg.m_led_communication_cmd.m_total_string.length();
  650. // memcpy(t_result_src+t_result_src_length, m_led_communication_msg.m_frame_crc, 2);
  651. // t_result_src_length += 2;
  652. //
  653. // //字符转义
  654. // character_escape(t_result_dst, &t_result_dst_length, t_result_src, &t_result_src_length);
  655. //
  656. // std::string str1 = std::string((char*)m_led_communication_msg.m_frame_head, 8);
  657. // std::string str2 = std::string((char*)t_result_dst, t_result_dst_length);
  658. // std::string str3 = std::string((char*)m_led_communication_msg.m_frame_tail, 1);
  659. // m_led_communication_msg.m_total_string = str1 + str2 + str3;
  660. //
  661. // return Error_code::SUCCESS;
  662. //}
  663. //