קלט אנלוגי ודיגיטלי עם ESP32

כל מיקרובקר יודע גם לקבל מידע מהסביבה - פה נסביר איך באמצעות חיישנים.

אחרי שלמדנו מעט אלקטרוניקה ומעגל חשמלי עם ESP32 על מנת להפעיל נורת LED במאמר הקודם, הגיע הזמן לקחת את הידע שצברנו הלאה ולחבר למיקרו בקר הזה גם משהו שמכניס מידע. למה? כי מה שיפה בציוד IoT שהוא לא רק יכול לבצע פלט (כמו להדליק נורה) אלא גם לקבל מידע מהסביבה ולפעול בהתאם או לשגר את המידע הלאה.

יש לא מעט חיישנים – חלק מהם דיגיטליים וחלק מהם אנלוגיים. ESP32 יודע לעבוד עם שניהם. ראשית – מאיפה משיגים חיישנים? במקרה הזה שוב עליאקספרס שבו אפשר לקנות קיטים של חיישנים ממש בדולרים בודדים. אפשר לחפש Arduino sensors kits (מה שטוב לארדואינו טוב גם לנו) ולראות שאפשר לקנות קיט של עשרות חיישנים ב-10 דולר כולל משלוח. יש עוד דילים שונים ומשונים. צריך לזכור שהסנסורים האלו הם לא מדויקים מי יודע מה אבל הם מספיק טובים לשימושים לא תעשייתיים.

לכל חיישן יש פינים עם כיתוב עליהם. הנה למשל חיישן שמזהה קול שאני מאד אוהב להשתמש בו.

אפשר לראות שבזה יש ארבעה פינים:

+ – עבור המתח.
G – עבור גראונד.
DO – ראשי תבות של פלט דיגיטלי (Digital Output)
AO – ראשי תבות של פלט אנלוגי (Analog Output)

יש סיכוי שבחיישן שלכם יהיה למשל רק שלושה פינים – אחד של פלט אנלוגי בלבד בלי דיגיטלי או רק דיגיטלי – וזה בסדר גמור. יש כל כך הרבה חיישנים אבל אפשר לעבוד עם כולם ובקלות.

החיבור הוא פשוט – אנו נפתח את מפת ה-pinout שלנו ונחבר עם קונקטורים מתאימים את החיישן ל-ESP32.

חיבור הפלוס הוא לפין המוציא מתח באופן קבוע, ה-G עבור הגראונד. אנו נחבר את הפלט האנלוגי לפין מתאים. הפעם לא כל פין מתאים ואנו צריכים לבחור ב-ADC. יש לא מעט פינים כאלו. אני בחרתי בחיבור הנוכחי ב-GPIO36 אבל אם יש לכם ESP32 אחר אז ייתכן שתרצו מספר פין אחר. מה שחשוב הוא שיהיה לו את סימול ADC.

אם נחבר את הכל כמו שצריך, בחיישן יידלקו נורות LED אדומות שמראות שהוא מקבל מתח מה-ESP32.

זה קל – אבל עכשיו מגיעה עבודת התכנות. נפתח את ה Thonny הנאמן שלנו ונכתוב סקריפט שיאזין ל GPIO36.

מה שאנו אמורים לקבל ממנו זה מתח. מה זאת אומרת? החיישן קולט סאונד מהסביבה וממיר את גלי הקול למתח חשמלי שאותו אנו יכולים לקלוט ולהמיר לנתון דיגיטלי. ווליום גבוה – מתח חשמלי גבוה. אנחנו נשתמש פה כמובן במודול machine אבל הפעם, אנו מגדירים את הפין כפין קלט – כלומר מקבלים ממנו מידע ולא סתם מידע אלא מידע אנלוגי. זה נעשה באמצעות machine.ADC שמקבלת כארגומנט את הפין והקריאה נעשית באמצעות read.

האמת שהקוד כה פשוט שהוא ממש מסביר את עצמו:

import machine
import time

# Define the pin number for the sensor
analog_pin = 36

# Set up the ADC (Analog to Digital Converter) for the analog pin
adc = machine.ADC(machine.Pin(analog_pin))

# Function to read the sound level
def read_sound_level():
    return adc.read()


while True:
    sound_level = read_sound_level()
    print("Sound Level:", sound_level)  
    time.sleep(0.1)

אם נטען אותו לתוך Thonny. אנו נוכל לראות בקונסולה את פלט עוצמת הקול כפי שמתקבלת מהחיישן!

תקלות נפוצות

ב-99 אחוז מהפעמים זה לא יעבוד כמובן וזה בגלל טעויות חיווט: אם אתם מקבלים 0 באופן קבוע או מספר קבוע כמו ״4095״ אז כדאי לשים לב שאתם באמת חיברתם את ה-AO לפין ב-ESP32 – שזה קורה לא מעט פעמים. שימו לב שלא חיברתם בטעות את ה-DO.

רגישות ופוטנציומטר

יש סיכוי שתקבלו ערכים שונים גבוהים או נמוכים מדי – למה? כי צריך לכייל את החיישן. איך? יש פוטנציומטר – ריבוע כחול קטן עם בורג זהוב – מסובבים את הבורג עם כיוון השעון כדי להגדיל רגישות ונגד כיוון השעון כדי להפחית נגישות. אם תעשו את זה עם הקוד – תוכלו לראות איך המספר של הרעש הסביבתי משתנה ככל שתסובבו יותר.

אפשר למחוא כפיים, לדפוק על השולחן או לצווח כדי לראות איך הרעש משתנה ולזכור לרשום את הערך הסביבתי ואת הערך שמתקבל כשמוחאים כפיים. למה? בשביל הנקודה הבאה:

שימושים

טוב, לראות את רמת הרעש זה נחמד, אבל מה אפשר באמת לעשות עם זה? מה דעתכם על חיישן שמזהה מחיאת כף כפולה? במקרה הזה הקוד פשוט:

import machine
import time

# Define the pin number for the sensor
analog_pin = 36

# Set up the ADC (Analog to Digital Converter) for the analog pin
adc = machine.ADC(machine.Pin(analog_pin))

# Threshold to determine if sound is detected
sound_threshold = 500

# Variables for tracking handclaps
clap_count = 0
last_clap_time = 0
time_between_claps = 1.0  # Time in seconds between two claps

def read_sound_level():
    return adc.read()

def detect_double_clap():
    global clap_count, last_clap_time
    
    current_time = time.time()
    sound_level = read_sound_level()

    if sound_level > sound_threshold:
        if current_time - last_clap_time < time_between_claps:
            clap_count += 1
            last_clap_time = current_time
        else:
            clap_count = 1
            last_clap_time = current_time
    
    if clap_count == 2:
        print("Double handclap detected!")
        clap_count = 0

while True:
    detect_double_clap()
    time.sleep(0.1)

מה שחשוב פה הוא ה:sound_threshold = 500 שהגדרתי אותו כ-500. אבל יכול להיות שאצלכם הוא יהיה שונה בגלל רגישות החיישן והפוטנציומטר שהסברתי עליו קודם.

ומה אפשר לעשות עם חיישן שמאבחן מחיאת כף כפולה? אפשר להדליק LED כחול או… להשמיע מוזיקה סליזית של שנות השבעים באמצעות בלוטות׳ ורמקול קטן! דבר שיהפוך את הדייט הרומנטי לבלתי נשכח. איך? לא לשכוח ש-ESP32 יודע לעבוד היטב עם מכשירי בלוטות׳ ועל זה נדבר במאמר הבא.

מה שראינו כאן הוא כמה קל לעבוד עם חיישנים מכל הסוגים ואפשר גם לשלב – בואו ונחבר גם חיישן קרבה בשם sr602 שלו דווקא יש פלט דיגיטלי. קניתי את החיישן הזה בנפרד כי רציתי חיישן ברמה גבוהה יותר והוא עלה לי 60 סנט כולל משלוח.

לחיישן יש שלושה פינים – אחד המסומן בפלוס, בשני במינוס והשלישי ב-Out. קל כבר להבין מה הולך לכל מקום.

+ – עבור המתח.
– – עבור גראונד.
OUT – עבור פין שיכול לקבל קלט דיגיטלי. שזה כל GPIO.

כיוון של-ESP32 יש כמה פיני גראונד וגם כמה פיני מתח. פשוט הצצתי ב-pinout וחיברתי את הפלוס והמינוס יחד עם החיישן. את הקלט הדיגיטלי חיברתי ל GPIO18 באופן שרירותי למדי.

אחרי שחיברתי, אפעיל את הקוד הזה עם Thonny. רק כדי לראות שהכל בסדר והוא עובד.

import machine
import time

# Define the pin number for the sensor
pir_pin = 18

# Set up the PIR sensor pin as an input
pir_sensor = machine.Pin(pir_pin, machine.Pin.IN)

while True:
    if pir_sensor.value() == 1:
        print("Motion detected!")
    else:
        print("No motion detected.")
    time.sleep(0.1)

כיוון שמדובר בקלט דיגיטלי – אז יש לי כאן 0 או אחד ולא ערכים כמו בחיישן הסאונד. מה שמתאים לי מאד ומפשט את הקוד. אם אני אפעיל את הקוד ב-Thonny, אני אוכל לראות בקונסולה אם החיישן עובד.

אם הוא לא עובד – כמובן שצריך לבדוק את החיבורים.

אם הוא עובד, יש לי בעצם ESP32 שמחוברים לו שני חישנים ועכשיו זה עניין של קוד בלבד. למשל להפעיל את בדיקת מחיאת הכפיים רק 5 שניות אחרי שהוא מזהה תנועה.

import machine
import time

# Define pin numbers for sensors
pir_pin = 18  # SR602 PIR sensor
sound_pin = 36  # Sound detection sensor (analog)

# Set up the PIR sensor pin as an input
pir_sensor = machine.Pin(pir_pin, machine.Pin.IN)

# Set up the ADC (Analog to Digital Converter) for the sound sensor
adc = machine.ADC(machine.Pin(sound_pin))

# Threshold for sound detection
sound_threshold = 200

# Time interval to allow double clap after motion detection (in seconds)
double_clap_interval = 5

def read_sound_level():
    return adc.read()

def is_double_clap_detected():
    sound_levels = []
    start_time = time.time()
    
    while time.time() - start_time < double_clap_interval:
        sound_level = read_sound_level()
        sound_levels.append(sound_level)
        
        if sound_level > sound_threshold:
            if len(sound_levels) >= 2:
                return True
    
    return False

while True:
    if pir_sensor.value() == 1:
        print("Motion detected!")
        
        if is_double_clap_detected():
            print("Double clap detected within 5 seconds of motion!")
    
    time.sleep(0.1)

אז בואו ונסכם מה למדנו – למדנו לחבר חיישנים שונים על מנת לקבל נתונים מהסביבה ולעבוד איתם באמצעות ESP32. גם נתונים בפורמט אנלוגי וגם דיגיטלי. זה כבר ממש מעניין במיוחד בהתחשב בכך שיש לנו גם חיבור בלוטות׳ וגם חיבור WiFi ואנחנו יכולים לשלוח קריאות או להציג את הנתונים בשרת ווב ממש.

במאמר הבא אנו עושים את זה בדיוק – חיבור חיישן גזים והפעלת שרת אינטרנט שמציג את התוצאות.

פוסטים נוספים שכדאי לקרוא

פתרונות ומאמרים על פיתוח אינטרנט

יישום של nonce על מנת להגן מפני התקפות injection

בפוסט הקודם הסברתי על hash עם CSP על משאבי inline – שזה נחמד ומעולה אבל פחות ישים בעולם האמיתי שבו בדרך כלל התוכן ה-inline (בין

גלילה לראש העמוד