导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. zwmasdf
    Z
    • 资料
    • 关注 0
    • 粉丝 0
    • 我的积分 256
    • 主题 2
    • 帖子 4
    • 最佳 1
    • 群组 0

    zwmasdfLV 3

    @zwmasdf

    256
    积分
    1
    声望
    1
    资料浏览
    4
    帖子
    0
    粉丝
    0
    关注
    注册时间 最后登录

    zwmasdf 取消关注 关注

    zwmasdf 发布的最佳帖子

    • 【XR806开发板试用】通过MQTT实现手机远程实现PWM控灯

      一、例程编译、烧录确认
      首先按照全志在线文档平台的点灯教程确保能正常编译、烧录和点灯:https://xr806.docs.aw-ol.com/study/soft_led/
      确保例程没问题后,我们再改造例程,实现我们想要的功能
      二、代码编写
      我们将led工程复制一份改文件夹名为mydemo,目录结构如下

          mydemo
          ├── BUILD.gn
          └── src
          └── main.c
      

      然后BUILD.gn内容增加头文件引用,部分配置如下:

      static_library("app_mydemo") {
      ...
      include_dirs += [
            "//kernel/liteos_m/kernel/arch/include",
            "//base/iot_hardware/peripheral/interfaces/kits",
      
            ".",
            "//utils/native/lite/include",
            "//foundation/communication/wifi_lite/interfaces/wifiservice",
            "//device/xradio/xr806/xr_skylark/project"
         ]
      }
      

      接下来是main.c,内容如下:

      #include <stdio.h>
      #include <string.h>
      #include "ohos_init.h"
      #include "kernel/os/os.h"
      
      #include "iot_gpio.h"
      #include "wifi_device.h"
      #include "common/framework/net_ctrl.h"
      #include "net/mqtt/MQTTClient-C/MQTTClient.h"
      #include "driver/chip/hal_pwm.h"
      
      static OS_Thread_t g_main_thread;
      static OS_Thread_t g_mqtt_thread;
      
      #define PWM_OUTPUT_CHL        PWM_GROUP1_CH2
      #define PWM_OUTPUT_MODE       PWM_CYCLE_MODE
      
      #define WIFI_DEVICE_CONNECT_AP_SSID "ssid"//这里填你家路由器的SSID
      #define WIFI_DEVICE_CONNECT_AP_PSK "pwm"//这里填你家路由器的PWD
      
      
      #define MQTT_DEMO_CLIENT_ID "12345"
      #define MQTT_DEMO_HOST_NAME "broker-cn.emqx.io"//这个是免费调试用的MQTT服务器地址
      #define MQTT_DEMO_PORT      "1883"
      #define MQTT_DEMO_USERNAME  "12345678"
      #define MQTT_DEMO_PASSWORD  "12345678"
      #define MQTT_RESP_TOPIC "/to/master/light" //手机发出来的TOPIC
      #define MQTT_RECV_TOPIC  "/to/slave/light" //设备发出来的TOPIC
      #define MQTT_DEMO_BUF_SIZE (2*1024)
      
      static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer;
      static Client mqtt_demo_client;
      static Network mqtt_demo_network;
      static int max_duty_ratio = 0;
      
      static int mqtt_demo_publish(char *topic, char *msg) ;
      
      static int mqtt_demo_init(void) {
      	char *send_buf;
      	char *recv_buf;
      
      	mqtt_demo_connectData.clientID.cstring = MQTT_DEMO_CLIENT_ID;
      	mqtt_demo_connectData.keepAliveInterval = 30; // 30s
      	mqtt_demo_connectData.cleansession = 0;
      	mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1
      
      	send_buf = malloc(MQTT_DEMO_BUF_SIZE);
      	if (send_buf == NULL) {
      		printf("no memory\n");
      		return -1;
      	}
      	recv_buf = malloc(MQTT_DEMO_BUF_SIZE);
      	if (recv_buf == NULL) {
      		free(send_buf);
      		printf("no memory\n");
      		return -1;
      	}
      
      	/* init network */
      	NewNetwork(&mqtt_demo_network);
      	/* init mqtt client object */
      	MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000,
      	           (unsigned char *)send_buf, MQTT_DEMO_BUF_SIZE,
      	           (unsigned char *)recv_buf, MQTT_DEMO_BUF_SIZE);
      
      	/* set username and password */
      	mqtt_demo_connectData.username.cstring = MQTT_DEMO_USERNAME;
      	mqtt_demo_connectData.password.cstring = MQTT_DEMO_PASSWORD;
      	return 0;
      }
      
      static int mqtt_demo_connect(char *host_name, char *host_port) {
      	int ret = -1;
      
      	ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port));
      	if (ret != 0) {
      		printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port);
      		goto exit;
      	}
      
      	ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData);
      	if (ret != 0) {
      		printf("mqtt connect faild, ret:%d\n", ret);
      		mqtt_demo_network.disconnect(&mqtt_demo_network);
      		goto exit;
      	}
      	printf("mqtt connected\n");
      exit:
      	return ret;
      }
      
      static void mqtt_demo_msg_cb(MessageData *data) {
      	printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len,
      	       data->topicName->lenstring.data, data->message->payloadlen,
      	       (char *)data->message->payload);
      	if(!strncmp(data->topicName->lenstring.data, "/to/slave/light", 15) && data->message->payloadlen) {
      		char *payload = data->message->payload;
      		char str[8] = "";
      		int max_len = data->message->payloadlen > 3 ? 3 : data->message->payloadlen;
      		strncpy(str, payload, max_len);
      		int duty = atoi(str);
      		HAL_Status status = HAL_PWM_ChSetDutyRatio(PWM_OUTPUT_CHL, duty * max_duty_ratio / 100);
      		if (status != HAL_OK)
      			printf("%s(): %d, PWM set duty ratio error\n", __func__, __LINE__);
      		
      		if(duty) {
      			mqtt_demo_publish(MQTT_RESP_TOPIC, "light on");
      		} else {
      			mqtt_demo_publish(MQTT_RESP_TOPIC, "light off");
      		}
      	} 
      }
      
      static int mqtt_demo_subscribe(char *topic) {
      	int ret = -1;
      	if (mqtt_demo_client.isconnected) {
      		ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb);
      		if (ret != 0)
      			printf("mqtt subscribe faild ret:%d\n", ret);
      	}
      	return ret;
      }
      
      static int mqtt_demo_unsubscribe(char *topic) {
      	int ret = -1;
      	if (mqtt_demo_client.isconnected) {
      		ret = MQTTUnsubscribe(&mqtt_demo_client, topic);
      		if (ret != 0)
      			printf("mqtt unsubscribe faild, ret:%d\n", ret);
      	}
      	return ret;
      }
      
      static int mqtt_demo_publish(char *topic, char *msg) {
      	int ret = -1;
      
      	MQTTMessage message;
      	memset(&message, 0, sizeof(message));
      	message.qos = 0;
      	message.retained = 0; /* disable retain the message in server */
      	message.payload = msg;
      	message.payloadlen = strlen(msg);
      	ret = MQTTPublish(&mqtt_demo_client, topic, &message);
      	if (ret != 0)
      		printf("mqtt publish faild, ret:%d\n", ret);
      	return ret;
      }
      
      static int mqtt_demo_disconnect(void) {
      	int ret = -1;
      
      	if (mqtt_demo_client.isconnected) {
      		ret = MQTTDisconnect(&mqtt_demo_client);
      		if (ret != 0)
      			printf("mqtt disconnect fail, ret:%d\n", ret);
      		mqtt_demo_network.disconnect(&mqtt_demo_network);
      	}
      	return ret;
      }
      
      static void mqtt_demo_deinit(void) {
      	if (mqtt_demo_client.buf) {
      		free(mqtt_demo_client.buf);
      		mqtt_demo_client.buf = NULL;
      	}
      	if (mqtt_demo_client.readbuf) {
      		free(mqtt_demo_client.readbuf);
      		mqtt_demo_client.readbuf = NULL;
      	}
      }
      
      static void mqtt_task(void *arg)   {
      	int ret;
      	int reconnect_times = 0;
      
      	mqtt_demo_init();
      
      	ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
      	if (ret != 0)
      		goto exit;
      
      	ret = mqtt_demo_subscribe(MQTT_RECV_TOPIC);
      	if (ret != 0)
      		goto exit;
      
      	mqtt_demo_publish(MQTT_RESP_TOPIC, "light ready");
      
      	while (1) {
      		ret = MQTTYield(&mqtt_demo_client, 300);
      		if (ret != 0) {
      			printf("mqtt yield err, ret:%d\n", ret);
      reconnect:
      			printf("mqtt reconnect\n");
      			mqtt_demo_disconnect();
      			ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
      			if (ret != 0) {
      				reconnect_times++;
      				if (reconnect_times > 5)
      					goto exit;
      				OS_MSleep(5000); //5s
      				goto reconnect;
      			}
      		}
      	}
      
      exit:
      	mqtt_demo_unsubscribe(MQTT_RECV_TOPIC);
      	mqtt_demo_disconnect();
      	mqtt_demo_deinit();
      	OS_ThreadDelete(&g_mqtt_thread);
      }
      
      static void net_cb(uint32_t event, uint32_t data, void *arg) {
      	uint16_t type = EVENT_SUBTYPE(event);
      	switch (type) {
      	case NET_CTRL_MSG_NETWORK_UP:
      		printf("NET_CTRL_MSG_NETWORK_UP\n");
      		if (!OS_ThreadIsValid(&g_mqtt_thread)) {
      			OS_ThreadCreate(&g_mqtt_thread, "connect_to_server_task",
      			                    mqtt_task, (void *)NULL,  OS_THREAD_PRIO_APP, (8 * 1024));
      		}
      		break;
      	case NET_CTRL_MSG_NETWORK_DOWN:
      		break;
      	default:
      		break;
      	}
      }
      
      static void MainThread(void *arg)   {
      	printf("MainThread start\r\n");
      	HAL_Status status = HAL_ERROR;
      	PWM_ClkParam clk_param;
      	PWM_ChInitParam ch_param;
      
      	clk_param.clk = PWM_CLK_HOSC;
      	clk_param.div = PWM_SRC_CLK_DIV_1;
      
      	status = HAL_PWM_GroupClkCfg(PWM_OUTPUT_CHL, &clk_param);
      	if (status != HAL_OK)
      		printf("%s(): %d, PWM group clk config error\n", __func__, __LINE__);
      
      	ch_param.hz = 1000;
      	ch_param.mode = PWM_OUTPUT_MODE;
      	ch_param.polarity = PWM_HIGHLEVE;
      	max_duty_ratio = HAL_PWM_ChInit(PWM_OUTPUT_CHL, &ch_param);
      	if (max_duty_ratio == -1)
      		printf("%s(): %d, PWM ch init error\n", __func__, __LINE__);
      
      	printf("max_duty_ratio=%d\n", max_duty_ratio);
      	status = HAL_PWM_ChSetDutyRatio(PWM_OUTPUT_CHL, 0);
      	if (status != HAL_OK)
      		printf("%s(): %d, PWM set duty ratio error\n", __func__, __LINE__);
      
      	status = HAL_PWM_EnableCh(PWM_OUTPUT_CHL, PWM_OUTPUT_MODE, 1);
      	if (status != HAL_OK)
      		printf("%s(): %d, PWM ch enable error\n", __func__, __LINE__);
      
      	if (WIFI_SUCCESS != EnableWifi()) {
      		printf("Error: EnableWifi fail\n");
      		return;
      	}
      
      	OS_Sleep(1);
      
      	if (WIFI_SUCCESS != Scan()) {
      		printf("Error: Scan fail.\n");
      		return;
      	}
      
      	OS_Sleep(3);//这里为了方便用延时,实际用回调更好,否则3秒可能不够
      
      	const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID;
      	const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK;
      	WifiScanInfo scan_results[30];
      	unsigned int scan_num = 30;
      
      	if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) {
      		printf("Error: GetScanInfoList fail.\n");
      		return;
      	}
      
      	WifiDeviceConfig config = { 0 };
      	int netId = 0;
      
      	int i;
      	for (i = 0; i < scan_num; i++) {
      		printf("ssid: %s    ", scan_results[i].ssid);
      		printf("securityType: %d\n", scan_results[i].securityType);
      		if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) {
      			memcpy(config.ssid, scan_results[i].ssid,
      			       WIFI_MAX_SSID_LEN);
      			memcpy(config.bssid, scan_results[i].bssid,
      			       WIFI_MAC_LEN);
      			strcpy(config.preSharedKey, psk);
      			config.securityType = scan_results[i].securityType;
      			config.wapiPskType = WIFI_PSK_TYPE_ASCII;
      			config.freq = scan_results[i].frequency;
      			break;
      		}
      	}
      
      	if (i >= scan_num) {
      		printf("Error: No found ssid in scan_results\n");
      		return;
      	}
      
      	if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {
      		printf("Error: AddDeviceConfig Fail\n");
      		return;
      	}
      	printf("Config Success\n");
      
      	if (WIFI_SUCCESS != ConnectTo(netId)) {
      		printf("Error: ConnectTo Fail\n");
      		return;
      	}
      	
      	observer_base *net_ob;
      	net_ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK, NET_CTRL_MSG_ALL, net_cb, NULL);
      	if (net_ob == NULL)
      		return;
      
      	if (sys_ctrl_attach(net_ob) != 0)
      		return;
      
      	while (1) {
      		OS_MSleep(500);
      	}
      }
      
      void LEDMain(void) {
      	if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
      		printf("[ERR] Create MainThread Failed\n");
      	}
      }
      
      SYS_RUN(LEDMain);
      

      三、配置上层的BUILD.gn,并编译
      部分内容如下:

      group("ohosdemo") {
          deps = [
              #"hello_demo:app_hello",
              #"iot_peripheral:app_peripheral",
              #"wlan_demo:app_WlanTest",
              "mydemo:app_mydemo",
          ]
      }
      

      然后执行hb build -f,编译成功(若编译失败见论坛有解决方案)
      然后烧录到开发板上
      四、运行实例
      烧录完成后,开发板重新上电,输出如下日志

      ====================================================================
      	Hello! OpenHarmony!
      	System tag : OpenHarmony 1.1.2_LTS
      ====================================================================
      	
      use default flash chip mJedec 0x0
      [FD I]: mode: 0x10, freq: 96000000Hz, drv: 0
      [FD I]: jedec: 0x0, suspend_support: 1
      mode select:e
      
      wlan information ===================================================
      firmware:
          version : R0-XR_C07.08.52.65_02.84 May 27 2021 11:41:33-Y02.84 
          buffer  : 8
      driver:
          version : XR_V02.05
      mac address:
          in use        : 1c:98:c9:bc:50:01
          in use        : 1c:98:c9:bc:50:02
      ====================================================================
      
      wlan mode:a
      [VFS INF] LittleFS mount success.
      
      platform information ===============================================
      XR806 SDK v1.2.0  Dec 13 2021 13:06:05
      
      heap space [0x2238d0, 0x24bc00), size 164656
      
      cpu  clock 160000000 Hz
      HF   clock  40000000 Hz
      
      sdk option:
          XIP           : enable
          INT LF OSC    : enable
          SIP flash     : enable
      
      mac address:
          efuse         : 80:74:84:21:38:8e
          in use        : 1c:98:c9:bc:50:01
      ====================================================================
      
      hiview init success.MainThread start
      
      max_duty_ratio=40000
      
      
      console init success
      
      [net INF] no need to switch wlan mode 0
      [net INF] msg <wlan scan success>
      ssid: TP-LINK_A668    securityType: 2
      Config Success
      [net INF] no need to switch wlan mode 0
      en1: Trying to associate with a4:c7:4b:71:f9:84 (SSID='XXXXXX' freq=2462 MHz)
      en1: Associated with a4:c7:4b:71:f9:84
      en1: WPA: Key negotiation completed with a4:c7:4b:71:f9:84 [PTK=CCMP GTK=CCMP]
      en1: CTRL-EVENT-CONNECTED - Connection to a4:c7:4b:71:f9:84 completed [id=0 id_str=]
      [net INF] msg <wlan connected>
      [net INF] netif is link up
      [net INF] start DHCP...
      [net INF] IPv6 addr state change: 0x0 --> 0x1
      [net INF] msg <>
      [net INF] netif (IPv4) is up
      [net INF] address: 192.168.3.48
      [net INF] gateway: 192.168.3.1
      [net INF] netmask: 255.255.255.0
      [net INF] msg <network IPv6 state>
      NET_CTRL_MSG_NETWORK_UP
      WAR drop=1117, fctl=0x00d0.
      mqtt connected
      get a message, topic: /to/slave/light, msg: 0
      

      可以看到,开发板成功连接路由器,并接入了MQTT服务器
      五、手机测试
      本人的手机是Iphone,也不会手机APP开发,于是我们下载了一个叫MQTTTool的第三方APP验证点灯,其界面如下:
      1e9f62ad-9c5b-4255-b85b-b43db8f2de07-image.png
      Host和Port填对,由于是免费开放的MQTT服务器,其他参数任意,设置好以后点Connect即可连接上MQTT服务器。然后底部切换至Subscribe栏,订阅主题:
      0bca5012-7907-45fc-9d34-89fbc7c91c57-image.png
      若手机比设备先连接服务器并订阅相关主题,那么你会在订阅栏收到topic为/to/master/light的消息:light ready,这是因为设备连上服务器就会发布该topic。
      接下来是发布主题,我们往/to/slave/light主题发送一个0~100的数字,就会让设备以这个数字为占空比控制LED灯亮灭,如0表示灭灯,50表示50%的占空比驱动LED灯,100表示100%的占空比驱动LED灯。同时设备收到LED控制指令后,若占空比不为0,则发送消息light on,否则发送消息light off
      031393e7-f44b-4062-9258-7171bcad5402-image.png
      79781989-d3af-43bd-b320-82c8b78784b3-image.png
      1c54a800-83f4-4921-9d1a-055cc2b5b91b-image.png
      部分日志如下:

      WAR drop=1117, fctl=0x00d0.
      mqtt connected
      get a message, topic: /to/slave/light, msg: 0
      [net INF] IPv6 addr state change: 0x0 --> 0x1
      [net INF] msg <>
      get a message, topic: /to/slave/light, msg: 100
      get a message, topic: /to/slave/light, msg: 100
      get a message, topic: /to/slave/light, msg: 50
      

      以上就是一个手机远程给LED进行PWM调光的应用实例

      发布在 Wireless & Analog Series
      Z
      zwmasdf

    zwmasdf 发布的最新帖子

    • 【XR806开发板试用】通过MQTT实现手机远程实现PWM控灯

      一、例程编译、烧录确认
      首先按照全志在线文档平台的点灯教程确保能正常编译、烧录和点灯:https://xr806.docs.aw-ol.com/study/soft_led/
      确保例程没问题后,我们再改造例程,实现我们想要的功能
      二、代码编写
      我们将led工程复制一份改文件夹名为mydemo,目录结构如下

          mydemo
          ├── BUILD.gn
          └── src
          └── main.c
      

      然后BUILD.gn内容增加头文件引用,部分配置如下:

      static_library("app_mydemo") {
      ...
      include_dirs += [
            "//kernel/liteos_m/kernel/arch/include",
            "//base/iot_hardware/peripheral/interfaces/kits",
      
            ".",
            "//utils/native/lite/include",
            "//foundation/communication/wifi_lite/interfaces/wifiservice",
            "//device/xradio/xr806/xr_skylark/project"
         ]
      }
      

      接下来是main.c,内容如下:

      #include <stdio.h>
      #include <string.h>
      #include "ohos_init.h"
      #include "kernel/os/os.h"
      
      #include "iot_gpio.h"
      #include "wifi_device.h"
      #include "common/framework/net_ctrl.h"
      #include "net/mqtt/MQTTClient-C/MQTTClient.h"
      #include "driver/chip/hal_pwm.h"
      
      static OS_Thread_t g_main_thread;
      static OS_Thread_t g_mqtt_thread;
      
      #define PWM_OUTPUT_CHL        PWM_GROUP1_CH2
      #define PWM_OUTPUT_MODE       PWM_CYCLE_MODE
      
      #define WIFI_DEVICE_CONNECT_AP_SSID "ssid"//这里填你家路由器的SSID
      #define WIFI_DEVICE_CONNECT_AP_PSK "pwm"//这里填你家路由器的PWD
      
      
      #define MQTT_DEMO_CLIENT_ID "12345"
      #define MQTT_DEMO_HOST_NAME "broker-cn.emqx.io"//这个是免费调试用的MQTT服务器地址
      #define MQTT_DEMO_PORT      "1883"
      #define MQTT_DEMO_USERNAME  "12345678"
      #define MQTT_DEMO_PASSWORD  "12345678"
      #define MQTT_RESP_TOPIC "/to/master/light" //手机发出来的TOPIC
      #define MQTT_RECV_TOPIC  "/to/slave/light" //设备发出来的TOPIC
      #define MQTT_DEMO_BUF_SIZE (2*1024)
      
      static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer;
      static Client mqtt_demo_client;
      static Network mqtt_demo_network;
      static int max_duty_ratio = 0;
      
      static int mqtt_demo_publish(char *topic, char *msg) ;
      
      static int mqtt_demo_init(void) {
      	char *send_buf;
      	char *recv_buf;
      
      	mqtt_demo_connectData.clientID.cstring = MQTT_DEMO_CLIENT_ID;
      	mqtt_demo_connectData.keepAliveInterval = 30; // 30s
      	mqtt_demo_connectData.cleansession = 0;
      	mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1
      
      	send_buf = malloc(MQTT_DEMO_BUF_SIZE);
      	if (send_buf == NULL) {
      		printf("no memory\n");
      		return -1;
      	}
      	recv_buf = malloc(MQTT_DEMO_BUF_SIZE);
      	if (recv_buf == NULL) {
      		free(send_buf);
      		printf("no memory\n");
      		return -1;
      	}
      
      	/* init network */
      	NewNetwork(&mqtt_demo_network);
      	/* init mqtt client object */
      	MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000,
      	           (unsigned char *)send_buf, MQTT_DEMO_BUF_SIZE,
      	           (unsigned char *)recv_buf, MQTT_DEMO_BUF_SIZE);
      
      	/* set username and password */
      	mqtt_demo_connectData.username.cstring = MQTT_DEMO_USERNAME;
      	mqtt_demo_connectData.password.cstring = MQTT_DEMO_PASSWORD;
      	return 0;
      }
      
      static int mqtt_demo_connect(char *host_name, char *host_port) {
      	int ret = -1;
      
      	ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port));
      	if (ret != 0) {
      		printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port);
      		goto exit;
      	}
      
      	ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData);
      	if (ret != 0) {
      		printf("mqtt connect faild, ret:%d\n", ret);
      		mqtt_demo_network.disconnect(&mqtt_demo_network);
      		goto exit;
      	}
      	printf("mqtt connected\n");
      exit:
      	return ret;
      }
      
      static void mqtt_demo_msg_cb(MessageData *data) {
      	printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len,
      	       data->topicName->lenstring.data, data->message->payloadlen,
      	       (char *)data->message->payload);
      	if(!strncmp(data->topicName->lenstring.data, "/to/slave/light", 15) && data->message->payloadlen) {
      		char *payload = data->message->payload;
      		char str[8] = "";
      		int max_len = data->message->payloadlen > 3 ? 3 : data->message->payloadlen;
      		strncpy(str, payload, max_len);
      		int duty = atoi(str);
      		HAL_Status status = HAL_PWM_ChSetDutyRatio(PWM_OUTPUT_CHL, duty * max_duty_ratio / 100);
      		if (status != HAL_OK)
      			printf("%s(): %d, PWM set duty ratio error\n", __func__, __LINE__);
      		
      		if(duty) {
      			mqtt_demo_publish(MQTT_RESP_TOPIC, "light on");
      		} else {
      			mqtt_demo_publish(MQTT_RESP_TOPIC, "light off");
      		}
      	} 
      }
      
      static int mqtt_demo_subscribe(char *topic) {
      	int ret = -1;
      	if (mqtt_demo_client.isconnected) {
      		ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb);
      		if (ret != 0)
      			printf("mqtt subscribe faild ret:%d\n", ret);
      	}
      	return ret;
      }
      
      static int mqtt_demo_unsubscribe(char *topic) {
      	int ret = -1;
      	if (mqtt_demo_client.isconnected) {
      		ret = MQTTUnsubscribe(&mqtt_demo_client, topic);
      		if (ret != 0)
      			printf("mqtt unsubscribe faild, ret:%d\n", ret);
      	}
      	return ret;
      }
      
      static int mqtt_demo_publish(char *topic, char *msg) {
      	int ret = -1;
      
      	MQTTMessage message;
      	memset(&message, 0, sizeof(message));
      	message.qos = 0;
      	message.retained = 0; /* disable retain the message in server */
      	message.payload = msg;
      	message.payloadlen = strlen(msg);
      	ret = MQTTPublish(&mqtt_demo_client, topic, &message);
      	if (ret != 0)
      		printf("mqtt publish faild, ret:%d\n", ret);
      	return ret;
      }
      
      static int mqtt_demo_disconnect(void) {
      	int ret = -1;
      
      	if (mqtt_demo_client.isconnected) {
      		ret = MQTTDisconnect(&mqtt_demo_client);
      		if (ret != 0)
      			printf("mqtt disconnect fail, ret:%d\n", ret);
      		mqtt_demo_network.disconnect(&mqtt_demo_network);
      	}
      	return ret;
      }
      
      static void mqtt_demo_deinit(void) {
      	if (mqtt_demo_client.buf) {
      		free(mqtt_demo_client.buf);
      		mqtt_demo_client.buf = NULL;
      	}
      	if (mqtt_demo_client.readbuf) {
      		free(mqtt_demo_client.readbuf);
      		mqtt_demo_client.readbuf = NULL;
      	}
      }
      
      static void mqtt_task(void *arg)   {
      	int ret;
      	int reconnect_times = 0;
      
      	mqtt_demo_init();
      
      	ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
      	if (ret != 0)
      		goto exit;
      
      	ret = mqtt_demo_subscribe(MQTT_RECV_TOPIC);
      	if (ret != 0)
      		goto exit;
      
      	mqtt_demo_publish(MQTT_RESP_TOPIC, "light ready");
      
      	while (1) {
      		ret = MQTTYield(&mqtt_demo_client, 300);
      		if (ret != 0) {
      			printf("mqtt yield err, ret:%d\n", ret);
      reconnect:
      			printf("mqtt reconnect\n");
      			mqtt_demo_disconnect();
      			ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
      			if (ret != 0) {
      				reconnect_times++;
      				if (reconnect_times > 5)
      					goto exit;
      				OS_MSleep(5000); //5s
      				goto reconnect;
      			}
      		}
      	}
      
      exit:
      	mqtt_demo_unsubscribe(MQTT_RECV_TOPIC);
      	mqtt_demo_disconnect();
      	mqtt_demo_deinit();
      	OS_ThreadDelete(&g_mqtt_thread);
      }
      
      static void net_cb(uint32_t event, uint32_t data, void *arg) {
      	uint16_t type = EVENT_SUBTYPE(event);
      	switch (type) {
      	case NET_CTRL_MSG_NETWORK_UP:
      		printf("NET_CTRL_MSG_NETWORK_UP\n");
      		if (!OS_ThreadIsValid(&g_mqtt_thread)) {
      			OS_ThreadCreate(&g_mqtt_thread, "connect_to_server_task",
      			                    mqtt_task, (void *)NULL,  OS_THREAD_PRIO_APP, (8 * 1024));
      		}
      		break;
      	case NET_CTRL_MSG_NETWORK_DOWN:
      		break;
      	default:
      		break;
      	}
      }
      
      static void MainThread(void *arg)   {
      	printf("MainThread start\r\n");
      	HAL_Status status = HAL_ERROR;
      	PWM_ClkParam clk_param;
      	PWM_ChInitParam ch_param;
      
      	clk_param.clk = PWM_CLK_HOSC;
      	clk_param.div = PWM_SRC_CLK_DIV_1;
      
      	status = HAL_PWM_GroupClkCfg(PWM_OUTPUT_CHL, &clk_param);
      	if (status != HAL_OK)
      		printf("%s(): %d, PWM group clk config error\n", __func__, __LINE__);
      
      	ch_param.hz = 1000;
      	ch_param.mode = PWM_OUTPUT_MODE;
      	ch_param.polarity = PWM_HIGHLEVE;
      	max_duty_ratio = HAL_PWM_ChInit(PWM_OUTPUT_CHL, &ch_param);
      	if (max_duty_ratio == -1)
      		printf("%s(): %d, PWM ch init error\n", __func__, __LINE__);
      
      	printf("max_duty_ratio=%d\n", max_duty_ratio);
      	status = HAL_PWM_ChSetDutyRatio(PWM_OUTPUT_CHL, 0);
      	if (status != HAL_OK)
      		printf("%s(): %d, PWM set duty ratio error\n", __func__, __LINE__);
      
      	status = HAL_PWM_EnableCh(PWM_OUTPUT_CHL, PWM_OUTPUT_MODE, 1);
      	if (status != HAL_OK)
      		printf("%s(): %d, PWM ch enable error\n", __func__, __LINE__);
      
      	if (WIFI_SUCCESS != EnableWifi()) {
      		printf("Error: EnableWifi fail\n");
      		return;
      	}
      
      	OS_Sleep(1);
      
      	if (WIFI_SUCCESS != Scan()) {
      		printf("Error: Scan fail.\n");
      		return;
      	}
      
      	OS_Sleep(3);//这里为了方便用延时,实际用回调更好,否则3秒可能不够
      
      	const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID;
      	const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK;
      	WifiScanInfo scan_results[30];
      	unsigned int scan_num = 30;
      
      	if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) {
      		printf("Error: GetScanInfoList fail.\n");
      		return;
      	}
      
      	WifiDeviceConfig config = { 0 };
      	int netId = 0;
      
      	int i;
      	for (i = 0; i < scan_num; i++) {
      		printf("ssid: %s    ", scan_results[i].ssid);
      		printf("securityType: %d\n", scan_results[i].securityType);
      		if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) {
      			memcpy(config.ssid, scan_results[i].ssid,
      			       WIFI_MAX_SSID_LEN);
      			memcpy(config.bssid, scan_results[i].bssid,
      			       WIFI_MAC_LEN);
      			strcpy(config.preSharedKey, psk);
      			config.securityType = scan_results[i].securityType;
      			config.wapiPskType = WIFI_PSK_TYPE_ASCII;
      			config.freq = scan_results[i].frequency;
      			break;
      		}
      	}
      
      	if (i >= scan_num) {
      		printf("Error: No found ssid in scan_results\n");
      		return;
      	}
      
      	if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {
      		printf("Error: AddDeviceConfig Fail\n");
      		return;
      	}
      	printf("Config Success\n");
      
      	if (WIFI_SUCCESS != ConnectTo(netId)) {
      		printf("Error: ConnectTo Fail\n");
      		return;
      	}
      	
      	observer_base *net_ob;
      	net_ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK, NET_CTRL_MSG_ALL, net_cb, NULL);
      	if (net_ob == NULL)
      		return;
      
      	if (sys_ctrl_attach(net_ob) != 0)
      		return;
      
      	while (1) {
      		OS_MSleep(500);
      	}
      }
      
      void LEDMain(void) {
      	if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
      		printf("[ERR] Create MainThread Failed\n");
      	}
      }
      
      SYS_RUN(LEDMain);
      

      三、配置上层的BUILD.gn,并编译
      部分内容如下:

      group("ohosdemo") {
          deps = [
              #"hello_demo:app_hello",
              #"iot_peripheral:app_peripheral",
              #"wlan_demo:app_WlanTest",
              "mydemo:app_mydemo",
          ]
      }
      

      然后执行hb build -f,编译成功(若编译失败见论坛有解决方案)
      然后烧录到开发板上
      四、运行实例
      烧录完成后,开发板重新上电,输出如下日志

      ====================================================================
      	Hello! OpenHarmony!
      	System tag : OpenHarmony 1.1.2_LTS
      ====================================================================
      	
      use default flash chip mJedec 0x0
      [FD I]: mode: 0x10, freq: 96000000Hz, drv: 0
      [FD I]: jedec: 0x0, suspend_support: 1
      mode select:e
      
      wlan information ===================================================
      firmware:
          version : R0-XR_C07.08.52.65_02.84 May 27 2021 11:41:33-Y02.84 
          buffer  : 8
      driver:
          version : XR_V02.05
      mac address:
          in use        : 1c:98:c9:bc:50:01
          in use        : 1c:98:c9:bc:50:02
      ====================================================================
      
      wlan mode:a
      [VFS INF] LittleFS mount success.
      
      platform information ===============================================
      XR806 SDK v1.2.0  Dec 13 2021 13:06:05
      
      heap space [0x2238d0, 0x24bc00), size 164656
      
      cpu  clock 160000000 Hz
      HF   clock  40000000 Hz
      
      sdk option:
          XIP           : enable
          INT LF OSC    : enable
          SIP flash     : enable
      
      mac address:
          efuse         : 80:74:84:21:38:8e
          in use        : 1c:98:c9:bc:50:01
      ====================================================================
      
      hiview init success.MainThread start
      
      max_duty_ratio=40000
      
      
      console init success
      
      [net INF] no need to switch wlan mode 0
      [net INF] msg <wlan scan success>
      ssid: TP-LINK_A668    securityType: 2
      Config Success
      [net INF] no need to switch wlan mode 0
      en1: Trying to associate with a4:c7:4b:71:f9:84 (SSID='XXXXXX' freq=2462 MHz)
      en1: Associated with a4:c7:4b:71:f9:84
      en1: WPA: Key negotiation completed with a4:c7:4b:71:f9:84 [PTK=CCMP GTK=CCMP]
      en1: CTRL-EVENT-CONNECTED - Connection to a4:c7:4b:71:f9:84 completed [id=0 id_str=]
      [net INF] msg <wlan connected>
      [net INF] netif is link up
      [net INF] start DHCP...
      [net INF] IPv6 addr state change: 0x0 --> 0x1
      [net INF] msg <>
      [net INF] netif (IPv4) is up
      [net INF] address: 192.168.3.48
      [net INF] gateway: 192.168.3.1
      [net INF] netmask: 255.255.255.0
      [net INF] msg <network IPv6 state>
      NET_CTRL_MSG_NETWORK_UP
      WAR drop=1117, fctl=0x00d0.
      mqtt connected
      get a message, topic: /to/slave/light, msg: 0
      

      可以看到,开发板成功连接路由器,并接入了MQTT服务器
      五、手机测试
      本人的手机是Iphone,也不会手机APP开发,于是我们下载了一个叫MQTTTool的第三方APP验证点灯,其界面如下:
      1e9f62ad-9c5b-4255-b85b-b43db8f2de07-image.png
      Host和Port填对,由于是免费开放的MQTT服务器,其他参数任意,设置好以后点Connect即可连接上MQTT服务器。然后底部切换至Subscribe栏,订阅主题:
      0bca5012-7907-45fc-9d34-89fbc7c91c57-image.png
      若手机比设备先连接服务器并订阅相关主题,那么你会在订阅栏收到topic为/to/master/light的消息:light ready,这是因为设备连上服务器就会发布该topic。
      接下来是发布主题,我们往/to/slave/light主题发送一个0~100的数字,就会让设备以这个数字为占空比控制LED灯亮灭,如0表示灭灯,50表示50%的占空比驱动LED灯,100表示100%的占空比驱动LED灯。同时设备收到LED控制指令后,若占空比不为0,则发送消息light on,否则发送消息light off
      031393e7-f44b-4062-9258-7171bcad5402-image.png
      79781989-d3af-43bd-b320-82c8b78784b3-image.png
      1c54a800-83f4-4921-9d1a-055cc2b5b91b-image.png
      部分日志如下:

      WAR drop=1117, fctl=0x00d0.
      mqtt connected
      get a message, topic: /to/slave/light, msg: 0
      [net INF] IPv6 addr state change: 0x0 --> 0x1
      [net INF] msg <>
      get a message, topic: /to/slave/light, msg: 100
      get a message, topic: /to/slave/light, msg: 100
      get a message, topic: /to/slave/light, msg: 50
      

      以上就是一个手机远程给LED进行PWM调光的应用实例

      发布在 Wireless & Analog Series
      Z
      zwmasdf
    • 回复: XR806 wlan_demo编译无法通过求助

      @salt_fish 是的,但是啥都没做就文件这么大了,还是显得臃肿

      发布在 Wireless & Analog Series
      Z
      zwmasdf
    • 回复: XR806 wlan_demo编译无法通过求助

      @zwmasdf 问题找到了,看来是鸿蒙系统太臃肿了,什么都没用就已经占了很多空间了,只能裁剪。从目前体验来看,鸿蒙还是不适合用在IOT WIFI上

      发布在 Wireless & Analog Series
      Z
      zwmasdf
    • XR806 wlan_demo编译无法通过求助
      [OHOS ERROR] ~/tools/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-objcopy -O binary -R .xip   audio_demo.elf audio_demo.bin
      [OHOS ERROR] ~/tools/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-size audio_demo.elf
      [OHOS ERROR]    text	   data	    bss	    dec	    hex	filename
      [OHOS ERROR] 1152240	   8032	  76248	1236520	 12de28	audio_demo.elf
      [OHOS ERROR] ~/tools/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-objcopy -O binary -j .xip audio_demo.elf audio_demo_xip.bin
      [OHOS ERROR] cp audio_demo_xip.bin ../image/"xr806"/app_xip.bin
      [OHOS ERROR] cd ../image/"xr806" && \
      [OHOS ERROR] chmod a+r *.bin && \
      [OHOS ERROR] ~/tools/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc -E -P -CC -DCONFIG_CHIP_ARCH_VER=3 -DCONFIG_ARCH_APP_CORE -DCONFIG_CPU_CM33F -DPRJ_XIP_SIZE=8M -DPRJ_BOOT_CERT="\"null\"" -DPRJ_IMAGE_BOOT_ATTR="\"0x1\"" -DPRJ_IMAGE_APP_SRAM_OFFS="\"0x00201000\"" -DPRJ_IMAGE_APP_EP="\"0x00201101\"" -DPRJ_IMAGE_BOOT_SRAM_OFFS="\"0x00230000\"" -DPRJ_IMAGE_BOOT_EP="\"0x00230101\"" -DPRJ_IMAGE_TZ_ATTR="\"0x25\"" -DPRJ_IMAGE_TZ_XIP_ATTR="\"0x26\"" -DPRJ_IMAGE_TZ_PSRAM_ATTR="\"0x25\"" -DPRJ_APP_BIN_CERT="\"null\"" -DPRJ_APP_XIP_BIN_CERT="\"null\"" -DPRJ_APP_PSRAM_BIN_CERT="\"null\"" -DPRJ_IMAGE_APP_ATTR="\"0x1\"" -DPRJ_IMAGE_APP_XIP_ATTR="\"0x2\"" -DPRJ_IMAGE_APP_PSRAM_ATTR="\"0x1\"" -DCONFIG_RAM_START=0x00201000 -DPRJ_RAM_SIZE=300K -DPRJ_PSRAM_START_OFFS="\"0x01400000\"" -DCONFIG_PSRAM_START=0x01400000 -DPRJ_PSRAM_SIZE=0K -DPRJ_IMAGE_BOOT_BIN="\"boot_"40"M.bin\"" -DPRJ_IMAGE_SYS_SDD_BIN="\"sys_sdd_"40"M.bin\""  -I../../../../../include/generated -include autoconf.h -o .image.cfg - < image.cfg && \
      [OHOS ERROR] true && \
      [OHOS ERROR] chmod 777 ../../../../../tools/mkimage && ../../../../../tools/mkimage  -c .image.cfg -o xr_system.img
      [OHOS ERROR] err: bin 1 and bin 2 were overlaped!
      [OHOS ERROR] Overlapped size: 1024 Byte(1kB)
      [OHOS ERROR] bin 1 name:app.bin    begin: 0x00008000    end: 0x00018000
      [OHOS ERROR] bin 2 name:app_xip.bin    begin: 0x00017C00
      [OHOS ERROR] 
      [OHOS ERROR] We've rearranged bin files and generated new cfg file 'image_auto_cal.cfg', the new one is recommended.
      [OHOS ERROR] Generate image file failed
      [OHOS ERROR] cfg string:
      [OHOS ERROR] /*
      [OHOS ERROR]  *
      [OHOS ERROR]  * Automatically generated file; DO NOT EDIT.
      [OHOS ERROR]  * XR806 SDK Configuration
      [OHOS ERROR]  *
      [OHOS ERROR]  */
      [OHOS ERROR] {
      [OHOS ERROR]     "magic" : "AWIH",
      [OHOS ERROR]     "version" : "0.5",
      [OHOS ERROR]     "image" : {"max_size": "1532K"},
      [OHOS ERROR]     "section" :[
      [OHOS ERROR]   {"id": "0xa5ff5a00", "bin" :"boot_40M.bin", "cert": "null", "flash_offs": "0K", "sram_offs": "0x00230000", "ep": "0x00230101", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5fe5a01", "bin" :"app.bin", "cert": "null", "flash_offs": "32K", "sram_offs": "0x00201000", "ep": "0x00201101", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5fd5a02", "bin" :"app_xip.bin", "cert": "null", "flash_offs": "95K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x2"},
      [OHOS ERROR]   {"id": "0xa5fa5a05", "bin" :"wlan_bl.bin", "cert": "null", "flash_offs": "1166K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5f95a06", "bin" :"wlan_fw.bin", "cert": "null", "flash_offs": "1169K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5f85a07", "bin" :"sys_sdd_40M.bin", "cert": "null", "flash_offs": "1194K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      [OHOS ERROR]   {}
      [OHOS ERROR]  ]
      [OHOS ERROR] }
      [OHOS ERROR] 
      [OHOS ERROR] make[2]: *** [../../../../project/project.mk:520: image] Error 255
      [OHOS ERROR] make[2]: Leaving directory '/home/openharmony/device/xradio/xr806/xr_skylark/project/demo/audio_demo/gcc'
      [OHOS ERROR] make[1]: *** [../../../../project/project.mk:493: __build] Error 2
      [OHOS ERROR] make[1]: Leaving directory '/home/openharmony/device/xradio/xr806/xr_skylark/project/demo/audio_demo/gcc'
      [OHOS ERROR] make: *** [Makefile:164: build] Error 2
      [OHOS ERROR] you can check build log in /home/openharmony/out/xr806/wifi_skylark/build.log
      [OHOS ERROR] command: "/home/tools/ninja/ninja -w dupbuild=warn -C /home/openharmony/out/xr806/wifi_skylark" failed
      [OHOS ERROR] return code: 1
      [OHOS ERROR] execution path: /home/openharmony
      

      看日志像是bin地址重叠了,不知道是什么情况

      发布在 Wireless & Analog Series
      Z
      zwmasdf