Mundarija:

Ovqatlanish uchun avtomat avtomatlashtirilgan dispenser: 9 qadam
Ovqatlanish uchun avtomat avtomatlashtirilgan dispenser: 9 qadam

Video: Ovqatlanish uchun avtomat avtomatlashtirilgan dispenser: 9 qadam

Video: Ovqatlanish uchun avtomat avtomatlashtirilgan dispenser: 9 qadam
Video: ЗАПРЕЩЁННЫЕ ТОВАРЫ с ALIEXPRESS 2023 ШТРАФ и ТЮРЬМА ЛЕГКО! 2024, Iyun
Anonim
YANGILIKLARNI AVTOMATLI DISPENSERI
YANGILIKLARNI AVTOMATLI DISPENSERI

Hech qachon uy hayvoningizni boqish uchun ko'p vaqt sarflashni his qilganmisiz? Siz ta'til paytida uy hayvonlarini boqish uchun kimgadir qo'ng'iroq qilishingiz kerak bo'lganmi? Men bu ikkala muammolarni ham hozirgi maktab loyiham bilan tuzatishga harakat qildim: Petfeed!

Ta'minotlar

Raspberry Pi 3b

Bar yuk kamerasi (10 kg)

HX711 yuk xujayrasi kuchaytirgichi

Suv darajasi sensori (https://www.dfrobot.com/product-1493.html)

Ultrasonik yaqinlik sensori

LCD 16 pinli

2x qadamli dvigatel 28byj-48

ULN2003 2x qadamli motorli haydovchi

1 -qadam: simlarni ulash

Ulanish
Ulanish
Ulanish
Ulanish

bu erda ko'plab kabellar. O'tish kabellarini chiqarib oling va mahkamlashni boshlang!

2 -qadam: Yuk xujayrasini ishlatishga yaroqli qiling

Yuk xujayrasini ishlatishga yaroqli qiling
Yuk xujayrasini ishlatishga yaroqli qiling

yuk xujayrasini ishlatish uchun biz avval uni ikkita plastinkaga yopishtirishimiz kerak: pastki plastinka va ovqatimizni tortadigan plastinka.

Sizga kerak bo'lgan vintlar mos keladigan murvatlarga ega M4 vintlardek va mos keladigan murvatli M5 vintlardandir. Teshiklarni tayyorlash uchun men kichik matkapdan foydalandim.

(rasm:

3 -qadam: normallashtirilgan ma'lumotlar bazasi

Normallashtirilgan ma'lumotlar bazasi
Normallashtirilgan ma'lumotlar bazasi

sensorlardan olingan ma'lumotlar ma'lumotlar bazasida saqlanishi kerak. Python fayllari ma'lumotlar bazasiga ulanishi uchun: pastga qarang.

keyin sizga ham konfiguratsiya fayli kerak bo'ladi:

[connector_python] user = * foydalanuvchi ismingiz * xost = 127.0.0.1 #if mahalliy port = 3306 parol = * parolingiz * ma'lumotlar bazasi = * yourdb * [application_config] haydovchi = 'SQL Server'

4 -qadam: yuk xujayrasini kodlash

RPi.

Barcha kutubxonalarimiz import qilinganidan so'ng (esda tutingki, biz yuk kamerasini haydash uchun HX711 kutubxonasidan foydalanmoqdamiz), biz haqiqiy kodimizni yozishni boshlashimiz mumkin.

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Bizning doimiylarimizni bilish uchun avval TARRA_CONSTANT = 0 va GRAM_CONSTANT = 1 ni o'rnating.

Keyin biz hech narsa o'lchanmaganida yuk kameramiz o'qiydigan qiymatni bilishimiz kerak. Bu qiymat TARRA_CONSTANT bo'ladi.

GRAM_CONSTANTga kelsak, o'z vazningizni biladigan ob'ektni oling (men spagetti paketini ishlatganman), uni torting va yuk xujayrasi o'qilishini ob'ektning haqiqiy og'irligiga bo'ling. Men uchun bu 101 edi.

LoadCell klassi (threading. Thread):

def _init _ (o'z -o'zidan, rozetka, lcd): thread. Thread._ init _ (o'zini) self.hx711 = HX711 (dout_pin = 5, pd_sck_pin = 6, kanal = 'A', daromad = 64) self.socket = soket o'zini.lcd = LCD

bu erda biz LoadCell sinfini ishga tushiramiz va pinlarni xaritaga joylashtiramiz.

def run (o'zini):

harakat qilib ko'ring: while True: self.hx711.reset () # Boshlashdan oldin, HX711 (majburiy emas) o'lchovlari_avg = sum (self.hx711.get_raw_data ()) / 5 vazn = dumaloq ((o'lchovlar_avg - TARRA_CONSTANT) / GRAM_CONSTANT 0) chop etish ("vazn: {0}". Format (vazn)) DataRepository.insert_weight (vazn) 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)}) chop etish ("yuklangan") writeWeight = "weight:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) in istisnolardan tashqari, e: chop etish ("Tarozida xato" + str (e))

5 -qadam: Suv sensorini kodlash

Ma'lumotlar omboridan import vaqtini import qilish. DataRepository DataRepository -ni RPi -dan import qilish GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (Noto'g'ri) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) sinf WaterSensor (threading. Thread): def _init _ self, socket): threading. Thread._ init _ (self) self.socket = socket self.vorige_status = 0 def run (self): harakat qilib ko'ring: while True: water = self.is_water () print (suv) holati = suv [" status "] harakat = suv [" harakat "] DataRepository.insert_water (str (holat), harakat) data_water = DataRepository.get_data_sensor (2) historyId = data_water [" SensorsHistory "] qiymati = data_water [" qiymat "] agar qiymat == "0": qiymat = "te weinig water" else: value = "genoeg water" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": value, "Vaqt": DataRepository.serializeDateTime (actionTime), "harakat": harakat}) time.sleep (5) istisnolardan tashqari, ex: print (ex) print ('error bij watersensor') def is_water (o'zini): status = GPIO.kirish (GPIO_Wate r) agar self.vorige_status == 0 va status == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water) if self.vorige_status == 1 va status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 va status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) if self.vorige_status == 0 va status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} sensor sensori

6 -qadam: yaqinlik sensorini kodlash

Ma'lumotlar omboridan ma'lumotlar uzatish vaqtini import qilish.. 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 = soket def run (o'zini): harakat qiling: last_reading = 0 interval = 5000 while True: if current_milli_time ()> last_reading + interval: dist = self.distance () print ("O'lchangan masofa = %.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, "Yaqinlik": prox, "Vaqt": DataRepository.serializeDateTime (actionTime)}) last_reading = current_milli_time () istisnolardan tashqari, ex: print (ex) de f masofa (o'z -o'zidan): # Triggerni yuqori GPIO.output (GPIO_Trig, True) ga o'rnatish # 0.01msdan keyin Triggerni LOW vaqtiga qo'yish time.time () # GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # esa StartTime vaqtini saqlash. boshlanish va kelish o'rtasidagi vaqt farqi TimeElapsed = StopTime - StartTime # sonic tezligi (34300 sm / s) # ga ko'payadi va 2 ga bo'linadi, chunki u erda va orqadagi masofa = (TimeElapsed * 34300) / 2 qaytish masofasi

7 -qadam: Stepper motorlarini kodlash

GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] pin_ pinlarida: GPIO.setup (pin, GPIO. OUT) GPIO..chiqish (pin, 0) halfstep_seq =

Bu kod boshqa step motorlar uchun qayta ishlatilishi mumkin, faqat nazorat pinlarining raqamlarini to'g'rilash pinlariga o'rnating va sinfni StepperWater deb o'zgartiring:

8 -qadam: LCD -ni kodlash

Kod juda ko'p, lekin biz deyarli tugatdik.

LCD klassi LCD.py fayl sifatida kiritilgan

LCD -dan LCD displeyni import qilish

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]) sinf LCDWrite: def xabar (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') tashqari: chop etish ("LCDWrite xatosi")

9 -qadam: Oxir

Yakun
Yakun
Yakun
Yakun

yakuniy natija: biz uni qanday chizganmiz va u qanday tugagan.

Tavsiya: