抢红包机器人解题报告

前言

这次的这个抢红包机器人是某天果壳的人说他们在策划一个这样的活动,然后我当时觉得很有意思就说要不和柴火的会员做一个吧,但是问题来了,就是这个活动办的时候我已经不在深圳了,然后最近要过年,也不是有很多会员过来。。。所以基本上只有杜传和我一直在做这个项目。(这里一定要感谢下杜传,我总结了下,基本上和你做东西的时候就没顺利的做出来过-_-!!!!)

先介绍下果壳提供了一个他们的机器人的demo,大致上,是张这个样子的:

我当时的感觉就是这太低效了,而且可靠性也有点问题。然后我想起了大约是去年的时候,当时流传过一个这样的东西。。

总的来说,他用光敏电阻识别是不是有树枝落下来,然后决定点击屏幕左边还是右边。这是他的项目的地址https://github.com/vheun/ArduinoPlaysTimberman
还有电路连接图。。。不得不说这个原作真的是。。。什么都没有写。。原理步骤一概没有,只有arduino程序。。。

模仿手指触摸屏幕

最初杜传和我的计划是用铜箔或者锡纸,柴火的铜箔有点窄,要几个拼起来才行,然后我们订了必胜客。。。(不知道给报销不)


但是最后发现有些不好用,最初因为我们发现大量的时候屏幕被按下但是没有抬起来,所以我们怀疑可能是导线太长,屏幕把导线识别成了手指,所以我们剪短了导线,但是后来发现成功率还是只有50%左右。。。后来杜传微信发了我一个youtube连接,发现有另外一个人做了一个类似的东西,用的是硬币,我在想也有可能是我们之前做的东西没有重量,所以有些接触不良。

然后改完方案以后成功率上升不少,大致就是这样的。。。


然而最后还是不行,工作的时候不稳定,就是不知道什么时候就会不工作。然后在过年那天晚上终于让我爹帮我做出来了。。。说起来我爸真的是一个神奇的人物设定,具体的以后有机会再慢慢说吧。。。
总的来说,我之前觉得因为人体是一个导体,所以连接屏幕的部分一定要是一个导体,而铜箔纸常见的都是单面的,另外一面是不导电的胶,所以如果我把胶贴在屏幕上的话应该是不起作用的,但是事实上其实因为屏幕是电容屏,电信号是交流的,所以中间有一部分是绝缘体也是可以通过的。。。最后就是直接把铜箔粘上去就行了。。。

传感器布局

恩,然后开始做传感部分,基本上就是用了光敏电阻,然后用蓝丁胶粘在屏幕上,下面是我测试的一些数据,我选取了屏幕上的5个点,分布如下图。


在聊天窗口和点开红包的两个页面

显示结果的页面

各种情况下传感器的数值变化

这次我第一次用了早就听说过的firmata,可以给processing写代码然后processing控制arduino对应的引脚,具体可以看这里https://github.com/firmata
然后我发现firmata不能通过串口绘图,而我需要实时的知道对应ADC数值,然后又找到这个基于firmata制作的processing程序arduinoscope,github的地址是https://github.com/konsumer/arduinoscope

收到一个红包
抢红包页面
抢红包页面(没有)
结果页面(全白)
收到一个红包

可以看到变化还是非常明显的,不过记得要把屏幕亮度调到最高,不然可能会因为环境光屏幕自动调低所有的亮度导致误差。。
(这个图和我最终使用的传感器布局可能有些不同,主要是为了体现传感器在不同页面下的数值)

电路连接

程序

所有define里sensor_val的部分都要在每次把传感器取下来后再次运行前标定,val1、2、3分别为三个画面电阻的阻值。
/*

--------------------------------------
|                                    |
|                                    |
|  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:写标题的时候突然想起来这个解题报告这个名字,当初学OI的时候没做一道题都把思路写下来,觉得特别有成就感,更神奇的地方是我好像基本上都写在了qq空间。。。那以后5、6年的时间没有以这个词为标题了。。。好像这次还挺合适这个题目的。。。

UPDATE:
鲁大师的人说想让我再做一个,时隔一年,把坑又重踩了一边。。。。
新的心得是,屏幕有一个防水算法,就是如果遇到了一个东西放在屏幕上发现一直是按下不能抬起来的话,那么说明屏幕把他识别成了水,关闭屏幕重开就好了。

然后迭代了一版,现在只需要三个传感器就行了。然后开机会自校准。

/*
release note
v2: 精简了传感器的数量


---------------------
---------------------
2
---------------------
---------------------
1
---------------------

| |
| |
| 3 |
| |

---------------------
---------------------
2
---------------------
---------------------
1
---------------------

  收到  打开  结果  等待

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;
}

目前的样子是这样的。


图片发自简书App
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容