---
tags: 社群專案, FablabTainan,
---
# 社交距離測距儀
----------
:::info
[TOC]
:::
----------
# 一、專案介紹
## 專案簡介
因應武漢肺炎需保持社交距離,以超音波測距模組加attiny85製作提醒社交距離的配戴式偵測器
## 授權方式
(創用CC授權)
----------
# 二、專案合作人
## 發起人:
- 詹富貴
## 合作人:
-
(有興趣參與共筆的人,可以直接在此列上你的大名!)
----------
# 三、實作討論
## 試作1.0
* 構想1:控制器用ATTiny85,以遙控器用的12V的電池作為電源,超音波模組作為量測距離的元作,最後由蜂鳴器模組發出聲音及ATTiny85的LED作為提醒,己在量測範圍內,並保留一個按鈕作為其他功能的備用輸入.

* 試作後發現幾個問題
1. 遙控器用的12V的電池,電容量太小(目前查到只有55mAh),用電源供應器直接供電看跑多少電流,最大會到50mA,最少也有20mA,所每次一上電就瞬間被吸乾,無法啟動ATTiny85
2. 由於這次的ATTiny85有6個點的設計,想把所有腳位全用完,因此把預留的按鈕接到5腳位上,但其實這個腳位是reset,所以上電後程式一直無法跑,最後找到是如果要用[reset當GPIO](http://projectsfromtech.blogspot.com/2013/04/using-reset-pin-as-io-on-attiny8545.html)的話需要一需特殊的設定才能用,但因為還多了一個腳位,最後將預留的按鈕移過去,reset還是當reset
## 試作2.0
* 藉由1.0的試作,找出大概的問題,電源改用3.7V的口香糖鋰聚合物電池,加個升壓充電保護三合一的充電板作為電源,且為了讓成品好作及縮小體積,畫了電路並用CNC試作.

[原理圖](https://drive.google.com/file/d/1pLIdncWv5ZIu6wNqu-GLLRlGdJcNXemY/view?usp=sharing)

[線路圖](https://drive.google.com/file/d/1_SFCv88eCxg3-79VW_dUt2TcQ_Y10ft0/view?usp=sharing)
* 用CNC試作電路板




* 作好後電路後,再用雷切作個外殼包起來,一開始是以御守為概念,但最後電路有點太厚了,變的不太像了.



[外殼雷切檔](https://drive.google.com/file/d/1JXDLt9HN4hk2iLT7N0c8lrEW4XxhATmQ/view?usp=sharing)
* 最後測試效果,距離量測算準確,大約在上下左右30度以內都能順利接收,只是因為超音波無法辨識人或物體,有偵測到就會叫,最後只是一個很吵的玩具.
# 四、程式碼
v1.0
:::danger
#include <NewPing.h> //Iclud Arduino Pin Library,https://www.14core.com/didispark-attiny85-with-ultrasonic-hc-sr04-sensor/
#define buzzer 0//蜂鳴器(SDA),0
#define led 1//板上led,1
#define zerobutton 2//歸零鈕(SCL)
//5(reset)
unsigned long zero_time[2] = {0, 0};//延遲暫存值
unsigned long led_time[4] = {0, 0, 0, 0}; //led延遲暫存值
unsigned long sonar_time[2] = {0, 0};//超音波延遲暫存值
uint8_t sensorzero[2] = {150, 0}; //超音波歸零值
bool bi_switch = 1;
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(4, 3, MAX_DISTANCE); //(TRIGGER_PIN, ECHO_PIN, DISTANCE)
void setup()
{
//Serial.begin(9600);
pinMode(zerobutton, INPUT);
pinMode(led, OUTPUT);
pinMode(buzzer, OUTPUT);
}
void loop()
{
/*連續取值*/
sonar_time[0] = millis();
if (sonar_time[0] - sonar_time[1] > 500)//每0.5秒取一次
{
sensorzero[1] = sonar.ping_cm();//超音波現在值
//Serial.println(sensorzero[1]);
sonar_time[1] = sonar_time[0];
}
/*偵測開始*/
if (sensorzero[1] > 0) //0:設定值,1:現在值
{
if (sensorzero[1] > sensorzero[0] * 0.7 && sensorzero[1] <= sensorzero[0] * 1 )//1~1.5米
{
Detect(500, bi_switch);
}
else if (sensorzero[1] <= sensorzero[0] * 0.7 )//1米
{
Detect(100, bi_switch);
}
else
{
digitalWrite(led, LOW);
digitalWrite(buzzer, LOW);
}
}
}
/*偵測輸出*/
void Detect(int delay_time, bool bi)
{
led_time[0] = millis();
if (led_time[0] - led_time[1] > delay_time)
{
digitalWrite(led, HIGH);
}
}
:::