背景
经过前一段时间的学习,我已经大致了解了树莓派的串口数据传输以及有人USR-LTE-7S4这一4G模块的使用方法。详情请查看以往的博客。现在我对这两个模块进行整合,构成一个系统一完成特定任务。
目标要求
任何地点的联网用户在手机上操作,可以控制特定树莓派上的LED亮灭。
实现方式
客户端(手机)发送开或关的命令到云端服务器,由于4G模块不断向服务器发送心跳包(一秒一次),服务器将会根据客户端提供的数据回复给4G模块“1”或“0”,以示开关。4G模块再通过串口将数据发送给树莓派,进而达到控制LED的目的。
硬件配置
硬件准备
- 树莓派*1
- 有人USR-LTE-7S4模块*1
- LED*1
- 杜邦线若干
硬件连接
将树莓派和4G模块的串口、地线对应连好即可
软件配置
云端
云端将会运行两个进程,response.py
用于回复4G模块的心跳包(即发送指令),server.py
用于接收客户端发送的指令。这两个进程操作同一个文件ctrl.in
以完成数据传输。
接收客户端指令:
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
|
import socket import re
HOST, PORT = '', 10082
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listen_socket.bind((HOST, PORT)) listen_socket.listen(1) while True: client_connection, client_address = listen_socket.accept() request = client_connection.recv(1024) request = request.decode() action = re.findall("GET /(.+) ", request) action = action[0] if action=="1" or action=="0": f = open("ctrl.in", 'w') f.write(action) f.close()
http_response = """ HTTP/1.1 200 OK
<a href="/1">ON</a><br/><a href="/0">OFF</a> """ client_connection.sendall(http_response.encode()) client_connection.close()
|
这段代码在前端生成了两个链接,客户端点击链接即可控制文件中数值为1或0,以供response.py
回复。
向4G模块回复(发送)指令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
import socket
HOST, PORT = '', 10081 listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listen_socket.bind((HOST, PORT)) listen_socket.listen(1)
while True: client_connection, client_address = listen_socket.accept() while True: req = client_connection.recv(1024) print req if req == '+++': resp = 'a' else: f = open("ctrl.in",'r') resp = f.read() f.close() client_connection.sendall(str(resp)) client_connection.close()
|
这段代码读取ctrl.in
并回复给4G模块。
被控端
4G模块配置
在官方配置工具中配置好服务器和心跳包,点击“设置并保存所有参数”
树莓派配置
树莓派的职责就是接受4G模块的数据并控制LED。
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
|
#include<iostream> #include<wiringPi.h> #include<wiringSerial.h>
#define LED 1
using namespace std;
int main() { int MySerial;
pinMode(LED, OUTPUT); if (wiringPiSetup()<0) { cout << "Setup Failed!\n"; exit(0); }
if ((MySerial=serialOpen("/dev/ttyS0", 115200))<0) { cout << "Serial Failed!\n"; exit(0); }
while (1) { if (serialDataAvail(MySerial)>0) { char ch=serialGetchar(MySerial); cout << ch << endl; int val=ch-48; digitalWrite(LED, val); } }
serialClose(MySerial);
return 0; }
|
此代码的作用是,从串口读取数据,并据此数据控制LED引脚电平高低。
运行测试
云端服务器执行
$ python2 server.py &
$ python2 response.py
被控端通电,树莓派执行
& sudo ./SERIAL-RECEIVE
(编译后的可执行文件)
手机访问http://[域名]:10082/0,即可操作。
各终端情况如动画所示
实物测试如动画所示
展望
既然可以点亮一盏LED,任何更加复杂的工作均可同理完成。