ESP8266模塊
ESP8266模塊簡介
-
ESP8266是一款超低功耗的UART-WiFi 透傳模塊,擁有業(yè)內(nèi)極富競爭力的封裝尺寸和超低能耗技術(shù),專為移動設(shè)備和物聯(lián)網(wǎng)應(yīng)用設(shè)計,可將用戶的物理設(shè)備連接到Wi-Fi 無線網(wǎng)絡(luò)上,進行互聯(lián)網(wǎng)或局域網(wǎng)通信,實現(xiàn)聯(lián)網(wǎng)功能。
-
支持無線802.11 b/g/n 標(biāo)準(zhǔn)
-
支持STA/AP/STA+AP三種工作模式
-
內(nèi)置TCP/IP協(xié)議棧,支持多路TCP Client連接
-
支持豐富的Socket AT指令
-
支持UART/GPIO數(shù)據(jù)通信接口
-
支持Smart Link 智能聯(lián)網(wǎng)功能
-
支持遠(yuǎn)程固件升級(OTA)
-
內(nèi)置32位MCU, 可兼作應(yīng)用處理器
-
超低能耗,適合電池供電應(yīng)用
-
3.3V 單電源供電
引腳介紹
ESP8266硬件接口豐富,可支持UART,IIC,PWM,GPIO,ADC等,適用于各種物聯(lián)網(wǎng)應(yīng)用場合
主要功能和工作模式
主要功能
-
ESP8266可以實現(xiàn)的主要功能包括:串口透傳,PWM 調(diào)控,GPIO控制。
-
串口透傳:數(shù)據(jù)傳輸,傳輸?shù)目煽啃院?,最大的傳輸速率為?60800bps。
-
PWM 調(diào)控:燈光調(diào)節(jié),三色LED 調(diào)節(jié),電機調(diào)速等。
-
GPIO控制:控制開關(guān),繼電器等。
工作模式
- ESP8266模塊支持STA/AP/STA+AP 三種工作模式。
- STA 模式:ESP8266模塊通過路由器連接互聯(lián)網(wǎng),手機或電腦通過互聯(lián)網(wǎng)實現(xiàn)對設(shè)備的遠(yuǎn)程控制。
- AP 模式:ESP8266模塊作為熱點,實現(xiàn)手機或電腦直接與模塊通信,實現(xiàn)局域網(wǎng)無線控制。
- STA+AP 模式:兩種模式的共存模式,即可以通過互聯(lián)網(wǎng)控制可實現(xiàn)無縫切換,方便操作。
調(diào)試模塊
硬件接線
ESP8266WIFI模塊 | USB轉(zhuǎn)TTL模塊 | 面包板 |
---|---|---|
TX | RX | None |
RX | TX | None |
GND | GND | GND |
EN | None | VCC |
3V3 | None | VCC |
IO0 | None | VCC |
IO2 | None | VCC |
RST | None | VCC |
注意: 面板板處于通電狀態(tài)
發(fā)送AT+RST指令
接好線后,將USB轉(zhuǎn)TTL模塊接入電腦打開串口助手,發(fā)送AT+RST指令
- 串口接收到模塊返回的信息,調(diào)試完成
參考資料
本小節(jié)參考:
ESP8266新手入門調(diào)試指導(dǎo)(ESP-01).pdf
ESP8266-01 WiFi模塊用戶手冊V1.0
機智云平臺
簡介
文檔中心
開發(fā)的一些教程和資料
開發(fā)者中心
創(chuàng)建產(chǎn)品、APP和自動生成代碼服務(wù)
基于機智云平臺的物聯(lián)網(wǎng)開發(fā)
開發(fā)流程:
- 在平臺開發(fā)者界面創(chuàng)建產(chǎn)品和小程序
- 將GAgent固件燒入WIFI模組中
- 平臺自動生成MCU方案代碼
- 將自動生成的代碼移植到ST標(biāo)準(zhǔn)庫(主要完成硬件功能設(shè)計、WIFI模塊與MCU的通信)
- 下面是開發(fā)時比較重要的一些概念
GAgent
-
官方提供的固件,可將其燒錄進ESP8266WIFI模組;燒錄后,模組原來的AT指令集失去作用,模組能夠接入機智云平臺,并自動完成模組與平臺間的數(shù)據(jù)交換
-
GAgent配網(wǎng)方式
- airlink
- softap
MCU與WIFI模塊的通信
ESP8266用UART通信,并有應(yīng)答機制;MCU與WIFI模塊的通訊可以用MCU自帶的USART(支持UART)資源
參考資料
本小節(jié)參考:
平臺概述 - Gizwits
機智云名詞定義解釋 - Gizwits
【機智云帶你一節(jié)課入門物聯(lián)網(wǎng)APP開發(fā)】
實操01: GAgent固件的燒寫(ESP8266)
燒錄的方法有兩種,一是用燒錄器燒錄,而是用USB轉(zhuǎn)TTL模塊燒錄,由于我沒有燒錄器,就只介紹用USB轉(zhuǎn)TTL燒錄的方式
1.下載GAgent固件包
下載好的固件包的內(nèi)容,根據(jù)參數(shù)選擇燒錄的固件包
- 下載安可信ESP8266資料
安信可ESP8266系列接入機智云方案及問題排查指引 - Gizwits
- 硬件接線(ESP-01s為例)(因為我買的是這款)
接線:
ESP-01s | USB轉(zhuǎn)TTL | 面包板 |
---|---|---|
RX | TX | None |
TX | RX | None |
3V3 | VCC | None |
IO0 | None | GND |
GND | GND | GND |
- 打開 第2步 ESP8266資料中的燒錄軟件
一直點進去直到找到.exe文件
打開后是這樣的
查看芯片參數(shù)(之前調(diào)試的時候有)
參數(shù)配置
點擊start
完成
參考資料
本小節(jié)參考資料:
(1條消息) 個人項目——STM32接入機智云教程_at指令能連機智云嗎_唯戀殊雨的博客-CSDN博客
【ESP8266固件燒錄詳解】
安信可ESP8266系列接入機智云方案及問題排查指引 - Gizwits
說明: 若問題無法解決 ESP01或ESP01-s系列接線可參考B站大佬的視頻,燒錄的步驟可參考官網(wǎng)文檔和另一個大佬寫的博客
注意: 燒寫失敗有可能是線接觸不良(Combine包比較大),有時候需重試幾次才能燒錄成功?。?!
實操02: 檢查GAgent固件是否燒錄成功
- 進入機智云平臺隨便新建一個產(chǎn)品
隨便加個數(shù)據(jù)點(不然調(diào)試助手會檢測不到產(chǎn)品)
- 可以看到左上角有PK和PS
- 下載機智云的串口調(diào)試助手
- 打開串口調(diào)試助手
- 將EPS8266模塊與usb-TTL連接
ESP-01s | USB轉(zhuǎn)TTL | 面包板 |
---|---|---|
RX | TX | None |
TX | RX | None |
3V3 | VCC | None |
IO0 | None | VCC |
GND | GND | GND |
ESP其他引腳都接VCC(手冊上說懸空也行,但有的芯片必須得全接好才能正常工作?。?!)
- 進入模擬MCU、選擇串口、SoftAP
- 點擊SoftAp后,串口向模塊發(fā)送進入SoftAP模式的信息,模塊收到后會進行應(yīng)答
- 若能接收到模塊的信息則說明GAgent燒錄成功
- 打開手機WIFI界面可以看到XPG-GAgent開頭的WIFI
實操03: 創(chuàng)建產(chǎn)品
參考資料
本小節(jié)參考:
【機智云帶你一節(jié)課入門物聯(lián)網(wǎng)APP開發(fā)】
更多細(xì)節(jié)參考官方視頻
實操04: 虛擬設(shè)備
- 下載中心下載機智云APP
- 開發(fā)者中心->虛擬設(shè)備->打開APP掃碼綁定設(shè)備
- APP上改變舵機角度,云端數(shù)據(jù)發(fā)生相應(yīng)變化
機智云虛擬設(shè)備
參考資料
本小節(jié)參考:
【機智云帶你一節(jié)課入門物聯(lián)網(wǎng)APP開發(fā)】
更多細(xì)節(jié)參考官方視頻
實操05: MCU自動代碼生成+代碼移植到標(biāo)準(zhǔn)庫(*)
1. 自動生成代碼服務(wù)
下載代碼即可
2. 自動生成代碼說明
-
兩個重要的包
自動生成代碼中,Gizwits和Utils是我們需要的(一個建立起與機智云的通訊,一個是工具包)
-
打開MDK-ARM文件夾,打開keil工程文件
-
可以看到,自動生成的代碼是基于Hal庫的,我們需要實現(xiàn)自己的功能,并將其移植到標(biāo)準(zhǔn)庫中
-
打開Gizwits中的gizwits_product.c
-
機智云服務(wù)用到的三個外設(shè)
可以看到,需要用一個定時器(Timer)和兩個串口(USART)
說明:
-
定時器也可以用TIM1、TIM3,同理串口也不一定要用USART1和USART2
-
USART1用于打印調(diào)試信息,這一部分功能可以刪去,但相應(yīng)要修改一些代碼
關(guān)于USART1:
在gizwits_product.c大概兩百多行的位置,重寫了fputc函數(shù)
然后再utils/common.h文件中可以看到GIZWITS_LOG(日志函數(shù))就是printf
在自動生成的代碼中,很多調(diào)試信息的打印都調(diào)用了GIZWITS_LOG
當(dāng)完成USART1的初始化并重寫fputc函數(shù)后, 將USART1的端口與usb轉(zhuǎn)TTL模塊連接后接入電腦,借助串口助手可以打印調(diào)試信息到串口助手
重寫的方式如上(本質(zhì)上就是用USART1發(fā)送數(shù)據(jù))
6. 主要文件和接口
文件 | 說明 |
---|---|
Gizwits_product.c | 該文件為產(chǎn)品相關(guān)處理函數(shù),如gizEventProcess()平臺相關(guān)硬件初始化,如串口、定時器等。 |
Gizwits_product.h | 該文件為gizwits_product.c的頭文件,存放產(chǎn)品相關(guān)宏定義如:HARDWARE_VERSION、SOFTWARE_VERSION |
Gizwits_protocol.c | 該文件為SDK API接口函數(shù)定義文件 |
Gizwits_protocol.h | 該文件為gizwits_protocol.c對應(yīng)頭文件,相關(guān)API的接口聲明均在此文件中。 |
API名稱 | API功能 |
---|---|
Void gizwitsInit(void) | gizwits 協(xié)議初始化接口。用戶調(diào)用該接口可以完成 Gizwits 協(xié)議相關(guān)初始化(包括協(xié)議相關(guān)定時器、串口的初始化)。 |
Void gizwitsSetMode(unit8_t mode) | 參數(shù)mode[in]:僅支持0,1和2,其他數(shù)據(jù)無效。參數(shù)為 0,恢復(fù)模組出廠配置接口,調(diào)用會清空所有配置參數(shù),恢復(fù)到出廠默認(rèn)配置; 參數(shù)為 1 時配置模組進入 SoftAp 模式; 參數(shù)為 2 配置模組進入 AirLink 模式。 |
Void gizwitsHandle(dataPoint_t *dataPoint) | 參數(shù) dataPoint[in]:用戶設(shè)備數(shù)據(jù)點。該函數(shù)中完成了相應(yīng)協(xié)議數(shù)據(jù)的處理即數(shù)據(jù)上報的等相關(guān)操作。 |
Int8_t gizwitsEventProcess(eventInfo_t *info,uint8_t *data,uint32_t len) | 參數(shù) info[in]:事件隊列參數(shù) ; data[in]:數(shù)據(jù); 參數(shù) len [in]:數(shù)據(jù)長度。用戶數(shù)據(jù)處理函數(shù),包括 wifi 狀態(tài)更新事件和控制事件。a) Wifi 狀態(tài)更新事件WIFI_開頭的事件為 wifi 狀態(tài)更新事件,data 參數(shù)僅在WIFI_RSSI 有效,data 值為 RSSI 值,數(shù)據(jù)類型為 uint8_t,取值范圍 0~7。 b) 控制事件與數(shù)據(jù)點相關(guān),本版本代碼會打印相關(guān)事件信息,相關(guān)數(shù)值也一并打印輸出,用戶只需要做命令的具體執(zhí)行即可。 |
可參考官方文檔: 獨立MCU方案接入機智云 - Gizwits
3. 代碼移植 (需要根據(jù)需求進行修改)
串口通信(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; // 搶占優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 響應(yīng)優(yōu)先級
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); // 解析數(shù)據(jù)
}
}
/*
* 調(diào)試端口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; //復(fù)用推挽輸出
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 ;//搶占優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
//USART 初始化設(shè)置
USART_InitStructure.USART_BaudRate = 9600;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
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; // 搶占優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3; // 響應(yīng)優(yōu)先級
NVIC_Init(&NVIC_InitStructure);
// 開啟TIM
TIM_Cmd(TIM1, ENABLE);
}
/*
* TIM3 中斷函數(shù)
*/
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update))
{
gizTimerMs(); // 機智云計數(shù)
// 清除標(biāo)志位
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
/*
* 按鍵初始化函數(shù) 下降沿觸發(fā) 配置為上拉輸入
*/
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; // 下降沿觸發(fā)
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; // 搶占優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; // 響應(yīng)優(yōu)先級
NVIC_Init(&NVIC_InitStructure);
}
/*
* EXTI 中斷函數(shù)
*/
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);
// 清除標(biāo)志位
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 下降沿觸發(fā)
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 上升沿觸發(fā)
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; // 搶占優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 響應(yīng)優(yōu)先級
NVIC_Init(&NVIC_InitStructure);
}
/*
* EXTI通道10-15中斷函數(shù) PB10 PB12 PB14 分別對應(yīng)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庫的內(nèi)容, 替換成ST庫,完成User Handle部分內(nèi)容)
/**
************************************************************
* @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
* 鏈接|增值?|開放|中立|安全|自有|自由|生態(tài)
* 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); // 設(shè)置電機角度
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*)¤tDataPoint, 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"
/*
* 單片機課設(shè)
* 2023年4月18日16:06:37
* 需求: 1. 上位機控制舵機旋轉(zhuǎn)的角度(0-180°)
* 2. 每5秒返回一次信息(傳給上位機和OLED屏幕)
* 3. 按下按鍵使舵機角度增加30°(若超過180°則回到0°)
* 4. LED燈閃爍作為系統(tǒng)指示燈
* 5. 光敏傳感器 控制蜂鳴器報警
* 6. 加入機智云物聯(lián)網(wǎng)方案
* 程序設(shè)計:
* 1. 硬件: STM32F103c8t6、面包板、舵機、OLED屏幕
* 2. 上位機與單片機的通信用USART1和DMA1(PA9 Tx, PA10 Rx)
* 3. TIM1用來計時
* 4. TIM2_CH1 用來輸出PWM信號控制舵機旋轉(zhuǎn)角度 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(); // 數(shù)據(jù)初始化
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 *)¤tDataPoint); // 機智云協(xié)議處理 必須
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(); //數(shù)據(jù)上行 必須 上行的數(shù)據(jù)可在gizwits_product.c中修改
}
}
4. 其他代碼 (MCU實現(xiàn)的功能)
LED.c
#include "stm32f10x.h"
#include "delay.h"
/*
* 初始化LED PB10 低電平驅(qū)動
*/
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 低電平驅(qū)動
*/
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 (舵機驅(qū)動)
#include "stm32f10x.h"
float Serve_Angle;
// TIM2_CH1 用來輸出PWM信號控制舵機旋轉(zhuǎn)角度 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);
// 選擇內(nèi)部時鐘作為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; // 設(shè)置有效電平
OC_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM2, &OC_InitStructure);
// 開啟TIM
TIM_Cmd(TIM2, ENABLE);
}
/*
* 設(shè)置OC1 CCR寄存器的值
*/
void Server_Set_Compare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2, Compare);
}
/*
設(shè)置舵機角度
因為舵機需要20ms的波長來驅(qū)動 可知頻率為50Hz 若ARR設(shè)置為 20000-1 則PSC設(shè)置為72-1
又0.5ms~2.5ms對應(yīng)舵機角度的0~180°
0.5ms 對應(yīng)ARR為500 2.5ms 對應(yīng)ARR為2500
對應(yīng)角度的CCR應(yīng)該設(shè)置為(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的數(shù)據(jù)
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);
// 選擇規(guī)則通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_55Cycles5);
// 配置ADC轉(zhuǎn)換器
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 單次轉(zhuǎn)換或者連續(xù)轉(zhuǎn)換
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 數(shù)據(jù)對齊模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // ADC模式, 單獨還是交叉
ADC_InitStructure.ADC_NbrOfChannel = 1; // 掃描的通道數(shù)
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 掃描模式或者非掃描模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 觸發(fā)控制
ADC_Init(ADC1, &ADC_InitStructure);
// 開啟DMA轉(zhuǎn)運
ADC_DMACmd(ADC1, ENABLE);
// 開啟模擬看門狗
ADC_AnalogWatchdogThresholdsConfig(ADC1, 0xFFF, 0x5DC); // 設(shè)置看門狗閾值
ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_7); // 對通道7設(shè)置看門狗
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校準(zhǔn)
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1) == SET); // 已初始化為零
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/*
* ADC中斷函數(shù)
*/
void ADC1_2_IRQHandler(void)
{
if(ADC_GetITStatus(ADC1, ADC_IT_AWD)==SET)
{
// 開啟警報燈
LED_On();
// 清除中斷標(biāo)志
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的數(shù)據(jù)寄存器
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; // 轉(zhuǎn)運方向
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 自動重裝
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 硬件觸發(fā)
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// 開啟DMA
DMA_Cmd(DMA1_Channel1, ENABLE); // 通道1
}
將移植后的代碼下載進單片機中,連接好硬件電路后,即可進入下一步
接線示范 (僅供參考,根據(jù)自己的實際需求接)
說明:
- A2、A3為USART的端口,分別接WIFI模塊的TX、RX
- WIFI模塊出了TX、RX和GND,其余引腳工作時接高電平(手冊解釋有些引腳浮空也行,但我這塊實測都得接高電平)
- B10、B12、B14為選擇WIFI模塊工作模式的三個按鍵分別對應(yīng)(RESET、SoftAP、AirLink)
- A7為光敏傳感器模擬信號輸入口
- A0為控制舵機PWM信號輸出口
- A1接按鍵,控制角度加30°
- 這里USART1的A9、A10未接線,可接USB轉(zhuǎn)TTL模塊將調(diào)試信息打印到電腦的串口助手
5. 設(shè)備連網(wǎng)
-
準(zhǔn)備工作
需要: 機智云APP,兩臺移動設(shè)備(手機,一臺用來開熱點,熱點頻率為2.4G)
-
機智云APP下載
- 用另外一臺設(shè)備開啟熱點 (注意頻段為2.4G)
- 進入機智云連接設(shè)備,然后…
輸入熱點密碼,下一步
選擇樂鑫 (選擇模塊對應(yīng)的模組) 繼續(xù)點直到進入,這時候先別點,先按下B10的按鍵(SoftAP模式的按鍵)讓模組進入SoftAP工作模式,然后點幾藍(lán)色字體
點擊XPG-GAgent-7067(漏了一步,在點擊XPG前,手機要先連上熱點)
若找不到: XPG開頭的,則可將MCU與WIFI模組通信的串口的發(fā)送口,通過USB轉(zhuǎn)TTL接到電腦上,用串口助手查看發(fā)送的信息是否正確(與實操02中的協(xié)議一致),若不一致則需進一步進行檢查
還有一種情況,需接受調(diào)試串口的信息,看程序是否運行正常,見參考資料【STM32移植機智云】超詳細(xì)教程#2ESP8266移植機智云教程‘代碼移植的最后
這是大佬文章的最后:
回到機智云調(diào)試APP,等待設(shè)備連接
若連接失敗: 則檢查熱點質(zhì)量,檢查輸入的熱點密碼是否正確
可以看到設(shè)備在線,點進去后
可以通過手機控制舵機的角度
參考資料
本小節(jié)參考以下資料
參考文檔:
獨立MCU方案接入機智云 - Gizwits
GAgent詳解 - Gizwits
安信可ESP8266系列接入機智云方案及問題排查指引 - Gizwits
參考視頻:
【機智云帶你一節(jié)課入門物聯(lián)網(wǎng)APP開發(fā)】
【機智云移植到stm32F103C8T6基于標(biāo)準(zhǔn)庫】
參考博客:
【STM32移植機智云】超詳細(xì)教程#2ESP8266移植機智云教程‘代碼移植
實操06: APP生成
-
創(chuàng)建 → \rightarrow →移動應(yīng)用 → \rightarrow →應(yīng)用名稱、應(yīng)用包名隨便填(應(yīng)用包名最好英文) → \rightarrow →關(guān)聯(lián)應(yīng)用,不關(guān)聯(lián)
在這里插入圖片描述 -
關(guān)聯(lián)應(yīng)用 → \rightarrow →選擇產(chǎn)品 (圖標(biāo)壁紙可以根據(jù)喜好,自己上傳資源)
- 構(gòu)建應(yīng)用 → \rightarrow →應(yīng)用構(gòu)建 → \rightarrow →構(gòu)建測試版
- 構(gòu)建成功后可以用手機下載
-
添加設(shè)備 (過程與在調(diào)試APP添加設(shè)備類似)
-
展示一下文章來源:http://www.zghlxwxcb.cn/news/detail-751437.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-751437.html
到了這里,關(guān)于機智云案例(ESP8266模塊接入機智云平臺實現(xiàn)APP控制舵機旋轉(zhuǎn))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!