### 第十四周周記
- 專案名稱:
感知變奏之旅
- 專案理念
一個能根據周遭環境變化的裝置,裝置有自己的性格,每個階梯偵測特定環境變數然後自在的變化,想讓使用者觀察的入神,想盡辦法在與裝置互動的過程中釐清他的脈絡,實則難以實現
- 硬體設備
- 使用材料
- 360 度伺服馬達 x 5
- 亮度感測器 x 1
- 溫溼度感測器 x 1
- 電路板
- 漆包線
- 螺絲釘、螺絲帽
- 壓克力板
- 接線圖 ( 電路板焊接 )
- 原本的線路
![原本的線](https://hackmd.io/_uploads/HksR_xG86.png)
由於使用五顆馬達和兩顆感測器,整體線路較為凌亂,因此改用電路板焊接重新整理線路,亦確保線路穩定不易脫落
- 後來的線路
![接線](https://hackmd.io/_uploads/H1N7txf8a.jpg)
- 齒輪 & pusher : 3D 列印
![齒輪](https://hackmd.io/_uploads/SkeG50ZLT.jpg)
使用他人專案提供的 3D 列印模型,然而每次列印出來的品質不一導致 pusher 無法伸進凹槽裡面或者無法被齒輪推動,後來透過使用砂紙沾水磨 pusher,上潤滑油,用小刀削凹槽等方式讓三者能相互搭配,之後再使用 M2 的螺絲與螺帽將其組裝在一起
- 盒子 : 雷切 ( 壓克力板 )
![盒子](https://hackmd.io/_uploads/rJGNqRWI6.jpg)
- 雷切圖
![盒子展開圖](https://hackmd.io/_uploads/S1ghzkzUa.png)
每邊多畫 3mm 的卡榫讓板子相接時更有著力點,然而當時太急著畫圖雷切而漏畫到階梯,盒子內部放齒輪組的地方也畫錯位置,因此後來改將齒輪組往上鎖在壓克力板上。板子本身原本想用三秒膠 + 小螺絲固定,然後來時間不夠的權衡下改用膠帶直接黏合
- 專案程式碼
```=c
#include "DHT.h"
#include "Servo.h"
// 光度
const int lightPin = A0;
// 溫溼度
#define DHTPIN 6
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE); // 溫溼度
// 馬達
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
// 樓梯
static int stairs[5] = {1,1,1,1,1};
float l_1, t_1, h_1, l_2, t_2, h_2;
// 位置
int location=0;
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0)+ millis()); // 使用類比引腳的讀數作為種子
dht.begin(); //初始化DHT
servo1.attach(9);
servo2.attach(10);
servo3.attach(11);
servo4.attach(12);
servo5.attach(13);
}
void moveMotor(int i, int randomValue, int rotate) {
if (rotate==0) // 上升
if (i==0) {
servo1.write(180);
}
else if (i==1) {
servo2.write(180);
}
else if (i==2) {
servo3.write(180);
}
else if (i==3) {
servo4.write(180);
}
else {
servo5.write(180);
}
else { //rotate=1下降
if (i==0) {
servo1.write(0);
}
else if (i==1) {
servo2.write(0);
}
else if (i==2) {
servo3.write(0);
}
else if (i==3) {
servo4.write(0);
}
else {
servo5.write(0);
}
}
delay(100*randomValue);
servo1.write(90);
servo2.write(90);
servo3.write(90);
servo4.write(90);
servo5.write(90);
}
void setLayer(int i, float first, float sec) {
int randomValue = random(1, 4);
int cur_s = stairs[i];
bool shouldMove = true;
if (first > sec) { // rotate=1下降
if (cur_s==1) {
moveMotor(i,randomValue,0); // 最底下改上升
stairs[i] = cur_s + randomValue;
}
else {
while (shouldMove) {
if (cur_s - randomValue >= 1) {
moveMotor(i,randomValue,1);
stairs[i] = cur_s - randomValue;
break;
}
else {
randomValue = random(1, 4);
}
}
}
}
else {
if (cur_s==5) {
moveMotor(i,randomValue,1); // 最上面改下降
stairs[i] = cur_s - randomValue;
}
else {
while (shouldMove) {
if (cur_s + randomValue <= 5) {
moveMotor(i,randomValue,0);
stairs[i] = cur_s + randomValue;
break;
}
else {
randomValue = random(1, 4);
}
}
}
}
Serial.print("stairs: ");
for (int i = 0; i < 5; i++) {
Serial.print(stairs[i]);
Serial.print(" ");
}
Serial.println();
delay(500);
if (stairs[location] == stairs[location+1]) {
location++ ;
}
Serial.print("location: ");
Serial.print(location);
Serial.println();
}
void handleLight(float l_1, float l_2) {
Serial.println("Layer 0: ");
setLayer(0,l_1, l_2);
delay(1000);
Serial.println("Layer 2: ");
setLayer(2,l_1, l_2);
delay(1000);
Serial.println("Layer 3: ");
setLayer(3,l_1, l_2);
delay(1000);
Serial.println("Layer 4: ");
setLayer(4,l_1, l_2);
delay(1000);
}
void handleTemp(float t_1, float t_2) {
Serial.println("Layer 1: ");
setLayer(1,t_1, t_2);
delay(1000);
Serial.println("Layer 4: ");
setLayer(4,t_1, t_2);
delay(1000);
}
void handleHumi(float h_1, float h_2) {
Serial.println("Layer 1: ");
setLayer(1,t_1, t_2);
delay(1000);
Serial.println("Layer 4: ");
setLayer(4,t_1, t_2);
delay(1000);
}
void loop()
{
// default
servo1.write(90);
servo2.write(90);
servo3.write(90);
servo4.write(90);
servo5.write(90);
l_1 = analogRead(lightPin); // 讀取光線感應器數據
h_1 = dht.readHumidity(); //取得濕度
t_1 = dht.readTemperature(); //取得溫度C
Serial.print("light1: ");
Serial.print(l_1);
Serial.print("\tHumidity1: ");
Serial.print(h_1);
Serial.print(" %\t");
Serial.print("Temperature1: ");
Serial.print(t_1);
Serial.println(" *C ");
if (l_1 - l_2 > 200 || l_2 - l_1 > 400) {
Serial.println("handleLight");
handleLight(l_2, l_1);
}
if (t_1 - t_2 > 5.0 || t_2 - t_1 > 5.0) {
Serial.println("handleTemp");
handleTemp(t_2, t_1);
}
if (h_1 - h_2 > 30.0 || h_2 - h_1 > 30.0) {
Serial.println("handleHumi");
handleHumi(h_2, h_1);
}
delay(3000);
l_2 = analogRead(lightPin); // 讀取光線感應器數據
h_2 = dht.readHumidity(); //取得濕度
t_2 = dht.readTemperature(); //取得溫度C
Serial.print("light2: ");
Serial.print(l_1);
Serial.print("\tHumidity2: ");
Serial.print(h_1);
Serial.print(" %\t");
Serial.print("Temperature2: ");
Serial.print(t_1);
Serial.println(" *C ");
if (l_2 - l_1 > 200 || l_1 - l_2 > 400) {
Serial.println("handleLight");
handleLight(l_1, l_2);
}
if (t_2 - t_1 > 3 || t_1 - t_2 > 3) {
Serial.println("handleTemp");
handleTemp(t_1, t_2);
}
if (h_2 - h_1 > 5 || h_1 - h_2 > 5) {
Serial.println("handleHumi");
handleHumi(h_1, h_2);
}
delay(3000);
}
```
- 成品
![S__10477590](https://hackmd.io/_uploads/SyZQqM38p.jpg)
@D-school五樓教室外
- demo 影片
[感知變奏之旅](https://youtu.be/tFItRj-V488?si=5Fi5_Z8c46Z9SYNN)