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

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

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

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

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

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

这玩意,制鸿说简单也不简单,蒙色说复杂吧也不复杂。灯板导

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

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

import("//build/lite/config/component/lite_component.gni") lite_component("app") {      features = [         "iothardware:wifi_demo",蒙色     ] } 

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

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

2.Hi3861作为客户端,灯板导PC作为服务端建立TCP连接。亮灭

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

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

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

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

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

static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info) {      if (!info) return;     printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);     PrintLinkedInfo(info);     if (state == WIFI_STATE_AVALIABLE) {          g_connected = 1;     } else {          g_connected = 0;     } } static void OnWifiScanStateChanged(int state, int size) {      printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size); } 

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

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

 1.3 开始真正的wifi连接流程

(void)arg; WifiErrorCode errCode; WifiEvent eventListener = {      .OnWifiConnectionChanged = OnWifiConnectionChanged,     .OnWifiScanStateChanged = OnWifiScanStateChanged }; WifiDeviceConfig apConfig = { 0}; int netId = -1; osDelay(10); errCode = RegisterWifiEvent(&eventListener); printf("RegisterWifiEvent: %d\r\n", errCode); strcpy(apConfig.ssid, "helloworld"); strcpy(apConfig.preSharedKey, "12345678"); apConfig.securityType = WIFI_SEC_TYPE_PSK; errCode = EnableWifi(); printf("EnableWifi: %d\r\n", errCode); osDelay(10); errCode = AddDeviceConfig(&apConfig, &netId); printf("AddDeviceConfig: %d\r\n", errCode); g_connected = 0; errCode = ConnectTo(netId); printf("ConnectTo(%d): %d\r\n", netId, errCode); while (!g_connected) {      osDelay(10); } printf("g_connected: %d\r\n", g_connected); osDelay(50); struct netif* iface = netifapi_netif_find("wlan0"); if (iface) {      err_t ret = netifapi_dhcp_start(iface);     printf("netifapi_dhcp_start: %d\r\n", ret);     osDelay(200); // wait DHCP server give me IP     ret = netifapi_netif_common(iface, dhcp_clients_info_show, NULL);     printf("netifapi_netif_common: %d\r\n", ret); } 

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

2.1 先配置TCP协议

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

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

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

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

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

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

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

GpioInit();   IoSetFunc(RED_LED_PIN_NAME,RED_LED_PIN_FUNCTION);   IoSetFunc(GREEN_LED_PIN_NAME,GREEN_LED_PIN_FUNCTION);   IoSetFunc(RELLOW_LED_PIN_NAME,RELLOW_LED_PIN_FUNCTION);   GpioSetDir(RED_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT);   GpioSetDir(GREEN_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT);   GpioSetDir(RELLOW_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT); 

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

if(strncmp(RED_ON,response,5) == 0){        printf("red on----------------");       GpioSetOutputVal(RED_LED_PIN_NAME,LED_BRIGHT);   }   else if(strncmp(RED_OFF,response,6) == 0){        printf("red off--------------");       GpioSetOutputVal(RED_LED_PIN_NAME,LED_DARK);   }else if(strncmp(GREEN_ON,response,7) == 0){        printf("red on----------------");       GpioSetOutputVal(GREEN_LED_PIN_NAME,LED_BRIGHT);   }   else if(strncmp(GREEN_OFF,response,8) == 0){        printf("red off--------------");       GpioSetOutputVal(GREEN_LED_PIN_NAME,LED_DARK);   }else       if(strncmp(RELLOW_ON,response,8) == 0){        printf("red on----------------");       GpioSetOutputVal(RELLOW_LED_PIN_NAME,LED_BRIGHT);   }   else if(strncmp(RELLOW_OFF,response,9) == 0){        printf("red off--------------");       GpioSetOutputVal(RELLOW_LED_PIN_NAME,LED_DARK);   }else   {        printf("error index");   } 

 上述所有源码见附件,香港云服务器有什么问题欢迎留言交流

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

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

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

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

系统运维
上一篇:只要我们做的是从目前的市场情况选择域名,从简单易记,从个性特征上,我们就可以找到一个好域名进行注册。域名注册进行域名记录和解析以及绑定网站后,客户可以通过URL登录您的网站。
下一篇:2. 不要花大价钱买域名,新手鉴别能力不足,容易投资失误。