基于实时数据的智能交通灯控制系统
元件与物料
| 元件 | 数量 | 备注 |
|---|---|---|
| Arduino Yun | 1 | 主控,自带 Linux 端可跑 PHP/MySQL 客户端 |
| Arduino UNO | 1 | 作为发射端测距 |
| HC-SR04 超声波测距模块 | 1 | 测车辆至红绿灯距离 |
| DS3231 RTC 模块 | 1 | 精准实时时钟 |
| LED(红/黄/绿) | 各1 | 模拟红绿灯 |
| 330Ω 电阻 | 3 | LED 限流 |
| 433 MHz 无线收发模块 | 1对 | 发射端发距离,接收端收 |
| Android 手机 | 1 | 运行客户端 APP |
| SD 卡 | 1 | 存放 PHP 脚本 |
| AllThingsTalk IOTOPIA 开发套件 | 1 | 可选 |
| 杜邦线若干 | 1 |
必备工具
- 电烙铁
应用与服务
- Arduino IDE
- Android Studio
- MySQL 数据库托管服务(如 freemysqlhosting.net)
项目简介
核心理念
交通拥堵让人抓狂,智能红绿灯能否缓解?本系统让驾驶员知道以何种匀速通过路口可赶上绿灯(不超速),或在必须等红灯时显示倒计时。

场景示例
限速 70 km/h,你保持限速行驶。前方红灯 30 秒后转绿,你距路口 500 m。系统建议以 60 km/h 匀速前行,刚好赶上绿灯。

系统架构
- 发射端(UNO + HC-SR04 + 433MHz Tx):测量车辆与红绿灯距离,无线发送;
- 接收端(Yun + 433MHz Rx + DS3231 + LED 红绿灯):
- 根据 RTC 产生红绿灯相位(固定间隔切换);
- 计算下一次绿/红灯 Unix 时间戳;
- 通过 Bridge 调用 Linux 端 PHP 脚本,将时间戳与距离写入云端 MySQL; - 云端数据库:存储
UnixTime_green_1,red_1,green_2,red_2,Distance; - Android APP:定期从 PHP 接口(JSON)拉取数据,结合 GPS 坐标计算距离(本演示用超声波代替 GPS),计算建议车速并显示倒计时。


分步实施指南
- 创建在线 MySQL 数据库(如 freemysqlhosting.net);
- 建表
TrafficL_data(字段见原文截图); - 搭建发射端硬件(原理图见文末),烧录 Arduino Transmitter Code;
- Yun 连 WiFi,用 Putty 登录 Linux 端:
opkg update && opkg install php5-mod-mysqli php5-cli nano
将MySQL_UpdateTrafficLData.php与MySQL_UpdateDistance.php放入/mnt/sda1/,chmod 755赋予执行权限; - 搭建接收端硬件,烧录 Arduino Receiver & MySQLdb;
- 打开串口监视器确认数据上传成功;
- Android Studio 导入项目(修改 URL),编译安装到手机。
低成本替代方案:ESP8266 方案
若嫌 Yun 太贵,可用 ESP8266(如 NodeMCU)直接通过 HTTP POST 写入 000webhost 免费空间的 MySQL:
- 注册 000webhost,建站、建库;
- 上传
CreateTable.php、PostDemo.php(修改数据库凭据); - 浏览器访问
CreateTable.php建表; - Arduino IDE 添加 ESP8266 开发板包(
https://arduino.esp8266.com/stable/package_esp8266com_index.json); - 烧录
ESP8266PostDemo.ino(每 10 秒随机上传一次测试数据),确认数据库更新成功; - 修改 Yun 端两个 PHP 调用函数指向新接口即可复用原有逻辑。
// ESP8266PostDemo.ino 关键片段
#include
#include
const char* ssid = "yourSSID";
const char* password = "yourPassword";
const char* dest = "https://yourhost/PostDemo.php"; // 必须 http
void loop() {
HTTPClient http;
String param = "UnixTime_green_1=" + String(random(100));
for(int i=1;i<4;i++) param += "&" + String("UnixTime_xxx") + "=" + String(random(100));
http.begin(dest);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int code = http.POST(param);
Serial.println(code); Serial.println(http.getString());
http.end();
delay(10000);
}
完整代码清单
- Arduino Transmitter Code(UNO 发射端)
- Arduino Receiver & MySQLdb(Yun 接收端)
- MySQL_UpdateTrafficLData.php
- MySQL_UpdateDistance.php
- EchoJSON.php(APP 拉取接口)
- MainActivity.java / AndroidManifest.xml / strings.xml / activity_main.xml(APP 源码)
发射端代码
#define tx_pin 3
#define trig_pin 5
#define echo_pin 6
#include
#include "HCSR04.h"
HCSR04 ultrasonic(trig_pin, echo_pin);
int distance; char CharMsg[21];
void setup() {
Serial.begin(9600);
vw_setup(2000); vw_set_tx_pin(tx_pin);
}
void loop() {
distance = ultrasonic.Ranging(CM);
while(distance < 0) distance = ultrasonic.Ranging(CM);
sprintf(CharMsg, "%d,", distance);
vw_send((uint8_t*)CharMsg, strlen(CharMsg));
vw_wait_tx();
Serial.print("Distance (cm): "); Serial.println(distance);
delay(250);
}
接收端代码
#define RedLED 5
#define OrangeLED 6
#define GreenLED 7
#define rx_pin 9
#include
#include
#include
#include "RTClib.h"
#include
long UnixTime_green_1, UnixTime_red_1, UnixTime_green_2, UnixTime_red_2;
long s_till_orange;
RTC_DS3231 rtc;
char StringReceived[22]; boolean i = 0;
int interval = 5; int distance;
void setup() {
rtc.begin();
Serial.begin(9600); Bridge.begin();
vw_setup(2000); vw_set_rx_pin(rx_pin); vw_rx_start();
Alarm.timerRepeat(interval, UpdateTrafficLData);
Alarm.timerRepeat(1, PrintCurrentTime);
pinMode(GreenLED, OUTPUT); pinMode(OrangeLED, OUTPUT); pinMode(RedLED, OUTPUT);
digitalWrite(GreenLED, LOW); digitalWrite(OrangeLED, LOW); digitalWrite(RedLED, LOW);
Serial.println("Setup finished");
}
void loop() { Alarm.delay(0); RF_Listen(); }
void RF_Listen() {
uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) {
for(int a=0;a0) Serial.print((char)p.read()); Serial.flush();
}
void MySQL_UpdateDistance() {
Process p; p.begin("/mnt/sda1/MySQL_UpdateDistance.php");
p.addParameter(String(distance)); p.run();
while(p.available()>0) Serial.print((char)p.read()); Serial.flush();
}
void PrintCurrentTime() {
DateTime now = rtc.now(); SetLEDsTrafficL();
Serial.print(now.hour()); Serial.print(':'); Serial.print(now.minute()); Serial.print(':'); Serial.print(now.second());
Serial.print(" "); Serial.println(now.unixtime());
}
void SetLEDsTrafficL() {
DateTime now = rtc.now();
s_till_orange = UnixTime_red_1 - now.unixtime();
if (i==0) { digitalWrite(GreenLED,LOW); digitalWrite(OrangeLED,LOW); digitalWrite(RedLED,HIGH); }
if (i==1 && s_till_orange<=3) { digitalWrite(GreenLED,LOW); digitalWrite(OrangeLED,HIGH); digitalWrite(RedLED,LOW); }
if (i==1 && s_till_orange>3) { digitalWrite(GreenLED,HIGH); digitalWrite(OrangeLED,LOW); digitalWrite(RedLED,LOW); }
}
PHP 脚本
connect_error) die('DB connect failed: '.$conn->connect_error);
$sql="UPDATE TrafficL_data SET UnixTime_green_1='$UnixTime_green_1',UnixTime_red_1='$UnixTime_red_1',UnixTime_green_2='$UnixTime_green_2',UnixTime_red_2='$UnixTime_red_2' WHERE id=1";
if($conn->query($sql)===false) die('SQL Error: '.$sql.' '.$conn->error);
echo "Data inserted!\n";
?>
connect_error) die('DB connect failed: '.$conn->connect_error);
$sql="UPDATE TrafficL_data SET Distance='$Distance' WHERE id=1";
if($conn->query($sql)===false) die('SQL Error: '.$sql.' '.$conn->error);
echo "Distance inserted!\n";
?>
Android APP 核心逻辑
// MainActivity.java 片段
private void speedCalc(){
double time = System.currentTimeMillis()/1000.0;
for(int i=0;i maxSpeed) speed = maxSpeed;
else speed = distance/(unixTimesGreen[interval]-time);
speed *= 5; // 换算显示单位
}
原理图
发射端: 433MHz Tx → D3;HC-SR04 Trig→D5, Echo→D6

接收端: 433MHz Rx → D3;LED 红/黄/绿 → D5/D6/D7;DS3231 SCL→SCL(3), SDA→SDA(2)

制造工艺