# 不要靠近我~留情面拒絕背心!!!
我是有勛,這週材料都在我這! 所以我負責把程式寫好,下周交給亮穎組裝並美化~~
以下是目前的專案進度:
### 功能介紹:
>
>當有喝醉的痴漢想抱你的時候,留情面拒絕器會在癡漢太靠近你的時候**閃燈及發出警報聲**提醒你!
>這時,你可以偷偷按下手上的按鈕,就會有一隻假手伸起來拒絕他。相信喝醉的癡漢只會笨笨的以為有經過的暖男幫你擋下來。
### 草圖設計:
>
### 材料:
> Arduino UNO x 1
> 超音波感測器 x 1
> 超亮黃色LED x 3
> 蜂鳴器 x 1
> 大按鈕模組 x 1
> MG996 180度舵機 x 1
> 電池盒 x 1
> 加油棒 x 1
> 工地背心 x 1
> 一坨杜邦線
### 程式架構:
> 我上網參考了[Arduino多工執行緒的寫法](https://itw01.com/FJHCJE3.html),因為我們需要同時執行兩項任務,分別是超音波感測器搭配LED和蜂鳴器以及按鈕搭配伺服馬達。這是我第一次寫多工執行,跟小時候玩樂高寫得非常不一樣,其實蠻好玩的。有點像是把任務包成function的概念,並同時執行多個函式。
>以下是我的程式碼~~
``` c++=
#include <SCoop.h>
#include "pitches.h"
#include <Servo.h>
Servo myServo;
int pos = 0;
int Button = 4;
int count = 0;
int TRIGPIN = 12; // Pin to send trigger pulse
int ECHOPIN = 13; // Pin to receive echo pulse
int LED = 2;
int Buzzer = 3;
int melody[] = {NOTE_C4, NOTE_C4};
int noteDurations[] = {8, 8};
defineTask (Distance);
void Distance::setup() {
//Serial.begin(9600);
pinMode(ECHOPIN, INPUT);
pinMode(TRIGPIN, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(Button, INPUT);
}
void Distance::loop() {
digitalWrite(TRIGPIN, LOW); // Set the trigger pin to low for 2us
delayMicroseconds(2);
digitalWrite(TRIGPIN, HIGH); // Send a 10uS high to trigger ranging
delayMicroseconds(10);
digitalWrite(TRIGPIN, LOW); // Send pin low again
int distance = pulseIn(ECHOPIN, HIGH); // Read in times pulse
distance = distance/58; // Calculate distance (in cm) from time of pulse
//Serial.println(distance);
sleep(50);
if(distance <= 10){
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
sleep(200);
for (int thisNote = 0; thisNote < 2; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(Buzzer, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
sleep(pauseBetweenNotes);
// stop the tone playing:
noTone(Buzzer);
}
}
else{
digitalWrite(LED, LOW);
}
}
defineTask(Hand)
void Hand::setup(){
Serial.begin(9600);
myServo.attach(9);
pinMode(Button, INPUT);
}
void Hand::loop(){
if(digitalRead(Button) == HIGH){
count++;
Serial.println(count);
sleep(50);
}
if(count % 2 == 0){
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myServo.write(pos); // tell servo to go to position in variable 'pos'
sleep(10); // waits 10 ms for the servo to reach the position
}
myServo.write(180);
}
else{
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
// in steps of 1 degree
myServo.write(pos); // tell servo to go to position in variable 'pos'
sleep(10); // waits 10 ms for the servo to reach the position
}
myServo.write(0);
}
}
void setup(){
mySCoop.start();
}
void loop(){
yield();
}
```
### 遇到的困難:(
#### 已解決
>**伺服馬達一直不轉!!!**
>後來發現好像是電壓不夠,所以跑去買了外接的電池盒就順利解決了!但我還是覺得很奇怪,MG996的工作電壓明明是4.8~7.2V,理論上5V是可以運作的。
#### 未解決(需要幫忙的地方)
>**伺服馬達不聽話!**
> 我宣告了一個叫做count的變數用來計算按按鈕的次數,當count是偶數的時候,伺服馬達會轉到0度,奇數時則轉到180度。
> 但是一切卻不如我預期:(
> 偶數的時候馬達可以乖乖地轉到0度,但是奇數時,馬達就會一直轉到180再轉回來,而且一直重複!!!明明奇數跟偶數的程式碼都長一樣嗚嗚嗚...
>**按鈕感應不靈敏!**
>可能要試試看接pull-up電路來避免floating訊號,但...都還沒讀書,所以先擺著哈哈哈。
### 影片講解
>以下是我拍的簡單介紹影片,裡面也有提到我所遇到的問題~
{%youtube _ooPuL86Dus %}