תוכן עניינים:

מחלק מזון אוטומטי לחיות מחמד: 9 שלבים
מחלק מזון אוטומטי לחיות מחמד: 9 שלבים

וִידֵאוֹ: מחלק מזון אוטומטי לחיות מחמד: 9 שלבים

וִידֵאוֹ: מחלק מזון אוטומטי לחיות מחמד: 9 שלבים
וִידֵאוֹ: צפו: דברים שבחיים אסור לעשות לכלב 2024, נוֹבֶמבֶּר
Anonim
מחלק מזון אוטומטי לחיות מחמד
מחלק מזון אוטומטי לחיות מחמד

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

אספקה

פטל פי 3b

תא עומס בר (10 ק ג)

מגבר תא עומס HX711

חיישן דרגת מים (https://www.dfrobot.com/product-1493.html)

חיישן קרבה קולי

LCD 16 פינים

מנוע צעד 2x28byj-48

2 x נהג מנוע צעד ULN2003

שלב 1: חיווט

תִיוּל
תִיוּל
תִיוּל
תִיוּל

הרבה כבלים כאן. הוציאו את כבלי המגשר והתחילו להצמיד!

שלב 2: הפוך את תא המטען שלך לשמיש

הפוך את תא המטען שלך לשמיש
הפוך את תא המטען שלך לשמיש

כדי להשתמש בתא המטען, תחילה עלינו לחבר אותו לשתי צלחות: צלחת תחתונה, וצלחת עליה נשקלל את האוכל שלנו.

הברגים שאתה צריך הם זוג ברגי M4 עם ברגים תואמים וזוג ברגי M5 עם ברגים תואמים. השתמשתי במקדח קטן כדי ליצור את החורים.

(תמונה:

שלב 3: מסד נתונים מנורמל

מסד נתונים מנורמל
מסד נתונים מנורמל

יש לשמור את הנתונים מהחיישנים שלנו במסד נתונים. לחיבור קבצי פייתון למסד הנתונים: ראה להלן.

אז אתה צריך גם קובץ config:

[connector_python] user = * שם המשתמש שלך * host = 127.0.0.1 #if יציאה מקומית = 3306 סיסמה = * yourpassword * database = * yourdb * [application_config] driver = 'שרת SQL'

שלב 4: קידוד תא הטעינה

ייבוא RPi. GPIO כ- GPIO ייבוא השחלת זמן ייבוא מ- hx711 יבוא HX711 מה- helpers.stepper ייבוא מזון Stepper מזון מסייעים. LCDWrite יבוא LCDWrite ממאגרים.

לאחר ייבוא כל הספריות שלנו (שימו לב, אנו משתמשים בספריית HX711 כדי להניע את תא הטעינה) נוכל להתחיל לכתוב את הקוד האמיתי שלנו.

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

כדי לברר את הקבועים שלנו, הגדר תחילה TARRA_CONSTANT = 0 ו- GRAM_CONSTANT = 1.

לאחר מכן עלינו לברר את הערך שבו תא העומס שלנו קורא כאשר אין שום משקל. ערך זה יהיה TARRA_CONSTANT.

באשר ל- GRAM_CONSTANT, פשוט קח חפץ שאתה יודע את משקלו (השתמשתי בחפיסת ספגטי), שקל אותו וחלק את קריאת תאי העומס עם המשקל האמיתי של האובייקט. בשבילי זה היה 101.

class LoadCell (threading. Thread):

def _init _ (self, socket, lcd): threading. Thread._ init _ (self) self.hx711 = HX711 (dout_pin = 5, pd_sck_pin = 6, channel = 'A', gain = 64) self.socket = socket self.lcd = lcd

כאן אנו מאתחלים את מחלקת LoadCell וממפים את הסיכות.

ריצה Def (עצמי):

נסה: בעוד נכון: self.hx711.reset () # לפני שנתחיל, אפס את HX711 (לא חייב) Measures_avg = sum (self.hx711.get_raw_data ()) / 5 weight = round ((Measures_avg - TARRA_CONSTANT) / GRAM_CONSTANT, 0) הדפס ("משקל: {0}". פורמט (משקל)) DataRepository.insert_weight (משקל) data_weight = DataRepository.get_data_sensor (3) historyId = data_weight ["SensorsHistory"] db_weight = data_weight ["value"] actionTime = data_weight ["actionTime"] self.socket.emit ('data_weight', {"id": historyId, "Weight": db_weight, "Time": DataRepository.serializeDateTime (actionTime)}) print ("zou צריך emitten") writeWeight = "weight:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) למעט חריגה כתור: הדפסה ("שגיאה בשקילה" + str (e))

שלב 5: קידוד חיישן המים

ייבוא threadimport threading from repositories. DataRepository ייבוא DataRepository מ- RPi יבוא GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) Class WaterSensor (threading. Thread): _in self, socket): threading. Thread._ init _ (self) self.socket = socket self.vorige_status = 0 def run (self): try: while True: water = self.is_water () print (water) status = water [" status "] action = water [" action "] DataRepository.insert_water (str (status), action) data_water = DataRepository.get_data_sensor (2) historyId = data_water [" SensorsHistory "] value = data_water [" value "] if value == "0": value = "te weinig water" else: value = "מספיק מים" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": value, "Time": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) למעט חריגה כמו ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO. קלט (GPIO_Wate r) if self.vorige_status == 0 ו- status == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water) אם self.vorige_status == 1 ו- status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 ו- status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) אם self.vorige_status == 0 ו- status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} החזר sensorData

שלב 6: קידוד חיישן הקרבה

ייבוא threading זמן ייבוא ממאגרים. DataRepository ייבוא DataRepository מ- RPi יבוא GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup (GPIO_Trig, GPIO. OUT) GPIO.seto (GPIOE. IN) def current_milli_time (): return int (round (time.time () * 1000)) class UltrasonicSensor (threading. Thread): def _init _ (self, socket): threading. Thread._ init _ (self) self.socket = socket def run (self): try: last_reading = 0 interval = 5000 while True: if current_milli_time ()> last_reading + interval: dist = self.distance () print ("Distance Distance = %.1f cm" % dist) DataRepository. insert_proximity (dist) data_prox = DataRepository.get_data_sensor (1) historyId = data_prox ["SensorsHistory"] prox = data_prox ["value"] actionTime = data_prox ["actionTime"] self.socket.emit ('data_proximity', {"id": historyId, "Proximity": prox, "Time": DataRepository.serializeDateTime (actionTime)}) last_reading = current_milli_time () למעט חריגה כמו ex: print (ex) de f מרחק (עצמי): # הגדר טריגר ל- HIGH GPIO.output (GPIO_Trig, True) # הגדר טריגר לאחר 0.01ms לזמן נמוך. שינה (0.00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # שמור StartTime בעוד GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # שמור את זמן ההגעה בעוד GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # הפרש הזמן בין התחלה להגעה TimeElapsed = StopTime - StartTime # הכפל עם המהירות הקולית (34300 ס"מ / שניות) # וחלק ב 2, כי שם וחזרה מרחק = (TimeElapsed * 34300) / 2 מרחק החזרה

שלב 7: קידוד מנועי הצעדים

ייבוא RPi. GPIO כ- GPIO ייבוא זמן שרשור ייבוא GPIO.setmode (GPIO. BCM) GPIO.setwarnings (שקר) control_pins = [12, 16, 20, 21] עבור סיכה ב- control_pins: GPIO.setup (pin, GPIO. OUT) GPIO. פלט (סיכה, 0) halfstep_seq =

קוד זה ניתן לשימוש חוזר עבור מנוע הצעד השני, פשוט הגדר את מספרי סיכת הבקרה לפינים החוזרים שלהם ושנה את שם המחלקה ל- StepperWater:

שלב 8: קידוד ה- LCD

הרבה קוד, אבל כמעט סיימנו.

מחלקת ה- LCD כלולה כקובץ LCD.py

מ- helpers. LCD ייבוא LCD

E = 26 RS = 25 D0 = 19 D1 = 13 D2 = 24 D3 = 22 D4 = 23 D5 = 8 D6 = 7 D7 = 10 lcd = LCD (E, RS, [D0, D1, D2, D3, D4, D5, D6, D7]) Class LCDWrite: def message (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (הודעה, '1') למעט: print ("שגיאת LCDWrite")

שלב 9: הסוף

הסוף
הסוף
הסוף
הסוף

התוצאה הסופית: איך ציירנו את זה לעומת איך שזה נגמר.

מוּמלָץ: