闲来无事,就根据网上提供的跳一跳外挂的思路,自己动手写了个。
分为3部分:
1、运行windows脚本,脚本前两句指令为将手机屏幕截图,然后推到pc上,自己指定存储路径即可;
2、运行.py文件,使用python的图像工具matplotlib,处理鼠标点击事件,测算前后两次跳跃距离,发送至串口;
3、运行.ion文件,使用arduino控制舵机模拟手指按压手机屏幕,实现跳跃。
基本上跳1000分没什么问题。
具体实现如下:
1、安装adb shell ,修改电脑的path设置或者在cmd打开到adb路径下,连接安卓手机,打开usb调试,使用命令获取截图,上传存储至电脑。
- adb shell /system/bin/screencap -p /sdcard/screenshot.png %获取手机屏幕截图,保存至手机%
- adb pull /sdcard/screenshot.png d:/screenshot.png %将手机截图上传至pc,路径自行设置即可%
windows脚本(.bat):
- :abc %为goto语句提供目标,即实现一直循环执行下面语句%
- adb shell /system/bin/screencap -p /sdcard/screenshot.png %获取手机屏幕截图,保存至手机%
- adb pull /sdcard/screenshot.png d:/screenshot.png %将手机截图上传至pc%
- python jump.py%执行.py程序%
- goto abc %跳回第一条语句,循环执行%
- %如果出现程序执行出错,将注释删除,重试%
2、安装python2 ,安装python matplotlib工具,可以使用pip安装,命令为python pip -m install matplotlib。
python 具体实现(.py):
- # -*- coding: utf-8 -*
- import math
- import matplotlib
- import matplotlib.pyplot as plt
- import numpy as np
- from numpy import *
- import Image
- import serial
- import time
- from pylab import *
- img=Image.open("d:/screenshot.png","r")#使用adb上传的图片存储的位置,“r”是只读打开
- img_gray = img.convert("L")
- plt.imshow(img)
- [a,b] = ginput(2)#两次鼠标点击事件,两次鼠标点击为当前所在点和下次跳跃目标点,记录两次鼠标点击的坐标
- plt.close()#关闭图片
- x=b[0]-a[0]#两次鼠标点击的横坐标的差值
- x=x/173.4#matplotlib显示的图片大小和屏幕实际大小比值,换算后的即为两个点在屏幕上的实际横坐标距离
- y=b[1]-a[1]#两次鼠标点击的纵坐标的差值
- y=y/173.4#matplotlib显示的图片大小和屏幕实际大小比值,换算后的即为两个点在屏幕上的实际纵坐标距离
- z=x*x+y*y
- z=math.sqrt(z)#根据勾股定理算出距离
- z=z*10#算出来的距离单位是厘米,乘十是换算为毫米为单位
- print int(z)#打印输出整形距离
- ser=serial.Serial("COM3",9600)#windows下的,实例化串口,“COM3”,波特率为“9600”
- #ser=serial.Serial('/dev/ttyUSB0',9600)#ubuntu下的,实例化串口,“/dev/ttyUSB0”,波特率为"9600"
- time.sleep(2)#等待2秒钟。这条语句必须要,没有等待直接进行数据发送,串口接收会出现问题。
- for i in range(0,int(z)):
- ser.write('1')#发送z次’1‘,
- time.sleep(7)#等待7秒。该操作为等待舵机按压屏幕,跳跃,以完成本次跳跃。
最后一条语句,目的是为保证此次跳跃按压有足够的时间执行,由于windows脚本文件是一直进行循环执行的,所以必须等待本次python 程序和arduino程序执行完毕再执行windows脚本。
如果成功运行程序,会出现上图所示。然后两次鼠标点击,两次分别点击当前位置和下次跳跃目标位置。
然后会会输出整形距离,相关参数许根据自己手机和电脑显示的图片大小相比较,自行调整。
我的两次跳跃距离为26。
测出距离后,会向串口发送数据。连接上arduino后,可以查看串口号,确认好发送串口与arduino使用的串口相同,否则会报错。
3、使用arduino从串口接收数据,根据距离计算出按压时间,控制舵机按压。使用的是arduino UNO 和9g舵机,舵机有三根线,红色接5V,棕色的接地,橙色的接4号引脚。将程序烧写至开发板即可,不需要使用串口调试助手查看当前串口状况,如果在arduino ide打开了串口调试助手查看串口情况,则会出现在python程序运行报错,串口只能被一个程序打开使用,不支持两个程序同时打开使用。
代码实现:(.ino)
- #include <Servo.h>
- Servo servo;
- void setup() {
- // put your setup code here, to run once:
- Serial.begin(9600);
- pinMode(4,OUTPUT);//使用4号引脚为舵机信号
- pinMode(2,OUTPUT);
- servo.attach(4);
- servo.write(120);//舵机初始化
- delay(200);
- }
- void loop() {
- float i=0;
- int j=0;
- String str1 = "";// 接收串口传输的数据,使用字符串接收
- while(!Serial.available());//等待数据
- while (Serial.available() > 0) //如果串口有数据,则接收
- {
- str1 += char(Serial.read()); //接收数据,放到字符串数组中
- delay(5);//delay5ms,防止遗漏数据。实测如果没有delay,会有字符丢失。
- }
- j=str1.length(); //确定字符串长度。字符串长度即为两个点之间距离。
- i=j*7;//i为舵机delay时间,即按压屏幕时间,j乘的参数根据实际自行调整。
- for(int q=140;q>=120;q--)//舵机转动范围
- {
- servo.write(q);
- }
- delay(i);//按压屏幕delay
- for(int q=120;q<=140;q++)//舵机回转
- {
- servo.write(q);
- }
- }
最后的说明:
1、我所有的程序都是在windows下运行的,想在ubuntu下运行的,可以自己写个shell,python 文件可以直接运行, 在ubuntu上再装个arduino ide即可,可在官网下载,官网网址https://www.arduino.cc/en/Main/Software;
2、python需要安装的其他工具,都可以使用python pip -m install ****安装;
3、三个程序有两个参数需要根据自己实际调整,第一个是.py中的第18、20行,根据手机屏幕实际大小和截图大小,进行比例换算,第二个是.ion中的第25行,根据实际对跳跃距离和按压时间的线性参数进行调整。
4、使用舵机按压手机屏幕时,舵机头可绑上蘸水棉签或者电容笔,同时打开手机手套模式,或者自己探索可以代替手指按压屏幕的物品;