Java+树莓派3交通灯程序:如何按指定时长控制模式循环?
解决交通灯时长控制的问题
嘿,作为Java新手能在树莓派上折腾交通灯项目,已经超棒啦!针对你说的时长控制需求,我给你两种实用的实现思路,一种是循环次数计算,另一种是时间戳判断(更精准),都给你写好代码示例,你可以直接参考:
思路1:通过循环次数控制时长
先算出每个模式单次循环的总耗时,再计算需要循环多少次才能达到目标时长,简单直观:
正常模式(2分30秒=150000ms)
你的正常模式单次循环总耗时是:1000(红亮)+100(红灭)+1000(黄亮)+1000(黄灭)+1000(绿亮)+1000(绿灭) = 5100ms
算下来循环29次就能覆盖约2分27秒,剩下的2.1秒补个简短的红亮,刚好凑够150秒。
黄灯闪烁模式(1分钟=60000ms)
单次闪烁耗时是1000(黄亮)+1000(黄灭)=2000ms,刚好循环30次就是整60秒。
完整代码示例:
public class TrafficLight { // 假设你的red、yellow、green是已经初始化好的GPIO控制对象 private static final RedLed red = new RedLed(); private static final YellowLed yellow = new YellowLed(); private static final GreenLed green = new GreenLed(); public static void main(String[] args) { try { // 1. 正常模式运行2分30秒 int normalModeCycles = 29; for (int i = 0; i < normalModeCycles; i++) { runNormalCycle(); } // 补充剩余时长,凑够150秒 red.on(); Thread.sleep(2100); red.off(); Thread.sleep(100); // 2. 黄灯闪烁模式运行1分钟 int blinkCycles = 30; for (int i = 0; i < blinkCycles; i++) { yellow.on(); Thread.sleep(1000); yellow.off(); Thread.sleep(1000); } // 3. 关闭所有灯光 shutdownAllLights(); } catch (InterruptedException e) { // 线程中断时也要确保关闭灯光 e.printStackTrace(); shutdownAllLights(); } } // 封装正常模式的单次循环逻辑 private static void runNormalCycle() throws InterruptedException { red.on(); Thread.sleep(1000); red.off(); Thread.sleep(100); yellow.on(); Thread.sleep(1000); yellow.off(); Thread.sleep(1000); green.on(); Thread.sleep(1000); green.off(); Thread.sleep(1000); } // 封装关闭所有灯光的逻辑 private static void shutdownAllLights() { red.off(); yellow.off(); green.off(); System.out.println("所有灯光已关闭"); } }
思路2:通过时间戳判断(更精准)
如果担心循环次数的误差,或者后续要调整灯的时长,用时间戳判断会更灵活:记录模式开始的时间,然后在循环里一直执行,直到当前时间减去开始时间超过目标时长。
完整代码示例:
public class TrafficLight { private static final RedLed red = new RedLed(); private static final YellowLed yellow = new YellowLed(); private static final GreenLed green = new GreenLed(); public static void main(String[] args) { try { // 1. 正常模式运行2分30秒(150000毫秒) long normalModeStartTime = System.currentTimeMillis(); while (System.currentTimeMillis() - normalModeStartTime < 150000) { runNormalCycle(); } // 退出循环后先关闭当前亮着的灯 shutdownAllLights(); // 2. 黄灯闪烁模式运行1分钟(60000毫秒) long blinkModeStartTime = System.currentTimeMillis(); while (System.currentTimeMillis() - blinkModeStartTime < 60000) { yellow.on(); Thread.sleep(1000); yellow.off(); Thread.sleep(1000); } // 3. 关闭所有灯光 shutdownAllLights(); } catch (InterruptedException e) { e.printStackTrace(); shutdownAllLights(); } } private static void runNormalCycle() throws InterruptedException { red.on(); Thread.sleep(1000); red.off(); Thread.sleep(100); yellow.on(); Thread.sleep(1000); yellow.off(); Thread.sleep(1000); green.on(); Thread.sleep(1000); green.off(); Thread.sleep(1000); } private static void shutdownAllLights() { red.off(); yellow.off(); green.off(); System.out.println("所有灯光已关闭"); } }
小提醒
- 一定要处理
InterruptedException:Thread.sleep()会抛出这个异常,如果线程被中断,得确保灯光都能关闭,避免树莓派GPIO引脚一直处于高电平状态。 - 封装重复逻辑:把正常循环和关闭灯光的代码抽成方法,不仅代码更整洁,后续修改也更方便。
内容的提问来源于stack exchange,提问作者TomS
相关产品推荐
相关产品推荐

