概述
本文介绍搭建一个简单的物联网系统,系统包括服务器、stm32单片机、手机三部分。
实现功能
手机通过服务器向单片机发送数据,单片机将接受到的数据通过串口打印出来,如果单片机接收到的是点灯指令则点亮小灯。
华为云
本系统使用的服务器是华为云【Flexus L实例】
一年36,爽的很。配置的服务器系统是Ubuntu。
本系统的服务器代码用Python编写,实现功能为:监听网络端口等待客户端的连接,如果某个客户端向服务器发送一段数据,服务器会把这段数据转发给除了发送数据的客户端以外其他所有客户端。
Python代码如下:
import socket
import threading
class Server:
def __init__(self, host='0.0.0.0', port=1234):
self.host = host
self.port = port
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((self.host, self.port))
self.clients = {}
self.lock = threading.Lock()
def start(self):
self.server.listen(5)
print(f"Server listening on {self.host}:{self.port}...")
while True:
client_socket, addr = self.server.accept()
print(f"New client connected from {addr}")
threading.Thread(target=self.handle_client, args=(client_socket, addr)).start()
def handle_client(self, client_socket, addr):
with self.lock:
self.clients[addr] = client_socket
try:
while True:
data = client_socket.recv(1024)
if not data:
break
print(data)
self.broadcast(data, addr)
finally:
with self.lock:
del self.clients[addr]
print(f"Client {addr} disconnected")
client_socket.close()
def broadcast(self, message, exclude_addr):
with self.lock:
for addr, client_socket in self.clients.items():
if addr != exclude_addr:
try:
client_socket.sendall(message)
except Exception as e:
print(f"Error sending message to {addr}: {e}")
# Remove disconnected client
del self.clients[addr]
if __name__ == "__main__":
server = Server()
server.start()
华为云的Ubuntu系统自带python3以及本程序用到的python库。
接下来是需要用到的linux命令:
查看系统是否安装了python3
python3 --version
如果没打印出版本号说明没有python3环境,需要自己安装。
创建一个文件夹Server
mkdir Server
进入Server
cd Server
在Server文件夹下创建一个server.py文件
touch server.py
打开server.py文件进行编辑
vim server.py
打开之后输入“i”进入插入模式,然后将上述的python代码拷贝进去。
然后按Esc退出插入模式,然后输入“:wq”保存并退出。
最后运行服务器程序
python3 server.py
一些注意事项:
在程序里设置监听的IP地址和端口号时,IP地址要设置成0.0.0.0,表示监听本机的所有IP地址。
host='0.0.0.0', port=1234
如果设置成云服务器的公网IP运行代码会报如下错误:
Traceback (most recent call last):
File "/root/a/a.py", line 53, in <module>
server = Server()
File "/root/a/a.py", line 11, in __init__
self.server.bind((self.host, self.port))
OSError: [Errno 99] Cannot assign requested address
运行之后发现客户端连不进来,是因为云服务器监听的端口还没打开,华为云打开监听端口在“更改安全组”中。
然后把Sys-FullAccessgou选上点击确定
这样就把所有的端口打开了,如果只想打开某些端口可以在新建安全组里研究一下。
stm32单片机
本系统使用的32单片机是野火的stm32f103zet6霸道开发板,开发版上集成了ESP8266网络通信模块。使用代码是野火的【ESP8266配套例程】其中的【2-WIFI透传】例程代码。可以在我主页中查看上传资料获取代码。
其中需要修改的是bsp_esp8266_test.h文件中的10-15行
/********************************** 用户需要设置的参数**********************************/
#define macUser_ESP8266_ApSsid "embedfire2" //要连接的热点的名称
#define macUser_ESP8266_ApPwd "wildfire" //要连接的热点的密钥
#define macUser_ESP8266_TcpServer_IP "192.168.0.45" //要连接的服务器的 IP
#define macUser_ESP8266_TcpServer_Port "8000" //要连接的服务器的端口
修改WIFI热点名称和WIFI密码,IP地址改成服务器的公网IP,端口号改成服务器程序监听的端口号,本例程中是1234。
本例程代码主要实现功能是把ESP8266接收到的网络数据通过串口打印出来,如果发现接收到的数据是点灯指令如下:
char *ledCmd[ LED_CMD_NUMBER ] = { "LED_RED","LED_GREEN","LED_BLUE","LED_YELLOW","LED_PURPLE","LED_CYAN","LED_WHITE","LED_RGBOFF" };
则进行点灯操作。
手机端
使用的测试软件是网络调试精灵。
实验
打开网络调试精灵,连接到云服务器,可以看到服务器有新客户端连接的打印。打开野火32单片机开发板,连接WIFI热点,连接云服务器,同样看到服务器端有打印。
通过网络调试精灵发送一段字符串,会看到32单片机通过串口将字符串打印出来。
将网络调试精灵发送数据的格式改成us-ascii,然后发送"LED_GREEN",会看到单片机上绿灯被点亮。