交通信号灯
本示例展示了如何设置一个行人过马路的路灯
开始时,汽车灯为绿灯,行人灯为红灯,代表车行人停。一旦行人,也就是你,按下按钮,请求过马路,那么汽车灯开始由绿变黄,等待3秒,然后,行人灯由红变绿,汽车灯变红。在行人通行的过程中,设置了一个过马路的时间 cross_time,一旦到点,行人绿灯开始闪烁3秒,提醒行人快速过马路。 闪烁完毕,最终,又回到了开始的状态,汽车灯为绿灯,行人灯为红灯。
硬件要求
- Arduino板卡
- 2个红色LED,2个绿色LED和1个黄色LED
- 5个220欧姆电阻
- 1个按钮
- 1个10k欧姆电阻
- 连接线
- 面包板
电路
用1个绿色LED和1个红色LED表示行人交通灯,通过220欧电阻将正极连接到数字信号引脚7和8上。用1个绿色LED、一个黄色LED和1个红色LED表示汽车交通灯,通过220欧姆电阻将正极连接到数字信号引脚10、11和12上。
将按钮同侧的两个引脚分别连接到5V电压和通过10k欧姆电阻接地,将接地引脚同时连接到数字引脚上接收按钮发出的信号。
电路图
代码
编译并运行示例
cargo build
cargo run
之后打开VS Code串行监视器,我们会看到终端上显示字母a,而如果我们输入任意字符串后,终端上会显示类似于"0,518,324"这样的信息。
完整代码如下:
src/main.rs
/*!
* Traffic light for vehicles and passagers
*
* At the beginning, the car light is green and the pedestrian light is red, indicating that cars and pedestrians
* have stopped.
* Once the pedestrian, that is, you, presses the button and requests to cross the road, the car lights start to
* change from green to yellow, wait for 3 seconds, then the pedestrian lights change from red to green, and the
* car lights turn red. During the pedestrian passage, a cross_time is set for crossing the road. Once the cross_time
* is reached, the pedestrian green light starts to flash for 3 seconds to remind pedestrians to cross the road quickly.
* The flashing is completed, and finally, it returns to the starting state, with the car light being green and the
* pedestrian light being red.
*/
#![no_std]
#![no_main]
use arduino_hal::{delay_ms, entry, pins, Peripherals};
use arduino_uno_example::utils::millis::{millis, millis_init};
use panic_halt as _;
#[entry]
fn main() -> ! {
let dp = Peripherals::take().unwrap();
let pins = pins!(dp);
const PREPARE_TIME: u32 = 3000;
const CROSS_TIME: u32 = 5000;
const WHOLE_TIME: u32 = 2 * PREPARE_TIME + CROSS_TIME;
const CROSS_ALARM_TIME: u32 = PREPARE_TIME + CROSS_TIME;
const BLINK_INTERVAL: u32 = 200;
let passenger_btn = pins.d9.into_floating_input();
let mut last_btn_is_high = false;
let mut padestrian_red = pins.d8.into_output();
let mut pedestrian_green = pins.d7.into_output();
padestrian_red.set_high();
pedestrian_green.set_high();
let mut vehicle_red = pins.d12.into_output();
let mut vehicle_yellow = pins.d11.into_output();
let mut vehicle_green = pins.d10.into_output();
vehicle_red.set_high();
vehicle_yellow.set_high();
vehicle_green.set_high();
delay_ms(1000);
pedestrian_green.set_low();
vehicle_red.set_low();
vehicle_yellow.set_low();
let mut pedestrian_start_time = 0u32;
let mut prev_time = 0u32;
millis_init(dp.TC0);
unsafe {
avr_device::interrupt::enable();
}
loop {
let elapsed_time = millis() - pedestrian_start_time;
let btn_is_high = passenger_btn.is_high();
if pedestrian_start_time == 0 || elapsed_time > CROSS_TIME + 2 * PREPARE_TIME {
if btn_is_high != last_btn_is_high {
if btn_is_high {
} else {
pedestrian_start_time = millis();
vehicle_green.set_low();
vehicle_yellow.set_high();
}
last_btn_is_high = btn_is_high;
}
} else {
if elapsed_time < PREPARE_TIME {
let current_time = millis() - pedestrian_start_time;
if current_time - prev_time > BLINK_INTERVAL {
vehicle_yellow.toggle();
prev_time = current_time;
}
} else if elapsed_time < CROSS_ALARM_TIME && elapsed_time >= PREPARE_TIME {
prev_time = 0;
vehicle_red.set_high();
pedestrian_green.set_high();
padestrian_red.set_low();
vehicle_yellow.set_low();
} else if elapsed_time >= CROSS_ALARM_TIME && elapsed_time < WHOLE_TIME {
let current_time = elapsed_time - CROSS_ALARM_TIME;
if current_time - prev_time > BLINK_INTERVAL {
pedestrian_green.toggle();
prev_time = current_time;
}
} else if elapsed_time == WHOLE_TIME {
vehicle_green.set_high();
vehicle_red.set_low();
pedestrian_green.set_low();
padestrian_red.set_high();
prev_time = 0;
}
}
}
}