學習目標 : 用faya電子積塊組出一倒車雷達系統
學習時間 : 180min
使用模組 : (1) faya brickNano
(2) faya 超音波距離感應模組
(3) faya 數位式蜂鳴器模組
(4) faya 自鎖開關模組
(5) faya 串列全彩LED模組 x 6
工具 : 樂高積木(相容)
====================相關知識====================
這篇文章中所用到的模組使用方式及相關知識整理如下,需進一步了解時可點進去參考:
模組介紹 : faya brickNano
模組介紹 : faya 超音波距離感應模組
模組介紹 : faya 數位式蜂鳴器模組
模組介紹 : faya 自鎖開關模組
模組介紹 : faya 串列全彩LED模組
模組介紹 : faya 串列全彩LED模組(使用fastLED函式庫)
======================開箱======================
彩虹倒車雷達(型號NTG-506)是fayalab的第六款創意組合系列作品,這個作品利用現有的faya模組,模擬了倒車雷達的現象,超音波距離感應模組與物體的距離會顯示在32顆串列全彩LED模組上,當物體愈靠近時,數位式蜂鳴器發出的聲音會愈急促,就像我們開車子的倒車雷達系統一樣。另外,我們加入了一個自鎖開關模組,用來決定是否開啟蜂鳴器的告警聲。
彩虹倒車雷達盒所需的全部模組及附件如下:
1. brickNano主板 2.超音波距離感應模組 3.自鎖開關模組 4.數位式蜂鳴器模組
5. 串列全彩LED模組 6. 電源線(B) 7. 電源線(A) 8. 積木柱子 9. 積木蓋子
10. 跳線包(含電容) 11. micro USB傳輸線 12.積木包 13. 積木底板 14. 積木補充包
===================範例實作=====================
目標:
(1) 利用faya電子積塊,製作倒車雷達系統
(2) 超音波距離感應模組偵測感應距離
(3) 偵測距離每減少一公分會多點亮一顆串列全彩LED
(4) 偵測距離愈短,蜂鳴器發出的聲音愈急促
(5) 自鎖開關用來切換是否開啟蜂鳴器
組裝:
首先把[1. brickNano主板]、[2.超音波距離感應模組]、[3.自鎖開關模組]、[4.數位式蜂鳴器模組]、[5. 串列全彩LED模組]的模組角落裝上[8.積木柱子]與[9. 積木蓋子]。其中[2.超音波距離感應模組]的前方兩個角落空間有限,因此只需要加裝柱子就好。
積木柱子的組裝過程可參考[功能介紹 : faya電子積塊與LEGO積木的結合]
積木蓋子的組裝過程可參考[小技巧 : 積木柱子太鬆時如何處理?]
完成後模組正面照如下圖所示:
背面照如下圖所示
接下來示範積木的組裝和線路的連接,大家可以按照底下的範例跟著做一次,熟悉安裝的步驟,之後再按照自己的喜好修改造型。如果照著我們的範例,組完後會長這個樣子:
顯示棒組裝
全彩倒車雷達會將測試到的距離透過32顆串列全彩LED模組顯示,因此我們必具製作一個長形結構,讓4個長形的[5. 串列全彩LED模組]能夠穩穩依附。
首先將[14. 積木補充包]裡的4個[2x10平板積木]擺成一直線
接著利用3個[2x6平板積木]從背面將以上的4個平板積木串起來,固定成一棒狀結構
然後在棒狀結構正面,安裝4個[5. 串列全彩LED模組],模組位置和方向請和下圖一致
接下來在[10. 跳線包(含電容) ]中利用紫色的短跳線,將相鄰的串列全彩LED模組的VCC、GND、DATA串起來。
透過9條短跳線就可將全部模組的電源和訊號線串起,完成後如下圖所示
主體與模組組裝
首先利用一片2x10平板積木和二片2x6平板積木將[13. 積木底板]固定成長方形狀,另外也請在右方安裝一片6x8平板積木,位置下圖所示
接著在6x8平板積木上組出2組2層的2x5立體結構,位置和形狀如下所示
接著我們要在圖中圈圈位置安裝模組,其中
藍色圈圈 : 超音波距離感應模組
橘色圈圈 : 自鎖開關模組
粉紅圈圈 : 數位式蜂鳴器模組
白色圈圈 : faya brickNano主板
模組安裝完成後如下圖所示
再來用三條[6. 電源線(B)]將模組電源串起來,電源線的連接詳細原理可參考這篇文章,我們的連接方式為:
brickNano 主板 <==> 數位式蜂鳴器模組
數位式蜂鳴器模組 <==> 超音波距離感應模組
超音波距離感應模組 <==> 自鎖開關模組
完成後,用3顆2x4積木蓋第二層,其中中間的那顆積木會將拉出的電源線蓋住
接下來我們用[10.跳線包]裡的信號線連接數位式蜂鳴器模組和自鎖開關模組的腳位
Arduino_A5 ===> 數位式蜂鳴器模組_Vin
Arduino_D2 ===> 自鎖開關模組_PU
接下來用4顆2x4模組,蓋出第三層,位置如下所示,注意到左右兩顆2x4的積木會有一半往後延伸,目的是為了和後方的積木結合,目前呈踩空狀態不用在意。
再來我們用兩條最長的綠色訊號線連接Arduino與超音波測距模組的腳位
Arduino_D11 ===> 超音波距離感應模組_Echo
Arduino_D12 ===> 超音波距離感應模組_Trig
完成後我們用3顆2x4的積木蓋第四層如下圖所示
接著蓋第五層,如下所示,注意到中間的兩顆為90度的轉角積木
請注意兩個90度的轉角積木的安裝方向,他們的後方要稍微突出才是正確的
完成後用一個1x2的積木將兩個90度轉角積木壓住,使其更固定
最後將我們剛開始組好的顯示棒安裝扣到90度的轉角積木上,安裝位置請大家參考以下幾張不同角度的照片
由近照看出最後組的1x2的積木上方緊鄰的就是串列全彩LED模組
利用顯示棒上的平板積木(第二格)和90度轉角積木結合
完成顯示棒的安裝後, 我們進行主體安裝的最後一步驟,連接顯示棒的電源線和信號線。電源線方面,用一條[5. 電源線(A)],將白色頭端接brickNano的電源座,另一端的紅黑針腳穿過正下方的積木縫隙,連接顯示棒的VCC(紅色-左邊)和GND(黑色-右邊)。
訊號線的連接方式也是穿過下方的積木空隙連接兩端
Arduino_D6 ===> 串列全彩LED模組_Din
前兩個步驟所提到的積木空隙位於下圖虛線方框處
到目前為止,倒車雷達的主體架構算是已經完成了,接下來我們可以用剩下的積木做一些點綴,大家可以依照自己的喜好組出自己的倒車雷達外觀。底下是筆者組出的外觀,大家可以參考參考!
正面照:
45度角側照
正面近照
側面照
背面照
背面近照:可以發現我們保留了一個孔讓USB線可以拉到外面
完成了主體和線路的安裝,我們接下來可以開始利用Arduino程式來控制每個模組了,底下我們把最終的彩虹倒車雷達作品循序的拆成3部分來介紹
(1) 量測感應距離
(2) 將感應到的距離顯示在LED顯示棒上
(3) 加入雷達示警聲
(1) 量測感應距離:
目標 : 將感測距離顯示在序列埠監控視窗
補充 : 偵測移動的距離最小單位為一公分
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/04/10 | |
// Faya-Nugget 範例程式 (Parking_Sensor_1.ino) | |
// 單元: 彩虹倒車雷達系統 | |
// 網址: https://fayalab.blogspot.com/2018/04/ParkingSensor.html | |
// 目標: (1) 利用超音波距離感應模組偵測感應距離 | |
// (2) 感應距離顯示在序列埠視窗 | |
// 接線: Arduino ==> faya模組 | |
// D12 ==> Trig (超音波距離感應模組) | |
// D11 ==> Echo (超音波距離感應模組) | |
// A5 ==> BZ (蜂鳴器模組) | |
// D2 ==> P.U. (自鎖開關模組) | |
// D6 ==> Din (串列全彩LED模組) | |
unsigned long distance=0; //宣告distance(量測距離)變數 | |
#define Trig 12 //超音波 Trig pin = D12 | |
#define Echo 11 //超音波 Echo pin = D11 | |
#define BZ_Vin A5 //數位蜂鳴器 Vin = A5 | |
#define SW_PU 2 //Buzzer Switch = D2 | |
unsigned long time; | |
void setup() { | |
Serial.begin(9600); | |
pinMode(Trig, OUTPUT); //設定Trig為輸出埠 | |
pinMode(Echo, INPUT); //設定Echo為輸入埠 | |
pinMode(BZ_Vin,OUTPUT); //設定Vin為輸出埠 | |
pinMode(SW_PU,INPUT); //設定SW_PU開關為輸入埠 | |
digitalWrite(BZ_Vin,LOW); //數位蜂鳴器拉LOW,預設靜音 | |
} | |
void loop() { | |
getDistance(); | |
Serial.println(distance); | |
} | |
void getDistance() //取得目前距離 | |
{ | |
int total_Distance = 0; | |
for(int i=0; i<=4; i++) //加幒5次測到的距離再取平均 (避免單次測得的誤差) | |
{ | |
digitalWrite(Trig, HIGH); // 輸出Trig為HIGH | |
delayMicroseconds(10); // 維持10uS | |
digitalWrite(Trig, LOW); // 再轉LOW | |
distance=(pulseIn(Echo, HIGH)/58); // 利用pulseIn計算Echo的寬度(時間),再除以58uS單位時間,算出感測距離 | |
total_Distance = total_Distance + distance; //距離加總 | |
delay(5); | |
} | |
distance = total_Distance / 5; | |
} |
備註:
- L41~L44: 取得一次感測距離的方式,我們在之前的文章介紹過原理了,請參考[模組介紹:faya超音波距離感應模組]
- L39~L48: 取五次的距離再取平均,讓量測誤差達到最小
- L28: 由於蜂鳴器的電源線和訊號線已經拉好了,因此我們在Setup裡面先下一個LOW訊號,使其靜音。
- 由於串列全彩LED模組的電源線和訊號線已經拉好了,此模組未給控制訊號時會全部點亮,因此下載程式前可以先把電源線的VCC拔掉,避免太亮。
觀察結果:
討論:
從影片中大家可以看到監控視窗內的數字隨著感應距離變短而降低,如果大家打開喇叭,會聽到類似風壓的聲音,其頻率隨著感應距離的靠近而變高,這是因為感測器打出的訊號頻率是超音波,我們的耳朵聽不到,但是手機的麥克風是接收的到的,透過錄影轉換後變成耳朵可以聽得到的音頻。當物體愈靠近時,超音波傳輸的距離也跟著變短,因此頻率變高了,這是很有意思的一個現象。
(2) 將感應到的距離顯示在LED顯示棒上
目標 : 將感測距離顯示在LED顯示棒上
補充 : 有效距離為4~35公分之間,每接近一公分亮一顆燈,所以當感應距離 =>
在36公分以上時,LED全滅
35公分時,LED亮1顆
34公分時,LED亮2顆
......
5公分時,LED亮31顆
4公分時,LED亮32顆 (全亮)
4公分以內,LED同樣全亮
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/04/10 | |
// Faya-Nugget 範例程式 (Parking_Sensor_2.ino) | |
// 單元: 彩虹倒車雷達系統 | |
// 網址: https://fayalab.blogspot.com/2018/04/ParkingSensor.html | |
// 目標: (1) 利用超音波距離感應模組偵測感應距離 | |
// (2) 感應距離顯示在全彩顯示棒上 | |
// (3) 有效距離 4~35公分,每接近一公分亮一顆燈 | |
// 接線: Arduino ==> faya模組 | |
// D12 ==> Trig (超音波距離感應模組) | |
// D11 ==> Echo (超音波距離感應模組) | |
// A5 ==> BZ (蜂鳴器模組) | |
// D2 ==> P.U. (自鎖開關模組) | |
// D6 ==> Din (串列全彩LED模組) | |
#include "FastLED.h" //引入FastLED標頭黨 | |
#define NUM_LEDS 32 //定義全彩LED數量 | |
#define DATA_PIN 6 //定義全彩LED訊號腳位 | |
CRGB faya_colorSticker[NUM_LEDS]; //定義FastLED類別 | |
unsigned long distance=0; //宣告distance(量測距離)變數 | |
#define Trig 12 //超音波 Trig pin = D12 | |
#define Echo 11 //超音波 Echo pin = D11 | |
#define BZ_Vin A5 //數位蜂鳴器 Vin = A5 | |
#define SW_PU 2 //Buzzer Switch = D2 | |
unsigned long time; | |
void setup() { | |
Serial.begin(9600); | |
pinMode(Trig, OUTPUT); //設定Trig為輸出埠 | |
pinMode(Echo, INPUT); //設定Echo為輸入埠 | |
pinMode(BZ_Vin,OUTPUT); //設定Vin為輸出埠 | |
pinMode(SW_PU,INPUT); //設定SW_PU開關為輸入埠 | |
digitalWrite(BZ_Vin,LOW); //數位蜂鳴器拉LOW,預設靜音 | |
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(faya_colorSticker, NUM_LEDS); //設定串列全彩LED參數 | |
} | |
void loop() { | |
getDistance(); //取得距離 | |
Serial.println(distance); //顯示在序列埠監控視窗 | |
showLED(); //顯示在串列LED | |
} | |
void getDistance() //取得目前距離 | |
{ | |
int total_Distance = 0; | |
for(int i=0; i<=4; i++) //加幒5次測到的距離再取平均 (避免單次測得的誤差) | |
{ | |
digitalWrite(Trig, HIGH); // 輸出Trigh為HIGH | |
delayMicroseconds(10); // 維持10uS | |
digitalWrite(Trig, LOW); // 再轉LOW | |
distance=(pulseIn(Echo, HIGH)/58); // 利用pulseIn計算Echo的寬度(時間),再除以58uS單位時間,算出感測距離 | |
total_Distance = total_Distance + distance; //距離加總 | |
delay(5); | |
} | |
distance = total_Distance / 5; | |
} | |
void showLED() //將取得的距離(35~4公分)顯示在32顆LED上,每接近一公分顯示一顆燈 | |
{ | |
if(distance>=36) //量測距離超過36公分以上時 => LED 全滅 | |
{ | |
for(int i=0;i<32;i++) | |
{ | |
faya_colorSticker[i] = CHSV(0,0,0); | |
} | |
FastLED.show(); | |
} | |
else //量測距離35公分以下時,LED開始點亮,每靠近1公分點亮1顆 | |
{ | |
for(int i=0;i<32;i++) | |
{ | |
if((36-distance)>i) // 判斷該點亮幾顆LED | |
faya_colorSticker[i] = CHSV(i*8, 255, 64); //決定第i顆的顏色 | |
else // 有效距離外的LED不點亮 | |
faya_colorSticker[i] = CHSV(0,0,0); | |
} | |
FastLED.show(); | |
} | |
} |
備註:
- 本程式需要用到[FastLED]函式庫,請下載並解壓縮至Arduino Libraries 資料夾
- L71~L79 : 利用FastLED函式庫控制32顆LED的顏色,請參考我們之前的教學[模組介紹:faya串列全彩LED模組(使用fastLED函式庫) ]
- L61、L70 : 超音波距離感測器大約在3公分以內是不準的,我們多給1公分緩衝,因此最近的有效感應距離從4公分開始算,另外我們有32顆LED,亮一顆LED代表接近一公分,因此我們真正的量測範圍在4~35公分之間,超過36公分以上的距離則無LED點亮。
- L63~L67 : 由於偵測距離大於36公分,因此我們跑一個32次的迴圈,讓每顆LED都熄滅
- L72~L79 : (36-distance)用來判斷有幾顆LED會亮起,如果距離distance為4時,代表36-4 = 32顆LED全亮,如果distance為35時,代表只有36-35 = 1顆LED亮。這邊同樣跑一個32次的迴圈,並用 (36-distance)是否大於i來判斷該LED是否點亮,點亮的顏色則設定在第75行的程式
- L75 : 平均分配LED的顏色,由於一個cycle有256種顏色,256/32(顆) = 8,因此我們每一顆的顏色間隔設定為8。
觀察結果:
討論:
從影片大家可以發現LED顯示棒如預期的隨著偵測距離變短,顯示的LED變多,在接近4公分時,LED全亮,超過36公分時,LED全滅。接下來我們會加入雷達示警聲的程式。
(3) 加入雷達示警聲
目標 : Buzzer產生的示警頻率隨著感應距離的變短而急促
補充 : 壓下自鎖開關時,啟動雷達告警聲,當偵測距離由30公分接近5公分時,示警頻率愈來愈急促,小於5公分時,示警聲長鳴
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/04/10 | |
// Faya-Nugget 範例程式 (Parking_Sensor_3.ino) | |
// 單元: 彩虹倒車雷達系統 | |
// 網址: https://fayalab.blogspot.com/2018/04/ParkingSensor.html | |
// 目標: (1) 利用超音波距離感應模組偵測感應距離 | |
// (2) 感應距離顯示在全彩顯示棒上 | |
// (3) 雷達示警聲隨著偵測距離降低而急促,最後長鳴 | |
// (4) 透過自鎖開關切換是否開啟示警音 | |
// 接線: Arduino ==> faya模組 | |
// D12 ==> Trig (超音波距離感應模組) | |
// D11 ==> Echo (超音波距離感應模組) | |
// A5 ==> BZ (蜂鳴器模組) | |
// D2 ==> P.U. (自鎖開關模組) | |
// D6 ==> Din (串列全彩LED模組) | |
#include "FastLED.h" //引入FastLED標頭檔 | |
#define NUM_LEDS 32 //定義全彩LED數量 | |
#define DATA_PIN 6 //定義全彩LED訊號腳位 | |
CRGB faya_colorSticker[NUM_LEDS]; //定義FastLED類別 | |
unsigned long distance=0; //宣告distance(量測距離)變數 | |
#define Trig 12 //超音波 Trig pin = D12 | |
#define Echo 11 //超音波 Echo pin = D11 | |
#define BZ_Vin A5 //數位蜂鳴器 Vin = A5 | |
#define SW_PU 2 //Buzzer Switch = D2 | |
int Buz_Counter = 0; //切換蜂鳴器聲響的暫存器 | |
unsigned long time; //暫存時間變數,用來計算時間間隔 | |
void setup() { | |
Serial.begin(9600); | |
pinMode(Trig, OUTPUT); //設定Trig為輸出埠 | |
pinMode(Echo, INPUT); //設定Echo為輸入埠 | |
pinMode(BZ_Vin,OUTPUT); //設定Vin為輸出埠 | |
pinMode(SW_PU,INPUT); //設定SW_PU開關為輸入埠 | |
digitalWrite(BZ_Vin,LOW); //數位蜂鳴器拉LOW,預設靜音 | |
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(faya_colorSticker, NUM_LEDS); //設定串列全彩LED參數 | |
} | |
void loop() { | |
getDistance(); //取得距離 | |
Serial.println(distance); //顯示在序列埠監控視窗 | |
showLED(); //顯示在串列LED | |
outBeeper(); //發出示警聲 | |
} | |
void getDistance() //取得目前距離 | |
{ | |
int total_Distance = 0; | |
for(int i=0; i<=4; i++) //加幒5次測到的距離再取平均 (避免單次測得的誤差) | |
{ | |
digitalWrite(Trig, HIGH); // 輸出Trigh為HIGH | |
delayMicroseconds(10); // 維持10uS | |
digitalWrite(Trig, LOW); // 再轉LOW | |
distance=(pulseIn(Echo, HIGH)/58); // 利用pulseIn計算Echo的寬度(時間),再除以58uS單位時間,算出感測距離 | |
total_Distance = total_Distance + distance; //距離加總 | |
delay(5); | |
} | |
distance = total_Distance / 5; | |
} | |
void showLED() //將取得的距離(35~4公分)顯示在32顆LED上,每接近一公分顯示一顆燈 | |
{ | |
if(distance>=36) //量測距離超過36公分以上時 => LED 全滅 | |
{ | |
for(int i=0;i<32;i++) | |
{ | |
faya_colorSticker[i] = CHSV(0,0,0); | |
} | |
FastLED.show(); | |
} | |
else //量測距離35公分以下時,LED開始點亮,每靠近1公分點亮1顆 | |
{ | |
for(int i=0;i<32;i++) | |
{ | |
if((36-distance)>i) // 判斷該點亮幾顆LED | |
faya_colorSticker[i] = CHSV(i*8, 255, 64); //決定第i顆的顏色 | |
else // 有效距離外的LED不點亮 | |
faya_colorSticker[i] = CHSV(0,0,0); | |
} | |
FastLED.show(); | |
} | |
} | |
void outBeeper() //計算雷達輸出頻率 | |
{ | |
if(millis()-time > (int)(10*distance)) //切換蜂鳴器聲響的頻率和感應距離成正比 | |
{ | |
if(digitalRead(SW_PU) == LOW) //自鎖開關被按下時啟動蜂鳴器 | |
{ | |
Beeper(); //呼叫蜂鳴器雷達聲 | |
} | |
else if(digitalRead(SW_PU) == HIGH) //自鎖開關彈開時關閉蜂鳴器 | |
{ | |
digitalWrite(BZ_Vin,LOW); | |
} | |
time = millis(); //更新時間 | |
} | |
else if(distance>30) // 距離超過30公分時蜂鳴器靜音 | |
digitalWrite(BZ_Vin,LOW); | |
} | |
void Beeper() //雷達聲 | |
{ | |
if(distance <= 30 & distance >5) // 量測距離在30cm~5cm時 | |
{ | |
if(Buz_Counter==0) // 發出嗶嗶聲 (間隔時間和隨距離成正比) | |
{ | |
digitalWrite(BZ_Vin,HIGH); | |
Buz_Counter = 1; | |
} | |
else if(Buz_Counter==1) | |
{ | |
digitalWrite(BZ_Vin,LOW); | |
Buz_Counter = 0; | |
} | |
} | |
else if (distance <= 5) // 量測距離在5cm以內時 | |
{ | |
digitalWrite(BZ_Vin,HIGH); // 發出長鳴 | |
} | |
} |
備註:
- L88 : 我們為了要讓雷達示警聲的頻率和感應距離成正比 (距離愈短,輸出聲音愈急促),因此加了millis()-time > (int)(10*distance)判斷式,例如偵測距離為20公分,此時當時間間隔為20x10=200ms時才進入雷達聲副程式產生響音,當偵測距離縮短到7公分時,時間間隔縮短到7x10=70ms就進入雷達聲副程式產生響音。
- L90、L94 : 利用兩個簡單的判別式,決定是否啟動雷達聲
- L100 : 判斷30公分以上的距離無雷達聲
- L106、L119 : 將雷達聲副程式分成兩種鳴叫方式,5公分以內雷達長鳴,5~30公分間雷達嗶嗶鳴叫,鳴叫的長度為 (10*distance) ms,休息的長度也是 (10*distance) ms。
觀察結果:
討論:
- 影片如預期的當偵測距離愈靠近時,顯示的燈愈多,且雷達示警聲愈急促,當接近到大約4公分左右時,雷達長鳴。
- 如果仔細聽雷達的示警聲,應該可以感覺出示警聲混著雜音,這是由於fastLED所產生的串列數位訊號,原本用來控制串列全彩LED的,但是由於共地(GND)的關係,此訊號也透過地線影響蜂鳴器模組,此時,我們只要在VCC和GND之間,加上一顆220uF的電容,就能把雜訊濾掉,安裝位置與方向如下所示
- 我們利用一段影片來比較加入電容前和電容後的聲音
最後我們再看一次安裝電容後的完整的彩虹倒車雷達影片
討論:
這一次的範例教學,我們利用過去所學的知識,將程式拆成三段,每次加入不同的faya電子積塊和程式,最後達到彩虹倒車雷達的功能。我們發現控制串列全彩LED所產生的串列訊號很明顯的影響到蜂鳴器的品質,因此利用一顆電容將雜訊去除,除了模擬了倒車雷達系統的動作,更加入了彩虹顯示棒,大大增加了作品的互動性。
歡迎大家在底下留言或到我們的粉絲團留言喔!
====================================
fayalab 粉絲團
FB本篇留言版
沒有留言:
張貼留言