博观而约取,厚积而薄发。这篇文章主要讲述用树莓派改装电风扇及实现Android500.gs遥控相关的知识,希望能为你提供帮助。
【用树莓派改装电风扇及实现Android500.gs遥控】最近天气很热,我租的房子又没有空调,基本上风扇一开就是一晚上,结果经常起床后发现口干舌燥的。我觉得这肯定是因为整晚吹风扇搞的,不管是不是,反正我觉得就是了。不开风扇吧,热!开风扇吧,早上起来不舒服,怎么办呢?能不能让风扇吹一会停一会这样的吹呢?让手机来当遥控器来控制风扇?加上语音控制?我看了下我那吃灰半年多的树莓派,觉得应该让它动一动了。
硬件准备首先,电扇是必须的,树莓派吃灰了半年,也该工作工作了。其他再需要啥的就该淘宝了。树莓派控制电扇嘛,3v-7v直流信号控制220v交流的电磁继电器得一个。连接树莓派和继电器的杜邦线若干,连接电风扇和继电器得卡口一对,注意需要能承受住风扇的电流的,不要太细的。其他的以后再说吧!
东西准备好后,先连接电路。PO上几张图,不用好看,只要能说明问题。
拆掉底座后,图是这样的,左边是定时的,坏了定不了。右边是调速的。把调速的电源线断开,接到继电器得被控端。使用继电器的常闭触点,就是把树莓派拿掉,风扇和原来一样用。

文章图片

文章图片

文章图片

文章图片

文章图片
GPIO控制风扇编写Python代码,来控制风扇开关,测试一下GPIO。这个是控制的基础,要是这步走不通,后续就没意义了。
#-*- coding: utf-8 -*-
import RPi.GPIO as GPIO# gpio初始化
def gpioInit():
GPIO.setmode(GPIO.BCM)
GPIO.setup(5,GPIO.OUT,initial=GPIO.LOW)# 风扇是GPIO05
def switchFan(open):
GPIO.output(5,open)
print(‘fan open‘ if open==0 else ‘fan close‘)if __name__ == ‘__main__‘:
order=‘a‘
gpioInit()
while order!=‘exit‘:
order=input(‘input you order:‘)
if order==‘open‘:
switchFan(0)
elif order==‘close‘:
switchFan(1)
else:
print(‘bad order‘)
GPIO.cleanup()
print(‘smart exit!‘)
- 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
- 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
实现定时功能做这个的初衷就是让风扇定时开一会儿关一会儿,所以能控制风扇后,第一时间自然就是把这个功能给实现掉了。用python来实现,代码自然简单的不能再简单了:
#-*- coding: utf-8 -*-
from SmartServer import SmartServer
import threading
import RPi.GPIO as GPIOfanState=[1]# gpio初始化
def gpioInit():
GPIO.setmode(GPIO.BCM)
GPIO.setup(5,GPIO.OUT,initial=GPIO.HIGH)# 风扇是GPIO02
def switchFan(open=[0]):
fanState[0]= 1 if not open[0] else 0
GPIO.output(5,fanState[0])
print(‘fan close‘ if fanState[0] else ‘fan open‘)# 定时任务,默认十五分钟执行一次
def timerCheck(time=60*15,func=0,args=()):
if func:
func(args)
timer=threading.Timer(time,timerCheck,(time,func,args))
timer.start()if __name__ == "__main__":
gpioInit()
# 十五分钟反转一下GPIO,开启时风扇是打开的
timerCheck(time=60*15,func=switchFan,args=(fanState))
print(‘now fanState :‘,fanState)
order=‘‘
while order!=‘exit‘:
order=input(‘input you order:‘)
GPIO.cleanup()
- 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
- 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
# 安装ntpdate
apt-get install ntpdate
# 选择时区
sudo tzselect
# 然后选择亚洲 Asia->
中国(China)->
北京(Beijing)
# 接着复制到etc下
cp /usr/share/zoneinfo/Asia/Shanghai/etc/localtime
# 更新时间,会得到正确时区的服务器时间
sudo ntpdate ntp.ubuntu.com
# 每天校准,添加到定时任务里面去
vi /etc/crontab
# 加入下面这个,每天6点十分校准
# 10 6* * *rootntpdate ntp.ubuntu.com
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
# 判断当前是否离家了
def isLeave(leave=[7,30],back=[21,30]):
now=time.localtime(time.time())
return not (((now.tm_hour==leave[0] and now.tm_min>
=leave[1]) or
now.tm_hour>
leave[0]) and
((now.tm_hour==back[0] and now.tm_min<
back[1]) or
now.tm_hour<
back[0]))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
想要手机控制树莓派,在树莓派上运行一个服务来接受来自手机的指令肯定是少不了的。一事不劳二主,依旧python了。先写一个SmartServer的类,来创建服务器的Socket,来接受客服端的连接以及连接后的指令。
#-*- coding: utf-8 -*-
from socket import *
from time import ctime
from time import localtime
import threading
import time
import datetimeclass SmartServer(object):
"""docstring for SmartServer"""HOST=‘‘
PORT=1122#设置侦听端口
BUFSIZ=1024 #buffer的大小
SERVERFLAG=TruefanSwitchTimestamp=0#风扇上次状态切换时候的时间
fanState=0#风扇当前状态
fanForceClose=True#是否强制关闭风扇,离家的时候def __init__(self):
super(SmartServer, self).__init__()def clientSocketDoWhat(self,client,address,clientId):
while True:
try:
data=client.recv(self.BUFSIZ)
except Exception as e:
print(‘error when recv data from client!‘)
break
if not data:
break
#python3使用bytes,所以要进行编码
#s=‘%s发送给我的信息是:[%s] %s‘ %(addr[0],ctime(), data.decode(‘utf8‘))
#对日期进行一下格式化
ISOTIMEFORMAT=‘%Y-%m-%d %X‘
stime=time.strftime(ISOTIMEFORMAT, localtime())
s=‘getIt %d , %s‘ %(clientId,data.decode(‘utf8‘))
client.send(s.encode(‘utf8‘))
print([clientId],[stime], ‘:‘, data.decode(‘utf8‘))
#如果输入quit(忽略大小写),则程序退出
quit=(data.decode(‘utf8‘).upper()=="QUIT")
if quit:
break
client.close()def openServer(self,host=‘‘,port=1122,bufsize=1024):
self.HOST=host
self.PORT=port
self.BUFSIZ=bufsize
ADDR=(self.HOST, self.PORT)
sock=socket(AF_INET, SOCK_STREAM)
sock.bind(ADDR)
sock.listen(5)
print(‘Server start‘)
while self.SERVERFLAG:
print(‘等待接入,侦听端口:%d‘ % (self.PORT))
tcpClientSock, addr=sock.accept()
print(‘接受连接,客户端地址:‘,addr)
clientId=int(time.time());
print(‘分派给客户端的ID:%d‘%(clientId))
th=threading.Thread(target=SmartServer.clientSocketDoWhat,args=(self,tcpClientSock,addr,clientId,))
th.setDaemon(True)
th.start()
sock.close()# 测试代码
if __name__ == "__main__":
server=SmartServer()
serverThread=threading.Thread(target=server.openServer,args=())
serverThread.setDaemon(True)
serverThread.start()
print(‘server thread start‘)
serverThread.join()
- 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
- 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
#-*- coding: utf-8 -*-
from socket import *class TcpClient:
#测试,连接服务器
HOST=‘192.168.1.102‘
#设置侦听端口
PORT=1122
BUFSIZ=1024
ADDR=(HOST, PORT)
def __init__(self):
self.client=socket(AF_INET, SOCK_STREAM)
self.client.connect(self.ADDR)while True:
data=input(‘>
‘)
if not data:
break
#python3传递的是bytes,所以要编码
self.client.send(data.encode(‘utf8‘))
print(‘发送信息到%s:%s‘ %(self.HOST,data))
if data.upper()=="QUIT":
break
data=self.client.recv(self.BUFSIZ)
if not data:
print(‘no info from server, exit!‘)
break
print(‘从%s收到信息:%s‘ %(self.HOST,data.decode(‘utf8‘)))if __name__ == ‘__main__‘:
client=TcpClient()
- 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
- 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
android端遥控器树莓派的服务器端已经准备好了,并且测试通过了,那下一步就是来做个客户端。其实也看的出来,Android端的代码会比较简单,写个Socket连接上树莓派,发送指令基本就OK了。主要代码如下:
public class SmartClient implements Runnable{private UserConfig config=UserConfig.getInstance();
private boolean socketFlag=false;
private Gson gson;
private String charSet="utf-8";
private byte[] dataFromServer=new byte[2048];
private Thread mThread;
private Socket mSocket;
private LinkedBlockingQueue<
Command>
commands;
public SmartClient(){
gson=new GsonBuilder().create();
commands=new LinkedBlockingQueue<
>
();
mThread=new Thread(this);
}public void connectServer(){
socketFlag=true;
mThread.start();
}private void connectToServer() throws IOException {
Log.e("wuwang","try connect to socket"+config.getIp()+":"+config.getPort());
mSocket=new Socket();
mSocket.connect(new InetSocketAddress(config.getIp(),config.getPort()));
Log.e("wuwang","try connect to socket");
while (!mSocket.isClosed()&
&
socketFlag){OutputStream stream=mSocket.getOutputStream();
try {
Command command=commands.poll(20, TimeUnit.SECONDS);
if(command==null) {
stream.write("{}".getBytes(charSet));
}else{
stream.write(gson.toJson(command).getBytes(charSet));
}
} catch (InterruptedException e) {
e.printStackTrace();
continue;
}
InputStream in=mSocket.getInputStream();
int result=in.read(dataFromServer);
if(result>
0){
String value=https://www.songbingjia.com/android/new String(dataFromServer,0,result);
Log.e("wuwang","dataFromServer::"+value);
}
}}public void addCommand(Command command){
commands.offer(command);
}public void addCommand(int type,int value){
Command c=new Command();
c.type=type;
commands.offer(c);
}@Override
public void run() {
try {
connectToServer();
} catch (IOException e) {
e.printStackTrace();
}
}public void close(){
socketFlag=false;
if(mSocket!=null){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
mThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 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
- 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
def clientSocketDoWhat(self,client,address,clientId):
while self.SERVERFLAG:
try:
data=client.recv(self.BUFSIZ)
except Exception as e:
print(‘error when recv data from client!‘)
break
if not data:
break
#python3使用bytes,所以要进行编码
#s=‘%s发送给我的信息是:[%s] %s‘ %(addr[0],ctime(), data.decode(‘utf8‘))
#对日期进行一下格式化
ISOTIMEFORMAT=‘%Y-%m-%d %X‘
stime=time.strftime(ISOTIMEFORMAT, localtime())
s=‘getIt %d , %s‘ %(clientId,data.decode(‘utf8‘))
client.send(s.encode(‘utf8‘))
print([clientId],[stime], ‘:‘, data.decode(‘utf8‘))
command=json.loads(data.decode(‘utf8‘))
type=command.get(‘type‘,-1)
if type==1 :
if self.fanControl:
self.fanControl([1])
elif type==0:
if self.fanControl:
self.fanControl([0])
#如果输入quit(忽略大小写),则程序退出
quit=(data.decode(‘utf8‘).upper()=="QUIT")
if quit:
break
client.close()
- 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
- 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
至此,风扇定时及android手机控制风扇的功能就OK了。
推荐阅读
- Android(制作Update.zip升级包)
- Android权限管理PermissionsDispatcher2.3.2使用+原生6.0权限使用
- Android 跳转到系统应用管理
- 教你如何反编译app,拿到加密方式
- 安卓学习课程
- class path resource [spring/ApplicationContext-springmvc.xml] cannot be opened because it does not e
- Android 系统开机logo的修改
- Kali硬件黑客和社会工程工具
- 什么是Wshom.ocx、用途以及如何修复它()