您现在的位置: 主页 > MCU > 单片机综合应用 > 单片机菜鸟自学记
本文所属标签:
为本文创立个标签吧:

单片机菜鸟自学记

来源:net 网络用户发布,如有版权联系网管删除 2018-08-19 

一天看到同学在玩节奏大师游戏,不知道为啥就想到用单片机自动玩这个。但是想想节奏大师这个游戏难操作且不好识别,于是想到相似的别踩白块儿这个游戏。

一有想法马上开始做,大家都在紧张的备战期末考试,我这是冒着挂科的风险在玩单片机啊!最先想到的是用Arduino做,这样最快。于是就开始做吧:

花了一晚上焊了个板子

单片机菜鸟自学记

用四个光敏电阻检测游戏里的黑块

单片机菜鸟自学记

一开始打算用舵机去动作触屏,后来觉得舵机太慢了,就改成了电磁铁(把继电器拆了得到~)

单片机菜鸟自学记

再来一张

单片机菜鸟自学记

四个全部就位了~

单片机菜鸟自学记

实在是找不到电容笔,于是把导线弄成这样凑合触屏吧(实际使用有时候不灵)

单片机菜鸟自学记

全家福在此

硬件差不多就是这样啦~ 接下来写个程序试试读取光敏电阻

单片机菜鸟自学记

数据还算正常,不过不够均衡,所以程序上简单的处理了一下数据,全部代码如下:

  1. /******************************************************

  2. *

  3. *

  4. * 说明:舵机玩别踩白块儿游戏程序

  5. * 日期:2017-01-08

  6. * 作者:TDA2030

  7. * 硬件:Arduino uno板

  8. *

  9. *

  10. *******************************************************/

  11. #include

  12. #define u16 unsigned int

  13. #define u8 unsigned char

  14. //光敏电阻数据校准值,调试得出具体数值

  15. #define S1_ADJ (0)

  16. #define S2_ADJ (20)

  17. #define S3_ADJ (-47)

  18. #define S4_ADJ (-120)

  19. #define C_V 620 //触发动作阀值

  20. #define PRESS_VAL 1//按下所对应的值

  21. #define BOUNCE_VAL 0//弹起所对应的值

  22. //传感器端口定义

  23. #define SENSOR_PORT1 0 // analog pin used to connect the potentiometer

  24. #define SENSOR_PORT2 1

  25. #define SENSOR_PORT3 2

  26. #define SENSOR_PORT4 3

  27. //舵机端口定义

  28. #define SERVO_PORT4 5

  29. #define SERVO_PORT3 6

  30. #define SERVO_PORT2 9

  31. #define SERVO_PORT1 10

  32. void setup()

  33. {

  34. Serial.begin(115200);

  35. while (!Serial) {

  36. ; // wait for serial port to connect. Needed for Leonardo only

  37. }

  38. Serial.println("*****************************************n");

  39. Serial.println(" * Play the game by MCUn");

  40. Serial.println(" * Author: TDA2030n");

  41. Serial.println(" * Date: 2017/01/08nn");

  42. Serial.println("*****************************************nn");

  43. pinMode(SENSOR_PORT1,INPUT);

  44. pinMode(SENSOR_PORT2,INPUT);

  45. pinMode(SENSOR_PORT3,INPUT);

  46. pinMode(SENSOR_PORT4,INPUT);

  47. pinMode(SERVO_PORT1,OUTPUT);

  48. pinMode(SERVO_PORT2,OUTPUT);

  49. pinMode(SERVO_PORT3,OUTPUT);

  50. pinMode(SERVO_PORT4,OUTPUT);

  51. }

  52. //全局变量定义

  53. u16 sv1,sv2,sv3,sv4;

  54. u8 flag1,flag2,flag3,flag4;

  55. u16 time1,time2,time3,time4;

  56. u16 core=0;

  57. u16 MAX1_TIME = 230; //最大按下时间定义

  58. u16 MAX2_TIME = MAX1_TIME+300; //免检测时间定义

  59. void loop()

  60. {

  61. //读取光敏电阻AD值

  62. sv1=analogRead(SENSOR_PORT1)+S1_ADJ;

  63. sv2=analogRead(SENSOR_PORT2)+S2_ADJ;

  64. sv3=analogRead(SENSOR_PORT3)+S3_ADJ;

  65. sv4=analogRead(SENSOR_PORT4)+S4_ADJ;

  66. //串口打印数据,调试时用

  67. Serial.print("sensor1:");

  68. Serial.println(sv1,DEC);

  69. Serial.print("sensor2:");

  70. Serial.println(sv2,DEC);

  71. Serial.print("sensor3:");

  72. Serial.println(sv3,DEC);

  73. Serial.print("sensor4:");

  74. Serial.println(sv4,DEC);

  75. Serial.println("n");

  76. delay(200);

  77. //-------当得分大于一定后加快速度按下

  78. // if(core>100)

  79. // {

  80. // MAX1_TIME = 200;

  81. // MAX2_TIME = MAX1_TIME+200;

  82. // }

  83. //判断是否大于阀值,执行按下并标识位

  84. if(flag1==0&&sv1>C_V)

  85. {

  86. digitalWrite(SERVO_PORT1,PRESS_VAL);

  87. flag1=1;core++;

  88. }

  89. if(flag2==0&&sv2>C_V)

  90. {

  91. digitalWrite(SERVO_PORT2,PRESS_VAL);

  92. flag2=1;core++;

  93. }

  94. if(flag3==0&&sv3>C_V)

  95. {

  96. digitalWrite(SERVO_PORT3,PRESS_VAL);

  97. flag3=1;core++;

  98. }

  99. if(flag4==0&&sv4>C_V)

  100. {

  101. digitalWrite(SERVO_PORT4,PRESS_VAL);

  102. flag4=1;core++;

  103. }

  104. /*在按下一段时间后自动弹起,不管是不是还大于阀值,

  105. 另外还要等待一段时间不检测,防止一个黑块多次按下*/

  106. if(flag1==1)

  107. {

  108. time1++;

  109. if(time1>MAX1_TIME)//大于了弹起时间,则自己弹起

  110. {

  111. digitalWrite(SERVO_PORT1,BOUNCE_VAL);

  112. if(time1>MAX2_TIME)//大于了免检测时间,复位标志位,以开始重新判断阀值

  113. {time1=0;flag1=0;}

  114. }

  115. }

  116. if(flag2==1)

  117. {

  118. time2++;

  119. if(time2>MAX1_TIME)

  120. {

  121. digitalWrite(SERVO_PORT2,BOUNCE_VAL);

  122. if(time2>MAX2_TIME)

  123. {time2=0;flag2=0;}

  124. }

  125. }

  126. if(flag3==1)

  127. {

  128. time3++;

  129. if(time3>MAX1_TIME)

  130. {

  131. digitalWrite(SERVO_PORT3,BOUNCE_VAL);

  132. if(time3>MAX2_TIME)

  133. {time3=0;flag3=0;}

  134. }

  135. }

  136. if(flag4==1)

  137. {

  138. time4++;

  139. if(time4>MAX1_TIME)

  140. {

  141. digitalWrite(SERVO_PORT4,BOUNCE_VAL);

  142. if(time4>MAX2_TIME)

  143. {time4=0;flag4=0;}

  144. }

  145. }

  146. }

做完感觉速度很慢,后来还测试了一下游戏的街机模式,发现最多能玩到160分,还没我同学玩的快呢。

简单分析了一下,主要是由于只有一个光敏电阻传感器,不能准确知道黑块走哪了,程序没法在时间上准确控制

所以我就想到了两个方法:

一是采用摄像头采集图像,并进行简单处理,来控制。

开始动手,试了一下用STM32F103驱动不带FIFO的OV7670摄像头,速度慢的不要不要的,大概每秒只有一两帧

单片机菜鸟自学记

这样的速度肯定不行啊,于是又找到了一个学长的视觉识别openmv板:

单片机菜鸟自学记

斑点识别

单片机菜鸟自学记

STM32F427芯片 180MHZ频率 加上 硬件 DCMI接口,这下达到了20帧每秒左右

但是由于使用Python编程,试了一下不太会搞,弄了半天可以识别出手机屏幕上的黑块了,但是干扰太大了,不稳定。

于是放弃这个方法了

我想到的第二个方法就是再加4个光敏电阻在前面,提前预知黑块。

这样Arduino的AD口就不够了,得换其他单片机,加上学校没几天就要封校了,差不多也要收拾收拾回家了,那就到此为止吧。

了解更多源代码,视频,请关注云汉电子社区微信公众号ickeybbs。



              查看评论 回复

游客   2018-08-26 08:24:12
看焊接搞得跟很漂亮
1楼 回复本楼
游客   2018-08-25 10:13:12
有点牛,就是有个缺点没有坚持到底,事情只做了一半
2楼 回复本楼


嵌入式交流网主页 > MCU > 单片机综合应用 > 单片机菜鸟自学记
 按下 这样 大于

网站地图

围观()