【XR806开发板试用】xr806使用tcp socket与手机通信

本文为极术社区XR806开发板活动试用文章。
参考:基于星辰处理器的全志XR806开源鸿蒙开发板上手体验 搭建环境。并成功编译。

项目源码 : https://gitee.com/kingwho/smart-home

在同一个局域网中,手机与xr806连接后,手机 APP 每隔 1s,发送按键的值给xr806,用于控制xr806的led,然后xr806在返回按键,温度,适度(温度,适度为模拟数据)数据给手机app显示。

将 smart_home 放入 device/xradio/xr806/ohosdemo 下的目录,并修改 device/xradio/xr806/ohosdemo/BUILD.gn 为

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

目录结构

.
├── BUILD.gn
└── src
    ├── main.c
    ├── tcp_net_socket.c
    └── tcp_net_socket.h

使用 WIFI 编译时会报错,进行如下操作即可,在随后的编译中可能还会出现,再次如下操作执行即可。

cd device/xradio/xr806/xr_skylark/project/demo/wlan_ble_demo/image/xr806
cp image_wlan_ble.cfg image_wlan_ble.cfg.bk
cat image_auto_cal.cfg > image_wlan_ble.cfg

cjson使用这些宏会报错,建议直接使用 cjson 宏定义后面函数。

#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))

xr806连接WIFI后 IP地址可由串口输出打印查看

[net INF] msg <wlan scan success>
GetScanInfoList Success.
AddDeviceConfig Success.
[net INF] no need to switch wlan mode 0
en1: Trying to associate with 94:83:c4:0e:70:be (SSID='GL-MT300N-V2-0be' freq=2437 MHz)
ConnectTo Success
en1: Associated with 94:83:c4:0e:70:be
en1: WPA: Key negotiation completed with 94:83:c4:0e:70:be [PTK=CCMP GTK=CCMP]
en1: CTRL-EVENT-CONNECTED - Connection to 94:83:c4:0e:70:be completed [id=0 id_str=]
[net INF] msg <wlan connected>
[net INF] netif is link up
[net INF] start DHCP...
[net INF] netif (IPv4) is up
[net INF] address: 192.168.8.248
[net INF] gateway: 192.168.8.1
[net INF] netmask: 255.255.255.0
[net INF] msg <network IPv6 state>
[net INF] IPv6 addr state change: 0x0 --> 0x1
[net INF] msg <>

xr806 的固件更新后,需要使用下载器软件重新加载下固件,否则下载的可能还是上次的固件。

BUILD.gn

import("//device/xradio/xr806/liteos_m/config.gni")

static_library("app_smart_home") {
   configs = []
   sources = [
      "src/main.c",
      "src/tcp_net_socket.c",
   ]
   cflags = board_cflags
   include_dirs = board_include_dirs
   include_dirs += [
      "//kernel/liteos_m/kernel/arch/include",
     "//base/iot_hardware/peripheral/interfaces/kits",
      "//utils/native/lite/include",
      "//foundation/communication/wifi_lite/interfaces/wifiservice",
      "//third_party/lwip/src/include",
      "//third_party/cJSON",
   ]
}

tcp_net_socket.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lwip/sockets.h"

int tcp_server_init(int port)
{
    int sfd = 0;
    struct sockaddr_in saddr;
    sfd = socket(AF_INET,SOCK_STREAM,0);
    
    memset(&saddr, 0, sizeof(struct sockaddr));
    saddr.sin_family  = AF_INET;
    saddr.sin_port    = htons(port);
    saddr.sin_addr.s_addr = INADDR_ANY;
    bind(sfd, (struct  socket*)&saddr, sizeof(struct sockaddr));

    listen(sfd,5);

    return sfd;
}

int tcp_server_accept(int sfd)
{
    int cfd = 0;
    struct  sockaddr_in caddr;
    memset(&caddr, 0, sizeof(struct sockaddr));
    int addrl = sizeof(struct sockaddr);
    cfd = accept(sfd , (struct sockaddr*)&caddr , &addrl);
    return cfd;
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "iot_gpio.h"
#include "wifi_device.h"
#include "cJSON.h"
#include "lwip/sockets.h"
#include "tcp_net_socket.h"


static void wifi_connect(char *ssid, char *passwd);
static OS_Thread_t g_main_thread;

static void MainThread(void *arg)
{

	unsigned int led_pin = 21; /* GPIOA_PIN21 */
	unsigned int key_pin = 11; /* GPIOA_PIN11 */
	IotGpioValue key_value;
	int led_value = 0;
	unsigned int tem = 0, hum = 0, s = 0;
	cJSON* dev_dat = NULL;

    int sfd = 0;
    int cfd = 0;
	char send_buf[512] = {0};
	char recv_buf[512] = {0};

	wifi_connect("GL-MT300N-V2-0be", "goodlife");

	IoTGpioInit(led_pin);
	IoTGpioSetDir(led_pin, IOT_GPIO_DIR_OUT);
	IoTGpioInit(key_pin);
	IoTGpioSetDir(key_pin, IOT_GPIO_DIR_IN);

	sfd = tcp_server_init(8080);
    cfd = tcp_server_accept(sfd);

	while (1) {

		srand( s++ );
		tem = rand()%10 + 20;
		hum = rand()%20 + 40;
		IoTGpioGetInputVal(key_pin, &key_value);
		printf("kw : hello world! key : %d tem : %d hum : %d\r\n", key_value, tem, hum);
		IoTGpioSetOutputVal(led_pin, led_value);

		recv(cfd, recv_buf, sizeof(recv_buf), 0);
		memset(send_buf, 0, sizeof(send_buf));

		sprintf(send_buf, "{\"led\":\"%d\",\"key\":\"%d\",\"tem\":\"%d\",\"hum\":\"%d\"}",\

						led_value, key_value, tem, hum);		

		send(cfd,send_buf, strlen(send_buf),0);
		dev_dat = cJSON_Parse(recv_buf);
		led_value = cJSON_GetObjectItem(dev_dat, "led")->valuestring[0] - '0';		
		printf("led data : %d\r\n", led_value);
		cJSON_Delete(dev_dat);
	}

}

static void wifi_connect(char *ssid, char *passwd)
{

	char *ssid_want_connect = ssid;
	char *psk = passwd;

	if (WIFI_SUCCESS != EnableWifi()) {
		printf("Error: EnableWifi fail.\n");
		return;
	}

	printf("EnableWifi Success.\n");

	if (WIFI_STA_ACTIVE == IsWifiActive())
		printf("Wifi is active.\n");
	OS_Sleep(1);

	if (WIFI_SUCCESS != Scan()) {
		printf("Error: Scan fail.\n");
		return;
	}

	printf("Wifi Scan Success.\n");
	OS_Sleep(1);

	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++) {
		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;
	}
	printf("GetScanInfoList Success.\n");
	if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {
		printf("Error: AddDeviceConfig Fail\n");
		return;
	}
	printf("AddDeviceConfig Success.\n");

	if (WIFI_SUCCESS != ConnectTo(netId)) {
		printf("Error: ConnectTo Fail\n");
		return;
	}

	printf("ConnectTo Success\n");
	OS_Sleep(3);
	WifiLinkedInfo get_linked_res;

	if (WIFI_SUCCESS != GetLinkedInfo(&get_linked_res)) {
		printf("Error: GetLinkedInfo Fail\n");
		return;
	}
	printf("GetLinkedInfo Success.\n");

	printf("ssid: %s\n", get_linked_res.ssid);
	printf("bssid: ");
	for (int j = 0; j < WIFI_MAC_LEN; j++) {
		printf("%02X", get_linked_res.bssid[j]);
	}

	printf("\n");
	printf("rssi: %d\n", get_linked_res.rssi);

	unsigned char get_mac_res[WIFI_MAC_LEN];
	if (WIFI_SUCCESS != GetDeviceMacAddress(get_mac_res)) {
		printf("Error: GetDeviceMacAddress Fail\n");
		return;
	}
	printf("GetDeviceMacAddress Success.\n");
	for (int j = 0; j < WIFI_MAC_LEN - 1; j++) {
		printf("%02X:", get_mac_res[j]);
	}
	printf("%02X\n", get_mac_res[WIFI_MAC_LEN - 1]);

}
void SmartHome(void)
{
	if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
			    OS_THREAD_PRIO_APP, 8 * 1024) != OS_OK) {
		printf("[ERR] Create MainThread Failed\n");
	}
}
SYS_RUN(SmartHome);
  • APP 采用 APIClode 开发,使用 html js 进行开发.
    APICloude Studio 软件下载,以及使用:
    https://docs.apicloud.com/apicloud3/#wifi-preview

  • 手机安装 Apploader,可以进行调试
    安装Apploader下载 : https://docs.apicloud.com/Download/download

  • 将 SmartHome 导入 APICloude Studio
    html/main.html 对应登录界面, 如下可修改默认 IP 和端口号

    <div id="bt_log">
        <form name="myForm" action="" onsubmit="return validateForm()" method="post">
           <div><label>IP地址</label><input type="text" name="ip" value="192.168.8.248"></div>
            <div><label>端口号</label><input type="text" name="port" value="8080"></div>
            <div><input type="submit" class="btn" value="登录" onmouseover="this.style.backgroundPosition='left -36px'"
                onmouseout="this.style.backgroundPosition='left top'"></div>
        </form>

     </div>

在这里插入图片描述

html/user_app.html 对应应用界面,与 xr806 在同一个局域网中,同进行通信,通信使用的为 json 数据。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/367623.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【开源】JAVA+Vue+SpringBoot实现就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

【对象属性拷贝】⭐️按照需要转换的类型反射设置拷贝后对象的属性

背景&#xff1a; 小伙伴们大家好&#xff0c;最近开发的时候遇到一种情况&#xff0c;项目引入了全局序列化器来实现Date&#xff0c;LocalDateTime类型的字段根据时区转换&#xff0c;总体来说接口没什么要改动的&#xff0c;只要原来字段的属性是以上两种就行&#xff0c;但…

Linux/Uinx 系统编程:进程管理(3)

Linux/Uinx 系统编程&#xff1a;进程管理&#xff08;3&#xff09; 本章来讲解进程管理的最后一部分内容。 文章目录 Linux/Uinx 系统编程&#xff1a;进程管理&#xff08;3&#xff09;I/O重定向原理FILE结构体的内部结构重定向的实现过程 scanf 与 printfscanfprintf 重定…

linux 组建和卸载raid1、raid0详细操作

组raid的最好是相同容量和型号的硬盘&#xff0c;否则会有木桶效应 linux下组raid有很多细节 一、安装raid软件 deb包 apt-get install mdadm或dnf包 dnf install mdadm二、组raid1-镜像&#xff0c;组raid0-并列 raid1和raid0只有在madam命令时一点点不同&#xff0c;其他…

了解野指针与assert断言 拿捏指针的使用!

目录 1.野指针 野指针的成因&#xff1a; 2.规避野指针 3.assert断言 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免费的赞哟~ 1.野指针 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的…

重写Sylar基于协程的服务器(5、IO协程调度模块的设计)

重写Sylar基于协程的服务器&#xff08;5、IO协程调度模块的设计&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器&#xff08;1、…

【论文阅读笔记】Taming Transformers for High-Resolution Image Synthesis

Taming Transformers for High-Resolution Image Synthesis 记录前置知识AbstractIntroductionRelated WorkMethodLearning an Effective Codebook of Image Constituents for Use in TransformersLearning the Composition of Images with Transformers条件合成合成高分辨率图…

阿狸与小兔子的奇幻之旅

在很久很久以前&#xff0c;有一个遥远的国度&#xff0c;这个国度里生活着各种各样的动物&#xff0c;它们和谐共处&#xff0c;幸福快乐。在这个国度里&#xff0c;有一只聪明伶俐的小狐狸&#xff0c;名叫阿狸。 一天&#xff0c;阿狸在森林里散步时&#xff0c;遇到了一只正…

【BIAI】Lecture10 - Motor System2

Motor System2 专业术语 descending spinal tracts 下行脊髓束 corticospinal tract 锥体束 reticulospinal tract 脊髓脑干束 vestibulospinal tract 脊髓脑干侧脊束 precentral gyrus 前中央回 population coding 群体编码 basal ganglia 基底节 thalamus 丘脑 Posterior pa…

Python中容器类型的数据

目录 序列 序列的索引操作 加和乘操作 切片操作 成员测试 列表 创建列表 追加元素 插入元素 替换元素 删除元素 元组 创建元组 元组拆包 集合 创建集合 修改集合 字典 创建字典 修改字典 访问字典视图 遍历字典 若我们想将多个数据打包并且统一管理&…

计算斐波那契数

前提需备知识&#xff1a; 斐波那契数列是第一项和第二项为1&#xff0c;第三项为前两项之和&#xff0c;然后以此类推的一个数列&#xff0c;即1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;8&#xff0c;13&#xff0c;21&#xff0c;34&#xff0c;5…

【开源】JAVA+Vue.js实现学生日常行为评分管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.2.1 登录注册模块2.2.2 用户管理模块2.2.3 评分项目模块2.2.4 评分数据模块2.2.5 数据字典模块 2.3 可行性设计2.4 用例设计2.5 数据库设计2.5.1 整体 E-R 图2.5.2 用户2.5.3 评分项目2.5.4 评分数据2.5.…

STM32MP135开发板助力电力行业,IEC61850协议移植笔记

1.概述 IEC61850是变电站自动化系统&#xff08;SAS&#xff09;中通信系统和分散能源&#xff08;DER&#xff09;管理的国际标准。它通过标准的实现&#xff0c;实现了智能变电站的工程运作标准化。使得智能变电站的工程实施变得规范、统一和透明&#xff0c;在电力和储能系…

评论区功能的简单实现思路

评论区功能是社交类项目中的核心组成部分&#xff0c;它涉及到前端的交云和后端的数据处理。基于你的技术栈&#xff08;前端 Vue3&#xff0c;后端 Java&#xff09;&#xff0c;下面是一个具体的实现思路和数据库设计建议&#xff0c;并探索一下知乎的评论系统。 数据库设计…

基于SpringBoot Vue学生信息管理

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

蓝桥杯---垒骰子

赌圣atm晚年迷恋上了垒骰子&#xff0c;就是把骰子一个垒在另一个上边&#xff0c;不能歪歪扭扭&#xff0c;要垒成方柱体。经过长期观察&#xff0c;atm 发现了稳定骰子的奥秘&#xff1a;有些数字的面贴着会互相排斥&#xff01;我们先来规范一下骰子&#xff1a;1的对面是4&…

Vue2+ElementUI 弹窗全局拖拽 支持放大缩小

拖拽组件 dialogDrag.vue <template><div></div> </template> <script>export default {name: dialogDrag,data() {return {originalWidth: null,originalHeight: null}},created() {this.$nextTick(()>{this.dialogDrag()})},mounted() {}…

vue3 之 组合式API—computed

computed计算属性函数 计算属性基本思想和Vue2的完全一致&#xff0c;组合式API下的计算属性只是修改了写法 核心步骤&#xff1a; 导入computed函数执行函数 在回调参数中return基于响应式数据做计算的值&#xff0c;用变量接收 vue <script setup> // 1.导入compute…

【数据结构】链表OJ面试题(题库+解析)

前言 还不清楚链表的码喵们可以看看前篇关于链表的详解 http://t.csdnimg.cn/X6t6P 1.链表面试题 既然已经懂得了链表该如何实现&#xff0c;那么现在就趁热打铁开始练习&#xff01;这里给码喵们整理了相对不错的一些OJ题来练习 1. 删除链表中等于给定值 val 的所有结点。 力…

代码随想录 Leetcode78. 子集

题目&#xff1a; 代码(首刷看解析 2024年2月3日&#xff09;&#xff1a; class Solution { private:vector<vector<int>> res;vector<int> path; public:void backtracking(vector<int>& nums, int startIndex) {res.push_back(path);for (int …