zoukankan      html  css  js  c++  java
  • #2020征文开发板#基于TCP控制鸿蒙3861三色灯板亮灭(附demo指导)

    目录:
    1.PC和Hi3861开发板之间使用无线连接到同一个局域网中
    2.Hi3861作为客户端,PC作为服务端建立TCP连接
    3.Hi3861作为客户端接受到PC端发送的相应指令来进行相应的控制三色灯板的操作
    4.源代码包

    跟着许思维老师的脚步,在许大神的影响之下才诞生了这个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);

    查看更多章节>>> 

     

    作者:Mr_qzk

    想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com/

  • 相关阅读:
    vuex状态管理
    vue3.0创建一个项目
    Django + Vue
    Django部署
    django简单使用
    Django模型
    Centos7编译openjdk8源码
    深入了解final
    深入了解java值传递
    java自带的Logger日志系统
  • 原文地址:https://www.cnblogs.com/HarmonyOS/p/14235438.html
Copyright © 2011-2022 走看看