熱門資訊
選擇困難癥福音: DIY“囚徒困境”搶答器
來源:3XMaker 發布時間:2019年03月26日選擇困難癥福音: DIY“囚徒困境”搶答器
0.序言
本作品是和幾名工業設計專業的同學在十一月一起做的一個 workshop 產物,有相關的 Arduino 課程。
主要的分工,我來寫代碼,調試程序,排布器件。工業設計的同學做了模型和實體。
這篇文章是我稍帶演繹的一篇紀錄~
成品做出來好漂亮,大家都是心靈手巧的人啊~
1.理念和需求
workshop 的主題是做一個兒童向的互動玩具,用于搶答情景。我覺得這個情景不局限于自身,在以下場景中:
“誰去拿快遞?”
“誰叫外賣?”
“誰來埋單?”
需求如下:
搶答場景:定然有兩個按鍵輸入。用于比誰更快速
輸出的指示: 有一個輸出的燈光指示,用于給予開始搶答的信號。
輸出的指示: 有若干計分燈光,用于計分。這部分和工設聯動,設計成了一個燈光爬山的效果。
勝利條件: 誰搶到山頂的“燈”誰就勝利!
輸入: 用于resetstart
2.作品設計
2.1 外觀設計
外觀是一座山,模擬兩個人攀比登峰,誰先到山頂,誰便勝利。手工制作實體,和輸入按鍵。可以看到我排的led燈在山的兩側
2.2 硬件設計
主控當然選用 Arduino,因為 workshop要求就是用它來當主控。
輸入我選用了3端入口,為了節省不太富裕的io口。一個用于 startreset,另外兩個是搶答端。
輸出的話依賴燈光。選用了4+4+1的設計,正好用足了所有的io口。因為沒必要加外部元件用于專門的燈光管理。索性直接用 Arduino 驅動。
另外說一句,pullup 功能可以自帶拉高點評。因此輸入端不需要人工布線拉高電平。
2.3 邏輯設計:
紅燈用于指示搶答。
狀態1:所有 led 跑馬燈,等待紅色按鈕輸入開始信號。
狀態2:開始搶答,紅燈亮起。若干秒后熄滅,開始按鈕搶答輸入
狀態3:成功搶答的一端判斷為勝利。計數加1,藍燈或綠燈亮起。亮滿4個最終勝利
狀態4:重新循環狀態1
2.4 代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | /* 趴會兒Project項目集 http://steinslab.xyz/archives/752 No.002 詳見http://steinslab.xyz/archives/1008 囚徒困境搶答器-《命運女神的抉擇》 SPtuan@steinslab.xyz */
int A[4]={10,11,12,13}; int B[4]={6,7,8,9}; int info = 5; int Ain = 4; int Bin = 3; int Cin = 2; volatile int flag=0; int Aflag=0,Bflag=0,ix=0,jx=0; int Atemp=Aflag; int Btemp=Bflag;
void setup() { Serial.begin(9600); for(ix=0;ix<4;ix++) { pinMode(A[ix],OUTPUT); digitalWrite(A[ix],LOW); pinMode(B[ix],OUTPUT); digitalWrite(B[ix],LOW); } pinMode(Ain,INPUT_PULLUP); pinMode(Bin,INPUT_PULLUP); pinMode(Cin,INPUT_PULLUP); pinMode(info,OUTPUT); digitalWrite(info,LOW); attachInterrupt(0,signal0,RISING); }
void signal0() { if(flag==0) flag = 1; }
void wait() { digitalWrite(info,HIGH); delay(3000); digitalWrite(info,LOW); }
void display0() { digitalWrite(B[Bflag-1],HIGH); digitalWrite(A[Aflag-1],HIGH); }
void display1() { if(Aflag==4) { for(ix=0;ix<3;ix++) { for(jx=0;jx<4;jx++) { digitalWrite(A[jx],HIGH); digitalWrite(B[jx],LOW); } delay(500); for(jx=0;jx<4;jx++) { digitalWrite(A[jx],LOW); } delay(500); } }
else if(Bflag==4) { for(ix=0;ix<3;ix++) { for(jx=0;jx<4;jx++) { digitalWrite(B[jx],HIGH); digitalWrite(A[jx],LOW); } delay(500); for(jx=0;jx<4;jx++) { digitalWrite(B[jx],LOW); } delay(500); } } } void loop() { Atemp=Aflag=Btemp=Bflag=0; do { for(ix=0;ix<4;ix++) { digitalWrite(A[ix],HIGH); digitalWrite(B[ix],HIGH); delay(300); if(flag==1) break; } for(ix=0;ix<4;ix++) { digitalWrite(A[ix],LOW); digitalWrite(B[ix],LOW); delay(300); if(flag==1) break;
} }while(flag==0); for(ix=0;ix<4;ix++) { digitalWrite(A[ix],LOW); digitalWrite(B[ix],LOW);
} delay(1000); do { do{ wait(); Atemp=Aflag; Btemp=Bflag; do{ if(digitalRead(Ain)==LOW) { delay(20); if(digitalRead(Ain)==LOW) Aflag++; Serial.print("Aflag"); while(digitalRead(Ain)==LOW); } else if(digitalRead(Bin)==LOW) { delay(20); if(digitalRead(Bin)==LOW) Bflag++; Serial.print("Bflag"); while(digitalRead(Bin)==LOW); } }while((Atemp==Aflag)&&(Btemp==Bflag)); display0(); if(Bflag<4) digitalWrite(B[3],LOW); if(Aflag<4) digitalWrite(A[3],LOW);
}while((Aflag!=4)&&(Bflag!=4)); display1(); flag = 0; }while(flag==1); } |
注:后來我也思考了一下。這個代碼還是有相當的改進余地的。
對于搶答按鈕的輸入,使用了循環掃描的方法,勢必會有一個優先級的問題,一旦一個持續按下,就會觸發 bug 必贏。
可以改用中斷,套用幾個 flag 變量,綜合判斷真正在搶答器結束后按擊的人。或者提前按下的人直接判負。
3 展示
3.1 成果
我和小崔在原形上就玩得不亦樂乎……生生玩了一晚上……
作品最后外觀是相當漂亮的~
工設同學做的項目記錄總是非常漂亮的,下面是制作過程若干圖片。
固定 LED。
在面包板上調試LED。
制作搶答按鈕。
連接導線。
在紙板上布線,固定。
將LED遷移到了做好的紙板上。
純手工剪紙技藝,做最后的裝飾。
大功告成!

南京合越智能,增強智造,增強感知,增強交互!
業務合作
(我們會第一時間與您聯系)聯系方式
- 微信:13815863530(手機同號)
- QQ:38260484
- 3XMaker@163.com