# 不要靠近我~留情面拒絕背心!!! 我是有勛,這週材料都在我這! 所以我負責把程式寫好,下周交給亮穎組裝並美化~~ 以下是目前的專案進度: ### 功能介紹: >![](https://i.imgur.com/LEEsHaV.png) >當有喝醉的痴漢想抱你的時候,留情面拒絕器會在癡漢太靠近你的時候**閃燈及發出警報聲**提醒你! >這時,你可以偷偷按下手上的按鈕,就會有一隻假手伸起來拒絕他。相信喝醉的癡漢只會笨笨的以為有經過的暖男幫你擋下來。 ### 草圖設計: >![](https://i.imgur.com/IsDrQQV.png) ### 材料: > 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 %}