שיתוף באמצעות volatile
חלק מהיחידה תזמון ללא Delay במסלול ה-Arduino של Coddy. שיעור 14 מתוך 18.
ISR אמור לבצע פעולה מהירה אחת, ולכן בדרך כלל הוא מגדיר משתנה ששאר הסקץ' קורא. משתנה ששניהם משתמשים בו חייב להיות מוכרז בתור volatile:
volatile bool started = false;
void onPress() {
started = true;
}כדי לחסוך זמן, המהדר (התוכנית שהופכת את ה-C++ שלך להוראות של השבב) עשוי לשמור עותק של משתנה בתוך המעבד במקום לקרוא מהזיכרון. הוא לא יודע שפסיקה יכולה לשנות את המשתנה, ולכן הסקץ' עלול להשתמש בעותק הישן לנצח. volatile גורם לו לקרוא את המשתנה מחדש בכל פעם.
הסקץ' הזה ממתין בתוך setup() באמצעות לולאת while: while (condition) { } חוזרת על מה שבתוך הסוגריים המסולסלים כל עוד התנאי אמת, ובמקרה הזה !started. כמו ביחידת הקלטים, ! פירושו לא: הלולאה חוזרת כל עוד started הוא false. בלי volatile, היא עלולה להמתין לנצח, אפילו אחרי הלחיצה.
אתגר
קלהסקץ' הזה אמור להמתין עד ללחיצה על הכפתור, ואז להבהב את ה-LED. כרגע הוא ממתין לנצח. תקן אותו:
- ב-
onPress(), הגדר אתstartedל-true - הכרז על
startedכ-volatile
לחץ על Run, לחץ על הכפתור, ואז על Check. נסה פעם אחת בלי volatile כדי לראות את הלוח נתקע.
נסו בעצמכם
const int ledPin = 13;
const int buttonPin = 2;
bool started = false; // נקבע על ידי הפסיקה, נקרא על ידי הסקץ׳
unsigned long previousMillis = 0;
int ledState = LOW;
void onPress() {
// הגדר כאן את started ל־true
}
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
// המתן כאן עד ללחיצה על הכפתור
while (!started) {
}
}
void loop() {
// הבהב כל 250 ms
unsigned long now = millis();
if (now - previousMillis >= 250) {
previousMillis = now;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תזמון ללא Delay
תרגלו בעצמכם: Arduino אונליין