前言
這次的這個(gè)搶紅包機(jī)器人是某天果殼的人說他們?cè)诓邉澮粋€(gè)這樣的活動(dòng)蝗岖,然后我當(dāng)時(shí)覺得很有意思就說要不和柴火的會(huì)員做一個(gè)吧碉输,但是問題來了跟继,就是這個(gè)活動(dòng)辦的時(shí)候我已經(jīng)不在深圳了密浑,然后最近要過年蛙婴,也不是有很多會(huì)員過來。肴掷。敬锐。所以基本上只有杜傳和我一直在做這個(gè)項(xiàng)目。(這里一定要感謝下杜傳呆瞻,我總結(jié)了下台夺,基本上和你做東西的時(shí)候就沒順利的做出來過-_-!!!!)
先介紹下果殼提供了一個(gè)他們的機(jī)器人的demo,大致上痴脾,是張這個(gè)樣子的:
我當(dāng)時(shí)的感覺就是這太低效了颤介,而且可靠性也有點(diǎn)問題。然后我想起了大約是去年的時(shí)候赞赖,當(dāng)時(shí)流傳過一個(gè)這樣的東西滚朵。。
總的來說前域,他用光敏電阻識(shí)別是不是有樹枝落下來辕近,然后決定點(diǎn)擊屏幕左邊還是右邊。這是他的項(xiàng)目的地址https://github.com/vheun/ArduinoPlaysTimberman
還有電路連接圖匿垄。移宅。归粉。不得不說這個(gè)原作真的是。漏峰。糠悼。什么都沒有寫。浅乔。原理步驟一概沒有倔喂,只有arduino程序。靖苇。席噩。
模仿手指觸摸屏幕
最初杜傳和我的計(jì)劃是用銅箔或者錫紙,柴火的銅箔有點(diǎn)窄顾复,要幾個(gè)拼起來才行班挖,然后我們訂了必勝客。芯砸。。(不知道給報(bào)銷不)
但是最后發(fā)現(xiàn)有些不好用给梅,最初因?yàn)槲覀儼l(fā)現(xiàn)大量的時(shí)候屏幕被按下但是沒有抬起來假丧,所以我們懷疑可能是導(dǎo)線太長(zhǎng),屏幕把導(dǎo)線識(shí)別成了手指动羽,所以我們剪短了導(dǎo)線包帚,但是后來發(fā)現(xiàn)成功率還是只有50%左右。运吓。渴邦。后來杜傳微信發(fā)了我一個(gè)youtube連接,發(fā)現(xiàn)有另外一個(gè)人做了一個(gè)類似的東西拘哨,用的是硬幣谋梭,我在想也有可能是我們之前做的東西沒有重量,所以有些接觸不良倦青。
然后改完方案以后成功率上升不少瓮床,大致就是這樣的。产镐。隘庄。
然而最后還是不行,工作的時(shí)候不穩(wěn)定癣亚,就是不知道什么時(shí)候就會(huì)不工作丑掺。然后在過年那天晚上終于讓我爹幫我做出來了。述雾。街州。說起來我爸真的是一個(gè)神奇的人物設(shè)定蓬豁,具體的以后有機(jī)會(huì)再慢慢說吧。菇肃。地粪。
總的來說,我之前覺得因?yàn)槿梭w是一個(gè)導(dǎo)體琐谤,所以連接屏幕的部分一定要是一個(gè)導(dǎo)體蟆技,而銅箔紙常見的都是單面的,另外一面是不導(dǎo)電的膠斗忌,所以如果我把膠貼在屏幕上的話應(yīng)該是不起作用的质礼,但是事實(shí)上其實(shí)因?yàn)槠聊皇请娙萜粒娦盘?hào)是交流的织阳,所以中間有一部分是絕緣體也是可以通過的眶蕉。。唧躲。最后就是直接把銅箔粘上去就行了造挽。。弄痹。
傳感器布局
恩饭入,然后開始做傳感部分,基本上就是用了光敏電阻肛真,然后用藍(lán)丁膠粘在屏幕上谐丢,下面是我測(cè)試的一些數(shù)據(jù),我選取了屏幕上的5個(gè)點(diǎn)蚓让,分布如下圖乾忱。
各種情況下傳感器的數(shù)值變化
這次我第一次用了早就聽說過的firmata,可以給processing寫代碼然后processing控制arduino對(duì)應(yīng)的引腳历极,具體可以看這里https://github.com/firmata
然后我發(fā)現(xiàn)firmata不能通過串口繪圖窄瘟,而我需要實(shí)時(shí)的知道對(duì)應(yīng)ADC數(shù)值,然后又找到這個(gè)基于firmata制作的processing程序arduinoscope执解,github的地址是https://github.com/konsumer/arduinoscope
可以看到變化還是非常明顯的寞肖,不過記得要把屏幕亮度調(diào)到最高,不然可能會(huì)因?yàn)榄h(huán)境光屏幕自動(dòng)調(diào)低所有的亮度導(dǎo)致誤差衰腌。新蟆。
(這個(gè)圖和我最終使用的傳感器布局可能有些不同,主要是為了體現(xiàn)傳感器在不同頁面下的數(shù)值)
電路連接
程序
所有define里sensor_val的部分都要在每次把傳感器取下來后再次運(yùn)行前標(biāo)定右蕊,val1琼稻、2、3分別為三個(gè)畫面電阻的阻值饶囚。
/*
--------------------------------------
| |
| |
| 5 |
| |
| 3 |
| --------------------- |
| | | |
| | | |
| | | |
| --------------------- |
| |
| |
| --------------------- |
| | | 4 |
| | | |
| | | |
| --------------------- |
| |
| |
| --------------------- |
| | | |
| | 1 | 2 |
| | | |
| --------------------- |
| |
--------------------------------------
*/
#define STATUS_ERRO -1
#define STATUS_RECV 1
#define STATUS_OPEN 2
#define STATUS_RSUT 3
#define STATUS_WAIT 4
#define SENSOR_PIN1 A4
#define SENSOR_PIN2 A3
#define SENSOR_PIN3 A2
#define SENSOR_PIN4 A1
#define SENSOR_PIN5 A0
#define TOUCH_PIN1 4
#define TOUCH_PIN2 3
#define TOUCH_PIN3 2
#define SENSOR1_VAL1 697
#define SENSOR1_VAL2 724
#define SENSOR1_VAL3 549
#define SENSOR1_VAL4 567
#define SENSOR2_VAL1 626
#define SENSOR2_VAL2 711
#define SENSOR2_VAL3 559
#define SENSOR2_VAL4 649
#define SENSOR3_VAL1 962
#define SENSOR3_VAL2 724
#define SENSOR3_VAL3 596
#define SENSOR4_VAL1 993
#define SENSOR4_VAL2 993
#define SENSOR4_VAL3 645
#define SENSOR5_VAL1 945
#define SENSOR5_VAL2 693
#define SENSOR5_VAL3 543
#define SENSOR_THRESHOLD 30
void setup()
{
pinMode(SENSOR_PIN1, INPUT);
pinMode(SENSOR_PIN2, INPUT);
pinMode(SENSOR_PIN3, INPUT);
pinMode(SENSOR_PIN4, INPUT);
pinMode(SENSOR_PIN5, INPUT);
pinMode(TOUCH_PIN1, OUTPUT);
pinMode(TOUCH_PIN2, OUTPUT);
pinMode(TOUCH_PIN3, OUTPUT);
digitalWrite(TOUCH_PIN1, LOW);
digitalWrite(TOUCH_PIN2, LOW);
digitalWrite(TOUCH_PIN3, LOW);
Serial.begin(115200);
}
void loop()
{
switch (getStatus()) {
case STATUS_WAIT:
new_come = 1;
break;
case STATUS_RECV:
touchScreen(TOUCH_PIN1);
delay(500);
break;
case STATUS_OPEN:
touchScreen(TOUCH_PIN2);
delay(500);
break;
case STATUS_RSUT:
touchScreen(TOUCH_PIN3);
delay(1000);
break;
}
delay(100);
}
void touchScreen(int pinNum){
digitalWrite(pinNum, HIGH);
delay(150);
digitalWrite(pinNum, LOW);
delay(100);
}
int getStatus(){
int sensor_value1,sensor_value2,sensor_value3,sensor_value4,sensor_value5;
sensor_value1 = analogRead(SENSOR_PIN1);
sensor_value2 = analogRead(SENSOR_PIN2);
sensor_value3 = analogRead(SENSOR_PIN3);
sensor_value4 = analogRead(SENSOR_PIN4);
sensor_value5 = analogRead(SENSOR_PIN5);
if((abs(sensor_value1 - SENSOR1_VAL1) < SENSOR_THRESHOLD) &&
(abs(sensor_value2 - SENSOR2_VAL1) < SENSOR_THRESHOLD) &&
(abs(sensor_value4 - SENSOR4_VAL1) < SENSOR_THRESHOLD))
{
Serial.println("STATUS_RECV");
return STATUS_RECV;
}
if((abs(sensor_value2 - SENSOR2_VAL2) < SENSOR_THRESHOLD) &&
(abs(sensor_value3 - SENSOR3_VAL2) < SENSOR_THRESHOLD))
{
Serial.println("STATUS_OPEN");
return STATUS_OPEN;
}
if((abs(sensor_value3 - SENSOR3_VAL3) < SENSOR_THRESHOLD) &&
(abs(sensor_value4 - SENSOR4_VAL3) < SENSOR_THRESHOLD) &&
(abs(sensor_value5 - SENSOR5_VAL3) < SENSOR_THRESHOLD))
{
Serial.println("STATUS_RSUT");
return STATUS_RSUT;
}
if((abs(sensor_value1 - SENSOR1_VAL4) < SENSOR_THRESHOLD) &&
(abs(sensor_value2 - SENSOR2_VAL4) < SENSOR_THRESHOLD) &&
(abs(sensor_value4 - SENSOR4_VAL1) < SENSOR_THRESHOLD))
{
Serial.println("STATUS_WAIT");
return STATUS_WAIT;
}
Serial.print(sensor_value1);
Serial.print(" , ");
Serial.print(sensor_value2);
Serial.print(" , ");
Serial.print(sensor_value3);
Serial.print(" , ");
Serial.print(sensor_value4);
Serial.print(" , ");
Serial.println(sensor_value5);
return STATUS_ERRO;
}
PS:寫標(biāo)題的時(shí)候突然想起來這個(gè)解題報(bào)告這個(gè)名字帕翻,當(dāng)初學(xué)OI的時(shí)候沒做一道題都把思路寫下來鸠补,覺得特別有成就感,更神奇的地方是我好像基本上都寫在了qq空間嘀掸。紫岩。。那以后5睬塌、6年的時(shí)間沒有以這個(gè)詞為標(biāo)題了泉蝌。。揩晴。好像這次還挺合適這個(gè)題目的勋陪。。硫兰。
UPDATE:
魯大師的人說想讓我再做一個(gè)诅愚,時(shí)隔一年,把坑又重踩了一邊劫映。违孝。瓤狐。。
新的心得是饲窿,屏幕有一個(gè)防水算法剪芍,就是如果遇到了一個(gè)東西放在屏幕上發(fā)現(xiàn)一直是按下不能抬起來的話,那么說明屏幕把他識(shí)別成了水鉴逞,關(guān)閉屏幕重開就好了。
然后迭代了一版,現(xiàn)在只需要三個(gè)傳感器就行了衅鹿。然后開機(jī)會(huì)自校準(zhǔn)。
/*
release note
v2: 精簡(jiǎn)了傳感器的數(shù)量
--------------------- | ||
--------------------- | ||
2 | ||
--------------------- | ||
--------------------- | ||
1 | ||
--------------------- | ||
| |
| |
| 3 |
| |
--------------------- | ||
--------------------- | ||
2 | ||
--------------------- | ||
--------------------- | ||
1 | ||
--------------------- | ||
收到 打開 結(jié)果 等待
1 紅 黑 白 黑
2 黑 紅 白 黑
3 -- 黑 紅 黑
*/
define STATUS_ERRO -1
define STATUS_RECV 1
define STATUS_OPEN 2
define STATUS_RSUT 3
define STATUS_WAIT 4
define SENSOR_PIN1 A4
define SENSOR_PIN2 A3
define SENSOR_PIN3 A2
define TOUCH_PIN1 3
define TOUCH_PIN2 4
define TOUCH_PIN3 5
define CALI_PIN 8
define LED_PIN 13
define SENSOR_THRESHOLD 30
int SENSOR1_VAL1 = 0;
int SENSOR1_VAL2 = 0;
int SENSOR1_VAL3 = 0;
int SENSOR1_VAL4 = 0;
int SENSOR2_VAL1 = 0;
int SENSOR2_VAL2 = 0;
int SENSOR2_VAL3 = 0;
int SENSOR2_VAL4 = 0;
int SENSOR3_VAL1 = 0;
int SENSOR3_VAL2 = 0;
int SENSOR3_VAL3 = 0;
int SENSOR3_VAL4 = 0;
void setup()
{
pinMode(SENSOR_PIN1, INPUT);
pinMode(SENSOR_PIN2, INPUT);
pinMode(SENSOR_PIN3, INPUT);
pinMode(TOUCH_PIN1, OUTPUT);
pinMode(TOUCH_PIN2, OUTPUT);
pinMode(TOUCH_PIN3, OUTPUT);
digitalWrite(TOUCH_PIN1, LOW);
digitalWrite(TOUCH_PIN2, LOW);
digitalWrite(TOUCH_PIN3, LOW);
Serial.begin(115200);
Serial.println("cali begin");
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(CALI_PIN, INPUT);
digitalWrite(CALI_PIN, HIGH);
digitalWrite(LED_PIN, HIGH);
while(digitalRead(CALI_PIN) == HIGH);
digitalWrite(LED_PIN, LOW);
SENSOR1_VAL1 = analogRead(SENSOR_PIN1);
SENSOR2_VAL1 = analogRead(SENSOR_PIN2);
SENSOR3_VAL1 = analogRead(SENSOR_PIN3);
delay(1000);
digitalWrite(LED_PIN, HIGH);
while(digitalRead(CALI_PIN) == HIGH);
digitalWrite(LED_PIN, LOW);
SENSOR1_VAL2 = analogRead(SENSOR_PIN1);
SENSOR2_VAL2 = analogRead(SENSOR_PIN2);
SENSOR3_VAL2 = analogRead(SENSOR_PIN3);
delay(1000);
digitalWrite(LED_PIN, HIGH);
while(digitalRead(CALI_PIN) == HIGH);
digitalWrite(LED_PIN, LOW);
SENSOR1_VAL3 = analogRead(SENSOR_PIN1);
SENSOR2_VAL3 = analogRead(SENSOR_PIN2);
SENSOR3_VAL3 = analogRead(SENSOR_PIN3);
delay(1000);
digitalWrite(LED_PIN, HIGH);
while(digitalRead(CALI_PIN) == HIGH);
digitalWrite(LED_PIN, LOW);
SENSOR1_VAL4 = analogRead(SENSOR_PIN1);
SENSOR2_VAL4 = analogRead(SENSOR_PIN2);
SENSOR3_VAL4 = analogRead(SENSOR_PIN3);
delay(1000);
digitalWrite(LED_PIN, LOW);
Serial.println("inin finished");
}
void loop()
{
switch (getStatus()) {
case STATUS_WAIT:
break;
case STATUS_RECV:
touchScreen(TOUCH_PIN1);
delay(500);
break;
case STATUS_OPEN:
touchScreen(TOUCH_PIN2);
delay(500);
break;
case STATUS_RSUT:
touchScreen(TOUCH_PIN3);
delay(1000);
break;
}
delay(100);
}
void touchScreen(int pinNum){
Serial.print("Pressing No.");
Serial.println(pinNum);
digitalWrite(pinNum, HIGH);
delay(150);
digitalWrite(pinNum, LOW);
delay(100);
}
int getStatus(){
int sensor_value1,sensor_value2,sensor_value3;
sensor_value1 = analogRead(SENSOR_PIN1);
sensor_value2 = analogRead(SENSOR_PIN2);
sensor_value3 = analogRead(SENSOR_PIN3);
Serial.print(sensor_value1);
Serial.print(" , ");
Serial.print(sensor_value2);
Serial.print(" , ");
Serial.print(sensor_value3);
if((abs(sensor_value1 - SENSOR1_VAL1) < SENSOR_THRESHOLD) &&
(abs(sensor_value2 - SENSOR2_VAL1) < SENSOR_THRESHOLD))
{
Serial.println();
Serial.println("STATUS_RECV");
return STATUS_RECV;
}
if((abs(sensor_value1 - SENSOR1_VAL2) < SENSOR_THRESHOLD) &&
(abs(sensor_value2 - SENSOR2_VAL2) < SENSOR_THRESHOLD) &&
(abs(sensor_value3 - SENSOR3_VAL2) < SENSOR_THRESHOLD))
{
Serial.println();
Serial.println("STATUS_OPEN");
return STATUS_OPEN;
}
if((abs(sensor_value1 - SENSOR1_VAL3) < SENSOR_THRESHOLD) &&
(abs(sensor_value2 - SENSOR2_VAL3) < SENSOR_THRESHOLD) &&
(abs(sensor_value3 - SENSOR3_VAL3) < SENSOR_THRESHOLD))
{
Serial.println();
Serial.println("STATUS_RSUT");
return STATUS_RSUT;
}
if((abs(sensor_value1 - SENSOR1_VAL4) < SENSOR_THRESHOLD) &&
(abs(sensor_value2 - SENSOR2_VAL4) < SENSOR_THRESHOLD) &&
(abs(sensor_value3 - SENSOR3_VAL4) < SENSOR_THRESHOLD))
{
Serial.println();
Serial.println("STATUS_WAIT");
return STATUS_WAIT;
}
Serial.print(" ");
Serial.print("SENSOR_VAL1: ");
Serial.print(SENSOR1_VAL1);
Serial.print(" , ");
Serial.print(SENSOR2_VAL1);
Serial.print(" , ");
Serial.print(SENSOR3_VAL1);
Serial.print(" ; ");
Serial.print("SENSOR_VAL2: ");
Serial.print(SENSOR1_VAL2);
Serial.print(" , ");
Serial.print(SENSOR2_VAL2);
Serial.print(" , ");
Serial.print(SENSOR3_VAL2);
Serial.print(" ; ");
Serial.print("SENSOR_VAL3: ");
Serial.print(SENSOR1_VAL3);
Serial.print(" , ");
Serial.print(SENSOR2_VAL3);
Serial.print(" , ");
Serial.print(SENSOR3_VAL3);
Serial.print(" ; ");
Serial.print("SENSOR_VAL4: ");
Serial.print(SENSOR1_VAL4);
Serial.print(" , ");
Serial.print(SENSOR2_VAL4);
Serial.print(" , ");
Serial.print(SENSOR3_VAL4);
Serial.println();
return STATUS_ERRO;
}
目前的樣子是這樣的过咬。