🛗 درس 94: آسانسور: ماشین حالت بزرگ
سه طبقه، دکمهها، چراغ طبقه، کابین و در — با حالتها و رویدادها.
سطح: پیشرفته · زمان: حدود 22 دقیقه · مفاهیم: ماشین حالت، رویداد، millis
قدمهای این درس
- چرا؟ آسانسور نباید با در باز حرکت کند
- قدم ۱ — اول نقشه، بعد کد
- قدم ۲ — مدار
- قدم ۳ — کد ماشین حالت
- اشتباه رایج: حالتهای قاطی
- چالش: صف درخواستها
نمونهای از کد این درس
// آسانسور سه طبقه: حالتها = ایستاده، در حرکت، در باز
#include <Servo.h>
Servo cab; // the servo angle is the cab's height
const int buttons[3] = {2, 3, 4}; // floor buttons (to GND)
const int lamps[3] = {5, 6, 7}; // floor LEDs
const int BUZZ = 8;
const int IDLE = 0, MOVING = 1, DOOR_OPEN = 2;
int state = IDLE;
int floorNow = 0, target = 0, angle = 0;
unsigned long t = 0;
void setup() {
for (int i = 0; i < 3; i++) {
pinMode(buttons[i], INPUT_PULLUP);
pinMode(lamps[i], OUTPUT);
}
cab.attach(9);
cab.write(0);
Serial.begin(9600);
}
void loop() {
unsigned long now = millis();
if (state == IDLE) { // event: a button
for (int i = 0; i < 3; i++) {
if (digitalRead(buttons[i]) == LOW && i != floorNow) {
target = i;
state = MOVING;
Serial.print("raftan be tabaghe ");
Serial.println(target);
}
}
} else if (state == MOVING && now - t >= 20) {
t = now; // one degree every 20 ms
int goal = target * 90;
if (angle < goal) angle++;
if (angle > goal) angle--;
cab.write(angle);
if (angle == goal) { // event: arrived
floorNow = target;
state = DOOR_OPEN;
tone(BUZZ, 880, 200);
Serial.println("ding! dar baz");
}
} else if (state == DOOR_OPEN && now - t >= 3000) {
state = IDLE; // event: door timer
Serial.println("dar baste shod");
}
for (int i = 0; i < 3; i++) digitalWrite(lamps[i], i == floorNow);
}
چرا این درس؟
دورهی تینکرکد فارسی تعاملی است: هر قدم را خودت داخل شبیهساز انجام میدهی — مدار واقعی میچینی، کد واقعی اجرا میکنی و نتیجه را همان لحظه میبینی. این درس روی درسهای قبلی ساخته شده، پس اگر تازه شروع کردهای از درس ۱ بیا!
این درس را رایگان در شبیهساز شروع کن 🎓