以下作品由安信可社區用戶
WT_0213制作
關于 FPM383C 指紋模塊 在之前的帖子介紹的已經比較詳細了可以看下這個帖子。
【外設移植】FPM383C 指紋模塊 +Ai-M61-32S
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=43963&fromuid=15918
這里主要說一下移植 FPM383C 指紋到 Ai-WB2 模塊時遇到的一些問題和移植完成示例。
首先是環境搭建
【Ai-WB2 入門篇】搭建 windows+eclipse 環境
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=45149&fromuid=15918
跟著園長的教程完成環境搭建基本不會出現什么意外情況,都可以正常跑起來。
這里有個小坑需要注意:
盡量使用克隆命令克隆項目,不要直接下載 zip
git clone --recursive
https://gitee.com/Ai-Thinker-Open/Ai-Thinker-WB2
如果對配置文件不熟悉的話盡量按照現有的一些目錄接口創建自己的項目這樣可以盡可能少的去修改配置文件。
如果在其他目錄下創建項目,需要注意的是 BL60X_SDK_PATH 這個值要能找到 sdkpath。
編譯過程有一些警告,如果不是自己代碼中的可以忽略。
如果編譯通過的話最終會生成 bin 文件。
Ai-WB2 燒錄軟件
https://docs.ai-thinker.com/_media/bl602_flash_download_tool.zip
燒錄過程參考
【Ai-WB2 入門篇】新建工程和燒錄指導
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=45156&fromuid=15918
這里有小坑需要注意一下:
1、如果出現 COM 口拒絕訪問,檢查下時候開啟的串口調試工具。
2、如果提示 BFLB IMG LOAD SHAKEHAND FAIL 應該是沒有進入燒錄模式,點擊 Create & Download 然后按住開發板右側的按鈕,再點按左側 EN 按鈕松手就可以了。
這里有大坑需要注意一下:
燒錄編譯的 bin 的時候需要使用這種燒錄方式進項燒錄,否則燒錄后程序不能正常運行。
序號 1、3、4 選擇的都是燒錄工具目錄下的文件
序號 2 選擇編譯的 bin 即可
燒錄完成后,開啟串口調試工具
波特率設置為 115200
這里日志通過 printf 方法打印出來的,不知道為啥 blog_info 不生效沒有深入去看
然后是代碼部分
#include
#include
#include
#include
#include "fpm383c.h"
#include
int is_register = 1;
int main(void) {
printf("rn");
// 初始化FPM383C指紋模塊
fpm383c_init();
printf("clear rn");
// 清空指紋庫
fpm383c_empty(2000);
printf("random idrn");
// 指紋id
int fpm383cPageId = 10;
while (1) {
if (is_register) {
// 開啟注冊指紋,指紋ID:0—59, 超時時間盡量在 10秒左右,需要錄入四次
fpm383c_enroll(fpm383cPageId, 10000);
// 休息600毫秒進行下次注冊
vTaskDelay(pdMS_TO_TICKS(600));
// 模塊休眠一下
fpm383c_sleep();
is_register = 0;
printf("register OKrn");
} else {
// printf("identifyrn");
// 開啟自動識別
fpm383c_identify();
}
vTaskDelay(pdMS_TO_TICKS(10));
}
return 0;
}
這里值得注意的是 int main(void)函數是有返回值的,返回值類型為 int
這個函數會在會執行在 FreeRTOS 任務中可以看下這篇分析的帖子
wb2 項目啟動流程分析
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=45352&fromuid=15918
fpm383c.h
#ifndef __FPM383C_H
#define __FPM383C_H
#include "stdint.h"
void fpm383c_init(void);
void fpm383c_senddata(int length, uint8_t buffer[]);
void fpm383c_sleep(void);
uint8_t fpm383c_getimage(uint32_t timeout);
uint8_t fpm383c_genchar(uint32_t timeout);
uint8_t fpm383c_search(uint32_t timeout);
uint8_t fpm383c_empty(uint32_t timeout);
uint8_t fpm383c_delete(uint16_t pageID,uint32_t timeout);
uint8_t fpm383c_controlled(uint8_t PS_ControlLEDBuf[],uint32_t timeout);
void fpm383c_identify(void);
void fpm383c_enroll(uint16_t pageID,uint16_t timeout);
#endif
fpm383c.c
#include "stdlib.h"
#include "string.h"
#include "bl_sys.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "fpm383c.h"
#define GPIO_LED_PIN 14
/**
* 控制模塊LED燈顏色
*/
uint8_t ps_blueledbuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x03,0x01,0x01,0x00,0x00,0x49};
uint8_t ps_redledbuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x02,0x04,0x04,0x02,0x00,0x50};
uint8_t ps_greenledbuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x3C,0x02,0x02,0x02,0x02,0x00,0x4C};
/**
* 休眠指令-設置傳感器進入休眠模式
*/
uint8_t ps_sleepbuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x33,0x00,0x37};
/**
* 清空指紋庫-刪除 flash 數據庫中所有指紋模板。
*/
uint8_t ps_emptybuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x0D,0x00,0x11};
/**
* 取消指令-取消自動注冊模板和自動驗證指紋。如表 2-1 中加密等級設置為 0 或 1 情況下支持此功能
*/
uint8_t ps_cancelbuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x30,0x00,0x34};
/**
* 自動注冊模板-一站式注冊指紋,包含采集指紋、生成特征、組合模板、存儲模板等功能。加密等級設置為 0 或 1 情況下支持此功能。
*/
uint8_t ps_autoenrollbuf[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x31,'','',0x04,0x00,0x16,'',''};
/**
* 驗證用獲取圖像-驗證指紋時,探測手指,探測到后錄入指紋圖像存于圖像緩沖區。返回確認碼表示:錄入成功、無手指等。
*/
uint8_t ps_getimagebuf[12] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x03,0x01,0x00,0x05};
/**
* 生成特征值-將圖像緩沖區中的原始圖像生成指紋特征文件存于模板緩沖區
*/
uint8_t ps_getcharbuf[13] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x04,0x02,0x01,0x00,0x08};
/**
* 搜索指紋-以模板緩沖區中的特征文件搜索整個或部分指紋庫。若搜索到,則返回頁碼。加密等級設置為 0 或 1 情況下支持
*/
uint8_t ps_searchbuf[17] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x04,0x01,0x00,0x00,0xFF,0xFF,0x02,0x0C};
/**
* 刪除模板-刪除 flash 數據庫中指定 ID 號開始的N 個指紋模板
*/
uint8_t ps_deletebuf[16] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x0C,'','',0x00,0x01,'',''};
/**
* 設置名為fpm383c_uart的外設句柄,用來執行串口指令的發送
*/
hosal_uart_dev_t fpm383c_uart = {
.config = {
.uart_id = 1,
.tx_pin = 4, // TXD GPIO
.rx_pin = 3, // RXD GPIO
.baud_rate = 57600,
.data_width = HOSAL_DATA_WIDTH_8BIT,
.parity = HOSAL_NO_PARITY,
.stop_bits = HOSAL_STOP_BITS_1,
.mode = HOSAL_UART_MODE_POLL,
},
};
/**
* 指紋ID和驗證指紋的分數
*/
uint16_t pageID,score;
/**
* USART串口接收緩沖數組
*/
uint8_t uart_receivebuf[20];
/**
* 主循環狀態標志位
*/
uint8_t scanstatus = 0;
/**
* @brief 獲取狀態
*
* @param timeout
*/
void fpm383c_receivedata(uint16_t timeout, uint8_t lenght)
{
// 輪詢fpm383c_uart接收到的字符
int ret;
uint8_t uart_receive_len = 0;
uint8_t receivebuf_cache[20];
memset(uart_receivebuf, 0xFF, sizeof(uart_receivebuf));
while(true){
ret = hosal_uart_receive(&fpm383c_uart, receivebuf_cache, sizeof(receivebuf_cache));
if (ret > 0) {
memcpy(uart_receivebuf + uart_receive_len, receivebuf_cache, ret);
uart_receive_len += ret;
/* Uart send poll */
if(uart_receive_len >= lenght){
uart_receive_len=0;
break;
}
}
vTaskDelay(1);
}
}
/**
* 初始化FPM383C指紋模塊
*/
void fpm383c_init(){
/* Uart init device */
hosal_uart_init(&fpm383c_uart);
printf("fpm383c_initrn");
}
/**
* USART串口發送數據
* @param length 發送數組長度
* @param fpm383c_databuf 需要發送的功能數組
*/
void fpm383c_senddata(int length, uint8_t fpm383c_databuf[])
{
hosal_uart_send(&fpm383c_uart, fpm383c_databuf, length);
}
/**
* 發送休眠指令 確認碼=00H 表示休眠設置成功。確認碼=01H 表示休眠設置失敗。
*/
void fpm383c_sleep(void)
{
fpm383c_senddata(12, ps_sleepbuf);
}
/**
* 驗證用獲取圖像
* @param timeout接收數據的超時時間
* @return 確認碼
*/
uint8_t fpm383c_getimage(uint32_t timeout)
{
uint8_t tmp;
fpm383c_senddata(12,ps_getimagebuf);
fpm383c_receivedata(timeout, 12);
tmp = (uart_receivebuf[6] == 0x07 ? uart_receivebuf[9] : 0xFF);
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return tmp;
}
/**
* 將圖像緩沖區中的原始圖像生成指紋特征文件存于模板緩沖區
* @param timeout 接收數據的超時時間
* @return 確認碼
*/
uint8_t fpm383c_genchar(uint32_t timeout)
{
uint8_t tmp;
fpm383c_senddata(13,ps_getcharbuf);
fpm383c_receivedata(timeout, 12);
tmp = (uart_receivebuf[6] == 0x07 ? uart_receivebuf[9] : 0xFF);
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return tmp;
}
/**
* 發送搜索指紋指令
* @param timeout 接收數據的超時時間
* @return 確認碼
*/
uint8_t fpm383c_search(uint32_t timeout)
{
fpm383c_senddata(17,ps_searchbuf);
fpm383c_receivedata(timeout, 16);
return (uart_receivebuf[6] == 0x07 ? uart_receivebuf[9] : 0xFF);
}
/**
* 刪除指定指紋指令
* @param pageID 需要刪除的指紋
* @param timeout 接收數據的超時時間
* @return 確認碼
*/
uint8_t fpm383c_delete(uint16_t pageID,uint32_t timeout)
{
uint8_t tmp;
ps_deletebuf[10] = (pageID>>8);
ps_deletebuf[11] = (pageID);
ps_deletebuf[14] = (0x15+ps_deletebuf[10]+ps_deletebuf[11])>>8;
ps_deletebuf[15] = (0x15+ps_deletebuf[10]+ps_deletebuf[11]);
fpm383c_senddata(16,ps_deletebuf);
fpm383c_receivedata(timeout, 12);
tmp = (uart_receivebuf[6] == 0x07 ? uart_receivebuf[9] : 0xFF);
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return tmp;
}
/**
* 清空指紋庫
* @param timeout 接收數據的超時時間
* @return 確認碼
*/
uint8_t fpm383c_empty(uint32_t timeout)
{
uint8_t tmp;
fpm383c_senddata(12,ps_emptybuf);
fpm383c_receivedata(timeout, 12);
tmp = (uart_receivebuf[6] == 0x07 ? uart_receivebuf[9] : 0xFF);
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return tmp;
}
/**
* 發送控制燈光指令
* @param ps_controlledbuf 不同顏色的協議數據
* @param timeout 接收數據的超時時間
* @return 確認碼
*/
uint8_t fpm383c_controlled(uint8_t ps_controlledbuf[],uint32_t timeout)
{
uint8_t tmp;
fpm383c_senddata(16,ps_controlledbuf);
fpm383c_receivedata(timeout, 12);
tmp = (uart_receivebuf[6] == 0x07 ? uart_receivebuf[9] : 0xFF);
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return tmp;
}
/**
* 驗證指紋是否注冊
*/
void fpm383c_identify(void)
{
if(fpm383c_getimage(2000) == 0x00)
{
if(fpm383c_genchar(2000) == 0x00)
{
bl_gpio_enable_output(GPIO_LED_PIN, 0, 0);
bl_gpio_output_set(GPIO_LED_PIN, 0);
if(fpm383c_search(2000) == 0x00)
{
score = (int)((uart_receivebuf[10] << 8) + uart_receivebuf[11]);
printf("success ID: %d rn",(int)score);
fpm383c_controlled(ps_greenledbuf,1000);
bl_gpio_output_set(GPIO_LED_PIN, 1);
vTaskDelay(pdMS_TO_TICKS(1000));
bl_gpio_output_set(GPIO_LED_PIN, 0);
// 重置接收數據緩存
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return;
}else{
printf("fail rn");
bl_gpio_output_set(GPIO_LED_PIN, 1);
vTaskDelay(pdMS_TO_TICKS(1000));
bl_gpio_output_set(GPIO_LED_PIN, 0);
// 重置接收數據緩存
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return;
}
}
}
}
/**
* 自動注冊
* @param pageID 輸入需要注冊的指紋ID號,取值范圍0—59
* @param timeout 設置注冊指紋超時時間,因為需要按壓四次手指,建議大于10000(即10s)
*/
void fpm383c_enroll(uint16_t pageID,uint16_t timeout)
{
blog_info("注冊指紋ID: %drn", pageID);
ps_autoenrollbuf[10] = (pageID>>8);
ps_autoenrollbuf[11] = (pageID);
ps_autoenrollbuf[15] = (0x54+ps_autoenrollbuf[10]+ps_autoenrollbuf[11])>>8;
ps_autoenrollbuf[16] = (0x54+ps_autoenrollbuf[10]+ps_autoenrollbuf[11]);
fpm383c_senddata(17,ps_autoenrollbuf);
fpm383c_receivedata(timeout, 14);
if(uart_receivebuf[9] == 0x00)
{
blog_info("指紋注冊完成rn");
// 亮綠燈2秒
fpm383c_controlled(ps_greenledbuf,2000);
// 重置接收數據緩存
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
return;
}
else if(timeout == 0)
{
// 超時取消注冊
fpm383c_senddata(12,ps_cancelbuf);
vTaskDelay(pdMS_TO_TICKS(50));
// 重置接收數據緩存
memset(uart_receivebuf,0xFF,sizeof(uart_receivebuf));
}
// 亮紅燈2秒
fpm383c_controlled(ps_redledbuf,2000);
}
以上就是主要邏輯代碼
接線方式
由于復用的 IO3 所以藍燈會亮
其他 Ai-WB2 相關知識可以看看社區整理的這篇文章
【Ai-WB2 教程合集】看這一篇就夠了??!
https://bbs.ai-thinker.com/foru
審核編輯 黃宇
-
模塊
+關注
關注
7文章
2670瀏覽量
47340 -
指紋
+關注
關注
1文章
84瀏覽量
23315 -
代碼
+關注
關注
30文章
4744瀏覽量
68344 -
安信可
+關注
關注
0文章
147瀏覽量
3957
發布評論請先 登錄
相關推薦
評論