Mündəricat:

OUTOMATİK PET Qida DISPENSERİ: 9 addım
OUTOMATİK PET Qida DISPENSERİ: 9 addım

Video: OUTOMATİK PET Qida DISPENSERİ: 9 addım

Video: OUTOMATİK PET Qida DISPENSERİ: 9 addım
Video: Checking on WellToBe food dispenser 2024, Dekabr
Anonim
AUTOMATİK PET Qida DISPENSERİ
AUTOMATİK PET Qida DISPENSERİ

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ə

Kablolama
Kablolama
Kablolama
Kablolama

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üceyrənizi İstifadə Edin
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ı

Normallaşdırılmış verilənlər bazası
Normallaşdırılmış 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

Son
Son
Son
Son

yekun nəticə: necə tərtib etdik və necə bitdi.

Tövsiyə: