Სარჩევი:

შინაური ცხოველების საკვების ავტომატური დისპენსერი: 9 ნაბიჯი
შინაური ცხოველების საკვების ავტომატური დისპენსერი: 9 ნაბიჯი

ვიდეო: შინაური ცხოველების საკვების ავტომატური დისპენსერი: 9 ნაბიჯი

ვიდეო: შინაური ცხოველების საკვების ავტომატური დისპენსერი: 9 ნაბიჯი
ვიდეო: ძაღლის კვება ჩემებური მეთოდით 2024, ნოემბერი
Anonim
შინაური ცხოველების საკვების ავტომატური დისპენსერი
შინაური ცხოველების საკვების ავტომატური დისპენსერი

ოდესმე გიგრძვნიათ ზედმეტი დროის დაკარგვა თქვენი შინაური ცხოველის კვებაზე? ოდესმე გიწევდათ ვინმესთან დარეკვა, რათა თქვენი შინაური ცხოველები გამოეკვებებინათ დასვენების დროს? მე შევეცადე ამ ორი საკითხის მოგვარება ჩემი ახლანდელი სკოლის პროექტით: Petfeed!

მარაგები

ჟოლო პი 3 ბ

ბარი ჩამტვირთავი უჯრედი (10 კგ)

HX711 დატვირთვის უჯრედის გამაძლიერებელი

წყლის დონის სენსორი (https://www.dfrobot.com/product-1493.html)

ულტრაბგერითი სიახლოვის სენსორი

LCD 16 პინიანი

2x სტეპერიანი ძრავა 28byj-48

2x სტეპერიანი ძრავის მძღოლი ULN2003

ნაბიჯი 1: გაყვანილობა

გაყვანილობა
გაყვანილობა
გაყვანილობა
გაყვანილობა

ბევრი კაბელი აქ. ამოიღეთ ჯუმბერის კაბელები და დაიწყეთ ჩამაგრება!

ნაბიჯი 2: გახადეთ თქვენი ტვირთის უჯრედი გამოსაყენებელი

გახადეთ თქვენი ტვირთის უჯრედი გამოსაყენებელი
გახადეთ თქვენი ტვირთის უჯრედი გამოსაყენებელი

დატვირთვის უჯრედის გამოსაყენებლად, ჩვენ პირველ რიგში უნდა დავამაგროთ იგი ორ თეფშზე: ქვედა ფირფიტაზე და თეფშზე, რომელზეც ჩვენ ვიწონით საკვებს.

ხრახნები გჭირდებათ M4 ხრახნები შესატყვისი ჭანჭიკებით და წყვილი M5 ხრახნები შესატყვისი ჭანჭიკებით. ხვრელების გასაკეთებლად პატარა საბურღი გამოვიყენე.

(სურათი:

ნაბიჯი 3: ნორმალიზებული მონაცემთა ბაზა

ნორმალიზებული მონაცემთა ბაზა
ნორმალიზებული მონაცემთა ბაზა

ჩვენი სენსორების მონაცემები უნდა იყოს შენახული მონაცემთა ბაზაში. პითონის ფაილების დასაკავშირებლად მონაცემთა ბაზასთან: იხილეთ ქვემოთ.

შემდეგ თქვენ ასევე გჭირდებათ კონფიგურაციის ფაილი:

[connector_python] user = * yourusername * host = 127.0.0.1 #if local port = 3306 password = * yourpassword * database = * yourdb * [application_config] driver = 'SQL Server'

ნაბიჯი 4: დატვირთვის უჯრედის კოდირება

იმპორტი RPi. GPIO როგორც GPIOimport threading იმპორტის დრო hx711– დან იმპორტი HX711 დამხმარეებიდან. stepperFood იმპორტი StepperFood დამხმარეებიდან. LCD დაწერეთ იმპორტი LCD დაწერეთ საცავიდან.

ჩვენი ყველა ბიბლიოთეკის იმპორტის შემდეგ (გაითვალისწინეთ, რომ ჩვენ ვიყენებთ HX711 ბიბლიოთეკას ჩამტვირთავი უჯრედის გადასაყვანად) ჩვენ შეგვიძლია დავიწყოთ ჩვენი რეალური კოდის წერა

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

ჩვენი მუდმივების გასარკვევად, ჯერ დააყენეთ TARRA_CONSTANT = 0 და GRAM_CONSTANT = 1.

შემდეგი, ჩვენ უნდა გავარკვიოთ, თუ რას კითხულობს ჩვენი მტვირთავი უჯრედი, როდესაც არაფერი იწონის. ეს მნიშვნელობა იქნება TARRA_CONSTANT.

რაც შეეხება GRAM_CONSTANT- ს, უბრალოდ აიღეთ ისეთი ობიექტი, რომლის წონაც იცით (მე სპაგეტის პაკეტი გამოვიყენე), აწონეთ და გაყავით დატვირთვის უჯრედის წაკითხვა ობიექტის რეალურ წონაზე. ჩემთვის ეს იყო 101.

კლასი LoadCell (threading. თემა):

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 (თვითმმართველობის):

სცადეთ: while True: self.hx711.reset () # სანამ დავიწყებთ, გადატვირთეთ HX711 (არ არის სავალდებულო) masë_avg = თანხა (self.hx711.get_raw_data ()) / 5 წონა = რაუნდი ((ღონისძიებები_ავგ - 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 moeten emitten") writeWeight = "წონა:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) გამონაკლისის გარდა e: print ("შეცდომა წონაში" + str (e))

ნაბიჯი 5: წყლის სენსორის კოდირება

იმპორტის დრო იმპორტის თემა საცავებიდან. DataRepository იმპორტი მონაცემთა მონაცემთა საცავი RPi– დან იმპორტი GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (false) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) class WaterSensor (threadting. 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, "დრო": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) გამონაკლისის გარდა, მაგალითად: print (ex) print ('error bijwaterensor') def is_water (self): status = GPIO.შემავალი (GPIO_Wate ს) თუ self.vorige_status == 0 და სტატუსი == 1: ამობეჭდვა ('წყლის gedetecteerd') sensorData = {"სტატუსი": სტატუსი, "მოქმედება": "წყალი gedetecteerd"} self.vorige_status = სტატუსი = GPIO.input სტატუსი (GPIO_Water) if self.vorige_status == 1 და სტატუსი == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 და სტატუსი == 0: ბეჭდვა ('წყლის weg') სენსორი Data = {"status": status, "action": "water weg"} self.vorige_status = სტატუსი = GPIO.input (GPIO_Water) თუ self.vorige_status == 0 და სტატუსი == 0: ბეჭდვა ('startpositie') სტატუსი = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} sensor sensorData

ნაბიჯი 6: სიახლოვის სენსორის კოდირება

იმპორტის დრო იმპორტის თემა საცავებიდან. DataRepository იმპორტის მონაცემთა რეპოზიტორი 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 (): int int (round (time.time () * 1000)) class UltrasonicSensor (threading. Thread): def _init _ (self, socket): threading. თემა._ 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, "სიახლოვე": პროქსი, "დრო": DataRepository.serializeDateTime (actionTime)}) last_reading = current_milli_time () გამონაკლისის გარდა: ex: print (ex) de f მანძილი (საკუთარი თავი): # მითითებული გამომწვევი HIGH GPIO.output (GPIO_Trig, True) # მითითებული გამომწვევი 0.01ms შემდეგ LOW time.sleep (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 (false) control_pins = [12, 16, 20, 21] pin in control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.გამოტანა (pin, 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 დაწერეთ: def შეტყობინება (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') გარდა: print ("შეცდომა LCDWrite")

ნაბიჯი 9: დასასრული

Დასასრული
Დასასრული
Დასასრული
Დასასრული

საბოლოო შედეგი: როგორ შევადგინეთ იგი და როგორ დასრულდა.

გირჩევთ: