思維導圖
需求分析
stm32mp157a單片機上移植Linux操作系統,包括LCD驅動、觸摸驅動、Ethernet/WiFi支持,設備樹信息包括ADC、GPIO、LCD,使用QT上位機在PC端顯示,通過TCP與stm32交互,將ad數據傳輸到PC端和云服務器,使用阿里云服務器,裝載MySQL數據庫包括所有上傳的數據。
云端服務器環境搭建
云端服務器中MySQL數據庫,QTCreator,python環境搭建的各個Linux命令
python實現tcp服務端/客戶端通信
tcp_server.py:需要注意的是,修改MySQL的密碼為自己的MySQL密碼,修改端口號,該代碼主要實現python下tcp服務端的監聽功能,并將接受到的參數保存到MySQL數據庫內。
import socket
import struct
import mysql.connector# MySQL 數據庫配置
db_config = {'host': 'localhost','user': 'root','password': '<你的密碼>', # 替換為你的 MySQL root 密碼'database': 'test_db' # 替換為你的數據庫名稱
}# 創建數據庫連接
def create_db_connection():try:connection = mysql.connector.connect(**db_config)return connectionexcept mysql.connector.Error as err:print(f"數據庫連接失敗: {err}")return None# 插入數據
def insert_sensor_data(connection, hum, tem):try:cursor = connection.cursor()query = "INSERT INTO sensor_data (hum, tem) VALUES (%s, %s)"cursor.execute(query, (hum, tem))connection.commit()print(f"數據插入成功: hum={hum}, tem={tem:.2f}")except mysql.connector.Error as err:print(f"數據插入失敗: {err}")# TCP 服務器
def start_tcp_server(host='0.0.0.0', port=<你的端口>):# 創建數據庫連接connection = create_db_connection()if connection is None:return# 創建 TCP socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen(5)print(f"TCP 服務器啟動,監聽 {host}:{port}")while True:# 接受客戶端連接client_socket, addr = server_socket.accept()print(f"Connected by {addr}")try:data = client_socket.recv(1024).decode('utf-8') # 解碼數據if data:print(f"接收到數據: {data}")# 解析數據(假設數據格式為 "hum,tem")hum, tem = data.split(',') # 按逗號分隔hum = int(hum) # 將 hum 轉換為 inttem = float(tem) # 將 tem 轉換為 float# 將數據插入數據庫insert_sensor_data(connection, hum, tem)# 接收數據(8字節:4字節int + 4字節float)#data = client_socket.recv(8)#if len(data) == 8:# 解析數據#hum = struct.unpack('!i', data[:4])[0] # 解析int#tem = struct.unpack('<f', data[4:])[0] # 解析float#print(f"Received int: {hum}, float: {tem}")#insert_sensor_data(connection, hum, tem) else:print("Invalid data received")except Exception as e:print(f"Error: {e}")finally:client_socket.close()# 關閉數據庫連接connection.close()if __name__ == "__main__":start_tcp_server()
tcp_client.py:云服務器本地python下tcp客戶端測試代碼
import socketdef send_sensor_data(host='<云端服務器IP>', port=<端口號>, hum=50, tem=25.5):client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.connect((host, port))message = f"{hum},{tem}"client_socket.send(message.encode('utf-8'))client_socket.close()print(f"數據已發送: {message}")if __name__ == "__main__":send_sensor_data()
tcp_client.c:本地Linux-c程序tcp客戶端上傳數據到云服務器代碼,需要注意字節序的問題
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define SERVER_IP "<云端服務器IP.address>" // 替換為云端的IP地址
#define SERVER_PORT <端口號>int main() {int sock;struct sockaddr_in server_addr;// 創建Socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);}// 設置服務器地址server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {perror("Invalid address/ Address not supported");exit(EXIT_FAILURE);}// 連接到服務器if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("Connection failed");exit(EXIT_FAILURE);}// 準備數據int int_value = 42; // 示例int數據float float_value = 3.14f; // 示例float數據// 序列化數據(將int和float轉換為字節流)char buffer[8];*(int *)buffer = htonl(int_value); // 將int轉換為網絡字節序*(float *)(buffer + 4) = float_value; // 直接存儲float(注意字節序問題)// 發送數據if (send(sock, buffer, sizeof(buffer), 0) < 0) {perror("Send failed");close(sock);exit(EXIT_FAILURE);}printf("Data sent: int=%d, float=%.2f\n", int_value, float_value);// 關閉Socketclose(sock);return 0;
}
以上代碼通過python語言進行tcp通信,以本地作為tcp客戶端上傳數據給云端tcp服務端,本地采集傳感器數據,此處客戶端代碼僅做示例,直接傳輸數據,具體根據實際情況將采集數據傳輸即可,云端tcp服務端將接受到的數據保存到云端MySQL數據庫,在云端數據庫中可以查看
擴展
以上示例代碼僅用于基礎理解,使用比較簡單的方式實現從本地獲取數據,通過tcp直接傳輸到云端服務器并保存到MySQL數據庫的功能,在實際開發中,可以增加mqtt數據傳輸json數據流,根據上端需求可以使用多進程、多線程對各模塊進行分組處理,多進程間可以使用共享內存、消息隊列、socket套接字進行交互等方式對整體架構進行增碼。