Mündəricat:
- Təchizat
- Addım 1: Kabel çəkmə
- Addım 2: Yük Hüceyrənizi İstifadə Edin
- Addım 3: Normalize Verilənlər Bazası
- Addım 4: Yük Hüceyrəsinin Kodlaşdırılması
- Addım 5: Su Sensorunun Kodlaşdırılması
- Addım 6: Yaxınlıq Sensorunun Kodlaşdırılması
- Addım 7: Stepper Motorlarının Kodlaşdırılması
- Addım 8: LCD -nin kodlaşdırılması
- Addım 9: Son
Video: OUTOMATİK PET Qida DISPENSERİ: 9 addım
2025 Müəllif: John Day | [email protected]. Son dəyişdirildi: 2025-01-13 06:56
Ev heyvanınızı qidalandırmaq üçün çox vaxt sərf etmək kimi hiss etdinizmi? Tətildə olarkən ev heyvanlarınızı qidalandırmaq üçün kiməsə zəng etməli oldunuzmu? Hazırkı məktəb layihəmlə hər iki problemi həll etməyə çalışdım: Petfeed!
Təchizat
Moruq Pi 3b
Bar Yük Hücrəsi (10 kq)
HX711 Yük Hüceyrə Gücləndiricisi
Su səviyyəsi sensoru (https://www.dfrobot.com/product-1493.html)
Ultrasonik yaxınlıq sensoru
LCD 16 pinli
2x step motor 28byj-48
2x step motor sürücüsü ULN2003
Addım 1: Kabel çəkmə
burada çoxlu kabel xətləri çəkilir. Tullanan kabellərinizi çıxarın və bağlamağa başlayın!
Addım 2: Yük Hüceyrənizi İstifadə Edin
yük hücrəsini istifadə etmək üçün əvvəlcə iki lövhəyə yapışdırmalıyıq: alt boşqab və yeməyimizi çəkəcəyimiz bir boşqab.
Lazım olan vintlər, uyğun boltlu M4 vida və uyğun boltlu M5 vintlərdir. Delikləri düzəltmək üçün kiçik bir qazma istifadə etdim.
(şəkil:
Addım 3: Normalize Verilənlər Bazası
Sensorlarımızdakı məlumatlar bir verilənlər bazasında saxlanılmalıdır. Python fayllarının verilənlər bazasına qoşulması üçün: aşağıya baxın.
sonra bir konfiqurasiya faylına da ehtiyacınız var:
[connector_python] user = * istifadəçi adınız * host = 127.0.0.1 #if lokal port = 3306 parol = * şifrəniz * verilənlər bazası = * yourdb * [application_config] sürücüsü = 'SQL Server'
Addım 4: Yük Hüceyrəsinin Kodlaşdırılması
RPi.
Bütün kitabxanalarımızı idxal etdikdən sonra (yük hüceyrəsini idarə etmək üçün HX711 Kitabxanasından istifadə edirik) faktiki kodumuzu yazmağa başlaya bilərik.
TARRA_CONSTANT = 80600
GRAM_CONSTANT = 101
Sabitlərimizi öyrənmək üçün əvvəlcə TARRA_CONSTANT = 0 və GRAM_CONSTANT = 1 təyin edin.
Sonra heç bir şey ölçülmədikdə yük hüceyrəmizin oxuduğu dəyəri öyrənməliyik. Bu dəyər TARRA_CONSTANT olacaq.
GRAM_CONSTANT -a gəldikdə, ağırlığını bildiyiniz bir obyekti götürün (mən bir paket spagetti istifadə etdim), çəkin və yük hüceyrəsinin oxunmasını obyektin həqiqi çəkisinə bölün. Mənim üçün bu 101 idi.
sinif LoadCell (threading. Thread):
def _init _ (özünü, yuva, lcd): iş parçacığı = lcd
burada LoadCell sinifini işə salırıq və sancaqları xəritəyə salırıq.
def run (özünü):
cəhd edin: while True: self.hx711.reset () # Başlamadan əvvəl, HX711 (məcburi deyil) tədbirlərini sıfırlayın_avg = sum (self.hx711.get_raw_data ()) / 5 çəki = yuvarlaq ((ölçülər_avg - TARRA_CONSTANT) / QRAM_DAVANI, 0) çap ("çəki: {0}". Format (çəki)) DataRepository.insert_weight (çəki) 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)}) yazdırın ("çox yayılmış") writeWeight = "weight:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) istisna olmaqla, e: print kimi ("Ölçmə xətası" + str (e))
Addım 5: Su Sensorunun Kodlaşdırılması
DataRepository, RPi -dən GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (Yanlış) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) sinif WaterSensor (threading. Thread): Def _init _ self, socket): threading. Thread._ init _ (self) self.socket = socket self.vorige_status = 0 def run (self): cəhd edin: while True: water = self.is_water () print (water) status = water [" status "] hərəkət = su [" hərəkət "] DataRepository.insert_water (str (status), hərəkət) data_water = DataRepository.get_data_sensor (2) historyId = data_water [" SensorsHistory "] dəyər = data_water [" dəyər "] əgər dəyər == "0": value = "te weinig water" else: value = "genoeg water" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": dəyər, "Zaman": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) ex istisna istisna olmaqla: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO. Giriş (GPIO_Wate r) əgər self.vorige_status == 0 və status == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water) əgər self.vorige_status == 1 və status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 və status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) self.vorige_status == 0 və status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData
Addım 6: Yaxınlıq Sensorunun Kodlaşdırılması
məlumatları depodan daxil edin. DataRepository, RPi -dən DataRepository idxal GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (Yanlış) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup (GPIO_Trig, GPIO. OUT) GPIO.seto, GPIO_Echo (GPIO_Echo). 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): cəhd edin: last_reading = 0 interval = 5000 isə Doğru: current_milli_time ()> last_reading + interval: dist = self.distance () print ("Ölçülmüş Məsafə = %.1f sm" % 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, "Yaxınlıq": prox, "Zaman": DataRepository.serializeDateTime (actionTime)}) last_reading = current_milli_time () ex istisna istisna olmaqla: print (ex) de f məsafəsi (özünü): # Tetikleyicini YÜKSEK GPIO. çıxışı (GPIO_Trig, Doğru) olaraq təyin edin # Tətiyi 0.01ms -dən sonra LOW vaxta qoyun. yuxu (0.00001) GPIO.çıxış (GPIO_Trig, Yanlış) StartTime = time.time () StopTime = time.time () # GPIO.input (GPIO_Echo) zamanı StartTime saxla == 0: StartTime = time.time () # GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # başlanğıc və gəliş arasındakı vaxt fərqi TimeElapsed = StopTime - StartTime # sonic sürəti (34300 sm / s) # ilə çoxalın və 2 -yə bölün, çünki ora və geri məsafə = (TimeElapsed * 34300) / 2 geri dönüş məsafəsi
Addım 7: Stepper Motorlarının Kodlaşdırılması
GPIO.setmode (GPIO. BCM) GPIO.setwarnings (Yanlış) control_pins = [12, 16, 20, 21] pin_pins üçün pin: GPIO.setup (pin, GPIO. OUT) GPIO.çıxış (pin, 0) halfstep_seq =
Bu kod digər step motor üçün təkrar istifadə edilə bilər, sadəcə nəzarət pin nömrələrini düzəldici pinlərinə qoyun və sinfin adını StepperWater olaraq dəyişdirin:
Addım 8: LCD -nin kodlaşdırılması
Çox kod var, amma demək olar ki, bitirdik.
LCD sinfi LCD.py faylı olaraq daxil edilir
köməkçilərdən. LCD idxal 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]) sinif LCDWrite: def mesajı (msg): cəhd edin: çap edin ("cəhd edin") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') istisna olmaqla: çap ("LCDWrite xətası")
Addım 9: Son
yekun nəticə: necə tərtib etdik və necə bitdi.