以下是一个基于 Laravel 12 和 STM32 的智能浇花系统完整开发方案,包含技术实现细节和工程实践要点:
一、硬件系统设计(STM32部分)
1. 硬件组件清单
模块 | 型号 | 接口方式 |
---|---|---|
主控 | STM32F103C8T6 | - |
Wi-Fi | ESP8266-01S | USART2 |
土壤湿度 | SEN0193 | ADC1_CH0 |
温湿度 | DHT22 | GPIO+单总线 |
光强度 | BH1750 | I2C |
水泵 | 微型潜水泵 | GPIO+继电器 |
LED补光灯 | 5050 RGB灯带 | PWM驱动 |
2. STM32关键代码实现
// main.c
#include "esp8266.h"
#include "dht22.h"
#include "bh1750.h"
// 引脚定义
#define PUMP_GPIO_PORT GPIOA
#define PUMP_GPIO_PIN GPIO_Pin_1
void System_Init() {
// 外设初始化
ADC1_Init();
I2C1_Init();
ESP8266_Init(USART2, 115200);
// GPIO配置
GPIO_InitTypeDef gpio;
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Pin = PUMP_GPIO_PIN;
GPIO_Init(PUMP_GPIO_PORT, &gpio);
}
void PostSensorData() {
float soil_hum = GetSoilHumidity(); // ADC读取
DHT22_Data dht = Read_DHT22();
uint16_t lux = BH1750_Read();
char json[128];
sprintf(json, "{\"soil\":%.1f,\"temp\":%.1f,\"humi\":%.1f,\"lux\":%d}",
soil_hum, dht.temperature, dht.humidity, lux);
ESP8266_HTTP_Post("http://your-domain.com/api/sensor", json);
}
3. 通信协议设计
// ESP8266通信模块核心逻辑
void ESP8266_SendCommand(const char* cmd, uint32_t timeout) {
USART_SendString(USART2, cmd);
USART_SendString(USART2, "\r\n");
Delay_ms(timeout);
}
void ConnectToWiFi() {
ESP8266_SendCommand("AT+CWMODE=1", 1000); // Station模式
ESP8266_SendCommand("AT+CWJAP=\"SSID\",\"PASSWORD\"", 5000); // 连接WiFi
ESP8266_SendCommand("AT+CIPSTART=\"TCP\",\"api.yourdomain.com\",80", 2000); // 连接服务器
}
二、Laravel后端服务开发
1. 数据库设计
// 迁移文件示例
Schema::create('sensor_data', function (Blueprint $table) {
$table->id();
$table->float('soil_humidity'); // 土壤湿度
$table->float('temperature'); // 空气温度
$table->float('humidity'); // 空气湿度
$table->integer('light'); // 光照强度
$table->timestamp('recorded_at');
});
Schema::create('control_settings', function (Blueprint $table) {
$table->id();
$table->float('soil_threshold')->default(30); // 浇水阈值
$table->boolean('auto_mode')->default(true); // 自动模式开关
});
2. API接口开发
// routes/api.php
Route::prefix('iot')->group(function () {
Route::post('/sensor', [SensorController::class, 'store']); // 传感器数据上报
Route::get('/command', [ControlController::class, 'getCommand']); // 获取控制指令
});
// SensorController.php
public function store(Request $request) {
$validated = $request->validate([
'soil' => 'required|numeric|min:0|max:100',
'temp' => 'required|numeric|between:-20,60',
'humi' => 'required|numeric|between:0,100',
'lux' => 'required|integer|min:0'
]);
SensorData::create($validated);
// 触发实时事件
broadcast(new SensorDataUpdated($validated));
return response()->json(['status' => 'success']);
}
3. 自动控制逻辑
// ControlController.php
public function getCommand() {
$settings = ControlSetting::first();
$latestData = SensorData::latest()->first();
$command = [
'pump' => ($latestData->soil < $settings->soil_threshold) ? 1 : 0,
'led' => ($latestData->lux < 2000) ? 1 : 0 // 光照不足开补光灯
];
return response()->json($command);
}
三、Web管理界面开发
1. Blade+Vue实时看板
<!-- resources/views/dashboard.blade.php -->
<div id="dashboard">
<real-time-chart :data="sensorData"></real-time-chart>
<div class="control-panel">
<button @click="togglePump" :class="{ active: pumpStatus }">
{{ pumpStatus ? '停止浇水' : '启动浇水' }}
</button>
<input type="range" v-model="soilThreshold" min="0" max="100">
</div>
</div>
<script>
new Vue({
el: '#dashboard',
data: {
sensorData: [],
pumpStatus: false,
soilThreshold: 30
},
mounted() {
Echo.channel('sensor')
.listen('SensorDataUpdated', (data) => {
this.sensorData.push(data);
});
}
});
</script>
2. 实时通信配置
// config/broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true
]
],
四、系统安全与优化
-
安全措施:
- API接口使用JWT认证
- 配置HTTPS加密通信
- 请求频率限制(Laravel Throttle)
- SQL注入防护(Eloquent ORM)
-
稳定性优化:
// STM32端数据缓存机制 typedef struct { float soil_hum; float temp; uint16_t lux; uint32_t timestamp; } SensorCache; #define CACHE_SIZE 50 SensorCache data_cache[CACHE_SIZE]; uint8_t cache_index = 0; void SaveToCache(SensorData data) { if(cache_index >= CACHE_SIZE) cache_index = 0; data_cache[cache_index++] = data; } void RetryFailedPosts() { for(uint8_t i=0; i<CACHE_SIZE; i++) { if(data_cache[i].timestamp != 0) { PostData(data_cache[i]); data_cache[i].timestamp = 0; // 标记为已发送 } } }
-
功耗管理:
- STM32进入Stop模式时的电流消耗可降至15μA
- 采样间隔动态调整(白天5分钟,夜间30分钟)
- 电源管理电路设计:
[电池] -> [TPS61097升压芯片] -> [3.3V LDO] -> STM32 | +-> [太阳能板输入]
五、系统部署
-
服务器端:
# 使用Laravel Horizon管理队列 composer require laravel/horizon php artisan horizon:install php artisan horizon # 配置Supervisor保持进程运行 [program:laravel-worker] command=php /var/www/artisan queue:work --sleep=3 --tries=3 autostart=true autorestart=true
-
硬件烧录:
- 使用ST-Link V2烧录器
- Keil MDK编译环境配置:
Target Options -> C/C++ -> Define: USE_STDPERIPH_DRIVER Debug -> Settings -> Flash Download: 添加STM32F10x Medium-density Flash
该方案实现了从传感器数据采集到云端控制的完整闭环,可通过增加 MQTT协议 提升实时性(推荐使用EMQX作为Broker),同时建议使用 InfluxDB 存储时序数据以提升查询效率。实际开发中需要注意STM32的ADC校准和传感器防腐蚀处理(建议给土壤传感器镀金)。