בשיעור הקודם למדנו את יסודות התכנות ב- Processing. היום נלמד איך לתקשר בין ארדואינו למחשב.
בעזרת יכולת זו, נוכל:
-
להרחיב את יכולות הקלט והפלט ה”טבעיות” של המחשב על-ידי שימוש בארדואינו (אליו יחוברו סנסורים, מתגים, מנועים וכו’).
-
להרחיב את יכולות המדיה של ארדואינו על-ידי השימוש במחשב – למשל להקרין וידאו, לנגן קולות וצלילים וכו’.
-
להשתמש ביכולות המיוחדות של המחשב בשביל פרוייקטי הארדואינו שלנו – תקשורת באינטרנט, ראיה ממוחשבת, עיבוד קול וכו’.
Arduino -> Processing
ראשית, נחבר פוטנציומטר לארדואינו, כמו שעשינו בסדנת קלט אנלוגי.
תוכנה לארדואינו (העתיקו והעלו לארדואינו):
int analogInputPin = 2;
int value;
void setup() {
Serial.begin(9600);
}
void loop() {
value =analogRead(analogInputPin);
Serial.write (value/4);
}
הסבר:
-
אנחנו קוראים את הערך של הפוטנציומטר מפין אנלוגי 2, ומציבים את הערך במשתנה בשם value.
-
את הערך הזה אנחנו מחלקים ב- 4 ושולחים למחשב על-ידי שימוש בפקודה Serial.write
-
חילקנו ב- 4 מכיון שבשיטה זו אנו יכולים לקרוא רק מספרים בין 0 ל- 255 ואילו הערך של value כפי שנקרא מהפין האנלוגי יכול להיות בין 0 ל- 1023 (1024/4=256).
תוכנה ל- Processing:
import processing.serial.*;
Serial port;
int value;
void setup(){
size(100,356);
// establish serial port connection
println(Serial.list());
port = new Serial(this, Serial.list()[1], 9600);
port.clear();
}
void draw(){
background (0);
while(port.available() == 0){
}
value = port.read();
rect (0,value,100,100);
port.clear();
}
לאחר הרצת התוכנה, בחלקו התחתון של החלון של העורך של Processing מוצגת רשימה של חיבורים של המחשב. עליכם למצוא את החיבור אליו מחובר הארדואינו ולראות מה המספר המופיע לידה. את המספר הזה צריך לרשום בתוך הסוגריים המרובעים בשורה הארוכה שב- setup. לדוגמה, מוצגת הרשימה הבאה:
[0] “COM1″
[1] “COM3″
אם ידוע לנו שהארדואינו מחובר ל- COM3 (עפ”י החיבור שבחרנו בעורך הארדואינו על-מנת להעלות אליו את התוכנה שכתבנו קודם), המספר הוא 1. השורה תשאר:
port = new Serial(this, Serial.list()[1], 9600);
הסבר:
-
שתי השורות הראשונות של התוכנה נועדו לאפשר ל-processing לתקשר עם הארדואינו על-ידי שימוש בתקשורת טורית (אין צורך להבין זאת, אך ניתן למצוא חומר רב על-כך – Serial Communication).
-
בתוך הפרוצדורה setup אחרי קביעת גודל החלון אנחנו מבצעים מספר פעולות שנועדו לבחירת החיבור בו הארדואינו מחובר למחשב, כפי שראינו לעיל.
-
בתוך הפרוצדורה loop, השורה שמתחילה ב- while גורמת למחשב להמתין (לא לעשות כלום) עד שמגיע מידע מהארדואינו.
-
לאחר מכן, אנחנו מציבים במשתנה value את הערך שהתקבל מהארדואינו.
-
ואז אנחנו מציירים ריבוע בעזרת מידע זה – מיקומו של הריבוע לגובה נקבע לפי הערך שהתקבל מהארדואינו.
-
הפקודה האחרונה – port.clear נועדה כדי ”לנקות” את צינור המידע שזורם בין הארדואינו למחשב. החסרתה של פקודה זו יגרום ל”פקק תנועה” של מידע (הארדואינו שולח כל הזמן והמחשב לא מספיק לקרוא את כל המידע) – מה שיגרום להתנהגות מוזרה של התוכנה (נסו!).
Processing -> Arduino
נראה עכשיו איך שולחים מידע מהמחשב לארדואינו, ומפעילים בעזרתו דברים “בעולם האמיתי”.
תוכנה לארדואינו:
int LEDpin = 13;
int value;
void setup(){
pinMode(LEDpin, OUTPUT);
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
value = Serial.read();
if (value == 1) {
digitalWrite(LEDpin, HIGH);
delay(500);
digitalWrite(LEDpin, LOW);
Serial.flush();
}
}
}
שימו לב: אם קיבלתם בעורך הארדואינו הודעת שגיאה כעין זו (כאשר ניסיתם להעלות את התוכנה לארדואינו):
Serial port ‘COM3′ already in use. Try quitting any programs that may be using it.
כנראה שלא סגרתם את התוכנה שהרצתם ב- Processing והיא עדיין מתקשרת עם הארדואינו – מה שמונע מהעורך לתקשר איתו (לצורך העברת התוכנה אליו).
הסבר התוכנה – כעת בוצע היפוך תפקידים בין הארדואינו והמחשב. הארדואינו עכשיו “מקשיב” למידע:
-
ראשית (בתוך loop) מתבצעת בדיקה אם הגיע מידע מהמחשב (על-ידי שימוש ב- Serial.available).
-
שנית, אם הגיע מידע, אנחנו קוראים אותו ומציבים את הערך שהתקבל בתוך המשתנה value.
-
לבסוף, אנחנו בודקים אם הערך שהתקבל הוא 1. אם כן – אנחנו מדליקים את הלד (פין 13) למשך חצי שניה ומכבים אותה.
-
הפקודה Serial.flush מבצעת מחיקה של מידע נוסף שהגיע בינתיים מהמחשב (כמו הפקודה port.clear מקודם).
תוכנה ל- Processing:
import processing.serial.*;
Serial port;
void setup(){
size(100,356);
// establish serial port connection
println(Serial.list());
port = new Serial(this, Serial.list()[1], 9600);
port.clear();
}
void draw(){
}
void mousePressed () {
if (mouseButton == LEFT) {
port.write (1);
}
}
ההתחלה דומה למדי לתוכנה הקודמת, אלא שהפעם הפרוצדורה loop ריקה ובמקומה הוספנו את הפרוצדורה mousePressed.
-
אם נלחץ אחד מלחצני העכבר, הפרוצדורה מופעלת, ואז:
-
אנחנו בודקים אם הלחצן שנלחץ הוא השמאלי (ראו הסבר בשיעור הכרות עם Processing). אם כן:
-
אנחנו שולחים לארדואינו את הערך 1, בעזרת הפקודה port.write.
-
באותה מידה, היינו יכולים לשלוח ערך של משתנה במקום מספר קבוע – למשל מיקומו האנכי של עכבר המחשב (mouseY). במקרה כזה, היינו משנים את התוכנה בארדואינו כך שתבצע פעולה בהתאם לערך שנשלח.
Arduino <-> Processing
כעת, נחבר את שני כיווני התקשורת וניצור תוכנה שתזיז את הריבוע על המסך בהתאם לפוטנציומטר ומצד שני תדליק את הלד שעל הארדואינו רק אם נלחץ על הריבוע הלבן.
תוכנה לארדואינו:
int analogInputPin = 2;
int LEDPin = 13;
int wValue;
int rValue;
void setup(){
pinMode(LEDPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
wValue =analogRead(analogInputPin);
Serial.write (wValue/4);
if (Serial.available() > 0) {
rValue = Serial.read();
if (rValue == 1) {
digitalWrite(LEDPin, HIGH);
delay(500);
digitalWrite(LEDPin, LOW);
Serial.flush();
}
}
}
נקודה אחת לציון – מכיוון שכאן יש שתי פעולות נפרדות (שליחת מידע אל המחשב ומנגד האזנה למידע המגיע ממנו), השתמשנו בשני משתנים נפרדים – wValue ו- rValue (קיצור של read ו- write).
תוכנה ל- Processing:
import processing.serial.*;
Serial port;
int value;
void setup(){
size(100,356);
// establish serial port connection
println(Serial.list());
port = new Serial(this, Serial.list()[1], 9600);
port.clear();
}
void draw(){
background (0);
while(port.available() == 0){
}
value = port.read();
rect (0,value,100,100);
port.clear();
}
void mousePressed () {
if (mouseButton == LEFT) {
if ((mouseY - value < 100)&&(mouseY - value >= 0)) {
port.write (1);
}
}
}
כאן כדאי לציין את משפט ה- if הנוסף שבתוך הפרוצדורה mousePressed. בתוכו נבדקים שני תנאים:
-
mouseY – value >= 0 בודק שההבדל בין המיקום האנכי של העכבר לבין הערך שהארדואינו שלח גדול מ- 0, כלומר החץ של העכבר לא נמצא מעל לקו העליון של הריבוע.
-
mouseY – value < 100 בודק שההבדל בין המיקום האנכי של העכבר לבין הערך שהארדואינו שלח קטן מ- 100, כלומר החץ של העכבר לא נמצא מתחת לקו התחתון של הריבוע (שגודלו 100 פיקסלים).
הסימון && בין שני תנאים אלו נקרא And והוא גורם לכך שרק אם גם התנאי הראשון וגם התנאי השני מתקיימים, המשפט כולו יתקיים (הפקודות שבסוגריים המסולסלים שאחרי ה- if יבוצעו).