Professional Documents
Culture Documents
מדריך למורה
-------מהדורה שנייה-------
4/2020
כתב :גדי הרמן
1
תוכן עניינים
8 משימה - 2התקנת סביבת העבודה EsPy - IDEעבור MicroPythonעל גבי בקר ESP32
12 משימה - 3הכרת סביבת העבודה וכתיבת תוכנית ראשונה לביצוע פלט בשפת Python
77 משימה - 17עדכון RTCפנימי בבקר תוך שימוש ב API -מבוסס JSON
90 נספח א' -בדיקת הספריות הזמינות לתכנות ב MicroPython -תחת בקר ESP32
92 נספח ג' -יבוא ספריות קוד תוך שימוש בכלי PIPיעודיים לMicroPython -
2
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
משימה - 1התקנת MicroPythonעל גבי בקר ESP32
קישורים:
https://micropython.org/download#esp8266
https://www.youtube.com/watch?v=-pb-qTTNQsM
היכרות עם בקר ESP32
ESP32הוא בקר רב עוצמה מסוג SoCכלומר System on Chipמערכת מחשב מלאה על גבי רכיב אחד .שפותח
על ידי חברת סינית בשם .Espressif Systems
https://www.espressif.com/en
לחברה מספר בקרים מסוג זה כאשר הפופולרי ביניהם הוא בקר בשם .ESP32 WROOM
הבקרים הנ"ל פופולריים מאוד ומשמשים בעיקר ליישומי IoTכלומר ליישומי "האינטרנט של הדברים" -
.internet of things
הבקר מספק ביצועים גבוהים עם מעבד ( )MCUבעל 2ליבות שבהם קישוריות ותפעול נמוך-כוח הם חובה.
בנוסף ESP32 ,מספק ביצועים גבוהים עם MCUליבה כפולה העובד בתדר של 200MHzכמו כן הבקר מצוייד
בזיכרון הבזק בנפח של 4מגה-בייט .הבקר מצוייד ברוב הממשקים הזמינים היום וכולל Wi-Fi, BTלצד I2Cו-
.SPI
לצורך עבודת פיתוח תוכנה תחת הבקר החברה מספקת מספר ערכות פיתוח כאשר הפופולרית בניהם היא
ESP32-DevkitCהנמכרת בעלות של כ 4 -עד 5דולר ליחידה.
3
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
https://he.aliexpress.com/item/33020838035.html?spm=a2g0o.productlist.0.0.25f53dec2yOScB&alg
o_pvid=d43a496a-6f0b-4a52-a6c1-adc687bc59cc&algo_expid=d43a496a-6f0b-4a52-a6c1-adc687bc5
9cc-3&btsid=b83c3942-8328-4b1d-8082-123d4ff34008&ws_ab_test=searchweb0_0,searchweb2016
02_6,searchweb201603_52
כרטיס הפיתוח מספק לנו את כל מה שאנו זקוקים לו כדי לתכנת את הבקר ,דרך ממשק USBהמאפשר לחבר
את הבקר לחשב PCולעבוד ישירות איתו.
את הבקר ניתן לתכנת במספר שפות פיתוח .במסמך זה נמקד את ההדרכה שלנו בפיתוח תוכנה בסביבת
Pythonאו לייתר דיוק בסיבבת MicroPythonשהיא גרסה רזה של שפת Pythonהמותאמת לעבודה על מספר
בקרים בניהם .ESP32
התקנת .esptool.py
מקור:
https://github.com/espressif/esptool
נעזר ב pip -להתקין את התוכנה אך לפני נבדוק שה pip -מותקן על ידי הקלדת ההוראה הבא
pip --version
4
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
נעזר ב pip -כדי להתקין את esptool
לאחר ההתקנה נחבר את הבקר ESP32למחשב PCהמריץ Windows10ונבדוק לאיזה ( comמפתח מחשב)
התחבר הבקר:
מקור:
https://micropython.org/download#esp32
5
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
כדי לצרוב בבקר את מערכת ההפעלה נוריד תחילה למחשב שלנו את הקובץ הבא:
https://micropython.org/download#esp32
קחו בחשבון שיש למקם את הקובץ שהורד מהאתר בתיקייה שבה ממופה חלון ה Windows PowerShell -
>C:\Users\gadi
6
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
לביצוע הצריבה נשתמש בהוראה הבאה:
כדי לבדוק שהקוד נצרב בהצלחה ניתן להיתחבר לבקר דרך מפתח המחשב COMתוך שימוש בתוכנה כמו
putty
7
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
מכאן אנו יכולים לכתוב קוד ראשון ב MicroPython-לדוגמה
משימה - 2התקנת סביבת העבודה EsPy - IDEעבור MicroPythonעל גבי בקר ESP32
מתוך מספר סביבת פיתוח שעבדתי איתם מצאתי את סביבת הפיתוח EsPyכמתאימה ביותר לצרכים של
תלמידים תוך כדי עבודה עם MicroPythonבמשימה זו נתאר את אופן ההתקנה והעבודה עם סביבת הפיתוח
זו .כמו כן צורפו קישורים להוראות התקנה לסביבת פיתוח נוספות כמו upycraftו.Visual studio code -
https://github.com/jungervin/EsPy
https://randomnerdtutorials.com/install-upycraft-ide-windows-pc-instructions/
https://lemariva.com/blog/2018/12/micropython-visual-studio-code-as-ide
https://lemariva.com/blog/2019/08/micropython-vsc-ide-intellisense
בשלב הראשון נוריד למחשב את קובץ ההפעלה של סביבת הפיתוח EsPyדרך הקישור הבא:
8
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
https://github.com/jungervin/EsPy/tree/master/EsPy/Release
9
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
בחלון שנפתח נבדוק שהבקר ESP32רשום כבקר שעליו אנו עובדים אחרת יש ללחוץ על הלחצן שליד הכיתוב
" "Edit your own listכמתואר באיור הבא:
ESP32; -p $PORT -b $BAUDRATE write_flash -fm dout -ff 20m -fs detect 0x1000
""$FIRMWARE
10
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
בשלב זה ניתן לאתחל את הבקר על ידי הלחצן Eeaseכמו כן לצרוב בו את המפרש (אנגלית )Interpreter :של
MicroPythonעל ידי לחיצה על .Write
הערה :בשלב האתחול כמו גם בשלב הצריבה חלון הבקרה נשאר ריק ויש תחושה שהתוכנה נתקעת .תהליכים
אלו לוקחים מספר שניות שנע בין 10ל ,20 -שבסיומם תקבלו על המסך הודעה כמתואר באיור הבא:
11
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
בחלון ה Terminal -שבתחתית התוכנה נקבל את הסמן <<< ,לאחר לחיצה על , CTRL+Dהמורה לנו שהמפרש
של Pythonמוכן לפעולה.
משימה - 3הכרת סביבת העבודה וכתיבת תוכנית ראשונה לביצוע פלט בשפת Python
בניסוי זה נתרגל כתיבת תוכנית ראשונה בפייתון העושה שימוש בפעולות פלט למפתח הבקר.
12
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
*קיימים בשוק מוצרי ESP32שבהם הדקי הרכיב ממופים באופן שונה.
נפעיל את קובץ ההרצה EsPy.exeונתחבר לבקר על ידי לחיצה על Deviceו Port -בחר את מספר המפתח
( )Portשאליו מחובר הבקר שלנו
13
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
:ונכתוב בו את הקוד הבא
import time
for x in range(10):
led.value(1)
time.sleep(0.5)
led.value(0)
time.sleep(0.5)
print(x)
14
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
הדק 15שבבקר ESP32מחובר ישירות לנורית LEDהממוקמת על גבי הבקר ,לאחר הרצת התוכנית נורית זו
תתחיל להבהב 10פעמים בקצב של חצי שנייה בין כל הדלקה וכיבוי.
במקביל להבהובים נקבל על מסך Terminalאת מספרים בין 0ל 9-המספקים לנו כמדד למספר הפעמים שנורית
ה LED-נדלקה.
הערה:
15
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
בדרך כלל כשמדובר תכנות מיקרו-בקרים מקובל לכתוב את התוכנית הראשית כלולאה אינסופית בדומה לקוד
הבא:
while True:
)led.value(1 #led on
)time.sleep(0.5
)led.value(0 #led off
)time.sleep(0.5
משמעות הדבר בתכנות תחת MicroPythonהיא שלאחר הרצת התוכנית יעבור הבקר להפעיל את הקוד
בלולאה אינסופית כך שלא ניתן יהיה לחזור ולתפעל את הבקר דרך סביבת הפיתוח ולהטעין בבקר שינויים
בתוכנה או תוכנות אחרות .אין הדבר אומר שלא ניתן יהיה לבצע איפוס חומרה של הבקר ,אך זה ידרוש
מהמשתמש התעסקת מיותרת.
כל כן מומלץ להתייחס בכתיבת קוד ב MicroPython -ככתיבת קוד בשפה עלית שבה לא מקובל לנעול את
התוכנה כלולאה אינסופית.
תרגיל:
for x in range(1,10,2):
)led.value(1
)time.sleep(0.5
)led.value(0
)time.sleep(0.5
)print(x
תשובה:
5פעמים
תרגיל:
תשובה:
import time
16
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
from machine import Pin
led=Pin(15,Pin.OUT)
for x in range(100):
led.value(1)
time.sleep(0.1)
led.value(0)
time.sleep(0.1)
led.value(1)
time.sleep(3)
led.value(0)
4 OK OK
13 OK OK
17
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
15 OK OK On board LED - outputs PWM signal at boot
כאשר אנו צריכים לעבוד עם אחד מהדקי הקלט פלט של רכיב ,נדרש לאתחל עצם מהמחלקה Pinלדוגמה:
ניתן לאתחל את העצם המייצג את ההדק בדרכים נוספות כמו הגדרת ההדק כ( open-drain output -מצב שבו
נקבל עבר 1לוגי הדק מוצא מקוצר לאדמה וב 0 -לוגי נקבל נתק).
18
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
פרטים נוספים ניתןPin.PULL_DOWN אוPin.PULL_UP :כמו כן ניתן לאתחל את ההדק במאפיינים נוספים כמו
:בקישור הבא
http://docs.micropython.org/en/v1.11/library/machine.Pin.html#machine-pin
:קישורים
https://www.youtube.com/watch?time_continue=42&v=Mku1Bq78nXw&feature=emb_logo
http://docs.micropython.org/en/v1.11/library/machine.Timer.html#machine-timer
של הבקר להבהב בקצב של שנייה13 המחוברת להדקLED בקוד הבא נגרום לנורית
led1 = Pin(13,Pin.OUT)
def handleTimerInterrupt(timer):
led1.value(not led1.value())
myTimer = Timer(0)
myTimer.init(period=1000, mode=Timer.PERIODIC, callback=handleTimerInterrupt)
כלומר ניתן להמשיך, אינה גורמת לבקר להיתקעTimer - על ידי הLED - שימו לב שהבהוב נורית ה:חשוב
Timer -להפעיל את הבקר במקביל לפעולת ה
19
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
:Timer ננצל את זה שהבקר פנוי ונציג על המסך את מספר הפעמים שהייתה פסיקת
interruptCounter = 0
led1 = Pin(13,Pin.OUT)
def handleTimerInterrupt(timer):
led1.value(not led1.value())
global interruptCounter
interruptCounter = interruptCounter+1
print("Interrupt has occurred: " + str(interruptCounter))
myTimer = Timer(0)
myTimer.init(period=1000, mode=Timer.PERIODIC, callback=handleTimerInterrupt
20
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
הטיפול בפסיקה אינו מצריך. פסיקות חומרה מאפשרות לבקר לטפל ביעילות בשינויים המתרחשים בחומרה
כאשר. מופעל אירוע הממומש כפונקציה בתוכנה,לבדוק כל הזמן את מצב החומרה אלה כאשר מתגלה שינוי
מבצע פונקציה מוכנה מראש ואז חוזר, המעבד מפסיק את ביצוע התוכנית הראשית,מתרחשת הפסיקה
.לתוכנית הראשית
.GPIO11 - וGPIO6 ניתן להגדיר פסיקות לכל הדקי הבקר פרט להדקיםESP32 בבקר
:קישורים
https://randomnerdtutorials.com/micropython-interrupts-esp32-esp8266/
https://docs.micropython.org/en/latest/library/machine.Pin.html
https://techtutorialsx.com/2017/10/08/esp32-micropython-external-interrupts/
על פי דוגמת הקוד בכל פעם שהרמה הלוגית במבוא. בבקר14 להלן דוגמה למימוש פונקציה פסיקה עבור הדק
:12 זה תעלה (מרמה נמוכה לרמה גבוהה) תעלה הרמה הלוגית בהדק
motion = False
def handle_interrupt(pin):
global motion
motion = True
global interrupt_pin
interrupt_pin = pin
pir.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt)
while True:
if motion:
print('Motion detected! Interrupt caused by:', interrupt_pin)
led.value(1)
sleep(20)
led.value(0)
print('Motion stopped!')
21
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
motion = False
בכל פעם שתתקיים פסיקה נכתב על המסך, של המיקרו בקר32 במשימה זו נגדיר פסיקה חיצונית דרך הדק
:את מספר ההדק שיזם את הפסיקה
import machine
def button_press(pin):
print(pin)
: כדי לקבוע באיזה שלב תתקיים הפסיקה להלן האפשריותtrigger ניתן להשתמש במאפיין
: המטפלת בכךButton במטרה לטפל בבעיית הריטוטים להלן מחלקה חדשה בשם
:מקור
https://gist.github.com/jedie/8564e62b0b8349ff9051d7c5a1312ed7
import time
BUTTON_A_PIN = const(32)
BUTTON_B_PIN = const(33)
class Button:
"""
Debounced pin handler
usage e.g.:
def button_callback(pin):
print("Button (%s) changed to: %r" % (pin, pin.value()))
22
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
button_handler = Button(pin=Pin(32, mode=Pin.IN, pull=Pin.PULL_UP),
callback=button_callback)
"""
self._blocked = False
self._next_call = time.ticks_ms() + self.min_ago
pin.irq(trigger=trigger, handler=self.debounce_handler)
def button_a_callback(pin):
print("Button A (%s) changed to: %r" % (pin, pin.value()))
def button_b_callback(pin):
print("Button B (%s) changed to: %r" % (pin, pin.value()))
23
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
קלט אות אנלוגי- 6 משימה
.32-39 ניתן לחבר לבקר אותות אנלוגיים דרך הדקים
4095 - ל0 המומר למספר בין1V - ל0 ברירת המחדל של הבקר היא המרה של אות אנלוגי לדיגיטלי בטווח שבין
.)12bit (כלומר מדובר בממיר
:קישורים
https://randomnerdtutorials.com/esp32-esp8266-analog-readings-micropython/
The ESP32 has 18 x 12 bits ADC input channels (while the ESP8266 only has 1x 10 bits ADC). These
are the GPIOs that can be used as ADC and respective channels:
ADC2_CH0 (GPIO 4)
ADC2_CH1 (GPIO 0)
ADC2_CH2 (GPIO 2)
24
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
The ESP32 ADC pins don’t have a linear behavior. You’ll probably won’t be able to distinguish
between 0 and 0.1V, or between 3.2 and 3.3V. You need to keep that in mind when using the ADC
pins. You’ll get a behavior similar to the one shown in the following figure.
: סיביות המחוברים להדקים הבאים8 בניDAC - Digital to Analog Converter c ממירי2 כוללESP32 בקר
DAC1 (GPIO25)
25
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
DAC2 (GPIO26)
.MicroPython - תמיכה דרך תכנות בDAC לפני בדיקה שעשיתי אין לממיר
import time
:קישורים
https://thepihut.com/blogs/raspberry-pi-tutorials/hc-sr04-ultrasonic-range-sensor-on-the-raspber
ry-pi
https://github.com/rsc1975/micropython-hcsr04
26
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
הבעיה המרכזית בחיבור מד מרחק hc-sr04לבקר ESP-32היא ההבדל בין מתחי העבודה של 2הרכבים .בעוד
hc-sr04עבוד במתח עבודה של 5Vמתח העבודה של ESP-32הוא 3.3Vמשמע שאנו זקוקים למתח אספקה
חיצוני של 5Vעבוד החיישן כמו כן חובה עלינו להתאים בין רמת המתחים של הדק Echoשמתקבל ברמות של
5Vלרמה של 3.3Vאחרת אנו נגרום נזק לבקר .המצב ההפוך שבו דרך Triggerהמסופק ברמות של 3.3vנכנס
לחיישן שעובד ברמות של 5Vלא יגרום נזק.
הדרך להתאים את רמות המתחים היא על ידי רכיב ייעודי לכך ,או דרך מחלק מתח פשוט המתואר הבאים הבא:
27
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
: הראשון מחלקה המטפלת ברכיב2-קוד התוכנית מחולק ל
__version__ = '0.2.0'
__author__ = 'Roberto Sánchez'
__license__ = "Apache License 2.0.
https://www.apache.org/licenses/LICENSE-2.0"
class HCSR04:
def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30):
self.echo_timeout_us = echo_timeout_us
self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None)
self.trigger.value(0)
self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
def _send_pulse_and_wait(self):
self.trigger.value(0)
time.sleep_us(5)
self.trigger.value(1)
time.sleep_us(10)
self.trigger.value(0)
try:
pulse_time = machine.time_pulse_us(self.echo, 1,
self.echo_timeout_us)
return pulse_time
28
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
except OSError as ex:
if ex.args[0] == 110:
raise OSError('Out of range')
raise ex
def distance_mm(self):
pulse_time = self._send_pulse_and_wait()
mm = pulse_time * 100 // 582
return mm
def distance_cm(self):
pulse_time = self._send_pulse_and_wait()
cms = (pulse_time / 2) / 29.1
return cms
import time
from hcsr04 import HCSR04
sensor = HCSR04(trigger_pin=15, echo_pin=2)
for x in range(10):
distance = sensor.distance_cm()
print('Distance:', distance, 'cm')
time.sleep(2)
29
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
בקרים2 ביןUART תקשורת- 9 משימה
:קישורים
https://docs.micropython.org/en/latest/library/machine.UART.html
UART1: (GPIO 9 and GPIO10) – connected to the ESP32 SPI flash memory, so you can’t use them.
: זמנים לבקר על ידי הרצת הקוד הבאUART ניתן לכתוב קוד שבודק אילו ממשקי
30
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
הבקרים2 שלשם נחבר את התקשורת ביןrx=16 - וtx=17 זמין דרך הדקיםUART2 - לא זמין וUART0 כלומר
:כמתואר באיור הבא
import time
import utime
print(uart)
num_successes = 0
num_failures = 0
lst =[utime.ticks_ms(),17,18,19]
print('Sending:', lst)
try:
uart.write(struct.pack('iiii', lst[0],lst[1],lst[2],lst[3]))
except OSError:
pass
start_time = utime.ticks_ms()
timeout = False
31
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
while not uart.any() and not timeout:
timeout = True
if timeout:
num_failures += 1
else:
num_successes += 1
utime.sleep_ms(250)
. כאשר הוא מקבל אותם הוא מחזיר תשובה לשולח,בקר זה שלוח ממתין לקבל נתונים מהבקר הראשון
while True:
if uart.any():
while uart.any():
buf = uart.read()
lst = struct.unpack('iiii', buf)
print('received:',lst[0],lst[1],lst[2],lst[3])
utime.sleep_ms(15)
32
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
utime.sleep_ms(10)
try:
uart.write(struct.pack('ii', lst[0],lst[1]))
print('sent response')
except OSError:
pass
:הבקר השולח
:הבקר שמקבל
33
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
HC-05 מבוססתBluetooth תקשורת- 10 משימה
:קישורים
http://www.martyncurrey.com/hc-05-and-hc-06-zs-040-bluetooth-modules-first-look/
https://heeed.net/micro-bit-and-the-blue-micropython/
34
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
במילים.Slave - יכול לשמש רק כHC-06 בעוד שהרכיבSlave - וגם כMaster - יכול לשמש גם כHC-05 רכיב
יכול רק לקבל חיבור ממכשירHC-06 - יכול ליזום חיבור למכשיר אחר והHC-05 -פשוטות המשמעות היא שה
. הכיוונים2- לאחר יצירת הקשר התקשורת יכולה להיות ל.אחר
Interface: UART
Antenna: Built-in
UART1: (GPIO 9 and GPIO10) – connected to the ESP32 SPI flash memory, so you can’t use them.
35
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
ניתן לכתוב קוד שבודק אילו ממשקי UARTזמנים לבקר על ידי הרצת הקוד הבא:
כלומר UART0לא זמין ו UART2 -זמין דרך הדקים tx=17ו rx=16 -שלשם חיברנו את הדקי התקשורת לBT -
36
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
:HC-06 -אתחול ההגדרות של ה
זאת.HC-06 -נכתוב את הקוד הבא לבקר במטרה לאתחל את הגדרות ההתקשרות בין הטלפון הנייד לבין ה
הסיסמה של הרכיב וקצב התקשורת עם, כמו שם הרכיב,במידה ואנו לא יודעים את הגדרות האתחול של הרכיב
.הרכיב
import utime
print("---------------------------------------------------------------------")
print("| Module HC-06 configuration |")
print("| enter AT -- To test serial communication |")
print("| enter AT+NAME?????? -- To modify the module name |")
print("| enter AT+PIN1234 -- To modify the module PIN code |")
print("| enter AT+BAUD4 -- To modify the module communication speed|")
print("| Note: 1 for 1200, 2 for 2400, 3 for 4800, 4 for 9600 |")
print("| 5 for 19200, 6 for 38400, 7 for 57600, 8 for 115200 |")
print("---------------------------------------------------------------------")
while True:
print("ENTER AT Commands: ")
try:
str = input()
37
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
uart.write(str)
utime.sleep_ms(100)
except OSError:
pass
38
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
לאחר אתחול הרכיב נעבור לתוכנית המבצעת תקשורת טקסט דו כיווני בין הבקר לטלפון נייד
:קוד התוכנית
while True:
if uart.any():
while uart.any():
buf = uart.read()
print('received:',buf)
utime.sleep_ms(15)
utime.sleep_ms(10)
try:
uart.write("OK")
print('sent response')
except OSError:
pass
39
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
נפתח תוכנה ייעודית לתקשורת BTדרך הטלפון הנייד ,כמו התוכנה : Serial Bluetooth Terminal
נחבר את הטלפון נייד לרכיב ה Bluetooth -על ידי כך שנסרוק את התקני ה Bluetooth -הזמינים:
40
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
לבסוף נפעיל את היישום שהתקנו ונשלח לבקר טקסט:
41
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
על מסך המחשב נקבל את הפלט הבא:
42
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
משימה - 11אתחול קישוריות ה WiFi -בבקר ESP32
בקר ESP32מספק ביצועים גבוהים כל ביסיס 2ליבות .כמו כן הבקר כולל קישוריות ישירה לרשת האינטרנט
דרך רכיב Wifiמובנה .במשימה זו נעשה היכרות על הקבצים boot.pyו main.py -ונלמד כיצד לחבר את הבקר
לרשת מייד לאחר האתחול.
קישורים:
http://docs.micropython.org/en/v1.9.3/esp8266/esp8266/tutorial/network_basics.html
https://diyprojects.io/micropython-tutorial-manage-wifi-connection-startup-esp8266-esp32/#.XcfkZ
VczaUk
לכל בקר מוגדרים 2קבצים ייחודיים הנשמרים בו .הראשון קובץ בשם boot.pyוהשני קובץ בשם .main.py
בקובץ boot.pyמשמש אותנו להקצת קוד עבור הוראות אתחול של הבקר ,קוד זה רץ פעם אחת בלבד בזמן
האתחול .בקובץ זה מקובל לייבא ספריות רלוונטיות ,הגדרת קבועים כמו שמות וסיסמאות .במשימה זו נעשה
שימוש בקובץ זה כדי לייצר לבקר את הקישורית לרשת האינטרנט.
הקובץ main.pyעתיד להכיל את קוד התוכנית שתעבוד באופן אוטומטי לאחר הרמת הקובץ boot.pyקובץ זה
שימושי להפעלת היישום שכתבנו לאחר שלב הפיתוח.
הערה :ברוב הפעמים כאשר כותבים קוד תוכנה עבור בקר בשפת MicroPythonתוכלו למצוא שני קבצים
המאוחסנים בבקר עצמו :הקובץ הראשון נקרא boot.py :והשני .main.pyברגע שהבקר מתקבל מתח עבודה
43
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
או מיד לאחר איפוס יזום ,הבקר מפעיל אוטומטית את הקוד השמור בקובץ boot.pyלאחר מכן הוא יפעיל את
תוכן הקובץ main.pyמשמעות הדבר היא שלאחר שמירת הקובץ main.pyבבקר .לא ניתן יהיה לבצע עדכוני
תוכנה בו ללא מחיקת הקובץ הנ"ל כאילו מדובר באתחול בקר חדש .לכן השתמשו באפשרות זו רק כאשר אתם
מעבירים את הקוד ממצב פיתוח למצב שימוש.
בקר ESP32מצוייד בזיכרון הבזק בנפח של 4מגה-בייט שבו ניתן לשמור קבצי קוד ונתונים .נעזר בסביבת
הפיתוח EsPyכדי לבחון את הקבצים שבזיכרון הבקר מיד לאחר אתחול בקר בקושחה חדשה .נעשה זאת על ידי
התחברות לבקר ולחיצה על :File Manager
בעזרת החלון שנפתח אנו יכולים לראות אילו קבצים שמורים בזיכרון של הבקר .כמו כן ניתן לבצע את כל
הפעולות הבסיסיות על הקבצים כמו הוספת קבצים ,מחיקת קבצים ,יצירה ומחיקה של תיקיות ושינוי של של
קובץ.
נעזר בממשק שפתחנו כדי להעתיק את הקובץ boot.pyמהזיכרון של הבקר למחשב על ידי לחיצה על
Download
44
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
:boot.py להלן קוד התוכנית עבור הקובץ
def connect():
ssid = "yourNetworkName"
password = "yourNetworkPassword"
station = network.WLAN(network.STA_IF)
if station.isconnected() == True:
print("Already connected")
return
station.active(True)
station.connect(ssid, password)
print("Connection successful")
print(station.ifconfig())
connect();
: הזמינה ואת הסיסמה במקום השורות הבאותWifi - עדכנו בקובץ את שם רשת ה:חשוב
45
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
"ssid = "yourNetworkName
= password ""yourNetworkPassword
לאחר כתיבת הקובץ boot.pyנעלה אותו לבקר על ידי לחיצה על :Upload to the current directory
כדי לבדוק שאכן הבקר התחבר לאינטרנט נבצע אתחול ונקבל את הפלט הבא:
בעקבות חיבורית מוצלחת נקבל בחלון ה Terminal -את מאפייני החיבור שהם:
כתובת MACהיא מספר המורכבת מ 48-סיביות שמטרתו לזהות באופן ייחודי רכיב המחובר לרשת .כתובת
ה MAC-מוטבעת בדרך כלל על כרטיס הרשת של המחשב כמובן שבמקרה שלנו כתובת ה MAC-מטבעת על
הבקר עצמו.
46
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
: של הבקר שלנו ניתן להריץ את הקוד הבאMAC-כדי לבדוק מה כתובת ה
import network
import ubinascii
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print (mac)
:מקור
https://docs.micropython.org/en/latest/esp8266/tutorial/network_tcp.html
def http_get(url):
import socket
_, _, host, path = url.split('/', 3)
addr = socket.getaddrinfo(host, 80)[0][-1]
s = socket.socket()
s.connect(addr)
s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
while True:
data = s.recv(100)
if data:
print(str(data, 'utf8'), end='')
else:
break
s.close()
47
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
)'http_get('http://micropython.org/ks/test.html
https://he.wikipedia.org/wiki/HTTP_POST
קישורים:
https://randomnerdtutorials.com/esp32-esp8266-micropython-web-server/
48
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
https://techtutorialsx.com/2017/06/11/esp32-esp8266-micropython-http-get-requests/
https://github.com/micropython/micropython/tree/master/examples/network
https://github.com/micropython/micropython-esp32/tree/esp32/tests/net_inet
https://github.com/micropython/micropython/blob/master/examples/network/http_server_simplist
ic.py
https://github.com/micropython/micropython-lib/blob/master/urequests/urequests.py
.11 כמתואר במשימהWiFi לפני ביצוע משימה זו יש לוודא שהבקר מחובר לרשת האינטרנט דרך
:כדי לבדוק שהבקר מחובר לאינטרנט יש לאתחל את הבקר ולבדוק שהשורה הבאה מופיע
import socket
def html_page():
html = """
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
"""
return html
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
49
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
print("Got a connection from %s" % str(addr))
request = conn.recv(1024)
response = html_page()
conn.send(str(len(response)))
conn.send("\nConnection: close\n")
conn.send("\n")
conn.send(response)
conn.close()
לפרטים נוספים ראה מידע, משמש להוראות עיצוב מסך הדפדפן בטלפונים ניידיםmeta name=viewport הצג
:בקישור הבא
https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag
: שלו ונקבל על מסך הדפדפן את הפלט הבאIP -נגלוש לבקר דרך כתובת ה
50
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
שילוב חומרה בבקר המפעיל שרת .WEB
נפתח תרגיל המפעיל נורית LEDהמחוברות להדק 15של הבקר תוך כדי קליטת הוראות ממך הדפדפן.
להלן קוד התוכנית עבור הקובץ תוכנת השרת להפעלת נורית דרך האינטרנט:
def web_page():
if led.value() == 1:
"gpio_state="ON
else:
"gpio_state="OFF
""" = html
><html
><head
51
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html{
display:inline-block;
text-align:
center;}
h1{
color: #0F3376;
padding: 2vh;}
p{
font-size: 1.5rem;}
button{
display: inline-block;
background-color: #3668b8;
border: none;
border-radius: 4px;
color: white;
font-size: 25px;
</style>
</head>
<body>
</body>
</html>
"""
return html
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
conn, addr = s.accept()
52
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
request = str(request)
print('Content = %s' % request)
led_on = request.find('/?led=on')
led_off = request.find('/?led=off')
if led_on == 6:
print('LED ON')
led.value(1)
if led_off == 6:
print('LED OFF')
led.value(0)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
53
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
HTTP GET - 13 משימה
WiFi הבקר יקבל גישה לרשת האינטרנט דרך חיבור.HTTP בפעילות זו נלמד כיצד להשתמש בבקר בלקוח
כל התקשורת.מקומי ובכך הוא יכול לקבל ולשחו נתונים לאינטרנט ממש כמו שדפדפן במחשב יכול לעשות
.80 דרך מפתחHTTP בפרוטוקולGET תעבוד תחת בקשות
https://he.wikipedia.org/wiki/HTTP_POST
:קישורים
https://randomnerdtutorials.com/esp32-esp8266-micropython-web-server/
https://techtutorialsx.com/2017/06/11/esp32-esp8266-micropython-http-get-requests/
https://github.com/micropython/micropython/tree/master/examples/network
https://github.com/micropython/micropython-esp32/tree/esp32/tests/net_inet
https://github.com/micropython/micropython/blob/master/examples/network/http_server_simplist
ic.py
https://github.com/micropython/micropython-lib/blob/master/urequests/urequests.py
.11 כמתואר במשימהWiFi לפני ביצוע משימה זו יש לוודא שהבקר מחובר לרשת האינטרנט דרך
:כדי לבדוק שהבקר מחובר לאינטרנט יש לאתחל את הבקר ולבדוק שהשורה הבאה מופיע
54
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
להלן קוד התוכנית התחבר לאתר של גוגל ומציג את המידע המתקבל כמחרוזת טקסט על מסך הטרמינל:
import socket
)(s = socket.socket
]addr = ai[0][-1
)s.connect(addr
)"s.send(b"GET / HTTP/1.0\r\n\r\n
))print(s.recv(4096
)(s.close
מצד אחד ניתן לראות שבקר ESP32מצליח להתחבר לכל אתר אינטרנט מצד שני לפי מבנה התשובה לא נראה
שניתן להשתמש בנתונים שהתקבלו באופן משמעותי.
במטרה לנצל את יכולת הקישוריות לאינטרנט בצורה טובה יותר נעשה שימוש בקבלת מבנה נתונים מסוג JSON
הנראה כך:
http://jsonplaceholder.typicode.com/albums/1
55
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
:תקבלו את המסך הבא
להלן קוד. ולפרק אותוJSON מסוג בקוד להתחבר לאתר לקבל את מבנה הנתונים בפורמטESP32 בקר
:התוכנית
ניתן להוריד,יש לקחת בחשבון שקוד זה עושה שימוש במחלקה שצריך להוריד את קוד המקור שלה לתוך הבקר
:את קוד המקור מהאתר הבא
https://github.com/micropython/micropython-lib/blob/master/urequests/urequests.py
import urequests
response = urequests.get('http://jsonplaceholder.typicode.com/albums/1')
print(type(response))
print(response.text)
print(type(response.text))
parsed = response.json()
print(type(parsed))
print(parsed["userId"])
print(parsed["id"])
print(parsed["title"])
ניתן לראות שהבוקר קלט את הנתונים והצליח לבודד כל אחד מהם להמשך טיפול
56
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
משימה - 14הפעלת צג גרפי דגם SSD1306 OLED display
במשימה זה תלמד כיצד להשתמש בתצוגת OLED SSD1306בגודל 0.96אינץ ' המחוברת לבקר ESP32
באמצעות תכנות ב .MicroPython -במהלך המשימה נלמד להציג הודעות טקסט למרות שמדובר במסך גרפי.
קישורים:
https://randomnerdtutorials.com/micropython-oled-display-esp32-esp8266/
57
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
: ssd1306.py תוכן הקובץ
import time
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
58
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
class SSD1306:
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
self.poweron()
self.init_display()
def init_display(self):
for cmd in (
# address setting
SET_DISP_START_LINE | 0x00,
SET_MUX_RATIO, self.height - 1,
SET_DISP_OFFSET, 0x00,
SET_DISP_CLK_DIV, 0x80,
# display
# charge pump
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
59
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
def poweroff(self):
self.write_cmd(SET_DISP | 0x00)
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_framebuf()
self.framebuf.fill(col)
self.framebuf.pixel(x, y, col)
self.framebuf.scroll(dx, dy)
self.framebuf.text(string, x, y, col)
class SSD1306_I2C(SSD1306):
60
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
# Add an extra byte to the data buffer to hold an I2C data/command byte
# buffer).
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_framebuf(self):
# Blast out the frame buffer using a single I2C transaction to support
self.i2c.writeto(self.addr, self.buffer)
def poweron(self):
pass
class SSD1306_SPI(SSD1306):
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
61
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
def write_cmd(self, cmd):
self.cs.high()
self.dc.low()
self.cs.low()
self.spi.write(bytearray([cmd]))
self.cs.high()
def write_framebuf(self):
self.cs.high()
self.dc.high()
self.cs.low()
self.spi.write(self.buffer)
self.cs.high()
def poweron(self):
self.res.high()
time.sleep_ms(1)
self.res.low()
time.sleep_ms(10)
self.res.high()
62
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
)oled.text('Hello, World 3!', 0, 20
)(oled.show
:Rendering timeהזמן שלוקח לעבד מסגרת ( )frameאחת עבור הצג .זמן זה מושפע מקצב העבודה של
הבקר ,הבקר של עובד בקצב של 200MHzאמור להספיק לביצוע העיבוד.
:Flushing timeהזמן שלוקח להעביר מסגרת אחת למסך .זמן זה מושפע מקצב התקשורת בין הצג למסך.
בפעילות זו התקשורת בין השניים תתבצע דרך ממשק טורי .SPIקצב התקשורת המקסימלי שמסוגל בקר
ESP32להעביר דרך ממשק SPIהוא .40MHzעבור צג בגודל 240*320פיקסלים שבו כל פיקסל בגודל של 16bit
- RGB565אנו זקוקים ל 1228000 -סיביות כדי להעביר מסגרת אחת למסך.
כלומר בקצב עבודה של 40MHzאנו יכולים להעביר למסך מסגרת ב.31msec -
1
𝑀40
𝑐𝑒𝑠𝑚× 1228000 = 31
קישורים:
https://github.com/adafruit/micropython-adafruit-rgb-display/releases
https://cdn-learn.adafruit.com/downloads/pdf/micropython-displays-drawing-shapes.pdf?timestam
p=1570796654
63
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
https://github.com/adafruit/micropython-adafruit-rgb-display
https://www.youtube.com/watch?v=9wsJzVeN_m8
https://github.com/adafruit/micropython-adafruit-gfx
https://www.digikey.co.il/en/maker/projects/3407b01f06f647b48983cd0cdfa8c809
There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins, and is
accessed via the machine.SPI class.
There are two hardware SPI channels that allow faster transmission rates (up to 80Mhz). These may
be used on any IO pins that support the required direction and are otherwise unused (see Pins and
GPIO) but if they are not configured to their default pins then they need to pass through an extra
layer of GPIO multiplexing, which can impact their reliability at high speeds. Hardware SPI channels
are limited to 40MHz when used on pins other than the default ones listed below.
sck 14 18
mosi 13 23
miso 12 19
:מיפוי רגליים
64
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
:מערך החיבורים בין הצג לבקר
D5 CS
D4 D/C
3.3V VCC
GND GND
65
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
RGB565
Especially (cheap) screens used with embedded devices do not provide 24 bit color-depth. Moreover,
storing and/or transmitting 3 bytes per pixel is consuming quite some memory and creates latency.
RGB565 requires only 16 (5+6+5) bits/2 bytes and is commonly used with embedded screens. It
provides 5 bits for Red and Blue and 6 bits for Green. Providing 5 bits for 2 colors and 6 bits for
another seems asymmetric but storing and transmitting something which cannot nicely be packed in
bytes would be complicated. Note that since we have less bits (information) available, we can
represent less colors. While RGB888 provides 2^24=16 777 216 colors, RGB565 only provides
2^16=65 536 colors.
:שאלה
66
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
help('modules')
:להלן הפלט
https://github.com/mcauser/micropython-pcd8544
https://docs.micropython.org/en/latest/esp32/quickref.html
https://github.com/TD-er/fritzing-parts
:מיפוי רגליים
67
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
2 CE Chip enable, active low
7 BL Backlight
8 GND Ground
.בלה בלה
There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins, and is
accessed via the machine.SPI class.
There are two hardware SPI channels that allow faster transmission rates (up to 80Mhz). These may
be used on any IO pins that support the required direction and are otherwise unused (see Pins and
GPIO) but if they are not configured to their default pins then they need to pass through an extra
layer of GPIO multiplexing, which can impact their reliability at high speeds. Hardware SPI channels
are limited to 40MHz when used on pins other than the default ones listed below.
sck 14 18
mosi 13 23
miso 12 19
:מיפוי רגליים
68
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
:מערך החיבורים בין הצג לבקר
RST D2
CS D5
D/C D4
VCC 3.3V
BL D15
GND GND
:שרטוט חשמלי
69
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
:)main.py( קוד התוכנית הראשית
import time
import pcd8544
from machine import Pin, SPI
lcd.fill(1) # fill(color)
lcd.show()
70
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
lcd.fill(0)
lcd.text(' ESP-32', 0, 0, 1) #text(string, x, y, color)
lcd.text(' &', 0, 10, 1)
lcd.text(' PCD-8544', 0, 20, 1)
lcd.text(' LCD', 0, 30, 1)
lcd.text('-----------', 0, 40, 1)
lcd.show()
time.sleep(5)
bl.value(0)
import framebuf
FUNCTION_SET = const(0x20)
POWER_DOWN = const(0x04)
ADDRESSING_VERT = const(0x02)
EXTENDED_INSTR = const(0x01)
DISPLAY_BLANK = const(0x08)
DISPLAY_ALL = const(0x09)
DISPLAY_NORMAL = const(0x0c)
DISPLAY_INVERSE = const(0x0d)
TEMP_COEFF_0 = const(0x04)
TEMP_COEFF_1 = const(0x05)
TEMP_COEFF_3 = const(0x07)
BIAS_1_100 = const(0x10)
BIAS_1_80 = const(0x11)
BIAS_1_65 = const(0x12)
71
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
BIAS_1_48 = const(0x13)
BIAS_1_24 = const(0x15)
BIAS_1_18 = const(0x16)
BIAS_1_10 = const(0x17)
SET_VOP = const(0x80)
# DDRAM addresses
# Display dimensions
WIDTH = const(0x54) # 84
HEIGHT = const(0x30) # 48
class PCD8544:
self.spi = spi
self.width = WIDTH
self.cs.init(self.cs.OUT, value=1)
self.dc.init(self.dc.OUT, value=0)
if self.rst:
self.rst.init(self.rst.OUT, value=1)
self.reset()
self.init()
self.fn = FUNCTION_SET
self.addressing(horizontal)
72
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
self.cmd(DISPLAY_NORMAL)
self.clear()
def reset(self):
self.rst(1)
sleep_us(100)
self.rst(0)
self.rst(1)
sleep_us(100)
def power_on(self):
self.cs(1)
self.cmd(self.fn)
def power_off(self):
self.fn |= POWER_DOWN
self.cmd(self.fn)
for cmd in (
self.fn | EXTENDED_INSTR,
temp,
bias,
SET_VOP | contrast,
self.cmd(cmd)
73
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
self.cmd(DISPLAY_INVERSE if invert else DISPLAY_NORMAL)
def clear(self):
self.position(0, 0)
if horizontal:
else:
self.fn |= ADDRESSING_VERT
self.cmd(self.fn)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([command]))
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(pack('B'*len(data), *data))
self.cs(1)
class PCD8544_FRAMEBUF(PCD8544):
74
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
def fill(self, col):
self.fbuf.fill(col)
self.fbuf.pixel(x, y, col)
self.fbuf.scroll(dx, dy)
# software scroll
self.fbuf.text(string, x, y, col)
self.fbuf.hline(x, y, w, col)
self.fbuf.vline(x, y, h, col)
self.fbuf.rect(x, y, w, h, col)
self.fbuf.fill_rect(x, y, w, h, col)
def show(self):
self.data(self.buf)
75
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
האחד בשם pcd8544.pyוהשני main.pyכמתואר באיור הבא:
נצרוב כל בנפרד את כל אחד ש 2-הקבצים שיצרנו על שימוש בלחצן ""Upload to the current directory
76
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
JSON מבוססAPI - פנימי בבקר תוך שימוש בRTC עדכון- 17 משימה
:קישורים
https://www.hackster.io/alankrantas/very-simple-micropython-esp8266-esp-12-web-clock-3c5c6f
https://gist.github.com/drrk/4a17c4394f93d0f9123560af056f6f30
https://randomnerdtutorials.com/esp32-ntp-client-date-time-arduino-ide/
https://docs.micropython.org/en/latest/esp32/quickref.html#real-time-clock-rtc
https://techtutorialsx.com/2017/06/11/esp32-esp8266-micropython-http-get-requests/
https://docs.micropython.org/en/latest/library/ujson.html
https://www.w3schools.com/python/python_tuples.asp
http://docs.micropython.org/en/v1.9.3/pyboard/library/pyb.RTC.html#pyb.RTC.datetime
:במשימה זו נפתח קוד תוכנה המתחבר לאינטרנט כדי לקבל עדכון זמן דרך הכתובת הבא
http://worldtimeapi.org/api/timezone/Asia/Jerusalem
: הכולל את השעה המדויקת באופן הבאJOSN קישור זה מחזיר לנו מחרוזת טקסט בפורמט
{
"week_number":40,
"utc_offset":"+03:00",
"utc_datetime":"2019-10-01T16:10:25.763035+00:00",
77
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
"unixtime":1569946225,
"timezone":"Asia/Jerusalem",
"raw_offset":7200,
"dst_until":"2019-10-26T23:00:00+00:00",
"dst_offset":3600,
"dst_from":"2019-03-29T00:00:00+00:00",
"dst":true,
"day_of_year":274,
"day_of_week":2,
"datetime":"2019-10-01T19:10:25.763035+03:00",
""client_ip":"77.138.54.225","abbreviation":"IDT
}
נפעיל את קובץ ההרצה EsPy.exeונתחבר לבקר על ידי לחיצה על Deviceו Port -בחר את מספר המפתח
( )Portשאליו מחובר הבקר שלנו
78
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
כתיבת קבצי הקוד:2 שלב
import network
import urequests
import ujson
import utime
from machine import RTC
# wifi connection
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)
while not wifi.isconnected():
pass
print("IP Address:" , str(wifi.ifconfig()[0]))
while True:
if not wifi.isconnected():
machine.reset() # if lose wifi connection reboot ESP32
79
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
if utime.ticks_ms() - update_time >= web_query_delay:
response = urequests.get(url)
if response.status_code == 200: # if query success
#print("Date&Time in JSON format: " + response.text)
js = ujson.loads(response.text) # you can also use parsed =
response.json()
s_dt = str(js["datetime"])
year = int(s_dt[0:4])
month = int(s_dt[5:7])
day = int(s_dt[8:10])
hour = int(s_dt[11:13])
minute = int(s_dt[14:16])
second = int(s_dt[17:19])
subsecond = int(round(int(s_dt[20:26]) / 10000))
# update internal RTC
rtc.datetime((year, month, day, 0, hour, minute, second,
subsecond))
update_time = utime.ticks_ms()
print("RTC updated\n")
dt = rtc.datetime()
s_date = "{:02}/{:02}/{:4}".format(dt[1], dt[2], dt[0])
s_time = "{:02}:{:02}:{:02}".format(dt[4], dt[5], dt[6])
print("Date: " + s_date)
print("Time: " + s_time)
utime.sleep(2)
80
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
נקבל פלט הדומה לזה המוצג כאן:
https://github.com/micropython/micropython/tree/master/drivers/nrf24l01
http://docs.micropython.org/en/v1.9.3/pyboard/library/pyb.SPI.html
משדר מקלט NRF24L01עובד בתדר של 2.4גיגה הרץ .הרכיב מסוגל להעביר תקשורת ספרתית בקצב שבין
250Kbpsעד .2Mbpsבטווח שנע בין סמפר מטרים בחלל סגור ועד 100מטר בחלל פתוח.
מקמ"ש (משדר/מקלט) NRF24L01יכול להשתמש ב 125 -ערוצי תקשורת שונים .כאשר כל עורץ להיות לתקשר
בו זמנית בין יחידה מרכזית אחת יחד עם עד 6יחידות משנה נוספות.
כל ערוץ תקשורת מקבל תדר פנוי בתחום שבין 2.401GHzעד 2.525GHz
81
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
להלן רשימת המאפיינים הטכניים של הרכיב
למרות זאת הדקי הבקרה של הרכיב יכולים.5V ולא3.3V שימו לב לכך שהמקמ"ש עובד במתח עבודה של
.5V המספקים מתחי בקרה ברמה שלArduino UNO להתחבר לבקרים כמו
:מיפוי רגליים
4 - CSN - This pin has to be kept high always, else it will disable the SPI
5 - SCK - Provides the clock pulse using which the SPI communication works
6 - MOSI - Connected to MOSI pin of MCU, for the module to receive data from the MCU
7 - MISO - Connected to MISO pin of MCU, for the module to send data from the MCU
82
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
:NRF24L01 לבין מקמ"שESP32 אופן החיבור בין בקר
There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins, and is
accessed via the machine.SPI class.
There are two hardware SPI channels that allow faster transmission rates (up to 80Mhz). These may
be used on any IO pins that support the required direction and are otherwise unused (see Pins and
GPIO) but if they are not configured to their default pins then they need to pass through an extra
layer of GPIO multiplexing, which can impact their reliability at high speeds. Hardware SPI channels
are limited to 40MHz when used on pins other than the default ones listed below.
sck 14 18
mosi 13 23
83
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
miso 12 19
מיפוי רגליים:
בתרגיל זה נעשה שימוש ב V_SPI -כאשר נשנה את הגדרות הדקי התקשורת שבין הבקר למקמ"ש על ידי
תוכנה .להלן הוראת האתחול של תקשורת SPIבקוד תוך כדי הגדרת הדקי העבודה:
במשימה זו נפתח קוד תוכנה המיצר תקשורת נתונים מבוססת טקסט בין יחידת בסיס ( )Masterלבין 2יחידות
משנה (.)Slave
במשימה נעשה שימוש בשלוש בקרים ESP32המחוברות כל אחת למקמ"ש NRF24L01ועובדים בו זמנית .אחד
מהם מוגדר בתוכנה כ Master -ו 2-האחרים יוגדרו בתוכנה כ.Slave-
כדי לממש את התרגיל נפתח במקביל 3סביבות פיתוח על גבי המחשב ובכל אחת מהם נתחבר לבקר אחר
בהתאם למפתח שאליו מחוברים כל אחד מהבקרים.
84
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
שלב :1חיבור שלוש בקרים למחשב אחד
נפעיל את קובץ ההרצה EsPy.exeשלוש פעמים על אותו המחשב ונתחבר לכל אחד מהבקרים על ידי לחיצה על
Deviceו Port -בחר את מספר המפתח ( )Portשאליו מחובר הבקר שלנו
נפתח קובץ Pythonחדש בכל אחד מהבקרים כדי להעתיק לבקר את קוד המחלקה .NRF2401.py
https://github.com/micropython/micropython/tree/master/drivers/nrf24l01
נצרוב את הקובץ שפתחנו על כל אחד משלוש הבקרים על שימוש בלחצן ""Upload to the current directory
85
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
שימתינו לפניותSalve תוכנות2- קודים ל2-) וMaster( קודים שונים האחד לבקר שיממש את השרת3 נכתבו
.מהשרת
import sys
import ustruct as struct
import utime
from machine import Pin, SPI
from nrf24l01 import NRF24L01
cfg = {'miso': 32, 'mosi': 33, 'sck': 25, 'csn': 26, 'ce': 27}
pipes = (b'\xf0\xf0\xf0\xf0\xe1', b'\xf0\xf0\xf0\xf0\xd2')
print('***************')
print('* Run master! *')
print('***************')
nrf.open_tx_pipe(pipes[0])
nrf.open_rx_pipe(1, pipes[1])
nrf.start_listening()
num_successes = 0
num_failures = 0
led_state = 0
86
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
try:
nrf.send(struct.pack('iiii', lst[0],lst[1],lst[2],lst[3]))
except OSError:
pass
if timeout:
print('Failed, response timed out')
num_failures += 1
else:
rlst = struct.unpack('ii', nrf.recv())
print('Got OK response from slave', rlst[1] ,'in',
utime.ticks_diff(utime.ticks_ms(), rlst[0]), 'ms')
num_successes += 1
utime.sleep_ms(250)
import sys
import ustruct as struct
import utime
from machine import Pin, SPI
from nrf24l01 import NRF24L01
from micropython import const
87
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
cfg = {'miso': 32, 'mosi': 33, 'sck': 25, 'csn': 26, 'ce': 27}
pipes = (b'\xf0\xf0\xf0\xf0\xe1', b'\xf0\xf0\xf0\xf0\xd2')
SLAVE_NUMBER = const(1)
print('************************')
print('* Run slave naumber', SLAVE_NUMBER ,' *')
print('************************')
nrf.open_tx_pipe(pipes[1])
nrf.open_rx_pipe(1, pipes[0])
nrf.start_listening()
while True:
if nrf.any():
while nrf.any():
buf = nrf.recv()
lst = struct.unpack('iiii', buf)
print('received:',lst[0],lst[1],lst[2],lst[3])
utime.sleep_ms(15)
88
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
)(nrf.start_listening
ההבדל היחיד בין 2תוכנות ה Slave -הוא מספרו כפי שמוגדר בשורה הבאה:
)SLAVE_NUMBER = const(1
נצרוב את כל אחד מהקבצים שיצרנו על שימוש בלחצן ""Upload to the current directory
חשוב :תוכנות ה Slave -חייבות לרוץ תחילה לפני הרצת תוכנת ה.Master -זה בגלל שתוכנת ה Master -היא זו
שיוזמת תקשורת עם ה .Slave -והאחרונה (תוכנת ה )Slave -מחזירה ל Master -הודעת אישור .ללא תוכנת
Slaveנקבל הודעת .Failed, response timed out
89
gadi.herman@gmail.comתכנות MicroPythonלמורי הנדסת אלקטרוניקה ומחשבים גדי הרמן
ESP32 תחת בקרMicroPython - בדיקת הספריות הזמינות לתכנות ב- 'נספח א
.בלה בלה
:קישורים
https://docs.micropython.org/en/latest/library/index.html
:שאלה
help('modules')
:להלן הפלט
:קישורים
https://github.com/peterhinch/micropython-async/blob/master/TUTORIAL.md
:התקנה
If micropip.py is not to be used the files should be copied from source. The following instructions
describe copying the bare minimum of files to a target device, also the case where uasyncio is to be
frozen into a compiled build as bytecode. For the latest release compatible with official firmware files
must be copied from the official micropython-lib.
90
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
Clone the library to a PC with
On the target hardware create a uasyncio directory (optionally under a directory lib) and copy the
following files to it:
uasyncio/uasyncio/__init__.py
uasyncio.core/uasyncio/core.py
uasyncio.synchro/uasyncio/synchro.py
uasyncio.queues/uasyncio/queues.py
The uasyncio modules may be frozen as bytecode in the usual way, by placing the uasyncio directory
and its contents in the port's modules directory and rebuilding.
:שאלה
loop = asyncio.get_event_loop()
loop.create_task(bar()) Schedule ASAP
loop.run_forever()
:להלן הפלט
:שאלה
91
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
print("Acquired lock in task", i)
await asyncio.sleep(0.5)
lock.release()
loop = asyncio.get_event_loop()
loop.create_task(task(1, lock))
loop.create_task(task(2, lock))
loop.create_task(task(3, lock))
:להלן הפלט
:שאלה
help('modules')
:להלן הפלט
MicroPython - יעודיים לPIP יבוא ספריות קוד תוך שימוש בכלי- 'נספח ג
.בלה בלה
:קישורים
https://lemariva.com/blog/2018/03/tutorial-installing-dependencies-on-micropython
:שאלה
92
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
def do_connect():
import network
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect(ssid_, wp2_pass)
while not sta_if.isconnected():
pass
print('network config:', sta_if.ifconfig())
do_connect()
import upip
upip.install('notes-pico')
:להלן הפלט
93
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
ESP32 מיפוי הדקי בקר- 'נספח ד
94
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן
תנאי השימוש
:תנאי השימוש במסמך זה האם לפי הסטנדרט הבא
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in
any way that suggests the licensor endorses you or your use.
NonCommercial — You may not use the material for commercial purposes.
ShareAlike — If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
95
למורי הנדסת אלקטרוניקה ומחשביםMicroPython תכנותgadi.herman@gmail.com גדי הרמן