基于TCP控制鸿蒙3861三色灯板亮灭(附Demo指导)

开发
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz

[[374609]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

跟着许思维老师的脚步,在许大神的影响之下才诞生了这个demo。

首先把整个demo跑起来的演示视频放上来,让大家看看最终实现的一个效果,视频链接(点击可看):基于TCP来控制鸿蒙Hi3861三色灯板的灯的亮灭。

这玩意,说简单也不简单,说复杂吧也不复杂。

这里先说一下demo源码如何使用:

这里我已经把整个demo源码作为附件上传了,大家把文件解压后放在源码目录中:applications/sample/wifi-iot/app文件夹下,然后修改该文件夹下的BUILD.gn,将其内容修改为:

  1. import("//build/lite/config/component/lite_component.gni"
  2.  
  3. lite_component("app") { 
  4.     features = [ 
  5.         "iothardware:wifi_demo"
  6.     ] 

 这里我还是先按照老规矩说一下总体的大概思路:

1.PC和Hi3861开发板之间使用无线连接到同一个局域网中。

2.Hi3861作为客户端,PC作为服务端建立TCP连接。

3.Hi3861作为客户端接受到PC端发送的相应指令来进行相应的控制三色灯板的操作。

说完了大概思路,就可以说操作需要注意的一个点了:在把Hi3861烧好之后进行测试的时候,需要先开启服务端(这里我是直接拿linux下的netcat,小伙伴完全可以换成自己熟悉的,都可以),然后在reset一下Hi3861开发板。

下面开始按照大概思路来分成三块讲解代码

1.PC和Hi3861开发板之间使用无线连接到同一个局域网中

1.1 首先定义了wifi需要的两个监听事件OnWifiConnectionChanged和OnWifiScanStateChanged

  1. static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info) 
  2.     if (!info) return
  3.  
  4.     printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state); 
  5.     PrintLinkedInfo(info); 
  6.  
  7.     if (state == WIFI_STATE_AVALIABLE) { 
  8.         g_connected = 1; 
  9.     } else { 
  10.         g_connected = 0; 
  11.     } 
  12. static void OnWifiScanStateChanged(int state, int size
  13.     printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size); 

 1.2 定义了一个打印wifi信息的辅助函数 

  1. static void PrintLinkedInfo(WifiLinkedInfo* info) 
  2.     if (!info) return
  3.     static char macAddress[32] = {0}; 
  4.     unsigned char* mac = info->bssid; 
  5.     snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X"
  6.         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 
  7.     printf("bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %s\r\n"
  8.         macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid); 

 1.3 开始真正的wifi连接流程

  1. (void)arg; 
  2. WifiErrorCode errCode; 
  3. WifiEvent eventListener = { 
  4.     .OnWifiConnectionChanged = OnWifiConnectionChanged, 
  5.     .OnWifiScanStateChanged = OnWifiScanStateChanged 
  6. }; 
  7. WifiDeviceConfig apConfig = {0}; 
  8. int netId = -1; 
  9. osDelay(10); 
  10. errCode = RegisterWifiEvent(&eventListener); 
  11. printf("RegisterWifiEvent: %d\r\n", errCode); 
  12. strcpy(apConfig.ssid, "helloworld"); 
  13. strcpy(apConfig.preSharedKey, "12345678"); 
  14. apConfig.securityType = WIFI_SEC_TYPE_PSK; 
  15. errCode = EnableWifi(); 
  16. printf("EnableWifi: %d\r\n", errCode); 
  17. osDelay(10); 
  18. errCode = AddDeviceConfig(&apConfig, &netId); 
  19. printf("AddDeviceConfig: %d\r\n", errCode); 
  20. g_connected = 0; 
  21. errCode = ConnectTo(netId); 
  22. printf("ConnectTo(%d): %d\r\n", netId, errCode); 
  23. while (!g_connected) { 
  24.     osDelay(10); 
  25. printf("g_connected: %d\r\n", g_connected); 
  26. osDelay(50); 
  27. struct netif* iface = netifapi_netif_find("wlan0"); 
  28. if (iface) { 
  29.     err_t ret = netifapi_dhcp_start(iface); 
  30.     printf("netifapi_dhcp_start: %d\r\n", ret); 
  31.     osDelay(200); // wait DHCP server give me IP 
  32.     ret = netifapi_netif_common(iface, dhcp_clients_info_show, NULL); 
  33.     printf("netifapi_netif_common: %d\r\n", ret); 

 2.Hi3861作为客户端,PC作为服务端建立TCP连接。

2.1 先配置TCP协议

  1. ssize_t retval = 0; 
  2. int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket 
  3. unsigned short port=5678; 
  4. struct sockaddr_in serverAddr = {0}; 
  5. serverAddr.sin_family = AF_INET;  // AF_INET表示IPv4协议 
  6. serverAddr.sin_port = htons(port);  // 端口号,从主机字节序转为网络字节序 
  7. if (inet_pton(AF_INET, PARAM_SERVER_ADDR, &serverAddr.sin_addr) <= 0) {  // 将主机IP地址从“点分十进制”字符串 转化为 标准格式(32位整数) 
  8. printf("inet_pton failed!\r\n"); 
  9. goto do_cleanup; 

 2.2 调用connect函数进行连接,这里确保连接之后,才可以

  1. if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) { 
  2.       printf("connect failed!\r\n"); 
  3.       goto do_cleanup; 
  4.   } 
  5.   printf("connect to server %s success!\r\n", PARAM_SERVER_ADDR); 

 2.3 调用recv接口接收从PC服务端发来的消息

  1. retval = recv(sockfd, &response, sizeof(response), 0); 
  2. if (retval <= 0) { 
  3.     printf("send response from server failed or done, %ld!\r\n", retval); 
  4.     goto do_cleanup; 
  5. response[retval] = '\0'
  6. printf("recv response{%s} %ld from server done!\r\n", response, retval); 

 3.Hi3861作为客户端接受到PC端发送的相应指令来进行相应的控制三色灯板的操作。

3.1 先进行Hi3861控制三色开发板的基础设置

  1. GpioInit(); 
  2.   IoSetFunc(RED_LED_PIN_NAME,RED_LED_PIN_FUNCTION); 
  3.   IoSetFunc(GREEN_LED_PIN_NAME,GREEN_LED_PIN_FUNCTION); 
  4.   IoSetFunc(RELLOW_LED_PIN_NAME,RELLOW_LED_PIN_FUNCTION); 
  5.   GpioSetDir(RED_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT); 
  6.   GpioSetDir(GREEN_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT); 
  7.   GpioSetDir(RELLOW_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT); 

 3.2 根据TCP协议接收到的信息,判断后选择GpioSetOutputVal进行三色灯开关控制

  1. if(strncmp(RED_ON,response,5) == 0){ 
  2.       printf("red on----------------"); 
  3.       GpioSetOutputVal(RED_LED_PIN_NAME,LED_BRIGHT); 
  4.   } 
  5.   else if(strncmp(RED_OFF,response,6) == 0){ 
  6.       printf("red off--------------"); 
  7.       GpioSetOutputVal(RED_LED_PIN_NAME,LED_DARK); 
  8.   }else if(strncmp(GREEN_ON,response,7) == 0){ 
  9.       printf("red on----------------"); 
  10.       GpioSetOutputVal(GREEN_LED_PIN_NAME,LED_BRIGHT); 
  11.   } 
  12.   else if(strncmp(GREEN_OFF,response,8) == 0){ 
  13.       printf("red off--------------"); 
  14.       GpioSetOutputVal(GREEN_LED_PIN_NAME,LED_DARK); 
  15.   }else 
  16.       if(strncmp(RELLOW_ON,response,8) == 0){ 
  17.       printf("red on----------------"); 
  18.       GpioSetOutputVal(RELLOW_LED_PIN_NAME,LED_BRIGHT); 
  19.   } 
  20.   else if(strncmp(RELLOW_OFF,response,9) == 0){ 
  21.       printf("red off--------------"); 
  22.       GpioSetOutputVal(RELLOW_LED_PIN_NAME,LED_DARK); 
  23.   }else 
  24.   { 
  25.       printf("error index"); 
  26.   } 

 上述所有源码见附件,有什么问题欢迎留言交流

ps:分享一个调试中困扰了我好长时间的一个问题,就是在调试过程中Hi3861的无线很不稳定,连接上一会儿就会掉,然后又连接,我一度以为是代码的问题,苦苦探求,之后才发现问题的根源是我公司的同时使用的wifi太多了,把无线信道都占了,导致我使用的只支持2.4G的小破路由器根本不稳定,给大家分享这个坑,遇到的话直接跳过去,别重蹈我的覆辙了......

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-08-05 19:37:59

鸿蒙Api框架

2023-01-08 13:46:49

2022-04-02 20:11:50

智慧交通灯鸿蒙操作系统

2021-08-06 11:46:46

Go三色标记法

2021-08-16 10:35:52

JVM标记法屏障

2020-12-31 12:22:15

鸿蒙Hi3861应用开发

2021-06-25 15:32:13

鸿蒙HarmonyOS应用

2022-08-15 08:01:00

三色标记JVM算法

2021-09-09 10:06:09

鸿蒙HarmonyOS应用

2020-12-15 11:57:49

Hi3861 HarmonyOS开发板

2021-09-16 10:03:39

鸿蒙HarmonyOS应用

2022-01-07 09:56:16

鸿蒙HarmonyOS应用

2020-07-09 15:45:22

GoGC内存

2023-06-19 07:12:51

JVM三色标记

2020-12-11 12:45:04

鸿蒙Hi3861游戏

2011-04-08 11:13:50

CISCO IOS令牌桶双桶

2021-09-28 10:02:26

鸿蒙HarmonyOS应用

2021-12-14 14:45:38

鸿蒙HarmonyOS应用

2012-06-12 11:28:51

精益扫描仪
点赞
收藏

51CTO技术栈公众号