تبديل الأوضاع بزر
جزء من قسم التوقيت دون delay في رحلة Arduino على Coddy. الدرس 11 من 18.
تحتوي كثير من الأجهزة على زر واحد للتنقّل بين الأوضاع: ينطفئ ضوء الدراجة، ثم يضيء، ثم يومض، ثم يومض بسرعة، ثم ينطفئ مجددًا. هذه آلة حالات، حيث يؤدي الضغط، لا الساعة، إلى الانتقال إلى الحالة التالية.
ضع خطوة الانتقال في دالة خاصة بها. يحدد switch على الوضع الحالي الوضع التالي، ويعود الوضع الأخير إلى الأول:
void nextMode() {
switch (mode) {
case OFF:
mode = ON;
Serial.println("ON");
break;
// ... وهكذا، حتى تعود FAST إلى OFF
}
}يستدعي المخطط nextMode() مرة واحدة عند كل ضغطة. تتم إزالة ارتداد الزر بالطريقة التي تعلمتها في قسم المدخلات: عندما تتغير القراءة، تصرّف بناءً على ذلك، ثم انتظر 20 ms حتى تستقر نقاط التلامس. ويحدد switch آخر على mode حالة LED.
التحدي
متوسطتمت كتابة كود الزر ومصباح LED من أجلك. اكتب nextMode() بحيث تنقلك كل ضغطة إلى الوضع التالي وتطبع اسمه: OFF، ON، BLINK، FAST، ثم OFF مرة أخرى.
اضغط على Run، ثم اضغط على الزر بضع مرات، وبعد ذلك اضغط على Check.
جرّب بنفسك
const int ledPin = 13;
const int buttonPin = 2;
enum Mode { OFF, ON, BLINK, FAST };
Mode mode = OFF;
bool wasPressed = false;
unsigned long blinkPrevious = 0;
int ledState = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
}
// ينتقل إلى الوضع التالي ويطبع اسمه.
void nextMode() {
// حالة واحدة لكل وضع: عيّن الوضع التالي، واطبع اسمه، ثم اخرج من الحالة
}
// يبدّل حالة مصباح LED كل interval ms.
void blinkEvery(unsigned long interval) {
unsigned long now = millis();
if (now - blinkPrevious >= interval) {
blinkPrevious = now;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
void loop() {
// 1. يؤدي الضغط على الزر (بعد إزالة ارتداد التلامس) إلى استدعاء nextMode()
bool pressed = digitalRead(buttonPin) == LOW;
if (pressed != wasPressed) {
if (pressed) {
nextMode();
}
wasPressed = pressed;
delay(20); // اترك نقاط التلامس تستقر
}
// 2. يحدد الوضع ما يفعله مصباح LED
switch (mode) {
case OFF:
digitalWrite(ledPin, LOW);
break;
case ON:
digitalWrite(ledPin, HIGH);
break;
case BLINK:
blinkEvery(500);
break;
case FAST:
blinkEvery(100);
break;
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس التوقيت دون delay
تدرّب بنفسك: Playground لـ Arduino