Lampu lalu lintas di Arduino Uno
Uno menjalankan penyeberangan pelikan, dengan 74HC04 yang menyalakan lampu WAIT langsung dari tombol. Seluruh rakitannya, Arduino Uno dan 12 komponen lainnya, berjalan di browsermu dengan firmware di bawah; buka di editor untuk mengubah rangkaian atau kodenya, lalu jalankan lagi.
Mengajar? Berikan sebagai tugas ke kelasmu dengan sekali klik.
Menengah About 30 minutes to build and run. Berjalan di browsermu. Gratis, dan tidak perlu akun.
Komponennya dijual sekitar $33. Di Mokxi, semuanya gratis.
Langkah demi langkah, dengan rangkaian dan kesalahan umumnya: Kode Lampu Lalu Lintas Arduino dengan Tombol Penyeberang
What you'll learn
- Interrupts that catch a press during
delay - Minimum and maximum timing for a phase
- A traffic light sequence
- Using a logic chip instead of code
- Pull-up inputs and active low buttons
- Difficulty: Menengah
- Time: About 30 minutes
- Board: Arduino Uno R3
- Parts: 14
Cara kerjanya
The Uno runs a pelican crossing. Green is the resting state, on pin 10. Pressing the button on pin 2 triggers an interrupt that sets a flag, even while the sketch is waiting. Green lasts di least 3 seconds, and at most 9 seconds if no one presses.
Then amber shows for 1.5 seconds, red and the walk lamp on pin 11 show for 4 seconds, and flashing amber with a flashing walk lamp runs for 6 seconds. The blue WAIT lamp is not controlled by the Uno di all: a 74HC04 inverter lights it straight from the button line.
Daftar komponen
14 komponen, ditambah kabel jumper. Harganya sekitar $33; di Mokxi, semuanya gratis.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Breadboard ukuran penuh
- 1 × 74HC04 hex inverter
- 1 × Tombol tekanIn Starter Kit, Christmas Lights Kit, Logic Lab Kit.
- 5 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × LED, merahIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, kuningIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, hijauIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, putihIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, biruIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Komponen dan pin | Connects to |
|---|---|
| 74HC04 hex inverter pin GND | Arduino Uno R3 pin GND |
| Pushbutton pin 2a | Arduino Uno R3 pin GND |
| LED, red pin C | Arduino Uno R3 pin GND |
| LED, yellow pin C | Arduino Uno R3 pin GND |
| LED, green pin C | Arduino Uno R3 pin GND |
| LED, white pin C | Arduino Uno R3 pin GND |
| LED, blue pin C | Arduino Uno R3 pin GND |
| Resistor, 220 Ω (4) pin 1 | Arduino Uno R3 pin 11 |
| Resistor, 220 Ω (3) pin 1 | Arduino Uno R3 pin 10 |
| Resistor, 220 Ω (2) pin 1 | Arduino Uno R3 pin 9 |
| Resistor, 220 Ω (1) pin 1 | Arduino Uno R3 pin 8 |
| 74HC04 hex inverter pin 1A | Arduino Uno R3 pin 2 |
| Pushbutton pin 1a | Arduino Uno R3 pin 2 |
| 74HC04 hex inverter pin VCC | Arduino Uno R3 pin 5V |
| Resistor, 220 Ω (5) pin 1 | 74HC04 hex inverter pin 1Y |
| LED, red pin A | Resistor, 220 Ω (1) pin 2 |
| LED, yellow pin A | Resistor, 220 Ω (2) pin 2 |
| LED, green pin A | Resistor, 220 Ω (3) pin 2 |
| LED, white pin A | Resistor, 220 Ω (4) pin 2 |
| LED, blue pin A | Resistor, 220 Ω (5) pin 2 |
Kodenya
Firmware persis seperti yang dibuka di editor. Ubah satu baris di sana lalu tekan Jalankan: kodenya dikompilasi di browser.
// Traffic light: a pelican crossing with a button that actually does
// something.
//
// pin 8 red pin 11 walk
// pin 9 amber pin 2 request button, to GND, internal pull-up
// pin 10 green
//
// The button is on INT0, so a press is caught by the interrupt even while
// loop() is asleep inside delay(). Without that the sketch would only notice a
// press if you happened to be holding the button when it got round to looking,
// which is exactly the bug every first crossing sketch has.
//
// Green is the resting state and it waits there for a request, but never for
// less than MIN_GREEN: a crossing that stopped the traffic the instant anyone
// asked would never let a car through.
//
// The WAIT lamp on the breadboard is not driven from here at all. It hangs off
// a 74HC04 inverter wired straight to the button line, so it lights the moment
// the contact closes, a reminder that not everything has to be the
// microcontroller's job.
const int RED = 8;
const int AMBER = 9;
const int GREEN = 10;
const int WALK = 11;
const int BUTTON = 2;
const unsigned long MIN_GREEN = 3000;
const unsigned long MAX_GREEN = 9000;
const unsigned long AMBER_MS = 1500;
const unsigned long WALK_MS = 4000;
volatile bool requested = false;
static void onPress() { requested = true; }
static void lights(int red, int amber, int green) {
digitalWrite(RED, red ? HIGH : LOW);
digitalWrite(AMBER, amber ? HIGH : LOW);
digitalWrite(GREEN, green ? HIGH : LOW);
}
// Hold green until someone asks, or until the maximum runs out.
static void waitForRequest() {
unsigned long started = millis();
for (;;) {
unsigned long waited = millis() - started;
if (waited >= MAX_GREEN) return;
noInterrupts();
bool asked = requested;
interrupts();
if (asked && waited >= MIN_GREEN) return;
delay(20);
}
}
void setup() {
pinMode(RED, OUTPUT);
pinMode(AMBER, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(WALK, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON), onPress, FALLING);
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: crossing ready, press the button");
}
void loop() {
lights(0, 0, 1);
Serial.println("green");
waitForRequest();
lights(0, 1, 0);
Serial.println("amber");
delay(AMBER_MS);
lights(1, 0, 0);
digitalWrite(WALK, HIGH);
Serial.println("walk");
delay(WALK_MS);
// the flashing period at the end of the walk phase
// The pelican's own ending: the walk lamp flashes to say "finish crossing"
// while the drivers get a flashing amber, which means "go if the crossing
// is clear". Then straight back to green. (A red-and-amber pair before
// green is the junction signal's sequence, not a crossing's.)
Serial.println("flashing amber");
for (int i = 0; i < 12; i++) {
int on = (i & 1) ? LOW : HIGH;
digitalWrite(WALK, on);
lights(0, on == HIGH, 0);
delay(500);
}
digitalWrite(WALK, LOW);
noInterrupts();
requested = false;
interrupts();
}
Code walkthrough
The key functions of the sketch, and what each one does.
onPress sketch.ino
The interrupt handler. It only sets the volatile flag requested to true. Keeping it tiny is the rule for interrupt code.
static void onPress() { requested = true; }waitForRequest sketch.ino
Holds green. It returns when MAX_GREEN has passed, or when a request exists and MIN_GREEN has passed. It copies the flag with interrupts off so the read is safe.
// Hold green until someone asks, or until the maximum runs out.
static void waitForRequest() {
unsigned long started = millis();
for (;;) {
unsigned long waited = millis() - started;
if (waited >= MAX_GREEN) return;
noInterrupts();
bool asked = requested;
interrupts();
if (asked && waited >= MIN_GREEN) return;
delay(20);
}
}lights sketch.ino
Sets the red, amber and green pins in one call. A non-zero argument turns that lamp on.
static void lights(int red, int amber, int green) {
digitalWrite(RED, red ? HIGH : LOW);
digitalWrite(AMBER, amber ? HIGH : LOW);
digitalWrite(GREEN, green ? HIGH : LOW);
}loop sketch.ino
Runs the whole sequence once per pass: green, amber, red with walk, then twelve half second flashes. At the end it clears the request flag.
void loop() {
lights(0, 0, 1);
Serial.println("green");
waitForRequest();
lights(0, 1, 0);
Serial.println("amber");
delay(AMBER_MS);
lights(1, 0, 0);
digitalWrite(WALK, HIGH);
Serial.println("walk");
delay(WALK_MS);
// the flashing period at the end of the walk phase
// The pelican's own ending: the walk lamp flashes to say "finish crossing"
// while the drivers get a flashing amber, which means "go if the crossing
// is clear". Then straight back to green. (A red-and-amber pair before
// green is the junction signal's sequence, not a crossing's.)
Serial.println("flashing amber");
for (int i = 0; i < 12; i++) {
int on = (i & 1) ? LOW : HIGH;
digitalWrite(WALK, on);
lights(0, on == HIGH, 0);
delay(500);
}
digitalWrite(WALK, LOW);
noInterrupts();
// ... 3 more lines in the editorTroubleshooting
The usual mistakes with this circuit, and the fix for each.
- A press is ignored. This project
The button must be on pin 2, the interrupt pin. It joins pin 2 to GND. - The WAIT lamp does not light. This project
It comes from the 74HC04, not the sketch. Check 5 V and GND on the chip, and the button line into 1A. - The crossing never leaves green. This project
That only happens beforeMIN_GREENhas passed. Wait three seconds after a press. - The outputs are random or noisy. 74HC04 hex inverter
Tie every unused input to GND or VCC. A floating CMOS input can oscillate, draw extra current and give random outputs. - The chip behaves badly or an LED is too dim. 74HC04 hex inverter
Add a 0.1 uF capacitor between VCC (pin 14) and GND (pin 7). Run it on 2 V to 6 V. An output gives only a few milliamps, so use a resistor with any LED. - The input reads random HIGH and LOW when the button is not pressed. Tombol tekan
A floating pin picks up noise. Add a 10 k pull-down or pull-up resistor, or use INPUT_PULLUP and wire the button between the pin and GND. Then pressed reads LOW. - The button seems always pressed, or never changes. Tombol tekan
A 4-leg tactile switch has legs joined in pairs. Place it across the breadboard center gap so the pairs sit on different rows. Wired along one side, the legs are already connected. - The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure.
Ubah dan simpan
Buka di editor, ubah rangkaian atau kodenya, lalu simpan versimu di akun gratis.