# 雄中生科作業(自主練習) ## 題目 請使用 [TinkerCAD](https://www.tinkercad.com/) ,建立一個新設計,製作一個電路和程式控制的怪獸存錢筒。 假設機構部分已經完成,請接著完成線路和程式的部分,用一塊 Arduino 完成此作品。 它可以偵測前方20公分內有錢幣的(20分)(一個超音波顯示器) 進行兩隻手的轉動 進而把錢幣吃進來(30分)(兩個伺服馬達方向相對) 而且錢幣進來的時候可以發出一段小音樂 (20分)(音符不超過10個) 搭配錢幣掉下去可以在七段顯示器上顯示數量 (30分)(顯示器可以亮起來但無法計數的話可得10分) ## 70分版本 ### 電路設計 ![](https://i.imgur.com/TbV97Yw.png) ### 程式碼 ```c= #include <Servo.h> // 超音波模組變數定義 const byte trigPin = 13; const int echoPin = 12; unsigned long during; // 儲存超音波模組時間 int distance; // 儲存硬幣距離 // 伺服馬達變數定義 const int servo_left_pin = 11; const int servo_right_pin = 10; Servo servo_left; Servo servo_right; // 蜂鳴器針腳定義 const int bebe_pin = 8; // 蜂鳴器旋律存檔 int melody[] = { 1568, 1760, 1976, 2093, 2349, 2093, 1976, 1760, 1568 }; // 蜂鳴器拍子存檔 int noteDurations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 2 }; int Distance() { // 距離偵測,回傳公分數 digitalWrite(trigPin, HIGH); // 觸發腳設定成高電位 delayMicroseconds(5); // 持續 5 微秒 digitalWrite(trigPin, LOW); // 觸發腳設定成低電位 during = pulseIn(echoPin, HIGH);// 傳回高脈衝的持續時間 return during / 58; // 轉換成公分單位 } void Melody(){ for (int thisNote = 0; thisNote < 9; thisNote++) { int noteDuration = 1000 / noteDurations[thisNote]; tone(bebe_pin, melody[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); noTone(bebe_pin); } } void setup() { // 開啟序列埠 Serial.begin(9600); // 超音波針腳設置 pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); //伺服馬達針腳設置 servo_left.attach(servo_left_pin); servo_right.attach(servo_right_pin); // 蜂鳴器針腳設置 pinMode(bebe_pin, OUTPUT); digitalWrite(bebe_pin, LOW); } void loop() { // 偵測硬幣距離 distance = Distance(); Serial.print("Distance = "); Serial.print(distance); Serial.print(" CM\n"); // 低於 20 公分啟動馬達 if(distance <= 20){ for(int i = 90; i >= 0; i=i-1){ servo_left.write(i); servo_right.write(180-i); delay(10); } delay(500); servo_left.write(90); servo_right.write(90); delay(10); Melody(); } } ``` ## 100分版本 ### 電路設計 圖中電阻為 220 歐姆 ![](https://i.imgur.com/xHpdJXS.png) ### 程式碼 ```c= #include <Servo.h> // 超音波模組變數定義 const byte trigPin = 13; const int echoPin = 12; unsigned long during; // 儲存超音波模組時間 int distance; // 儲存硬幣距離 // 硬幣數量儲存 int number = 0; // 伺服馬達變數定義 const int servo_left_pin = 11; const int servo_right_pin = 10; Servo servo_left; Servo servo_right; // 蜂鳴器針腳定義 const int bebe_pin = 8; // 蜂鳴器旋律存檔 int melody[] = { 1568, 1760, 1976, 2093, 2349, 2093, 1976, 1760, 1568 }; // 蜂鳴器拍子存檔 int noteDurations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 2 }; // 七段顯示器針腳資料 byte moniter_pin[8] = {0, 9, 2, 3, 4, 5, 6, 7}; bool moniter_data[10][8] = { {0, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 1, 0, 0, 0, 0}, {0, 1, 1, 0, 1, 1, 0, 1}, {0, 1, 1, 1, 1, 0, 0, 1}, {0, 0, 1, 1, 0, 0, 1, 1}, {0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 0, 1, 1} }; int Distance() { // 距離偵測,回傳公分數 digitalWrite(trigPin, HIGH); // 觸發腳設定成高電位 delayMicroseconds(5); // 持續 5 微秒 digitalWrite(trigPin, LOW); // 觸發腳設定成低電位 during = pulseIn(echoPin, HIGH);// 傳回高脈衝的持續時間 return during / 58; // 轉換成公分單位 } void Melody(){ // 播放聲音,不回傳資料 for (int thisNote = 0; thisNote < 9; thisNote++) { int noteDuration = 1000 / noteDurations[thisNote]; tone(bebe_pin, melody[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); noTone(bebe_pin); } } void Display(int num){ // 七段顯示器,不回傳資料 for(byte i=0;i<8;i++){ digitalWrite(moniter_pin[i], moniter_data[num][i]); } } void setup() { // 開啟序列埠 Serial.begin(9600); // 超音波針腳設置 pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); //伺服馬達針腳設置 servo_left.attach(servo_left_pin); servo_right.attach(servo_right_pin); // 蜂鳴器針腳設置 pinMode(bebe_pin, OUTPUT); digitalWrite(bebe_pin, LOW); // 七段顯示器針腳設置 for(int i=0;i<8;i++){ pinMode(moniter_pin[i], OUTPUT); } // 七段顯示器初始化 Display(0); } void loop() { // 偵測硬幣距離 distance = Distance(); Serial.print("Distance = "); Serial.print(distance); Serial.print(" CM\n"); // 低於 20 公分啟動馬達 if(distance <= 20){ for(int i = 90; i >= 0; i=i-1){ servo_left.write(i); servo_right.write(180-i); delay(10); } delay(500); servo_left.write(90); servo_right.write(90); delay(10); number++; if(number >= 10){ number = 0; } Display(number); Serial.print("number = "); Serial.print(number); Serial.print(" .\n"); Melody(); } } ``` ## 150分版本 ### 電路設計 圖中電阻均為 220 歐姆,黑色長方型電子零件為 74HC595 移位寄存器。 ![](https://i.imgur.com/iT44JIJ.png) ### 程式碼 ```c= #include <Servo.h> // 超音波模組變數定義 const byte trigPin = 13; const byte echoPin = 12; unsigned long during; // 儲存超音波模組時間 int distance; // 儲存硬幣距離 // 硬幣數量儲存 int number_right = 0; int number_left = 0; // 伺服馬達變數定義 const int servo_left_pin = 11; const int servo_right_pin = 10; Servo servo_left; Servo servo_right; // 蜂鳴器針腳定義 const int bebe_pin = 8; // 蜂鳴器旋律存檔 int melody[] = { 1568, 1760, 1976, 2093, 2349, 2093, 1976, 1760, 1568 }; // 蜂鳴器拍子存檔 int noteDurations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 2 }; // 七段顯示器針腳資料 bool moniter_data[10][8] = { {0, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 1, 0, 0, 0, 0}, {0, 1, 1, 0, 1, 1, 0, 1}, {0, 1, 1, 1, 1, 0, 0, 1}, {0, 0, 1, 1, 0, 0, 1, 1}, {0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 0, 1, 1} }; // 位移寄存器針腳 const int data_right = 2; const int big_right = 3; const int push_right = 4; const int data_left = 5; const int big_left = 6; const int push_left = 7; int Distance() { // 距離偵測,回傳公分數 digitalWrite(trigPin, HIGH); // 觸發腳設定成高電位 delayMicroseconds(5); // 持續 5 微秒 digitalWrite(trigPin, LOW); // 觸發腳設定成低電位 during = pulseIn(echoPin, HIGH);// 傳回高脈衝的持續時間 return during / 58; // 轉換成公分單位 } void Melody(){ // 播放聲音,不回傳資料 for (int thisNote = 0; thisNote < 9; thisNote++) { int noteDuration = 1000 / noteDurations[thisNote]; tone(bebe_pin, melody[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); noTone(bebe_pin); } } void Display_right(int num){ // 右邊七段顯示器,不回傳資料 digitalWrite(big_right, LOW); for(int i=7;i>=0;i--){ digitalWrite(push_right, LOW); digitalWrite(data_right, moniter_data[num][i]); digitalWrite(push_right, HIGH); } digitalWrite(big_right, HIGH); } void Display_left(int num){ // 左邊七段顯示器,不回傳資料 digitalWrite(big_left, LOW); for(int i=7;i>=0;i--){ digitalWrite(push_left, LOW); digitalWrite(data_left, moniter_data[num][i]); digitalWrite(push_left, HIGH); } digitalWrite(big_left, HIGH); } void setup() { // 開啟序列埠 Serial.begin(9600); // 超音波針腳設置 pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); //伺服馬達針腳設置 servo_left.attach(servo_left_pin); servo_right.attach(servo_right_pin); // 蜂鳴器針腳設置 pinMode(bebe_pin, OUTPUT); digitalWrite(bebe_pin, LOW); // 位移寄存器針腳設置 for(int i=2;i<8;i++){ pinMode(i, OUTPUT); } // 七段顯示器初始化 Display_right(0); Display_left(0); } void loop() { // 偵測硬幣距離 distance = Distance(); Serial.print("Distance = "); Serial.print(distance); Serial.print(" CM\n"); // 低於 20 公分啟動馬達 if(distance <= 20){ for(int i = 90; i >= 0; i=i-1){ servo_left.write(i); servo_right.write(180-i); delay(10); } delay(500); servo_left.write(90); servo_right.write(90); delay(10); number_right++; if(number_right >= 10){ number_right = 0; number_left++; if(number_left >= 10){ number_left = 0; } } Display_right(number_right); Display_left(number_left); Serial.print("number = "); Serial.print(number_left); Serial.print(number_right); Serial.print(" .\n"); Melody(); } } ``` ## 成果影片 {%youtube zVcAkGkszd4 %}