Skip to content

WIFI 蓝牙模块 AI-WB2-12f

曾经这个模块以超低的价格遥遥领先于同行,也在之前购买过此模块
但是相比较于ESP32 或者是ESP8266 这几个模块,安信可的指令则是有些许的差异,
而网上相关的教程又比价少,那么这个时候就需要我来写一个教程。来展示之前调试带来的一些经验。

1.1 需要购买的模块

alt text 2024年5月2日 现在看的价格在5.8元,作为一个有蓝牙和WiFi两个功能的模块,我感觉性价比还是可以尝试的。

2. 相关的AT指令

首先给出官方的AI指令文档连接
官方文档--基础指令

wifi AT指令集

3. 操作链接WiFi

查询模式

C
AT+WMODE?

扫描WiFi

C
AT+WSCAN

链接WiFi

super_2G:是WiFi的名称
123456798 是WiFi的密码

C
AT+WJAP=super_2G,123456798

成功的话会显示相关的网络信息 alt text

查询 一般成功查询的话就是可以正常访问了

C
AT+WJAP?

断开连接

C
AT+WDISCONNECT

获取b站粉丝数据 这个只显示粉丝,显示的内容比较少
API 1 :https://api.bilibili.com/x/relation/stat?vmid=2044983862

C
AT+HTTTPCLIENTLINE=2,2,"text/html","api.bilibili.com",443,"/x/relation/stat?vmid=2044983862"

这个API显示的内容比较多
API 2: https://api.bilibili.com/x/web-interface/card?mid=2044983862

C
AT+HTTTPCLIENTLINE=2,2,"text/html","api.bilibili.com",443,"/x/web-interface/card?mid=2044983862"

这边需要注意,区分HTTP和HTTPS的差异,否则就无法正确的读取到信息 笔者在这一块花费了很多的时间,网上还只有野火的模块去获取的,以为此模块是否无这个功能,后来发现还是http相关的信息没有配置正确

4. 使用cubmx 配置代码

以上已经描述了如何使用指令来实现控制wifi模块。那么下面开始配置代码 需要配置的模块如下

  1. USB --串口模式
  2. 串口---和模块通信
  3. debug口
  4. 时钟口
  5. 配置GPIO使能wifi模块

下面是配置好的界面 alt text

因为使用了USB口作为一个串口的功能来使用,所以配置成了com口的模式 alt text

5. 编写代码

首先添加代码中使用到的头文件

C
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include  <string.h>
#include "usbd_cdc_if.h"
/* USER CODE END Includes */

USB 卸载操作,取消按复位键后无法识别的问题

C
void USB_Disconnected(void) 
{
    __HAL_RCC_USB_FORCE_RESET();
    HAL_Delay(200);
    __HAL_RCC_USB_RELEASE_RESET();
 
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOA_CLK_ENABLE();
 
    GPIO_Initure.Pin = GPIO_PIN_11 | GPIO_PIN_12;
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Initure.Pull = GPIO_PULLDOWN;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_Initure);
 
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_Delay(300);
}

先在mian函数定义一些变量

C

unsigned char A12_one_buf;
const int A12Buf_size = 500;//buff 缓冲区 缓存USART 接收到的数据。
int A12Buf_Number = 0;//
uint8_t A12Buf[A12Buf_size] = {0};
uint8_t AT[] = "AT\r\n";
uint8_t ATWJAP[] = "AT+WJAP=yghcyoul,102172you@\r\n";
uint8_t HTTTPCLIENTLINE[] = "AT+HTTTPCLIENTLINE=2,2,\"text/html\",\"api.bilibili.com\",443,\"/x/relation/stat?vmid=2044983862\"\r\n";

下面开始main函数的内容

C

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
 //USB 卸载操作,取消按复位键后无法识别的问题
  USB_Disconnected();
  HAL_Delay(100);
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */

  //开启中断
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&A12_one_buf, 1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);                                                                                 
  HAL_Delay(5000);
  while (1)
  {
        
        HAL_Delay(1000);
        HAL_UART_Transmit(&huart1, AT, sizeof(AT)-1,0xFFFF);
        HAL_Delay(3000);
        //接收到结束标志,跳出接收循环
        if(strstr((char *)A12Buf, "OK"))//6,7
        {
            CDC_Transmit_FS((uint8_t *)A12Buf,sizeof(A12Buf)); //USB 串口发送数据
            A12Buf_Number = 0;//清除位置
            memset(A12Buf, 0, sizeof(A12Buf));    //清空数组
        }

        
        HAL_UART_Transmit(&huart1, ATWJAP, sizeof(ATWJAP)-1,0xFF);
        HAL_Delay(10000);
        if(strstr((char *)A12Buf, "WIFI_GOT_IP"))
        {
                CDC_Transmit_FS((uint8_t *)A12Buf,sizeof(A12Buf)); //USB 串口发送数据
                A12Buf_Number = 0;//清除位置
                memset(A12Buf, 0, sizeof(A12Buf));    //清空数组
        }
    
        
        HAL_UART_Transmit(&huart1, HTTTPCLIENTLINE, sizeof(HTTTPCLIENTLINE)-1,0xFF);
        HAL_Delay(10000);
        if(strstr((char *)A12Buf, "}}"))
        {
                CDC_Transmit_FS((uint8_t *)A12Buf,sizeof(A12Buf)); //USB 串口发送数据
                A12Buf_Number = 0;//清除位置
                memset(A12Buf, 0, sizeof(A12Buf));    //清空数组
        }
        while(1);
        
  }
}

在main函数的底部添加串口中断的回调函数

C
/* USER CODE BEGIN 4 */
/**
  * @brief 串口收发中断回调函数
  * @param
  * @retval
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

    if(A12Buf_Number > A12Buf_size) //超范围,就清零
    {
        A12Buf_Number = 0;//位置归零
        memset(A12Buf, 0, sizeof(A12Buf));    //清空数组
        //给溢出标志位
    }
    else
    {
        if(A12_one_buf != 0x00)//strstr 函数遇到00 会停止,规避此问题
        {
            //存入buffer
            A12Buf[A12Buf_Number] = A12_one_buf;
            A12Buf_Number++;
            
        }
    }
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&A12_one_buf, 1);   //再开启接收中断
}
/* USER CODE END 4 */

修改“ usbd_cdc_if.c”文件中的 CDC_Transmit_FS 函数 作者尝试下来,如果不加,USB会只发送一部分数据,无法将全部数据都发送出来

C

/**
  * @brief  CDC_Transmit_FS
  *         Data to send over USB IN endpoint are sent over CDC interface
  *         through this function.
  *         @note
  *
  *
  * @param  Buf: Buffer of data to be sent
  * @param  Len: Number of data to be sent (in bytes)
  * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
  */
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
	uint32_t Timeout = HAL_GetTick();
  /* USER CODE BEGIN 7 */
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  if (hcdc->TxState != 0){
    return USBD_BUSY;
  }
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
  /* USER CODE END 7 */
	while(hcdc->TxState)
	{
		if(HAL_GetTick() - Timeout >=10)//超时
		{
			break;
		}
	}
  return result;
}