Robotika ● שיעור 5Lesson 5
→ חזרה← Back
קורס ארדואינו · מפגש 5Arduino course · Session 5

מרכז שליטה
המכונית בדפדפן
Command center
the car in the browser

מסיימים לחבר את המכונית ב-Bluetooth — ואז נוהגים בה מדף אינטרנט, ורואים בזמן אמת מה החיישן שלה רואה. We finish connecting the car over Bluetooth — then drive it from a web page and watch, live, what its sensor sees.

Web Serial — דף אינטרנט שמדבר עם הארדואינוa web page that talks to the Arduino
D=23,M=F — קוראים את השפה של המכוניתreading the car's language
▲ ◀ ■ ▶ — נוהגים מהמקלדתdriving from the keyboard

ניווט: חצים ← → במקלדת, או הכפתורים למטה · לחצו EN לבדיקת מונחים באנגלית Navigate: ← → arrow keys, or the buttons below · press עב for Hebrew

2היום: שני מסלולים, נקודת סיום אחתToday: two tracks, one finish line

מסלול א — כולם, יחד איתיTrack A — everyone, together with me

  • מסיימים את מכונית ה-Bluetooth: שיעור 4, שלבים 1–3Finish the Bluetooth car: Lesson 4, levels 1–3
  • מעלים את car_telemetry.ino — המכונית מתחילה לדווחUpload car_telemetry.ino — the car starts reporting
  • פותחים את מרכז השליטה המוכן ונוהגים מהדפדפןOpen the ready-made command center and drive from the browser

מסלול ב — מתקדמים, בקצב שלכםTrack B — advanced, at your own pace

  • מקבלים גרסת התחלה של מרכז השליטה: החיבור כבר עובד, התצוגה עליכםYou get a starter version of the command center: the connection already works, the display is yours
  • 7 משימות — מצבע ועד פקודה חדשה שעוברת מהדף עד הצופר במכונית7 missions — from colors to a new command that travels from the page all the way to the car's horn
בסוף המפגש: כולם נוהגים מהדפדפן. רוצים לדעת איך Bluetooth עובד מבפנים? יש קריאה לבית בסוף המצגת.At the end of the session: everyone drives from the browser. Curious how Bluetooth works inside? There's home reading at the end of the deck.

3תזכורת: השפה של המכוניתRecap: the car's language

מהמחשב ← למכוניתComputer → car

אותLetterמשמעותMeaning
F B L Rקדימה, אחורה, שמאלה, ימינהforward, back, left, right
Sעצירהstop
1 … 9מהירות (1 לאט, 9 הכי מהר)speed (1 slow, 9 fastest)

הפקודה "נשארת" עד הבאה — לכן הדף שולח S כשעוזבים את המקש.A command "stays on" until the next — so the page sends S when you let go of the key.

מהמכונית ← למחשב (5 פעמים בשנייה)Car → computer (5 times a second)

D=23,M=F,S=160
  • D — מרחק בס"מ (999 = אין כלום מלפנים)distance in cm (999 = nothing in front)
  • M — התנועה הנוכחיתcurrent move
  • S — מהירות (0–255)speed (0–255)
שורה אחת = הודעה אחת. היום נלמד דף אינטרנט לקרוא את השורות האלה.One line = one message. Today we teach a web page to read these lines.

4איך דף אינטרנט מדבר עם המכונית?How does a web page talk to the car?

Arduino Serial.print HC-05 laptop COM port Chrome · Web Serial command center HTML + JavaScript "D=23,M=F,S=160" → ← "F" USB cable? same chain, just a different COM port

Web Serial היא יכולת של הדפדפן לפתוח פורט COM — בדיוק כמו ה-Serial Monitor, אבל מתוך דף אינטרנט שאנחנו כותבים.Web Serial lets the browser open a COM port — just like the Serial Monitor, but from a web page we write ourselves.

  • Chrome או Edge במחשב בלבד (לא Firefox, לא Safari, לא טלפון)Chrome or Edge on a computer only (not Firefox, Safari, or phones)
  • הדף לא יכול להתחבר לבד: לוחצים על כפתור והדפדפן שואל אתכם איזה פורט. זו הגנה — אתר זר לא יכול לדבר עם המכשירים שלכם בלי אישורThe page can't connect on its own: you click a button and the browser asks which port. That's a safeguard — a random site can't talk to your devices without permission
  • עובד מאתר הקורס, וגם מקובץ שפותחים ב-Chrome בלחיצה כפולהWorks from the course site, and also from a file opened in Chrome by double-click
⚠️ רק תוכנה אחת יכולה להשתמש בפורט. אם ה-Serial Monitor של Arduino IDE פתוח — הדף לא יצליח להתחבר. סוגרים אותו קודם.⚠️ Only one program can use a port. If the Arduino IDE's Serial Monitor is open — the page can't connect. Close it first.

5כולם: נוהגים מהדפדפןEveryone: drive from the browser

  1. מעלים למכונית את car_telemetry.ino (חוטי המודול מנותקים בזמן ההעלאה)Upload car_telemetry.ino to the car (module data wires unplugged while uploading)
  2. סוגרים את ה-Serial MonitorClose the Serial Monitor
  3. פותחים את מרכז השליטה ב-Chrome ולוחצים מצב הדגמה — מכונית מדומה, כדי להכיר את הדףOpen the command center in Chrome and press Demo — a pretend car, to get to know the page
  4. ניתוק ← התחברות למכונית ← בוחרים פורט: קודם פורט ה-USB של הארדואינו, אחר כך הפורט של ה-HC-05Disconnect → Connect → pick a port: first the Arduino's USB port, then the HC-05's port
  5. מחזיקים חץ = נוסעים, עוזבים = עוצרים. מסתכלים על הגרף כשמתקרבים לקירHold an arrow = drive, let go = stop. Watch the chart as you approach a wall

🕹️ פתיחת מרכז השליטהOpen the command center

איזה פורט לבחור?Which port to pick?

  • בכבל: הפורט עם השם Arduino Uno / USB SerialCable: the port named Arduino Uno / USB Serial
  • Bluetooth ב-Windows: "Standard Serial over Bluetooth link" — אותו פורט Outgoing משיעור 4. ב-Chrome חדש לפעמים מופיע ישר שם המודולBluetooth on Windows: "Standard Serial over Bluetooth link" — the same Outgoing port as in Lesson 4. Newer Chrome sometimes shows the module's name directly
  • Mac: cu.HC-05 (או השם החדש של המודול)Mac: cu.HC-05 (or the module's new name)

בחיבור בכבל הארדואינו מתאפס — הנתונים מתחילים להגיע אחרי כ-2 שניות. זה תקין.On the cable the Arduino resets on connect — data starts after about 2 seconds. That's normal.

6מה יש בתוך הדף? ארבעה חלקיםWhat's inside the page? Four parts

חלקPartמה הוא עושהWhat it doesנוגעים?Edit?
1. CONNECTIONפותח את הפורט, קורא שורות, שולח אותיותopens the port, reads lines, sends lettersמוכןready
2. PROTOCOLהופך שורה לנתונים: D=23 → D: 23turns a line into data: D=23 → D: 23מוכןready
3. DISPLAYמציג את הנתונים: מספר, צבע, גרףshows the data: number, color, chartכאן אתם!this is you!
4. CONTROLSמקלדת וכפתורים ← פקודותkeyboard and buttons → commandsמשימות 5, 7missions 5, 7

שימו לב: זה אותו מבנה כמו בארדואינו — קלט ← עיבוד ← פלט.Notice: it's the same structure as on the Arduino — input → process → output.

הקבציםThe files

⬇ גרסת התחלה (למסלול ב)Starter version (Track B)

⬇ הגרסה המלאה (פתרון)Full version (solution)

  • שומרים את הקובץ, פותחים אותו ב-VS Code (או כל עורך טקסט) לעריכהSave the file, open it in VS Code (or any text editor) to edit
  • לחיצה כפולה פותחת אותו ב-Chrome. אחרי כל שינוי: שמירה ← F5 בדפדפןDouble-click opens it in Chrome. After every change: save → F5 in the browser
  • שגיאה? F12 ← לשונית Console מראה מה ובאיזו שורהAn error? F12 → the Console tab shows what and on which line

7הנתונים מגיעים בחתיכות — לא בשורותData arrives in chunks — not in lines

הדפדפן מקבל מה שהגיע עד עכשיו — לפעמים חצי שורה, לפעמים שורה וחצי. לכן אוספים הכול למאגר (buffer), וחותכים ממנו שורה רק כשמגיע \n.The browser gets whatever has arrived so far — sometimes half a line, sometimes a line and a half. So we collect everything into a buffer, and cut a line out of it only when a \n arrives.

הגיע עכשיו:Just arrived:
במאגר (מחכה לסוף שורה):In the buffer (waiting for an end of line):
שורות שלמות ← handleLine():Whole lines → handleLine():
let buffer = '';
while (true) {
  const { value, done } = await reader.read();   // a chunk
  if (done) break;
  buffer += value;                                // add it to the buffer

  // cut out every WHOLE line (ends with \n)
  let nl;
  while ((nl = buffer.indexOf('\n')) >= 0) {
    const line = buffer.slice(0, nl).trim();
    buffer = buffer.slice(nl + 1);                // keep the rest
    if (line) handleLine(line);
  }
}

await = "חכה כאן עד שמגיע משהו" — בלי לתקוע את הדף.await = "wait here until something arrives" — without freezing the page.

8מפרקים שורה לנתוניםBreaking a line into data

// "D=23,M=F,S=160"  ->  { D: "23", M: "F", S: "160" }
function parseLine(line) {
  const data = {};
  for (const part of line.split(',')) {   // "D=23", "M=F", "S=160"
    const [key, value] = part.split('='); // "D", "23"
    if (key && value !== undefined) data[key.trim()] = value.trim();
  }
  return data;
}

function onTelemetry(data) {
  if (data.D !== undefined) updateDistance(parseInt(data.D, 10));
  if (data.M !== undefined) updateMove(data.M);
  if (data.S !== undefined) $('speedText').textContent = data.S;
}

נסו: כתבו שורהTry it: type a line

מה parseLine מחזירה:What parseLine returns:

שימו לב: הערכים מגיעים כטקסט ("23"). כדי להשוות מספרים (d <= 15) הופכים אותם למספר עם parseInt.Note: the values arrive as text ("23"). To compare numbers (d <= 15) we turn them into a number with parseInt.

9שולחים פקודות: מחזיקים = נוסעיםSending commands: hold = drive

const KEYS = { ArrowUp: 'F', ArrowDown: 'B',
               ArrowLeft: 'L', ArrowRight: 'R', ' ': 'S' };
let held = null;          // which command is held right now

function press(cmd)   { if (held === cmd) return; held = cmd; send(cmd); }
function release(cmd) { if (held !== cmd) return; held = null; send('S'); }

document.addEventListener('keydown', e => {
  const cmd = KEYS[e.key];
  if (cmd && !e.repeat) press(cmd);   // once, not 30 times a second
});
document.addEventListener('keyup', e => {
  const cmd = KEYS[e.key];
  if (cmd) release(cmd);
});
  • keydown — המקש נלחץ. מחזיקים מקש? המחשב שולח keydown שוב ושוב — e.repeat מסנן את החזרותkeydown — the key went down. Holding a key? The computer fires keydown again and again — e.repeat filters out the repeats
  • keyup — עזבנו את המקש ← שולחים Skeyup — we let go of the key → send S
  • send() שולחת אות אחת — אותה אות שהקלדתם בשיעור 4 ב-Serial Monitorsend() sends one letter — the same letter you typed in the Serial Monitor in Lesson 4
⚠️ מה אם עוברים לחלון אחר תוך כדי לחיצה? ה-keyup לא מגיע לדף — והמכונית ממשיכה לנסוע. לכן בדף המלא, כשהחלון מאבד פוקוס (blur) נשלח S.⚠️ What if you switch windows while holding a key? The keyup never reaches the page — and the car keeps driving. So in the full page, when the window loses focus (blur) we send S.

10מסלול ב: משימות 1–4Track B: missions 1–4

  • 1. היכרות: פותחים את גרסת ההתחלה, מצב הדגמה, נוהגים וקוראים את היומן. מה נשלח כשלוחצים ומה כשעוזבים?1. Get to know it: open the starter, Demo, drive and read the log. What's sent when you press, and when you let go?
  • 2. המכונית האמיתית: מחברים בכבל, ואז ב-Bluetooth. אין מכונית? level0_fake_car.ino — "מכונית" מפוטנציומטר2. The real car: connect on the cable, then over Bluetooth. No car? level0_fake_car.ino — a "car" made of a potentiometer
  • 3. כרטיס המרחק: בקוד מחפשים MISSION 3. צבע לפי אזור (אדום עד 15, צהוב עד 30, ירוק), טקסט האזור, והפס. ו-999? מציגים "—"3. The distance card: search the code for MISSION 3. Color by zone (red up to 15, yellow up to 30, green), the zone text, and the bar. And 999? Show "—"
  • 4. גרף חי: MISSION 4. הנתונים כבר נאספים ב-samples; מציירים אותם על ה-canvas: ציר X = זמן, ציר Y = מרחק4. A live chart: MISSION 4. The data is already collected in samples; draw it on the canvas: X axis = time, Y axis = distance
נתקעתם? בגרסה המלאה יש פתרון לשתיהן — אבל נסו קודם לבד 🙂Stuck? The full version has solutions to both — but try on your own first 🙂

11מסלול ב: משימות 5–7 (שני הצדדים)Track B: missions 5–7 (both sides)

5. צופר 📯5. Horn 📯

פקודה חדשה מקצה לקצה: H.A new command end to end: H.

  • במכונית: באזר על D8; כשמגיע 'H' — tone(8, 880, 200)Car: a buzzer on D8; when 'H' arrives — tone(8, 880, 200)
  • בדף: כפתור + המקש H ששולחים send('H')Page: a button + the H key that send('H')

6. אזעקה 🚨6. Alarm 🚨

כשהמרחק יורד מתחת ל-15 ס"מ: הדף מהבהב באדום, או משמיע צפצוף קצר.When the distance drops under 15 cm: the page flashes red, or plays a short beep.

רמז: document.body.style.background, או AudioContext לצליל. ואל תצפצפו 5 פעמים בשנייה — רק כשנכנסים לאזור.Hint: document.body.style.background, or AudioContext for sound. And don't beep 5 times a second — only when entering the zone.

7. דופק 💓7. Heartbeat 💓

הבעיה: Bluetooth נופל באמצע נסיעה — והמכונית ממשיכה (הפקודה "נשארת").The problem: Bluetooth drops mid-drive — and the car keeps going (the command "stays on").

  • בדף: כל עוד מקש לחוץ — שולחים את הפקודה שוב כל 300ms (setInterval)Page: while a key is held — re-send the command every 300 ms (setInterval)
  • במכונית: אם לא הגיעה פקודה שנייה שלמה — עוצרים (millis())Car: if no command arrived for a whole second — stop (millis())

12אין מכונית ביד? "מכונית" מפוטנציומטרNo car at hand? A potentiometer "car"

level0_fake_car.ino מדבר בדיוק באותה שפה כמו המכונית — כך אפשר לפתח את הדף ליד השולחן, רק עם ארדואינו וכבל USB.level0_fake_car.ino speaks exactly the same language as the car — so you can develop the page at your desk, with just an Arduino and a USB cable.

  • מסובבים את הפוטנציומטר = מזיזים את "הקיר" (5–120 ס"מ, הכי רחוק = 999)Turn the potentiometer = move the "wall" (5–120 cm, farthest = 999)
  • נורית ה-L דולקת כשה"מכונית" נוסעתThe L LED is on while the "car" is driving
  • אותו כלל בטיחות: קדימה מתחת ל-15 ס"מ ← עוצרת לבדSame safety rule: forward under 15 cm → it stops by itself
פוטנציומטרPotentiometerלאןTo
רגל אמצעיתmiddle legA0
רגל קיצונית אחתone outer leg5V
רגל קיצונית שנייהother outer legGND
זה גם רעיון שימושי בכל פרויקט: מדמים את החלק שעוד לא מוכן, וממשיכים לעבוד על השאר.It's a useful idea in any project: simulate the part that isn't ready yet, and keep working on the rest.

13משהו לא עובד? בודקים לפי הסדרSomething's not working? Check in order

מה רואיםWhat you seeמה בודקיםWhat to check
"הדפדפן לא תומך ב-Web Serial""This browser doesn't support Web Serial"Chrome או Edge, במחשב. לא Firefox, לא Safari, לא טלפוןChrome or Edge, on a computer. Not Firefox, Safari, or a phone
"לא הצלחתי לפתוח את הפורט""Couldn't open the port"ה-Serial Monitor פתוח? (או לשונית אחרת עם הדף). סגרו ונסו שובIs the Serial Monitor open? (Or another tab with the page.) Close it and try again
מחובר, אבל המספרים לא זזיםConnected, but the numbers don't moveהמכונית מריצה את car_telemetry.ino? בחרתם את הפורט הנכון? בכבל — חוטי ה-HC-05 מנותקים?Is the car running car_telemetry.ino? Right port? On the cable — are the HC-05 data wires unplugged?
הנורית בדף אדומה, "הודעה אחרונה" עולהThe page's light is red, "last message" keeps growingהקשר נפל: סוללות, טווח, או שהמודול התנתק. ניתוק ← התחברות מחדשThe link dropped: batteries, range, or the module disconnected. Disconnect → connect again
הנתונים מגיעים, המכונית לא מגיבה לחציםData arrives, the car ignores the arrowsלחצתם קודם על שדה (למשל המהירות)? לחצו על רקע הדף. ביומן רואים > F?Did you click into a field (e.g. speed) first? Click the page background. Does the log show > F?
שיניתי את הקוד ושום דבר לא השתנהI changed the code and nothing changedשמרתם? רעננו (F5). ואם הדף ריק או תקוע — F12 ← ConsoleSaved? Refresh (F5). And if the page is blank or stuck — F12 → Console

14סיכוםSummary

הרעיון האחד להיוםThe one idea for today

פרוטוקול פשוט — אות אחת לפקודה, שורה אחת להודעה — מאפשר לכל תוכנה לדבר עם המכונית: Serial Monitor, אפליקציה בטלפון, או דף אינטרנט שכתבנו בעצמנו.A simple protocol — one letter per command, one line per message — lets any program talk to the car: the Serial Monitor, a phone app, or a web page we wrote ourselves.

מילים חדשותNew words

  • Web Serial · מאגר (buffer)buffer · await
  • split() · parseInt() · keydown / keyup
  • הדמיה · דופק (heartbeat)simulation · heartbeat

הקבציםThe files

🕹️ מרכז השליטהCommand center

⬇ גרסת התחלהStarter version

💻 קבצי הקוד של השיעור (ארדואינו) — הורדה והסברThis lesson's Arduino code — download & walkthrough

רוצים להבין איך Bluetooth עובד מבפנים? שלוש השקופיות הבאות הן קריאה לבית.Want to understand how Bluetooth works inside? The next three slides are home reading.

תודה — נתראה בפעם הבאה! 👋Thanks — see you next time! 👋

15מאיפה בא השם?Where does the name come from?קריאה לביתhome reading

הרלד "שן כחולה" (Harald Bluetooth) היה מלך דני במאה העשירית, שאיחד את שבטי דנמרק תחת שלטון אחד. כשחיפשו שם לטכנולוגיה שאמורה לאחד מכשירים של חברות שונות — השם שלו התאים.Harald "Bluetooth" was a 10th-century Danish king who united the tribes of Denmark under one rule. When they looked for a name for a technology meant to unite devices from different companies — his name fit.

  • 1994 — מהנדסים ב-Ericsson בשוודיה מתחילים לפתח תקשורת רדיו קצרת טווח במקום כבלים1994 — engineers at Ericsson in Sweden start developing short-range radio to replace cables
  • 1998 — Ericsson, IBM, Intel, Nokia ו-Toshiba מקימות את Bluetooth SIG — הארגון שקובע את התקן עד היום1998 — Ericsson, IBM, Intel, Nokia and Toshiba found the Bluetooth SIG — the group that still sets the standard
  • השם היה אמור להיות זמני — ונשארThe name was meant to be temporary — and it stuck
ᚼ + ᛒ

הלוגו הוא שתי אותיות רוניות — H ו-B, ראשי התיבות של Harald Bluetooth — מחוברות לסימן אחד.The logo is two runic letters — H and B, Harald Bluetooth's initials — joined into one symbol.

16איך זה עובד: קפיצות תדרHow it works: frequency hoppingקריאה לביתhome reading

  • Bluetooth משדר בתחום 2.4GHz — אותו תחום של Wi-Fi ושל המיקרוגל במטבח. צפוף שם!Bluetooth transmits in the 2.4 GHz band — the same band as Wi-Fi and the kitchen microwave. It's crowded there!
  • Bluetooth "קלאסי" (כמו ה-HC-05) מחלק את התחום ל-79 ערוצים צרים"Classic" Bluetooth (like the HC-05) splits the band into 79 narrow channels
  • שני המכשירים קופצים יחד מערוץ לערוץ, 1,600 פעמים בשנייה, לפי סדר ששניהם מכיריםBoth devices hop together from channel to channel, 1,600 times a second, in an order both of them know
  • אם ערוץ אחד רועש — מפסידים רק רגע קטנטן, וממשיכים בערוץ הבא. כך עשרות מכשירים חיים באותו חדרIf one channel is noisy — you lose only a tiny moment and carry on in the next. That's how dozens of devices share one room
  • "מאסטר" אחד מנהל את הקצב ועד 7 מכשירים פעילים מצטרפים אליו (piconet). ה-HC-05 יכול להיות מאסטר או עבד; ה-HC-06 רק עבדOne "master" sets the rhythm and up to 7 active devices join it (a piconet). The HC-05 can be master or slave; the HC-06 only slave

שני זוגות באותו חדרTwo pairs in the same room

כאן הקפיצות איטיות פי ~600 מהמציאות. אדום = שני הזוגות נפלו על אותו ערוץ באותו רגע — ובקפיצה הבאה זה כבר מסתדר.Here the hops are ~600× slower than reality. Red = both pairs landed on the same channel at the same moment — and by the next hop it's sorted out.

17קלאסי מול BLE — ולמה אייפון לא רואה את ה-HC-05Classic vs BLE — and why iPhones don't see the HC-05קריאה לביתhome reading

Bluetooth ClassicBluetooth Low Energy (BLE)
מתי נולדBorn1999 (גרסה 1.0)1999 (version 1.0)2010 (גרסה 4.0)2010 (version 4.0)
מה הוא טוב בוGood atזרם נתונים רציף: אוזניות, רמקולים, "כבל סיריאלי"a continuous data stream: headphones, speakers, a "serial cable"הודעות קצרות ומעט סוללה: שעונים, חיישנים, צמידי כושרshort messages on little battery: watches, sensors, fitness bands
ערוציםChannels79 × 1 MHz40 × 2 MHz
"שפה" לנתוניםData "language"פרופיל SPP — מתנהג בדיוק כמו פורט סיריאליthe SPP profile — behaves exactly like a serial portGATT — "תיבות" של ערכים שקוראים וכותביםGATT — "boxes" of values you read and write
מודולים לארדואינוArduino modulesHC-05, HC-06HM-10
מי מתחברWho connectsWindows, Mac, Android. לא אייפוןWindows, Mac, Android. Not iPhoneכולם — כולל אייפון, וגם דפדפן (Web Bluetooth)everyone — including iPhone, and the browser too (Web Bluetooth)
לכן ה-HC-05 מתאים לנו: הוא מעמיד פנים שהוא כבל סיריאלי, והקוד שלנו לא צריך לדעת שום דבר על רדיו. מחיר: אייפון לא משתמש ב-SPP, אז הוא פשוט לא רואה את המודול.That's why the HC-05 suits us: it pretends to be a serial cable, and our code doesn't need to know anything about radio. The price: iPhones don't use SPP, so they simply don't see the module.