机智云案例(ESP8266模块接入机智云平台实现APP控制舵机旋转)

本文介绍了如何使用ESP8266模块连接到机智云平台,涉及ESP8266的特性、工作模式、串口通信、固件烧录步骤、以及MCU(如STM32)与ESP8266的硬件接线和代码移植。通过创建产品、虚拟设备,实现了远程控制和数据交换功能。
摘要由CSDN通过智能技术生成

ESP8266模块

ESP8266模块简介

  • ESP8266是一款超低功耗的UART-WiFi 透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi 无线网络上,进行互联网或局域网通信,实现联网功能。

  • 支持无线802.11 b/g/n 标准

  • 支持STA/AP/STA+AP三种工作模式

  • 内置TCP/IP协议栈,支持多路TCP Client连接

  • 支持丰富的Socket AT指令

  • 支持UART/GPIO数据通信接口

  • 支持Smart Link 智能联网功能

  • 支持远程固件升级(OTA)

  • 内置32位MCU, 可兼作应用处理器

  • 超低能耗,适合电池供电应用

  • 3.3V 单电源供电

引脚介绍

ESP8266硬件接口丰富,可支持UART,IIC,PWM,GPIO,ADC等,适用于各种物联网应用场合

在这里插入图片描述

在这里插入图片描述

主要功能和工作模式

主要功能

  • ESP8266可以实现的主要功能包括:串口透传,PWM 调控,GPIO控制。

  • 串口透传:数据传输,传输的可靠性好,最大的传输速率为:460800bps。

  • PWM 调控:灯光调节,三色LED 调节,电机调速等。

  • GPIO控制:控制开关,继电器等。

工作模式

  • ESP8266模块支持STA/AP/STA+AP 三种工作模式。
  • STA 模式:ESP8266模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制。
  • AP 模式:ESP8266模块作为热点,实现手机或电脑直接与模块通信,实现局域网无线控制。
  • STA+AP 模式:两种模式的共存模式,即可以通过互联网控制可实现无缝切换,方便操作。

调试模块

硬件接线

ESP8266WIFI模块USB转TTL模块面包板
TXRXNone
RXTXNone
GNDGNDGND
ENNoneVCC
3V3NoneVCC
IO0NoneVCC
IO2NoneVCC
RSTNoneVCC

注意: 面板板处于通电状态

发送AT+RST指令

接好线后,将USB转TTL模块接入电脑打开串口助手,发送AT+RST指令

在这里插入图片描述

  • 串口接收到模块返回的信息,调试完成

参考资料

本小节参考:

ESP8266新手入门调试指导(ESP-01).pdf

ESP8266-01 WiFi模块用户手册V1.0

机智云平台

简介

在这里插入图片描述

文档中心

在这里插入图片描述

开发的一些教程和资料

开发者中心

在这里插入图片描述

创建产品、APP和自动生成代码服务

基于机智云平台的物联网开发

在这里插入图片描述

开发流程:

  • 在平台开发者界面创建产品和小程序
  • 将GAgent固件烧入WIFI模组中
  • 平台自动生成MCU方案代码
  • 将自动生成的代码移植到ST标准库(主要完成硬件功能设计、WIFI模块与MCU的通信)
  • 下面是开发时比较重要的一些概念

GAgent

在这里插入图片描述

  • 官方提供的固件,可将其烧录进ESP8266WIFI模组;烧录后,模组原来的AT指令集失去作用,模组能够接入机智云平台,并自动完成模组与平台间的数据交换

  • GAgent配网方式

    • airlink
    • softap

在这里插入图片描述

MCU与WIFI模块的通信

ESP8266用UART通信,并有应答机制;MCU与WIFI模块的通讯可以用MCU自带的USART(支持UART)资源

参考资料

本小节参考:

平台概述 - Gizwits

机智云名词定义解释 - Gizwits

【机智云带你一节课入门物联网APP开发】

实操01: GAgent固件的烧写(ESP8266)

烧录的方法有两种,一是用烧录器烧录,而是用USB转TTL模块烧录,由于我没有烧录器,就只介绍用USB转TTL烧录的方式

1.下载GAgent固件包

在这里插入图片描述

下载好的固件包的内容,根据参数选择烧录的固件包

在这里插入图片描述

  1. 下载安可信ESP8266资料

在这里插入图片描述

安信可ESP8266系列接入机智云方案及问题排查指引 - Gizwits

  1. 硬件接线(ESP-01s为例)(因为我买的是这款)

接线:

ESP-01sUSB转TTL面包板
RXTXNone
TXRXNone
3V3VCCNone
IO0NoneGND
GNDGNDGND
  1. 打开 第2步 ESP8266资料中的烧录软件

在这里插入图片描述

一直点进去直到找到.exe文件

在这里插入图片描述

打开后是这样的
在这里插入图片描述

查看芯片参数(之前调试的时候有)

在这里插入图片描述

参数配置

在这里插入图片描述

点击start

在这里插入图片描述

完成

在这里插入图片描述

参考资料

本小节参考资料:

(1条消息) 个人项目——STM32接入机智云教程_at指令能连机智云吗_唯恋殊雨的博客-CSDN博客

【ESP8266固件烧录详解】

安信可ESP8266系列接入机智云方案及问题排查指引 - Gizwits


说明: 若问题无法解决 ESP01或ESP01-s系列接线可参考B站大佬的视频,烧录的步骤可参考官网文档和另一个大佬写的博客

注意: 烧写失败有可能是线接触不良(Combine包比较大),有时候需重试几次才能烧录成功!!!

实操02: 检查GAgent固件是否烧录成功

  1. 进入机智云平台随便新建一个产品

在这里插入图片描述

随便加个数据点(不然调试助手会检测不到产品)

在这里插入图片描述

  1. 可以看到左上角有PK和PS

在这里插入图片描述

  1. 下载机智云的串口调试助手

在这里插入图片描述

  1. 打开串口调试助手

在这里插入图片描述

  1. 将EPS8266模块与usb-TTL连接
ESP-01sUSB转TTL面包板
RXTXNone
TXRXNone
3V3VCCNone
IO0NoneVCC
GNDGNDGND

ESP其他引脚都接VCC(手册上说悬空也行,但有的芯片必须得全接好才能正常工作!!!)

  1. 进入模拟MCU、选择串口、SoftAP
    在这里插入图片描述
  • 点击SoftAp后,串口向模块发送进入SoftAP模式的信息,模块收到后会进行应答
  • 若能接收到模块的信息则说明GAgent烧录成功
  1. 打开手机WIFI界面可以看到XPG-GAgent开头的WIFI

在这里插入图片描述

实操03: 创建产品

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

参考资料

本小节参考:

【机智云带你一节课入门物联网APP开发】

更多细节参考官方视频

实操04: 虚拟设备

  1. 下载中心下载机智云APP

在这里插入图片描述

  1. 开发者中心->虚拟设备->打开APP扫码绑定设备

在这里插入图片描述

  1. APP上改变舵机角度,云端数据发生相应变化

机智云虚拟设备

参考资料

本小节参考:

【机智云带你一节课入门物联网APP开发】

更多细节参考官方视频

实操05: MCU自动代码生成+代码移植到标准库(*)

1. 自动生成代码服务

在这里插入图片描述

下载代码即可

2. 自动生成代码说明

  1. 两个重要的包

在这里插入图片描述

自动生成代码中,Gizwits和Utils是我们需要的(一个建立起与机智云的通讯,一个是工具包)

  1. 打开MDK-ARM文件夹,打开keil工程文件
  2. 可以看到,自动生成的代码是基于Hal库的,我们需要实现自己的功能,并将其移植到标准库中

在这里插入图片描述

  1. 打开Gizwits中的gizwits_product.c

在这里插入图片描述

  1. 机智云服务用到的三个外设

在这里插入图片描述

可以看到,需要用一个定时器(Timer)和两个串口(USART)

说明:

  • 定时器也可以用TIM1、TIM3,同理串口也不一定要用USART1和USART2

  • USART1用于打印调试信息,这一部分功能可以删去,但相应要修改一些代码

关于USART1:

在gizwits_product.c大概两百多行的位置,重写了fputc函数

在这里插入图片描述

然后再utils/common.h文件中可以看到GIZWITS_LOG(日志函数)就是printf

在这里插入图片描述

在自动生成的代码中,很多调试信息的打印都调用了GIZWITS_LOG

在这里插入图片描述

当完成USART1的初始化并重写fputc函数后, 将USART1的端口与usb转TTL模块连接后接入电脑,借助串口助手可以打印调试信息到串口助手

在这里插入图片描述

重写的方式如上(本质上就是用USART1发送数据)

6. 主要文件和接口
文件说明
Gizwits_product.c该文件为产品相关处理函数,如gizEventProcess()平台相关硬件初始化,如串口、定时器等。
Gizwits_product.h该文件为gizwits_product.c的头文件,存放产品相关宏定义如:HARDWARE_VERSION、SOFTWARE_VERSION
Gizwits_protocol.c该文件为SDK API接口函数定义文件
Gizwits_protocol.h该文件为gizwits_protocol.c对应头文件,相关API的接口声明均在此文件中。
API名称API功能
Void gizwitsInit(void)gizwits 协议初始化接口。用户调用该接口可以完成 Gizwits 协议相关初始化(包括协议相关定时器、串口的初始化)。
Void gizwitsSetMode(unit8_t mode)参数mode[in]:仅支持0,1和2,其他数据无效。参数为 0,恢复模组出厂配置接口,调用会清空所有配置参数,恢复到出厂默认配置; 参数为 1 时配置模组进入 SoftAp 模式; 参数为 2 配置模组进入 AirLink 模式。
Void gizwitsHandle(dataPoint_t *dataPoint)参数 dataPoint[in]:用户设备数据点。该函数中完成了相应协议数据的处理即数据上报的等相关操作。
Int8_t gizwitsEventProcess(eventInfo_t *info,uint8_t *data,uint32_t len)参数 info[in]:事件队列参数 ; data[in]:数据; 参数 len [in]:数据长度。用户数据处理函数,包括 wifi 状态更新事件和控制事件。a) Wifi 状态更新事件WIFI_开头的事件为 wifi 状态更新事件,data 参数仅在WIFI_RSSI 有效,data 值为 RSSI 值,数据类型为 uint8_t,取值范围 0~7。 b) 控制事件与数据点相关,本版本代码会打印相关事件信息,相关数值也一并打印输出,用户只需要做命令的具体执行即可。

可参考官方文档: 独立MCU方案接入机智云 - Gizwits

3. 代码移植 (需要根据需求进行修改)

串口通信(Serial.c)

#include "stm32f10x.h"
#include "Server.h"
#include "gizwits_protocol.h"
/*
 * WIFI模块通信初始化 USART2
 */
void Serial_WIFI_Init(uint32_t BoundRate)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 配置GPIO
	// Tx
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// Rx
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置USART
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate=BoundRate;
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStructure.USART_Parity=USART_Parity_No;  // 无奇偶校验
	USART_InitStructure.USART_StopBits=USART_StopBits_1; // 一位停止位
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;  // 传输字长
	USART_Init(USART2, &USART_InitStructure);
	
	// 打开USART中断
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  // 打开接收寄存器非空中断
	// 配置NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;  // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;  // 响应优先级
	NVIC_Init(&NVIC_InitStructure);
	// 启动USART
	USART_Cmd(USART2, ENABLE);
}

void USART2_IRQHandler(void)
{
	uint8_t Data=0;
	if(USART_GetITStatus(USART2, USART_IT_RXNE)!=RESET)
	{
		Data = USART_ReceiveData(USART2);
		gizPutData(&Data, 1);  // 解析数据
	}
}

/*
 *  调试端口USART1
 */
void Serial_DebugInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	
	//TX   PA9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);
   
	//RX	PA10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	
  
   //USART 初始化设置
	USART_InitStructure.USART_BaudRate = 9600;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

	USART_Init(USART1, &USART_InitStructure); //初始化串口1
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
	USART_Cmd(USART1, ENABLE);                    
}	

void USART1_IRQHandler(void)   
{
	
}

Timer.c

#include "stm32f10x.h"
#include "Serial.h"
#include "gizwits_product.h"

// TIM3
void Timer_TIM3Init(uint16_t PSC, uint16_t CNT)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	TIM_InternalClockConfig(TIM3);
	// TimeBase
	TIM_TimeBaseInitTypeDef TimerBaseInitStructure;
	TimerBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TimerBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TimerBaseInitStructure.TIM_Period=CNT;
	TimerBaseInitStructure.TIM_Prescaler=PSC;
	TimerBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM1, &TimerBaseInitStructure);
	TIM_ClearFlag(TIM1, TIM_FLAG_Update);
	// 使能更新中断
	TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;  // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;  // 响应优先级
	NVIC_Init(&NVIC_InitStructure);
	// 开启TIM
	TIM_Cmd(TIM1, ENABLE);
}

/*
 *  TIM3 中断函数
 */
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update))
	{
		gizTimerMs();  // 机智云计数
		// 清除标志位
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);	
	}
}

Key.c (用于配置模式)

#include "stm32f10x.h"
#include "delay.h"
#include "Server.h"
#include "gizwits_protocol.h"
// PA1作为按键输入
// 2023年4月18日16:32:06

/*
 *  按键初始化函数  下降沿触发 配置为上拉输入
 */
void Key_Init(void)
{
	// RCC 使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	// 配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置AFIO
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);  // PA1
	
	// 配置EXTI
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line1;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;  // 下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	// 配置NVIC分组 只需配置一次
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	// 配置NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;  // 响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
}

/*
 *  EXTI 中断函数
 */
void EXTI1_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line1))
	{
		// 消抖
		Delay_ms(40);
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)
		{	
			Serve_Angle += 30;
		}
		while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0);
		if(Serve_Angle>180)
		{
			Serve_Angle = 0;
		}
		Server_SetAngle((float)Serve_Angle);
		// 清除标志位
		EXTI_ClearITPendingBit(EXTI_Line1);
	}

}

// 机智云模式配置按钮 AirLink SoftAP Reset 三种模式
void Key_WIFIModeInit(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	// PB10 按下低电平 配置成上拉输入
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	// PB12 PB13 按下高电平 配置成下拉输入
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_14;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	// AFIO
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
	// EXTI
	// PB1 下降沿触发
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line10;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; 
	EXTI_Init(&EXTI_InitStructure);
	
	// PB12 PB14 上升沿触发
	EXTI_InitStructure.EXTI_Line=EXTI_Line12|EXTI_Line14;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
	EXTI_Init(&EXTI_InitStructure);

	// NVIC
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;  // 响应优先级
	NVIC_Init(&NVIC_InitStructure);
}

/*
 *	EXTI通道10-15中断函数 PB10 PB12 PB14 分别对应WIFI模块工作的三种模式
 */
void EXTI15_10_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line10))
	{
		// 消抖
		Delay_ms(40);
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0)
		{	
			gizwitsSetMode(WIFI_AIRLINK_MODE);
			GIZWITS_LOG("AirLink mode\r\n");
		}
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0);
		
		// clear
		EXTI_ClearITPendingBit(EXTI_Line10);
	}
	else if(EXTI_GetITStatus(EXTI_Line12))
	{
		// 消抖
		Delay_ms(40);
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1)
		{	
			gizwitsSetMode(WIFI_SOFTAP_MODE);
			GIZWITS_LOG("Soft AP mode\r\n");  
		}
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1);
		
		// clear
		EXTI_ClearITPendingBit(EXTI_Line12);
	}
	else if(EXTI_GetITStatus(EXTI_Line14))
	{
		// 消抖
		Delay_ms(40);
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1)
		{	
			gizwitsSetMode(WIFI_RESET_MODE);
			GIZWITS_LOG("Reset mode\r\n");
		}
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1);
		// clear
		EXTI_ClearITPendingBit(EXTI_Line14);
	}

}

gizwits_product.c (注释掉Hal库的内容, 替换成ST库,完成User Handle部分内容)

/**
************************************************************
* @file         gizwits_product.c
* @brief        Gizwits control protocol processing, and platform-related       hardware initialization 
* @author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @copyright    Gizwits
* 
* @note         机智云.只为智能硬件而生
*               Gizwits Smart Cloud  for Smart Products
*               链接|增值ֵ|开放|中立|安全|自有|自由|生态
*               www.gizwits.com
*
***********************************************************/

#include <stdio.h>
#include <string.h>
// #include "hal_key.h"
#include "gizwits_product.h"
#include "common.h"
#include "LED.h"
#include "Server.h"
#include "AD.h"
static uint32_t timerMsCount;
//static uint32_t timerMsCount;
uint8_t aRxBuffer;

/** User area the current device state structure*/
dataPoint_t currentDataPoint;

//extern TIM_HandleTypeDef htim2;
//extern UART_HandleTypeDef huart1;
//extern UART_HandleTypeDef huart2;

/**@} */
/**@name Gizwits User Interface
* @{
*/

/**
* @brief Event handling interface

* Description:

* 1. Users can customize the changes in WiFi module status

* 2. Users can add data points in the function of event processing logic, such as calling the relevant hardware peripherals operating interface

* @param [in] info: event queue
* @param [in] data: protocol data
* @param [in] len: protocol data length
* @return NULL
* @ref gizwits_protocol.h
*/
int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len)
{
    uint8_t i = 0;
    dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata;
    moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)gizdata;
    protocolTime_t *ptime = (protocolTime_t *)gizdata;
    
#if MODULE_TYPE
    gprsInfo_t *gprsInfoData = (gprsInfo_t *)gizdata;
#else
    moduleInfo_t *ptModuleInfo = (moduleInfo_t *)gizdata;
#endif

    if((NULL == info) || (NULL == gizdata))
    {
        return -1;
    }

    for(i=0; i<info->num; i++)
    {
        switch(info->event[i])
        {


        case EVENT_Angle:
            currentDataPoint.valueAngle = dataPointPtr->valueAngle;
            GIZWITS_LOG("Evt:EVENT_Angle %4f\n",currentDataPoint.valueAngle);
            //user handle
			Serve_Angle=currentDataPoint.valueAngle;
			Server_SetAngle(currentDataPoint.valueAngle);  // 设置电机角度
            break;


        case WIFI_SOFTAP:
            break;
        case WIFI_AIRLINK:
            break;
        case WIFI_STATION:
            break;
        case WIFI_CON_ROUTER:
 
            break;
        case WIFI_DISCON_ROUTER:
 
            break;
        case WIFI_CON_M2M:
 
            break;
        case WIFI_DISCON_M2M:
            break;
        case WIFI_RSSI:
            GIZWITS_LOG("RSSI %d\n", wifiData->rssi);
            break;
        case TRANSPARENT_DATA:
            GIZWITS_LOG("TRANSPARENT_DATA \n");
            //user handle , Fetch data from [data] , size is [len]
            break;
        case WIFI_NTP:
            GIZWITS_LOG("WIFI_NTP : [%d-%d-%d %02d:%02d:%02d][%d] \n",ptime->year,ptime->month,ptime->day,ptime->hour,ptime->minute,ptime->second,ptime->ntp);
            break;
        case MODULE_INFO:
            GIZWITS_LOG("MODULE INFO ...\n");
#if MODULE_TYPE
            GIZWITS_LOG("GPRS MODULE ...\n");
            //Format By gprsInfo_t
            GIZWITS_LOG("moduleType : [%d] \n",gprsInfoData->Type);
#else
            GIZWITS_LOG("WIF MODULE ...\n");
            //Format By moduleInfo_t
            GIZWITS_LOG("moduleType : [%d] \n",ptModuleInfo->moduleType);
#endif
        break;
        default:
            break;
        }
    }

    return 0;
}

/**
* User data acquisition

* Here users need to achieve in addition to data points other than the collection of data collection, can be self-defined acquisition frequency and design data filtering algorithm

* @param none
* @return none
*/
void userHandle(void)
{
	currentDataPoint.valueLED = LED_Info();//Add Sensor Data Collection
    currentDataPoint.valueAD_Voltage = AD_Voltage;//Add Sensor Data Collection
}

/**
* Data point initialization function

* In the function to complete the initial user-related data
* @param none
* @return none
* @note The developer can add a data point state initialization value within this function
*/
void userInit(void)
{
    memset((uint8_t*)&currentDataPoint, 0, sizeof(dataPoint_t));
    
    /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/ 
    /*
    currentDataPoint.valueLED = ;
    currentDataPoint.valueAD_Voltage = ;
    currentDataPoint.valueAngle = ;
    */

}


/**
* @brief Millisecond timing maintenance function, milliseconds increment, overflow to zero

* @param none
* @return none
*/
void gizTimerMs(void)
{
    timerMsCount++;
}

/**
* @brief Read millisecond count

* @param none
* @return millisecond count
*/
uint32_t gizGetTimerCount(void)
{
    return timerMsCount;
}

/**
* @brief MCU reset function

* @param none
* @return none
*/
void mcuRestart(void)
{
    __set_FAULTMASK(1);
    NVIC_SystemReset();
}

/**@} */

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART1 and Loop until the end of transmission */
//  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
	USART_SendData(USART1, (uint8_t)ch);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
	return ch;
}

///**
//  * @brief  Period elapsed callback in non blocking mode 
//  * @param  htim : TIM handle
//  * @retval None
//  */
//void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//{
//	if(htim==&htim2)
//	{
//			keyHandle();
//			gizTimerMs();
//	}
//}

///**
//* @brief Timer TIM3 init function

//* @param none
//* @return none
//*/
//void timerInit(void)
//{
//	HAL_TIM_Base_Start_IT(&htim2);
//}

///**
//  * @brief  This function handles USART IDLE interrupt.
//  */
//void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)  
//{  
//    if(UartHandle->Instance == USART2)  
//    {  
//				gizPutData((uint8_t *)&aRxBuffer, 1);

//        HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断  
//    }  
//}  

///**
//* @brief USART init function

//* Serial communication between WiFi modules and device MCU
//* @param none
//* @return none
//*/
//void uartInit(void)
//{
//	HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断  
//}

/**
* @brief Serial port write operation, send data to WiFi module
*
* @param buf      : buf address
* @param len      : buf length
*
* @return : Return effective data length;-1,return failure
*/
int32_t uartWrite(uint8_t *buf, uint32_t len)
{
	uint8_t crc[1] = {0x55};
    uint32_t i = 0;
	
    if(NULL == buf)
    {
        return -1;
    }

    for(i=0; i<len; i++)
    {
//        HAL_UART_Transmit_IT(&huart2, (uint8_t *)&buf[i], 1);
//				while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission

//        if(i >=2 && buf[i] == 0xFF)
//        {
//						HAL_UART_Transmit_IT(&huart2, (uint8_t *)&crc, 1);
//						while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission
//        }
		USART_SendData(USART2, (uint8_t)buf[i]);
		while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET);
		if(i>=2 && buf[i] == 0xFF)
		{
			USART_SendData(USART2, crc[0]);
			while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET);
		}
    }

#ifdef PROTOCOL_DEBUG
    GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
    for(i=0; i<len; i++)
    {
        GIZWITS_LOG("%02x ", buf[i]);

        if(i >=2 && buf[i] == 0xFF)
        {
            GIZWITS_LOG("%02x ", 0x55);
        }
    }
    GIZWITS_LOG("\n");
#endif
		
		return len;
}  

gizwits_protocol.c (注释掉Hal库的代码)

main.c

#include "stm32f10x.h" 
#include "delay.h"
#include "OLED.h"
#include "key.h"
#include "Server.h"
#include "Timer.h"
#include "Serial.h"
#include "AD.h"
#include "LED.h"
#include "gizwits_protocol.h"
#include "gizwits_product.h"

/*
 *  单片机课设
 *  2023年4月18日16:06:37
 *  需求: 1. 上位机控制舵机旋转的角度(0-180°)
 *        2. 每5秒返回一次信息(传给上位机和OLED屏幕)
 *        3. 按下按键使舵机角度增加30°(若超过180°则回到0°)
 *        4. LED灯闪烁作为系统指示灯
 *        5. 光敏传感器 控制蜂鸣器报警
 *        6. 加入机智云物联网方案
 *  程序设计:
 *        1. 硬件: STM32F103c8t6、面包板、舵机、OLED屏幕
 *        2. 上位机与单片机的通信用USART1和DMA1(PA9 Tx, PA10 Rx)
 *        3. TIM1用来计时
 *        4. TIM2_CH1 用来输出PWM信号控制舵机旋转角度  PA0
 * 		  5. B6、B7、B8、B9接OLED屏幕
 *        6. PA1作为按键输入 
 */

void Gitwits_Init(void)
{
	Timer_TIM3Init(10-1, 7200-1);  // 1ms
	Serial_WIFI_Init(9600);  // 波特率9600
	Serial_DebugInit();  // 串口初始化
	userInit();  // 数据初始化
	gizwitsInit();  // 机智云初始化
	Key_WIFIModeInit();  // 模式选择按键初始化
}

int main(void)
{
	OLED_Init();
	Gitwits_Init();
	Key_Init();
	Server_Init();
	AD_Init();
	LED_Init();
	OLED_ShowString(1, 1, "Angle:");
	OLED_ShowString(2, 1, "AD_Value:");
	OLED_ShowString(3, 1, "Voltage:0.00V");
	
	while(1)
	{
		gizwitsHandle((dataPoint_t *)&currentDataPoint);  // 机智云协议处理 必须
		OLED_ShowNum(1, 7, Serve_Angle, 3);
		OLED_ShowNum(2, 10, AD_Value, 4);
		AD_Voltage = (float)AD_Value*3.3/4096;
		OLED_ShowNum(3, 9, AD_Voltage, 1);
		OLED_ShowNum(3, 11, (uint16_t)(AD_Voltage * 100)% 100, 2);
		LED_Off();
		userHandle(); //数据上行 必须  上行的数据可在gizwits_product.c中修改
	}
}

4. 其他代码 (MCU实现的功能)

LED.c

#include "stm32f10x.h"
#include "delay.h"

/*
 *	初始化LED  PB10  低电平驱动
 */
void LED_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB, GPIO_Pin_10);
}

/*
 *  LED灭
 */
void LED_Off(void)
{
	GPIO_SetBits(GPIOB, GPIO_Pin_10);
}

/*
 *  LED亮
 */
void LED_On(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_10);

}

uint8_t LED_Info(void)
{
	return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10);
}
#include "stm32f10x.h"
#include "delay.h"

/*
 *	初始化LED  PB10  低电平驱动
 */
void LED_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB, GPIO_Pin_10);
}

/*
 *  LED灭
 */
void LED_Off(void)
{
	GPIO_SetBits(GPIOB, GPIO_Pin_10);
}

/*
 *  LED亮
 */
void LED_On(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_10);

}

uint8_t LED_Info(void)
{
	return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10);
}

Server.c (舵机驱动)

#include "stm32f10x.h"
float Serve_Angle;
// TIM2_CH1 用来输出PWM信号控制舵机旋转角度  PA0
// 频率50Hz
void Server_Init(void)
{
	// RCC使能时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	// 选择内部时钟作为TIM2的时钟
	TIM_InternalClockConfig(TIM2);
	
	// 配置时基单元
	TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
	TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TimeBase_InitStructure.TIM_Period=20000-1;   // ARR
	TimeBase_InitStructure.TIM_Prescaler=72-1;
	TimeBase_InitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2, &TimeBase_InitStructure);
	
	// 配置OC单元(输出比较单元 OutPut Compare)  OC1
	TIM_OCInitTypeDef OC_InitStructure;
	TIM_OCStructInit(&OC_InitStructure);
	OC_InitStructure.TIM_OCMode=TIM_OCMode_PWM1;
	OC_InitStructure.TIM_Pulse=0;  // CCR寄存器
	OC_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平
	OC_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC1Init(TIM2, &OC_InitStructure);
	
	// 开启TIM
	TIM_Cmd(TIM2, ENABLE);
}

/*
 *  设置OC1 CCR寄存器的值
 */
void Server_Set_Compare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);  
}


/*
	设置舵机角度 
	因为舵机需要20ms的波长来驱动 可知频率为50Hz 若ARR设置为 20000-1 则PSC设置为72-1
	又0.5ms~2.5ms对应舵机角度的0~180°
	0.5ms 对应ARR为500  2.5ms 对应ARR为2500
	对应角度的CCR应该设置为(Angle / 180 * 2000 + 500)
*/
void Server_SetAngle(float Angle)
{
	Server_Set_Compare1(Angle / 180 * 2000 + 500);
}


AD.c

#include "stm32f10x.h"
#include "MyDMA.h"
#include "LED.h"
uint16_t AD_Value;
float AD_Voltage;
/*
 *  初始化ADC
 */
void AD_Init(void)
{
	// 初始化DMA通道1运输ADC1的数据
	AD_MyDMA_Init();
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 12MHz mm
	// 配置GPIO口
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// 选择规则通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_55Cycles5);
	
	// 配置ADC转换器
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 单次转换或者连续转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据对齐模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // ADC模式, 单独还是交叉
	ADC_InitStructure.ADC_NbrOfChannel = 1;  // 扫描的通道数
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 扫描模式或者非扫描模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 触发控制
	ADC_Init(ADC1, &ADC_InitStructure);
	
	// 开启DMA转运
	ADC_DMACmd(ADC1, ENABLE);
	
	// 开启模拟看门狗
	ADC_AnalogWatchdogThresholdsConfig(ADC1, 0xFFF, 0x5DC);  // 设置看门狗阈值
	ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_7); // 对通道7设置看门狗
	ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);  // 使能单通道模拟看门狗
	ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);  // 开启模拟看门狗中断
	
	// 配置NVCI
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=ADC1_2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_InitStructure);
	// 开启ADC功能
	ADC_Cmd(ADC1, ENABLE);
	
	// ADC校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);  // 已初始化为零
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET); 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

/*
 *  ADC中断函数
 */
void ADC1_2_IRQHandler(void)
{
	if(ADC_GetITStatus(ADC1, ADC_IT_AWD)==SET)
	{
		// 开启警报灯
		LED_On();
		// 清除中断标志
		ADC_ClearITPendingBit(ADC1, ADC_IT_AWD);
	}

}

MyDMA.c

#include "stm32f10x.h"
#include "Serial.h"
#include "AD.h"
#define TXBUFFERSIZE 11
#define RXBUFFERSIZE 15

/*
 *	ADC DMA初始化
 */
void AD_MyDMA_Init(void)
{
	// RCC使能时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	// 配置DMA
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // ADC的数据寄存器
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	// 地址非自增, ADC可以理解为上菜的桌子只有一个
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value;  // 保存的地址
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  // 这里要自增
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  // 转运方向
	DMA_InitStructure.DMA_BufferSize = 1;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 自动重装
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;	 // 硬件触发
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	// 开启DMA
	DMA_Cmd(DMA1_Channel1, ENABLE);  // 通道1
}

将移植后的代码下载进单片机中,连接好硬件电路后,即可进入下一步

接线示范 (仅供参考,根据自己的实际需求接)

在这里插入图片描述

说明:

  • A2、A3为USART的端口,分别接WIFI模块的TX、RX
  • WIFI模块出了TX、RX和GND,其余引脚工作时接高电平(手册解释有些引脚浮空也行,但我这块实测都得接高电平)
  • B10、B12、B14为选择WIFI模块工作模式的三个按键分别对应(RESET、SoftAP、AirLink)
  • A7为光敏传感器模拟信号输入口
  • A0为控制舵机PWM信号输出口
  • A1接按键,控制角度加30°
  • 这里USART1的A9、A10未接线,可接USB转TTL模块将调试信息打印到电脑的串口助手

5. 设备连网

  1. 准备工作

    需要: 机智云APP,两台移动设备(手机,一台用来开热点,热点频率为2.4G)

  2. 机智云APP下载

在这里插入图片描述

  1. 用另外一台设备开启热点 (注意频段为2.4G)

在这里插入图片描述

  1. 进入机智云连接设备,然后…
    在这里插入图片描述
    在这里插入图片描述

输入热点密码,下一步

在这里插入图片描述

选择乐鑫 (选择模块对应的模组) 继续点直到进入,这时候先别点,先按下B10的按键(SoftAP模式的按键)让模组进入SoftAP工作模式,然后点几蓝色字体

在这里插入图片描述

点击XPG-GAgent-7067(漏了一步,在点击XPG前,手机要先连上热点)

在这里插入图片描述

若找不到: XPG开头的,则可将MCU与WIFI模组通信的串口的发送口,通过USB转TTL接到电脑上,用串口助手查看发送的信息是否正确(与实操02中的协议一致),若不一致则需进一步进行检查

在这里插入图片描述

还有一种情况,需接受调试串口的信息,看程序是否运行正常,见参考资料【STM32移植机智云】超详细教程#2ESP8266移植机智云教程‘代码移植的最后

这是大佬文章的最后:
在这里插入图片描述

回到机智云调试APP,等待设备连接

在这里插入图片描述

若连接失败: 则检查热点质量,检查输入的热点密码是否正确

可以看到设备在线,点进去后

在这里插入图片描述

可以通过手机控制舵机的角度

在这里插入图片描述

参考资料

本小节参考以下资料

参考文档:

独立MCU方案接入机智云 - Gizwits

GAgent详解 - Gizwits

安信可ESP8266系列接入机智云方案及问题排查指引 - Gizwits

参考视频:

【机智云带你一节课入门物联网APP开发】

【机智云移植到stm32F103C8T6基于标准库】

参考博客:

【STM32移植机智云】超详细教程#2ESP8266移植机智云教程‘代码移植

实操06: APP生成

  1. 创建 → \rightarrow 移动应用 → \rightarrow 应用名称、应用包名随便填(应用包名最好英文) → \rightarrow 关联应用,不关联
    在这里插入图片描述

  2. 关联应用 → \rightarrow 选择产品 (图标壁纸可以根据喜好,自己上传资源)

在这里插入图片描述
在这里插入图片描述

  1. 构建应用 → \rightarrow 应用构建 → \rightarrow 构建测试版

在这里插入图片描述

  1. 构建成功后可以用手机下载

在这里插入图片描述

  1. 添加设备 (过程与在调试APP添加设备类似)

  2. 展示一下

在这里插入图片描述
在这里插入图片描述

评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值