# 雄中生科作業(自主練習)
## 題目
請使用 [TinkerCAD](https://www.tinkercad.com/) ,建立一個新設計,製作一個電路和程式控制的怪獸存錢筒。
假設機構部分已經完成,請接著完成線路和程式的部分,用一塊 Arduino 完成此作品。
它可以偵測前方20公分內有錢幣的(20分)(一個超音波顯示器)
進行兩隻手的轉動
進而把錢幣吃進來(30分)(兩個伺服馬達方向相對)
而且錢幣進來的時候可以發出一段小音樂
(20分)(音符不超過10個)
搭配錢幣掉下去可以在七段顯示器上顯示數量
(30分)(顯示器可以亮起來但無法計數的話可得10分)
## 70分版本
### 電路設計

### 程式碼
```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 歐姆

### 程式碼
```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 移位寄存器。

### 程式碼
```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 %}