Πίνακας περιεχομένων:

AUTOMATIC PET FOOD DISPENSER: 9 Βήματα
AUTOMATIC PET FOOD DISPENSER: 9 Βήματα

Βίντεο: AUTOMATIC PET FOOD DISPENSER: 9 Βήματα

Βίντεο: AUTOMATIC PET FOOD DISPENSER: 9 Βήματα
Βίντεο: Собаку и 9 щенков выбросили из машины, но произошло нечто невероятное! 2024, Νοέμβριος
Anonim
ΑΥΤΟΜΑΤΟΣ ΔΙΑΔΟΤΗΣ ΤΡΟΦΙΜΩΝ ΓΙΑ ΤΑ ΖΩΑ
ΑΥΤΟΜΑΤΟΣ ΔΙΑΔΟΤΗΣ ΤΡΟΦΙΜΩΝ ΓΙΑ ΤΑ ΖΩΑ

Έχετε νιώσει ποτέ να χάνετε πολύ χρόνο για να ταΐζετε το κατοικίδιο ζώο σας; Έπρεπε ποτέ να καλέσετε κάποιον για να ταΐσει τα κατοικίδια σας ενώ ήσασταν σε διακοπές; Προσπάθησα να διορθώσω και τα δύο αυτά ζητήματα με το τρέχον σχολικό μου έργο: Petfeed!

Προμήθειες

Raspberry Pi 3b

Κυψέλη φορτίου μπαρ (10kg)

HX711 Ενισχυτής κυψέλης φορτίου

Αισθητήρας Waterlevel (https://www.dfrobot.com/product-1493.html)

Αισθητήρας εγγύτητας υπερήχων

LCD 16 ακίδων

2x βηματικό μοτέρ 28byj-48

2x οδηγός βηματικού κινητήρα ULN2003

Βήμα 1: Καλωδίωση

Καλωδίωση
Καλωδίωση
Καλωδίωση
Καλωδίωση

πολλά καλώδια εδώ. Βγάλτε τα καλώδια από το βραχυκυκλωτήρα σας και ξεκινήστε να καρφιτσώνετε!

Βήμα 2: Κάντε το κελί φορτίου σας χρήσιμο

Κάντε το κελί φορτίου σας χρήσιμο
Κάντε το κελί φορτίου σας χρήσιμο

για να χρησιμοποιήσουμε τη κυψέλη φορτίου, πρέπει πρώτα να την συνδέσουμε σε δύο πλάκες: μια κάτω πλάκα και μια πλάκα στην οποία θα ζυγίσουμε το φαγητό μας.

Οι βίδες που χρειάζεστε είναι ένα ζευγάρι βίδες Μ4 με αντίστοιχα μπουλόνια και ένα ζεύγος βιδών Μ5 με αντίστοιχα μπουλόνια. Χρησιμοποίησα ένα μικρό τρυπάνι για να κάνω τις τρύπες.

(εικόνα:

Βήμα 3: Κανονικοποιημένη βάση δεδομένων

Κανονικοποιημένη βάση δεδομένων
Κανονικοποιημένη βάση δεδομένων

τα δεδομένα από τους αισθητήρες μας πρέπει να αποθηκευτούν σε μια βάση δεδομένων. Για να συνδεθούν τα αρχεία python στη βάση δεδομένων: δείτε παρακάτω.

τότε χρειάζεστε επίσης ένα αρχείο διαμόρφωσης:

[connector_python] user = * yourusername * host = 127.0.0.1 #if local port = 3306 password = * yourpassword * database = * yourdb * [application_config] πρόγραμμα οδήγησης = 'SQL Server'

Βήμα 4: Κωδικοποίηση του κελιού φόρτωσης

εισαγωγή RPi. GPIO ως GPIOimport νήμα χρόνου εισαγωγής από hx711 εισαγωγή HX711 από βοηθούς. stepperFood εισαγωγή StepperFood από βοηθούς. LCD Εγγραφή εισαγωγής LCD Γράψτε από αποθετήρια. DataRepository import DataRepository

Αφού εισαγάγουμε όλες τις βιβλιοθήκες μας (σημειώστε ότι χρησιμοποιούμε τη Βιβλιοθήκη HX711 για να οδηγήσουμε το κελί φόρτωσης) μπορούμε να αρχίσουμε να γράφουμε τον πραγματικό μας κώδικα

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Για να μάθετε τις σταθερές μας, ορίστε πρώτα TARRA_CONSTANT = 0 και GRAM_CONSTANT = 1.

Στη συνέχεια πρέπει να μάθουμε την τιμή που διαβάζει το κελί φορτίου μας όταν δεν ζυγίζεται τίποτα. Αυτή η τιμή θα είναι TARRA_CONSTANT.

Όσο για το GRAM_CONSTANT, απλά πάρτε ένα αντικείμενο για το οποίο γνωρίζετε το βάρος (χρησιμοποίησα ένα πακέτο μακαρόνια), ζυγίστε το και διαιρέστε την ανάγνωση της κυψέλης φορτίου με το πραγματικό βάρος του αντικειμένου. Για μένα αυτό ήταν 101.

κλάση 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 run (self):

try: while True: self.hx711.reset () # Πριν ξεκινήσουμε, επαναφέρετε το HX711 (δεν είναι υποχρεωτικό) μέτρα_avg = άθροισμα (self.hx711.get_raw_data ()) / 5 βάρος = γύρο ((μέτρα_avg - TARRA_CONSTANT) / GRAM_CONSTANT, 0) print ("weight: {0}". Format (weight)) DataRepository.insert_weight (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 moeten emitten") writeWeight = "weight:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) εκτός Εξαίρεση ως e: print ("Σφάλμα ζύγισης" + str (e))

Βήμα 5: Κωδικοποίηση του αισθητήρα νερού

εισαγωγή χρόνου εισαγωγής νήματος από αποθετήρια. DataRepository εισαγωγή δεδομένωνRepository από RPi εισαγωγή GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) class WaterSensor def (threading. Th) 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 [" κατάσταση "] 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 = "genoeg water" 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) εάν self.vorige_status == 0 και κατάσταση == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water) if self.vorige_status == 1 και status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) εάν self.vorige_status == 1 και κατάσταση == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) εάν self.vorige_status == 0 και κατάσταση == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

Βήμα 6: Κωδικοποίηση του αισθητήρα εγγύτητας

εισαγωγή χρόνου εισαγωγή νήματος από αποθετήρια. DataRepository εισαγωγή δεδομένωνRepository από RPi εισαγωγή GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup (GPIO_Trig, GPIO. OUE). 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 ("Measured 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 απόσταση (εαυτός): # set Trigger to HIGH GPIO.output (GPIO_Trig, True) # set Trigger after 0.01ms to LOW time.sleep (0.00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # save StartTime while GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # εκτός χρόνου άφιξης ενώ GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # διαφορά ώρας μεταξύ έναρξης και άφιξης TimeElapsed = StopTime - StartTime # πολλαπλασιάστε με την ηχητική ταχύτητα (34300 cm / s) # και διαιρέστε με 2, επειδή εκεί και πίσω απόσταση = (TimeElapsed * 34300) / 2 απόσταση επιστροφής

Βήμα 7: Κωδικοποίηση των Stepper Motors

εισαγωγή RPi. GPIO ως GPIOimport time import threading GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] for pin in control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.έξοδος (καρφίτσα, 0) halfstep_seq =

Αυτός ο κωδικός είναι επαναχρησιμοποιήσιμος για τον άλλο βηματικό κινητήρα, απλώς ορίστε τους αριθμούς των ακίδων ελέγχου στις αντίστοιχες ακίδες τους και μετονομάστε την κλάση σε StepperWater:

Βήμα 8: Κωδικοποίηση της οθόνης LCD

Πολλοί κωδικοί, αλλά σχεδόν τελειώσαμε.

Η κλάση LCD περιλαμβάνεται ως αρχείο LCD.py

από βοηθούς. 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]) LCD classWrite: def message (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') εκτός: εκτύπωση ("σφάλμα LCDWrite")

Βήμα 9: Το τέλος

Το τέλος
Το τέλος
Το τέλος
Το τέλος

τελικό αποτέλεσμα: πώς το σχεδιάσαμε έναντι του πώς κατέληξε.

Συνιστάται: