CH582M MESH 低功耗按鈕睡眠問(wèn)題

我使用模板?adv_vendor_self_provision_with_peripheral 創(chuàng)建了工程,用來(lái)實(shí)現(xiàn)相關(guān)功能。目前LED燈燈設(shè)備正常,但是想要開發(fā)一個(gè)用電池供電的按鈕可以實(shí)現(xiàn)燈具控制時(shí),在令CH582M睡眠這里出現(xiàn)了問(wèn)題。


我的想法是使用 vendor_message_srv_send_trans 把數(shù)據(jù)發(fā)出后等待若干時(shí)間,待數(shù)據(jù)妥善發(fā)出后再令CH582M進(jìn)入睡眠狀態(tài),目前使用過(guò)Timer0定時(shí)、SysTick定時(shí)、RTC定時(shí)、32KCycle定時(shí)執(zhí)行此過(guò)程,但是只要寫上睡眠的代碼,實(shí)際執(zhí)行時(shí)不會(huì)等待,而是立即進(jìn)入了睡眠,導(dǎo)致TMOS無(wú)法送達(dá)數(shù)據(jù)。下面是app_main.c的代碼,app.c和peripheral.c中只是在接收部分執(zhí)行了相應(yīng)邏輯。


millis的宏定義為 #define millis() __millis

__millis為一個(gè)uint32_t全局變量


論壇的樓層更新功能有BUG,會(huì)導(dǎo)致空白字符顯示成 ? 可能是字符集問(wèn)題,代碼已在下面的樓層中重新發(fā)出


因?yàn)槭菧y(cè)試代碼,所以按鍵使用了主循環(huán)輪詢檢測(cè),沒(méi)有使用中斷

因?yàn)槭菧y(cè)試代碼,所以按鍵沒(méi)有使用中斷,是在主循環(huán)中使用輪詢實(shí)現(xiàn)的



/**********************************?(C)?COPYRIGHT?*******************************
?*?File?Name??????????:?main.c
?*?Author?????????????:?WCH
?*?Version????????????:?V1.1
?*?Date???????????????:?2022/01/18
?*?Description????????:
?*********************************************************************************
?*?Copyright?(c)?2021?Nanjing?Qinheng?Microelectronics?Co.,?Ltd.
?*?Attention:?This?software?(modified?or?not)?and?binary?are?used?for?
?*?microcontroller?manufactured?by?Nanjing?Qinheng?Microelectronics.
?*******************************************************************************/

/******************************************************************************/
/*?頭文件包含?*/

#include?"CONFIG.h"
#include?"MESH_LIB.h"
#include?"HAL.h"
#include?"app_mesh_config.h"
#include?"app.h"
#include?"app_vendor_model_srv.h"
#include?"var.h"
#include?"sha256.h"

#define?ThisFirmwareIsForRemote

#ifdef??ThisFirmwareIsForRemote

volatile?uint32_t?pressedTime?=?0;
volatile?uint8_t?sent?=?0;
volatile?uint32_t?count?=?0;

#endif

void?Timer0_timerInit(uint32_t?time_data);

#include?"CH58x_common.h"
/*********************************************************************
?*?GLOBAL?TYPEDEFS
?*/
__attribute__((aligned(4)))????????????uint32_t?MEM_BUF[BLE_MEMHEAP_SIZE?/?4];
#if(defined(BLE_MAC))?&&?(BLE_MAC?==?TRUE)
const?uint8_t?MacAddr[6]?=?{0x84,?0xC2,?0xE4,?0x03,?0x02,?0x02};
#endif

uint8_t?pendingProcess?=?1;

/*********************************************************************
?*?@fn??????Main_Circulation
?*
?*?@brief???主循環(huán)
?*
?*?@return??none
?*/
__HIGH_CODE
__attribute__((noinline))
void?Main_Circulation()?{
????while(6)
????{
????????TMOS_SystemProcess();

#ifdef??ThisFirmwareIsForRemote

????????if(sent)?{
????????????if(millis()?>?10)?{
????????????????//LowPower_Sleep(0);?//?此代碼取消注釋則會(huì)忽略設(shè)定的Timeout立即執(zhí)行睡眠
????????????}
????????}

????????if(GPIOB_ReadPortPin(GPIO_Pin_22)?==?0)?{
????????????if(!pressedTime)?{
????????????????pressedTime?=?millis();
????????????}
????????}?else?{
????????????if(pressedTime)?{
????????????????uint32_t?gap?=?millis()?-?pressedTime;
????????????????pressedTime?=?0;
????????????????if(gap?>?50?&&?gap?<?500)?{
????????????????????//printf("pressed\n");
????????????????????//pressed

????????????????????//重置數(shù)據(jù)發(fā)送
????????????????????vendor_message_srv_trans_reset();
????????????????????uint8_t?status;

????????????????????//定義數(shù)據(jù)發(fā)送參數(shù)
????????????????????struct?send_param?param?=?{.addr?=?BLE_MESH_ADDR_ALL_NODES,?//?此消息發(fā)往的目的地地址,例程為發(fā)往訂閱地址,包括自己
????????????????????????.trans_cnt?=?0x01,//?此消息的用戶層發(fā)送次數(shù)
????????????????????????.period?=?K_MSEC(500),//?此消息重傳的間隔,建議不小于(200+50*TTL)ms,若數(shù)據(jù)較大則建議加長(zhǎng)
????????????????????????.rand?=?(100),//?此消息發(fā)送的隨機(jī)延遲
????????????????????????.tid?=?vendor_srv_tid_get(),//?tid,每個(gè)獨(dú)立消息遞增循環(huán),srv使用128~191
????????????????????????.send_ttl?=?BLE_MESH_TTL_DEFAULT,//?ttl,無(wú)特定則使用默認(rèn)值
????????????????????};

????????????????????//用于存儲(chǔ)發(fā)送的數(shù)據(jù)
????????????????????//8字節(jié)數(shù)據(jù)?+?32字節(jié)sha256?+?2字節(jié)opIndex
????????????????????uint8_t?bufSend[MESSAGE_LENGTH?+?32?+?2]?=?{0};

????????????????????//需要發(fā)送的數(shù)據(jù),?目前只使用了8字節(jié)中的4個(gè)字節(jié)
????????????????????char?cmd[4]?=?{'l',?'u',?'a',?'x'};

????????????????????//發(fā)送的數(shù)據(jù)拷貝到緩沖區(qū)
????????????????????memcpy(bufSend,?cmd,?4);

????????????????????//opIndex拷貝到數(shù)據(jù)緩沖區(qū)
????????????????????memcpy(bufSend?+?MESSAGE_LENGTH?+?32,?&opIndex,?2);
????????????????????++opIndex;

????????????????????//取數(shù)字摘要
????????????????????uint8_t?hash[32]?=?{0};
????????????????????sha256(bufSend,?MESSAGE_LENGTH?+?34,?hash);

????????????????????//printf("SHA256?OK\n?HEX:?\n");
????????????????????//for?(int?i?=?0;?i?<?32;?++i)?{
????????????????????//????printf("%02x?",?hash[i]);
????????????????????//}
????????????????????//printf("\n");

????????????????????//拷貝數(shù)字摘要到本地暫存區(qū)
????????????????????memcpy(hashes[hashesIndex],?hash,?32);
????????????????????++hashesIndex;
????????????????????if?(hashesIndex?>=?99)?{
????????????????????????hashesIndex?=?0;
????????????????????}

????????????????????//拷貝數(shù)字摘要到發(fā)送數(shù)據(jù)緩沖區(qū)
????????????????????memcpy(bufSend?+?MESSAGE_LENGTH,?hash,?32);

????????????????????//vendor_message_srv_trans_reset();
????????????????????//或者調(diào)用自定義模型服務(wù)的透?jìng)骱瘮?shù)發(fā)送數(shù)據(jù),只發(fā)送,無(wú)應(yīng)答機(jī)制
????????????????????vendor_message_srv_send_trans(&param,?bufSend,
????????????????????????????MESSAGE_LENGTH?+?34);

????????????????????printf("message?re?send?to?others\n");

????????????????????//關(guān)閉Timer0中斷
????????????????????TMR0_ITCfg(DISABLE,?TMR0_3_IT_CYC_END);
????????????????????PFIC_DisableIRQ(TMR0_IRQn);

????????????????????R8_TMR0_CTRL_MOD?=?RB_TMR_ALL_CLEAR;
????????????????????R8_TMR0_CTRL_MOD?&=?0b11111011;;

????????????????????//重置計(jì)數(shù)
????????????????????__millis?=?0;

????????????????????//設(shè)定標(biāo)志
????????????????????sent?=?1;

????????????????????//重新啟動(dòng)Timer0,?以1000ms為單位,?此函數(shù)為自定義的函數(shù),?進(jìn)行了時(shí)間轉(zhuǎn)換
????????????????????Timer0_timerInit(1000);

????????????????}
????????????}
????????}
#endif
????}
}

/*********************************************************************
?*?@fn??????bt_mesh_lib_init
?*
?*?@brief???mesh?庫(kù)初始化
?*
?*?@return??state
?*/
uint8_t?bt_mesh_lib_init(void)?{
????uint8_t?ret;

????if?(tmos_memcmp(VER_MESH_LIB,?VER_MESH_FILE,?strlen(VER_MESH_FILE))?==?FALSE)?{
????????PRINT("mesh?head?file?error...\n");
????????while(1);
????}

????ret?=?RF_RoleInit();

#if((CONFIG_BLE_MESH_PROXY)?||???\
????(CONFIG_BLE_MESH_PB_GATT)?||?\
????(CONFIG_BLE_MESH_OTA))
????ret?=?GAPRole_PeripheralInit();
#endif?/*?PROXY?||?PB-GATT?||?OTA?*/

#if(CONFIG_BLE_MESH_PROXY_CLI)
????ret?=?GAPRole_CentralInit();
#endif?/*?CONFIG_BLE_MESH_PROXY_CLI?*/

????MeshTimer_Init();
????MeshDeamon_Init();
????ble_sm_alg_ecc_init();

#if(CONFIG_BLE_MESH_IV_UPDATE_TEST)
????bt_mesh_iv_update_test(TRUE);
#endif
????return?ret;
}

void?Timer0_timerInit(uint32_t?time_data)?{
????//定時(shí)器0
????TMR0_TimerInit(FREQ_SYS?/?(1000?/?time_data));?//?time_data為設(shè)置定時(shí)時(shí)間值,設(shè)置多少時(shí)間就等于多少時(shí)間(單位ms)

????TMR0_ITCfg(ENABLE,?TMR0_3_IT_CYC_END);?//?開啟中斷
????PFIC_EnableIRQ(TMR0_IRQn);???//使能TMR0的中斷,并指定中斷號(hào)為?TMR0_IRQn

}

__INTERRUPT
__HIGH_CODE
void?TMR0_IRQHandler(void)?//?TMR0?定時(shí)中斷
{
????if?(TMR0_GetITFlag(TMR0_3_IT_CYC_END))?{
????????TMR0_ClearITFlag(TMR0_3_IT_CYC_END);?//?清除中斷標(biāo)志
????????++__millis;
????}
}

/*********************************************************************
?*?@fn??????main
?*
?*?@brief???主函數(shù)
?*
?*?@return??none
?*/
int?main(void)?{
????SetSysClock(CLK_SOURCE_PLL_60MHz);

????//??自動(dòng)重新加載計(jì)數(shù)值,計(jì)數(shù)時(shí)鐘60M的話,以1ms為例,參數(shù)是60000
????//SysTick_Config(?GetSysClock()?/?1000?*?SYSTICK_INTERVAL);??//設(shè)定嘀嗒時(shí)間1000ms

????PRINT("%s\n",?VER_LIB);
????PRINT("%s\n",?VER_MESH_LIB);

????CH58X_BLEInit();
????HAL_Init();
????bt_mesh_lib_init();
????App_Init();

????GPIOB_ModeCfg(GPIO_Pin_0,?GPIO_ModeOut_PP_20mA);
????GPIOB_ModeCfg(GPIO_Pin_4,?GPIO_ModeOut_PP_5mA);

????for?(int?i?=?0;?i?<?16;?++i)?{
????????GPIOB_InverseBits(GPIO_Pin_0);
????????GPIOB_InverseBits(GPIO_Pin_4);
????????DelayMs(100);
????}

????printf("\nPrepare?loading?user?config\n");
????EEPROM_READ(USER_DATA_ADDR,?&userData,?sizeof(userData));
????printf("User?config?loaded\n");
????printf("my?role?is:?%c\n",?userData.role);

????__millis?=?0;
????Timer0_timerInit(1);

#ifdef??ThisFirmwareIsForRemote
????userData.remote.isRemote?=?1;
????userData.remote.targetRole[0]?=?'a';
????userData.remote.repeatTimes?=?1;

????GPIOB_ModeCfg(GPIO_Pin_22,?GPIO_ModeIN_PU);
#endif

????Main_Circulation();
}

/********************************?endfile?@?main?******************************/



您好,一般是建議跑mesh的低功耗節(jié)點(diǎn)+長(zhǎng)供電的朋友節(jié)點(diǎn)方案,可以按下方博客修改。

藍(lán)牙m(xù)esh組網(wǎng)實(shí)踐(手機(jī)配網(wǎng)例程改低功耗) - JayWell - 博客園 (cnblogs.com)

如果想用按鍵控制喚醒,可以參考下方博客:

在TMOS系統(tǒng)中手動(dòng)管理休眠 - JayWell - 博客園 (cnblogs.com)

按鍵喚醒,是一定要用到中斷的;手動(dòng)管理休眠時(shí),針對(duì)mesh組網(wǎng),還要求至少每隔24h,啟用一次維持10s的接受掃描,來(lái)保持IV值同步。


謝謝回復(fù),我使用low power sleep 方法嘗試手動(dòng)管理電源狀態(tài),代碼如下

Screenshot 2023-12-08 144530.png實(shí)際使用時(shí)發(fā)現(xiàn)GPIO中斷喚醒后,打印了wake up from sleep,主循環(huán)也進(jìn)入了一次,顯示是發(fā)送了數(shù)據(jù)(實(shí)際沒(méi)有發(fā)送成功,可能是因?yàn)閯倖拘堰€未加入mesh網(wǎng)絡(luò)),之后GPIO中斷可以正常執(zhí)行,但是主循環(huán)似乎退出了,我嘗試在這行printf后手動(dòng)運(yùn)行主循環(huán),但是消息也無(wú)法成功發(fā)送,似乎未能加入mesh網(wǎng)絡(luò),嘗試了在喚醒后運(yùn)行main函數(shù)中的所有初始化代碼均無(wú)法使用,而且會(huì)報(bào)錯(cuò)-7 unable to send message,似乎是協(xié)議棧底層未能正確發(fā)送數(shù)據(jù),導(dǎo)致上層消息隊(duì)列已滿,請(qǐng)問(wèn)這個(gè)該如何解決呢?非常感謝


您好,喚醒之后發(fā)包,需要先校準(zhǔn)RF。

在TMOS系統(tǒng)中手動(dòng)管理休眠 - JayWell - 博客園 (cnblogs.com)

報(bào)錯(cuò)-7,一般是由于發(fā)包頻次高??梢哉{(diào)大app_mesh_config.h中的CONFIG_MESH_ADV_BUF_COUNT_DEF,或者減小send接口函數(shù)的發(fā)送參數(shù)param中的發(fā)送次數(shù)trans_cnt,或者等待底層發(fā)送完成后再發(fā)下一則消息,都可以減小發(fā)包壓力。

可以在一段時(shí)間內(nèi)停止發(fā)包,查看是否會(huì)出現(xiàn)報(bào)錯(cuò)-7。理論上發(fā)包緩存發(fā)送完畢就會(huì)恢復(fù)發(fā)包。如果一直報(bào)錯(cuò)-7,可以聯(lián)系我司技術(shù)支持025-8969-2370

藍(lán)牙m(xù)esh組網(wǎng)實(shí)踐(常見(jiàn)調(diào)試問(wèn)題整理) - JayWell - 博客園 (cnblogs.com)


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频