在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>智能頸部按摩器原型開源分享

智能頸部按摩器原型開源分享

2023-06-15 | zip | 0.00 MB | 次下載 | 2積分

資料介紹

描述

概述

無論是因為睡得怪怪的、玩手機太多,還是彎腰坐著盯著電腦看幾個小時,我們大多數人都會時不時地處理脖子上的扭結。緩解頸部疼痛的最佳方法之一是按摩療法。因此,我們改造了傳統的頸部按摩器,讓它變得聰明,輕松消除壓力。

頸部放松按摩器結合了中國傳統理療中的多種按摩手法,采用低頻電脈沖技術模擬真人按摩。能促進局部血液循環,有效緩解頸部疲勞和肌肉緊張。由于我們已經使這款按摩器支持物聯網,因此我們只需一部手機即可控制它。

特征

  • 五種模式:智能、放松、主動、敲擊和刮擦。不同的模式讓您體驗不同的按摩樂趣。
  • 15級強度由弱到強:您可以自由調節適合自己的強度。
  • 三級溫度調節:高、低、關。持續的熱按摩可以放松血管和頸部肌肉。

硬件

?
pYYBAGNof1-AFuF2AACpjHWAGVE051.png
?

腳步

第 1 步:硬件設計

使用涂鴉智能智能生活應用程序實現遠程控制,我們使用涂鴉的BTU 網絡模塊作為微控制器。

電路由BTU模塊、電池充電、語音播放、按鍵檢測、低頻脈沖電流輸出、加熱、溫度檢測等部分組成。

1.微控制器

?
pYYBAGNof2SARPA4AAM9XBe8QyM624.png
?

?

poYBAGNof2eAOt-rAALzh_FfYM0081.png
?

?

2. 功能模塊

NTC熱敏電阻是環氧樹脂涂層的小尺寸,用于溫度測量。它具有電阻范圍廣、精度穩定性和靈敏度高、響應速度快等特點。對于熱敏電阻的參數,我們使用:B=3950,R=10k。

?

poYBAGNof2qANsVWAAAZsy4jOv4452.png
?

?

  • 溫度與電阻的關系

?

pYYBAGNof3CAc4iBAAUgcjr7q7k403.png
?
  • 溫度檢測電路

?

pYYBAGNof3KAIMtJAAAduF__51A240.png
?

模塊的 ADC 收集電壓并將其轉換為溫度值。然后,模塊相應地調整溫度。

  • 加熱絲

白線是發熱絲。

?

pYYBAGNof3WATHL2AAAktQlmfig990.png
?
  • 加熱回路

?

poYBAGNof3eAakL5AAApAkKkTOM072.png
?

模塊上的P7輸出PWM波來調節電熱絲的溫度。當 P7 輸出低電平時,加熱關閉。當 P7 以某個頻率輸出方波時,發熱處于低水平。當 P7 輸出高電平時,加熱處于高電平。

  • 揚聲器

?

pYYBAGNof3qALh6DAAAWN6yffdc095.png
?
?
poYBAGNof36AE5KGAABmKRMDbv8316.png
?

在單線串口模式下,BTU模塊可以通過DATA線控制和發送數據到語音芯片,進行語音播放、停止、循環等。

  • 電極墊

按摩器上有兩個不銹鋼電極墊。

?

pYYBAGNof4CAd6JSAAA5n56qYSk792.png
?

?

poYBAGNof4OAZ-rNAABqiHSZCQw393.png
?

低頻脈沖電流輸出

P24 和 P9 輸出的脈沖是對稱的。這兩個引腳不能同時輸出高電平。

  • 當P24輸出高電平,P9輸出低電平時,Q2導通,Q5截止。由于人體的阻抗,Q4、Q6、Q8 截止,Q3 處于飽和(導通狀態)。

P17 輸出高電平。它輸出兩個低頻對稱脈沖。

  • 當P24輸出低電平,P9輸出高電平時,Q2截止,Q5導通。Q4、Q6 和 Q8 處于導通狀態,Q3 處于截止狀態。

P17 輸出低電平。它輸出兩個低頻對稱脈沖。

?

P24 和 P9 輸出的脈沖是不對稱的。PB5 和 PCO 都輸出高電平。

  • 當 Q5、Q2 和 Q6 處于導通狀態時,Q4 和 Q3 處于導通狀態。這樣,三極管可能會燒壞。
  • S8050晶體管的開/關取決于二極管D4正端的電壓,該電壓由通過二極管的電流決定。因此,我們可以提供過流保護。一旦通過二極管D4的電流超過10mA,D4的壓降就會超過0.7V,三極管Q2就會導通。
  • 模塊上的P24和P9可以輸出不同頻率的脈沖信號(P24和P9輸出的脈沖是對稱的),針對各種模式產生不同的波形。

二極管D4參數

  • 電池

我們買了一塊700毫安的鋰聚合物電池,額定電壓為3.7V,充電電壓為4.2V。內置保護電路,防止過充、過放、過流、短路。

?

poYBAGNof4aAdr9-AAA0y-5FZCk806.png
?

尺寸:10 毫米(厚)x 23 毫米(寬)x 30 毫米(長)

?

poYBAGNof4iAaxZ_AAC77XtDlxg867.png
?

電池充電器電路和升壓電路

  • 電池充電器電路:XT2051是單節鋰離子電池的恒流恒壓充電器電路。該組件包括一個內部功率晶體管,不需要外部電流檢測電阻器和阻塞二極管。XT2051 需要最少的外部元件并符合 USB 總線規范。它非常適合現場的便攜式應用。
  • 升壓電路原理:當三極管MMBT5551導通時,肖特基二極管D1處于反向偏置狀態。通過電感器 L1 到晶體管 Q1 的電流完成了一個電路。施加到升壓電感器的輸入電壓被轉換成磁能進行存儲。當三極管Q1關斷時,肖特基二極管D1正向偏置,電感中的磁能轉化為電能。該電壓與輸入電壓一起為負載供電并為輸出電容器 C6 充電。需要幾個脈沖來提供足夠的能量來增加輸出電壓。

?

第 2 步:創建產品

本節介紹如何在涂鴉IoT平臺上創建智能頸椎按摩器。有關詳細信息,請參閱創建產品

1.登錄涂鴉IoT平臺。

2.在標準類別選項卡上,單擊運動與健康>運動與健康。填寫產品信息并選擇藍牙作為協議。

pYYBAGNof42AEltCAACLqE8oCg0142.png
?

3.點擊創建后,出現添加標準函數對話框。保留三個選定的所需功能。自定義函數部分中,單擊添加并創建兩個函數。有關要設置的項目,請參見下面的屏幕截圖。

poYBAGNof5CAaMS9AAEItdIVats167.png
?

4.在設備面板步驟中,選擇DIY風格面板。然后,進入硬件開發,選擇涂鴉標準模塊 SDKBT3L 藍牙模塊。單擊屏幕右側的獲取 10 個免費許可證。您將在編碼中獲得 UUID、密鑰和 MAC 地址。

第 3 步:獲取 SDK 并設置 IDE

poYBAGNof5OAA9HUAACuIaGZpsM149.png
?

安裝 IDE 后,導入您的項目。

  • 用項目開發1.編輯產品ID。
pYYBAGNof5mAAZ8YAAHRxDIhXos731.png
?

2.編輯auth_key、device_idmac。

?

poYBAGNof5yAIULDAAIkjvXXIVk068.png
?

?

poYBAGNof6CAHfFpAAIXDpWwptw205.png
?

3.編譯代碼。

?

pYYBAGNof6KARGHYAAHOnK8-eLY039.png
?

?

pYYBAGNof6iAa9TpAAF4JkXG6Qc535.png
?

1.8258選擇芯片類型和EVK下載模式。單擊文件并選擇bin要下載到開發板的文件,該文件位于tuya_ble_sdk_Demo_Project_tlsr8253\telink_kite_ble_sdk_v3.4.0_20190816\ble_sdk_multimode\8258_module\8258_module.bin.

2.下載后點擊Reset運行。

3.我們使用泰凌的作家。將板上的 SWM 接頭連接到寫入器上的 SWM 接頭。

?

poYBAGNof62AMdKYAAVnWCxL7JU017.png
?

?

注意日志打印的引腳默認為TL_C2,波特率為230400。由于我們沒有足夠的I/O,我們將日志打印的引腳改為TL_D3。您可以在編輯后編譯代碼。配置文件位于tuya_ble_sdk_Demo_Project_tlsr8253\telink_kite_ble_sdk_v3.4.0_20190816\ble_sdk_multimode\vendor\8258_module\app_config.h. 當 GPIO 讀高時,它返回一個大于 1 的值,可能是 1、2 或 128。

在第 47 行:

#define DEBUG_INFO_TX_PIN				GPIO_PC2 

變成:

#define DEBUG_INFO_TX_PIN				GPIO_PD3

第四步:軟件設計

電脈沖按摩器采用中國傳統物理療法的電脈沖模擬,可促進血液循環,放松局部肌肉,電極墊設計達到雙重按摩效果。

我們實現了五種脈沖模式:智能、放松、主動、敲擊和刮擦。

脈沖模式

模式 時間間隔 放松模式 30 毫秒 主動模式 20 毫秒 輕敲模式 40 毫秒 抓取模式 50 毫秒 智能模式 20 毫秒、30 毫秒、40 毫秒或 50 毫秒隨機生成。

  • 原理圖,示意圖

P9 和 P24 控制三極管的開/關以產生電脈沖并啟用不同的脈沖模式。

?

poYBAGNof4OAZ-rNAABqiHSZCQw393.png
?

?

  • 波形圖

P9 和 P24 輸出 PWM 信號,正占空比為 26.5%,周期為 1 ms。注意這兩個引腳不能同時輸出高電平。否則三極管會燒壞。

以 30 ms 的間隔一次輸出四個 PWM 波,以實現放松模式。

pYYBAGNof7KAQ48uAAFga_QesqQ854.png
?

一個脈沖有四個 PWM 波,如上圖所示。以 30 ms 的間隔產生脈沖。

pYYBAGNof7aAWQzpAAFBuNsImOg538.png
?
  • 模式實現

五種脈沖模式是通過改變脈沖間隔來實現的,如下表所示。

pYYBAGNof7iAeeRVAAAqy_5ACcI137.png
?

?

實現代碼

引腳初始化

void pattern_pin_init(void)
{
gpio_set_func(PATTERN_PIN_A, AS_PWM1_N);
gpio_set_func(PATTERN_PIN_B, AS_PWM5);
gpio_set_func(HEAT_PIN, AS_GPIO);
gpio_set_output_en(PATTERN_PIN_A, 1);
gpio_set_output_en(PATTERN_PIN_B, 1);
gpio_set_output_en(HEAT_PIN, 1);
gpio_write(PATTERN_PIN_A, 0);
gpio_write(PATTERN_PIN_B, 0);
//    gpio_write(HEAT_PIN, 1);
//PWM0 1ms cycle  26.5% duty 	 1,000 Hz
pwm_set_mode(PWM1_ID, PWM_NORMAL_MODE);
pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
pwm_set_phase(PWM1_ID, 0);   // No phase at PWM beginning
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
pwm_polo_enable(PWM1_ID, 1);  // Enable the PWM polarity
pwm_start(PWM1_ID);
// PWM5 1 ms cycle, 26.5% duty  1,000 Hz
pwm_set_mode(PWM5_ID, PWM_NORMAL_MODE);
pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
pwm_set_phase(PWM5_ID, 0);   // No phase at PWM beginning
pwm_set_cycle_and_duty(PWM5_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
}

GPIO_PC1 (PATTERN_PIN_A)和電平調整引腳GPIO_PC2 (BOOST_PIN)使用 PWM 功能。管腳GPIO_PC1 (PATTERN_PIN_A)只支持PWM_0通道,所以GPIO_PC2 (BOOST_PIN)使用PWM_0通道。GPIO_PC1 (PATTERN_PIN_A)使用AS_PWM1_N通道,因此您只需要編輯pwm_polo_enable(PWM1_ID, 1)即可更改 PWM 極性。

?

poYBAGNof7uAKyIHAABzMqUtM2E925.png
?

?

由于 PWM 波的數量和脈沖間隔是通過時間延遲來實現的,因此會產生誤差。程序運行在裸機上,而不是 RTOS,所以這個函數必須while(1)循環運行。

void switching_pattern(unsigned char pat)
{
if (pat > 4) {
TUYA_APP_LOG_ERROR("*********No such model!!!**********");
}
switch (pat) {
case relieve:
pwm_start(PWM5_ID);
sleep_us(450);	 	// Delay 480 μs to prevent the triode from being burned out.
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
sleep_us(5 * TIME_MS);
pwm_stop(PWM5_ID);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
sleep_us(30 * TIME_MS);
break;
case vitality:
pwm_start(PWM5_ID);
sleep_us(450);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
sleep_us(5 * TIME_MS);
pwm_stop(PWM5_ID);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
sleep_us(20 * TIME_MS);
break;
case hammering:
pwm_start(PWM5_ID);
sleep_us(450);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
sleep_us(5 * TIME_MS);
pwm_stop(PWM5_ID);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
sleep_us(40 * TIME_MS);
break;
case scraping_therapy:
pwm_start(PWM5_ID);
sleep_us(450);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
sleep_us(5 * TIME_MS);
pwm_stop(PWM5_ID);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
sleep_us(50 * TIME_MS);
break;
case intelligent:
pwm_start(PWM5_ID);
sleep_us(450);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
sleep_us(5 * TIME_MS);
pwm_stop(PWM5_ID);
pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
sleep_us(((rand() % 4 + 2) * 10) * TIME_MS);	 // 20 ms, 30 ms, 40 ms, or 50 ms is generated randomly.
break;
default:
break;
}
return;
}

我們已經實現了五種脈沖模式,接下來是語音提示、加熱和電平調節。

1.語音提示

WTN6是一款多功能單語音芯片,語音合成4位MCU。

?

poYBAGNof76AGhi8AAD9fFd-L4M516.png
?
  • 工作電壓:2.8V至5.2V
  • 在待機模式下,靜態電流小于 5 μA。
  • 帶有內置電阻器 (+/- 1%) 的精確嵌入式振蕩器。支持低電壓復位(LVR=1.8V)和看門狗復位。
  • 高品質 12 位 PWM 直接驅動 8Ω 0.5W 揚聲器或蜂鳴器。DAC轉換器音頻輸出可以通過外部音頻放大器放大音量。
  • 內置看門狗。
  • 串口控制方式:單線串口和兩線串口。最多可加載 224 條語音。
  • 支持忙碌狀態下的輸出功能。

?

pYYBAGNof8CAVzx8AABXtJVRtrc694.png
?

單線串行通訊

在單線串口模式下,BTU模塊可以通過DATA線控制和發送數據到語音芯片,進行語音播放、停止、循環等。

引腳 描述 PA1 DATA PA2 BUSY 數據(十六進制) 功能 00H 不播放音頻。01H 第一次音頻播放。02H 第二次音頻播放。…… …… DFH 第 222 段音頻播放。

  • 引腳配置
poYBAGNof8WAD3PcAAAMzeFN34g257.png
?
  • 單行音頻地址關聯

?

pYYBAGNof8eAQY17AAAnL2Qr5Sk104.png
?

?

單線串口時序圖

將數據線拉低至 5ms,然后發送 8 位數據,先低位,后高位。用高電平與低電平的比值來表示每個數據位的值。

?

poYBAGNof8mAVuXvAAA2fc97RpA023.png
?

?

pYYBAGNof8yAODXeAAA4ykPlYF8383.png
?

?

實現代碼

  • 引腳初始化
void voice_prompt_init(void)
{
	gpio_set_func(WTN6_DATA_PIN | WTN6_BUSY_PIN, AS_GPIO);
	gpio_set_input_en(WTN6_BUSY_PIN, 1);
	gpio_set_output_en(WTN6_DATA_PIN, 1);

	gpio_write(WTN6_BUSY_PIN, 0);
}

?

  • 音頻播放
void voice_playing(uint8_t sb_data)
{
	uint8_t s_data, j;
	bool b_data;
	s_data = sb_data;
	gpio_write(WTN6_DATA_PIN, 0);
		sleep_us(5000);	 	// Delay 5 ms
	b_data = s_data & 0X01;

	for (j=0; j<8; j++) {
		if (b_data == 1) {
			gpio_write(WTN6_DATA_PIN, 1);
			   sleep_us(600); // Delay 600 μs
			gpio_write(WTN6_DATA_PIN, 0);
			   sleep_us(200); // Delay 200 μs
		} else {
			gpio_write(WTN6_DATA_PIN, 1);
			   sleep_us(200); // Delay 200 μs
			gpio_write(WTN6_DATA_PIN, 0);
			   sleep_us(600); // Delay 600 μs
		}
			s_data = s_data >> 1;
			b_data = s_data & 0X01;
	}
	gpio_write(WTN6_DATA_PIN, 1);
}

指定參數voice_playing(0x01)以播放離線音頻。

2:加熱

?

poYBAGNof4OAZ-rNAABqiHSZCQw393.png
?

?

我們向上或向下拉 P7 來控制加熱的開/關。頸部按摩器有一個內置傳感器來檢測溫度。當溫度超過 40°C 時,將關閉加熱以避免過熱。

?

poYBAGNof3eAakL5AAApAkKkTOM072.png
?

?

int switching_heat(unsigned char warm)
{
	if (warm > 1) {
		TUYA_APP_LOG_ERROR("*********No such model!!!**********");
	}
//	printf("wram%d massage_state.heat%d\r\n", warm, massage_state.heat);

	switch (warm) {
	case strong_heat:
		TUYA_APP_LOG_INFO("**********strong_heat************");
		gpio_write(HEAT_PIN, 1);
		temperature_detection();
		break;
	case off_heat:
		TUYA_APP_LOG_INFO("**********off_heat************");
		gpio_write(HEAT_PIN, 0);
		break;

	default:
		break;
	}

	return 0;
}

?

/*Temperature detection, which is called when heating feature is in high or low level.*/
int temperature_detection(void)
{
	int Rntc = 0, Vcc = 0;
	adc_channel_checkout(channel_x1);
	Vcc = adc_sample_and_get_result();	 // Unit: mV
	Rntc = Vcc*R25 / (3300-Vcc);
	TUYA_APP_LOG_INFO("Rntc_val=%dΩ", Rntc);
	if (Rntc >= 5311) {  	// NTC resistance value is 5311Ω at 40°C.
		TUYA_APP_LOG_WARNING("********High Temperature Warning!!!********");
		 gpio_write(HEAT_PIN, 0);  // When the temperature exceeds 40°C, heating will be turned off.
	}

	return 0;
}

有關 NTC 溫度如何與電阻相關的更多信息,請參閱溫度和電阻之間的關系。

3:強度調整

按摩器提供從弱到強的 15 級強度。我們使用升壓電路實現此功能。

?

poYBAGNof4iAaxZ_AAC77XtDlxg867.png
?

?

我們可以改變 P8 輸出的 PWM 波的正占空比來提升電壓。下表列出了具體值。

?

pYYBAGNof9iAGPjtAAAlYb2iVuE883.png
?

強度通過按鈕調整。單按可增加等級,雙按可降低等級。由于 SDK 配置,P8 在固件刷新后模塊復位時被拉高。因此,我們需要下拉P8。

void boost_init(void)
{
gpio_set_func(BOOST_PIN, AS_PWM0);
gpio_set_output_en(BOOST_PIN, 1);
// PWM0 1ms cycle
pwm_set_mode(PWM0_ID, PWM_NORMAL_MODE);
pwm_set_clk(CLOCK_SYS_CLOCK_HZ, BOOST_PWM_CLOCK_HZ); // When voltage is stepped up, the frequency of PWM is 16M / (968-1) ≈ 16.55 kHz.
pwm_set_phase(PWM0_ID, 0);   // No phase at PWM beginning
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
pwm_start(PWM0_ID);
}

初始化后,您可以指定占空比的值來升壓。

void switching_gear(unsigned char gears)
{
if (gears > 15) {
TUYA_APP_LOG_ERROR("*********There is no such gear!!!**********");
}
switch (gears) {
case first_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (10 * CLOCK_SYS_CLOCK_1US) );
break;
case second_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (20 * CLOCK_SYS_CLOCK_1US) );
break;
case third_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (40 * CLOCK_SYS_CLOCK_1US) );
break;
case fourth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (60 * CLOCK_SYS_CLOCK_1US) );
break;
case fifth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (70 * CLOCK_SYS_CLOCK_1US) );
break;
case sixth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (90 * CLOCK_SYS_CLOCK_1US) );
break;
case seventh_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (120 * CLOCK_SYS_CLOCK_1US) );
break;
case eighth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (160 * CLOCK_SYS_CLOCK_1US) );
break;
case ninth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (180 * CLOCK_SYS_CLOCK_1US) );
break;
case tenth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (220 * CLOCK_SYS_CLOCK_1US) );
break;
case eleventh_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (240 * CLOCK_SYS_CLOCK_1US) );
break;
case twelfth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (260 * CLOCK_SYS_CLOCK_1US) );
break;
case thirteenth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (300 * CLOCK_SYS_CLOCK_1US) );
break;
case fourteenth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (340 * CLOCK_SYS_CLOCK_1US) );
break;
case fifteenth_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (360 * CLOCK_SYS_CLOCK_1US) );
break;
case max_gear:
pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (360 * CLOCK_SYS_CLOCK_1US) );
break;
default:
break;
}
}

4:斷電記憶

將設備掉電前的狀態數據寫入可用的閃存中。當設備再次上電時從閃存中讀取數據。這樣,設備上電后可以恢復到之前的狀態。

TLSR8253芯片的flash如下圖所示。

?

poYBAGNof9uARR3xAABJoYPGEqA283.png
?

?

0x040000to0x060000是設備可以寫入數據的未使用空間。

1.將狀態寫入閃存。

/***********************************************************
*   Function:  write_massage_status_to_flash
*   Input:     none
*   Output:    none
*   Return:    none
*   Notice:    Write massager status to the flash memory.
***********************************************************/
void write_massage_status_to_flash(void)
{
	Flash_Write_Buff[0] = massage_state.on_off;
	Flash_Write_Buff[1] = massage_state.pattern;
	Flash_Write_Buff[2] = massage_state.gear;
	Flash_Write_Buff[3] = massage_state.heat;

	flash_write_page(FLASH_ADDR, FLASH_BUFF_LEN, (unsigned char *)Flash_Write_Buff);

	return;
}

2.從閃存中讀取狀態。

/***********************************************************
*   Function:  write_massage_status_to_flash
*   Input:     none
*   Output:    none
*   Return:    none
*   Notice:    Write massager status to the flash memory.
***********************************************************/
void write_massage_status_to_flash(void)
{
Flash_Write_Buff[0] = massage_state.on_off;
Flash_Write_Buff[1] = massage_state.pattern;
Flash_Write_Buff[2] = massage_state.gear;
Flash_Write_Buff[3] = massage_state.heat;
flash_write_page(FLASH_ADDR, FLASH_BUFF_LEN, (unsigned char *)Flash_Write_Buff);
return;
}/**********************************************************************
*   Function:  read_massage_status_to_flash
*   Input:     none
*   Output:    none
*   Return:    none
* Notice:   Read the massager status data before power-off from the flash memory, and save it to the status struct.
**********************************************************************/
void read_massage_status_to_flash(void)
{
	flash_read_page(FLASH_ADDR, FLASH_BUFF_LEN, (unsigned char *)Flash_Read_Buff);

	// Store the data read from the flash memory into the struct.
	massage_state.on_off = Flash_Read_Buff[0];
	massage_state.pattern = Flash_Read_Buff[1];
	massage_state.gear = Flash_Read_Buff[2];
	massage_state.heat = Flash_Read_Buff[3];

	return;
}
/***********************************************************
*   Function:  erase_massage_flash
*   Input:     none
*   Output:    none
*   Return:    none
*   Notice:    Restore defaults
***********************************************************/
void erase_massage_flash(void)
{
massage_state.on_off = OFF;
massage_state.pattern = relieve;
massage_state.gear = first_gear;
massage_state.heat = off_heat;
Flash_Write_Buff[0] = OFF;
Flash_Write_Buff[1] = relieve;
Flash_Write_Buff[2] = first_gear;
Flash_Write_Buff[3] = off_heat;
flash_write_page(FLASH_ADDR, FLASH_BUFF_LEN, (unsigned char *)Flash_Write_Buff);
return;
}
  • 恢復默認值。
/***********************************************************
*   Function:  erase_massage_flash
*   Input:     none
*   Output:    none
*   Return:    none
*   Notice:    Restore defaults
***********************************************************/
void erase_massage_flash(void)
{
	massage_state.on_off = OFF;
	massage_state.pattern = relieve;
	massage_state.gear = first_gear;
	massage_state.heat = off_heat;

	Flash_Write_Buff[0] = OFF;
	Flash_Write_Buff[1] = relieve;
	Flash_Write_Buff[2] = first_gear;
	Flash_Write_Buff[3] = off_heat;

	flash_write_page(FLASH_ADDR, FLASH_BUFF_LEN, (unsigned char *)Flash_Write_Buff);

	return;
}

5:云端控制

對于低功耗藍牙模塊,單個數據點 (DP) 的所有數據都存儲在一個數組中。以 DP ID 104 為例。它的數組如下。

unsigned char mode_buf[]   = {0x68, 0x04, 0x01, 0x00};  //{DP_ID, DP_type, DP_len, DP_data}
tuya_ble_dp_data_report(mode_buf, 4);  // Data reporting function.

調用tuya_ble_dp_data_report(uint8_t *p_data,uint32_t len)將單個DP的狀態數據上報到云端。

來自移動應用程序的控制命令存儲在數組中dp_data_array[255+3]。您可以編寫一個DP數據發送處理函數,并dp_data_array[255+3]作為參數傳遞給該函數tuya_cb_handler(tuya_ble_cb_evt_param_t* event)tuya_ble_demo.c以實現從移動應用程序發送命令。

void app_dp_handle(uint8_t *dp_data)
{
printf("dp_data:%d  %d  %d  %d\r\n", dp_data[0], dp_data[1], dp_data[2], dp_data[3]);
switch (dp_data[0]) {
case 0x66:
if (dp_data[3] == strong_heat) {
massage_state.heat = strong_heat;
} else {
massage_state.heat = off_heat;
}
printf("dp_data[3]:%d massage_state.heat:%d\r\n", dp_data[3], massage_state.heat);
if (!app_flag) {
switching_heat(massage_state.heat);
}
break;
case 0x67:
printf("dp_data[3]:%d \r\n", dp_data[3]);
switch (dp_data[3]) {
case first_gear:
massage_state.gear = first_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case second_gear:
massage_state.gear = second_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case third_gear:
massage_state.gear = third_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case fourth_gear:
massage_state.gear = fourth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case fifth_gear:
massage_state.gear = fifth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case sixth_gear:
massage_state.gear = sixth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case seventh_gear:
massage_state.gear = seventh_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case eighth_gear:
massage_state.gear = eighth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case ninth_gear:
massage_state.gear = ninth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case tenth_gear:
massage_state.gear = tenth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case eleventh_gear:
massage_state.gear = eleventh_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case twelfth_gear:
massage_state.gear = twelfth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case thirteenth_gear:
massage_state.gear = thirteenth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case fourteenth_gear:
massage_state.gear = fourteenth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case fifteenth_gear:
massage_state.gear = fifteenth_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
case max_gear:
massage_state.gear = max_gear;
if (!app_flag) {
switching_gear(massage_state.gear);
}
break;
default:
break;
}
break;
case 0x68:
if (dp_data[3] == relieve) {
massage_state.pattern = relieve;
} else if (dp_data[3] == vitality) {
massage_state.pattern = vitality;
} else if (dp_data[3] == hammering) {
massage_state.pattern = hammering;
} else if (dp_data[3] == scraping_therapy) {
massage_state.pattern = scraping_therapy;
} else {
massage_state.pattern = intelligent;
}
break;
case 0x69:
if (dp_data[3] == ON) {
massage_state.on_off = ON;
rs2255_init();
voice_prompt_init();
pattern_pin_init();
app_flag = 0;
} else {
massage_state.on_off = OFF;
power_off_init();
app_flag = 1;
}
break;
default:
break;
}
}

第 5 步:設備控制

在手機上安裝涂鴉智能應用或智能生活應用。它們在移動應用市場上可用。打開應用程序并單擊右上角的+圖標以配對設備。設備連接后,您可以通過應用程序對其進行控制。

概括

恭喜!您已成功設計出智能頸部按摩器的原型。

這款多功能物聯網按摩器與 TENS 技術相結合,有助于緩解頸部酸痛和疼痛。內置NTC傳感器,采用先進的精確恒溫控制技術,可改善血液循環,緩解疼痛、結節和肌肉緊張。基于這個項目,您可以探索更多很棒的功能!

涂鴉物聯網平臺提供便捷的物聯網開發工具和服務,旨在讓您的物聯網項目更輕松、更高效。查看并發現更多很棒的想法。

?
?
?

?


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數據手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費
主站蜘蛛池模板: 特黄特色大片免费播放器9 特黄特色大片免费视频播放 | 亚洲韩国日本欧美一区二区三区 | 日本偷偷操 | 男人视频网 | 欧美八区 | 午色影院| 国产精品久久久久久久成人午夜 | 青青青久97在线观看香蕉 | 伊人丁香婷婷综合一区二区 | 色综合综合色 | 久久亚洲一级毛片 | 欧美片欧美日韩国产综合片 | 午夜视频在线观看一区二区 | 亚洲香蕉视频 | 欧美最猛黑人xxxxwww | 久久精品99无色码中文字幕 | 欧美日韩一卡2卡三卡4卡新区 | 最新bt合集 | 奇米奇米 | 色综合天天综久久久噜噜噜久久〔 | 午夜在线视频免费观看 | 男男宿舍高h炒肉bl 男男污肉高h坐便器调教 | 久久国产中文字幕 | 五月天天色| 最近2018免费中文字幕视频 | 婷婷中文字幕 | 91成人免费在线视频 | 最刺激黄a大片免费网站 | 天天摸日日添狠狠添婷婷 | 欧美性色黄大片四虎影视 | 亚洲一区高清 | 色婷婷六月桃花综合影院 | 好硬好湿好爽再深一点h | 香蕉成人999视频 | 又粗又硬又爽又黄毛片 | 成人激情综合网 | 午夜性a一级毛片 | 日本系列 1页 亚洲系列 | 啪啪啦资源站永久 | 国产手机在线观看视频 | 三级天堂 |