Съдържание:

АВТОМАТИЧЕН ДОЗАТОР ЗА ХРАНИТЕЛНИ ХРАНИ: 9 стъпки
АВТОМАТИЧЕН ДОЗАТОР ЗА ХРАНИТЕЛНИ ХРАНИ: 9 стъпки

Видео: АВТОМАТИЧЕН ДОЗАТОР ЗА ХРАНИТЕЛНИ ХРАНИ: 9 стъпки

Видео: АВТОМАТИЧЕН ДОЗАТОР ЗА ХРАНИТЕЛНИ ХРАНИ: 9 стъпки
Видео: Aтоматична хранилка за куче и котка - грижа за вашите домашни любимци докато ви няма вкъщи 2024, Ноември
Anonim
АВТОМАТИЧЕН ДОЗАТОР ЗА ХРАНИТЕЛНИ ХРАНИ
АВТОМАТИЧЕН ДОЗАТОР ЗА ХРАНИТЕЛНИ ХРАНИ

Чувствало ли ви се е да губите твърде много време в храненето на вашия домашен любимец? Случвало ли ви се е да се обадите на някого, за да нахраните вашите домашни любимци, докато сте на почивка? Опитах се да поправя и двата проблема с настоящия си училищен проект: Petfeed!

Консумативи

Малина Pi 3b

Бара натоварваща клетка (10 кг)

HX711 усилвател за натоварване на клетки

Сензор за водно ниво (https://www.dfrobot.com/product-1493.html)

Ултразвуков сензор за близост

LCD 16-пинов

2x стъпков двигател 28byj-48

2x драйвер за стъпков двигател ULN2003

Стъпка 1: Окабеляване

Електрически инсталации
Електрически инсталации
Електрически инсталации
Електрически инсталации

много кабели тук. Извадете джъмперните си кабели и започнете да закопчавате!

Стъпка 2: Направете вашата клетка за зареждане използваема

Направете вашата клетка за зареждане използваема
Направете вашата клетка за зареждане използваема

за да използваме товарната клетка, първо трябва да я прикрепим към две чинии: долна чиния и чиния, върху която ще претегляме храната си.

Винтовете, от които се нуждаете, са чифт винтове М4 със съвпадащи болтове и чифт винтове М5 със съвпадащи болтове. Използвах малка бормашина, за да направя дупките.

(снимка:

Стъпка 3: Нормализирана база данни

Нормализирана база данни
Нормализирана база данни

данните от нашите сензори трябва да бъдат записани в база данни. За свързване на python файлове с базата данни: вижте по -долу.

тогава имате нужда и от конфигурационен файл:

[конектор_питон] потребител = * вашето име на потребител * хост = 127.0.0.1 #ако локален порт = 3306 парола = * вашата парола * база данни = * yourdb * [application_config] драйвер = 'SQL Server'

Стъпка 4: Кодиране на клетката за зареждане

импортиране на RPi. GPIO като GPIOimport импортиране на време за импортиране от hx711 импортиране на HX711 от helpers.stepperFood импортиране на StepperFood от помощници. LCDWrite импортиране LCDWrite от хранилища. DataRepository импортиране на 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 (самостоятелно):

опитайте: while True: self.hx711.reset () # Преди да започнем, нулирайте HX711 (не е задължително) mjere_avg = сума (самостоятелно.hx711.get_raw_data ()) / 5 тегло = кръг ((мерки_avg - TARRA_CONSTANT) / GRAM_CONSTANT, 0) print ("тегло: {0}". Формат (тегло)) DataRepository.insert_weight (тегло) data_weight = DataRepository.get_data_sensor (3) historyId = data_weight ["SensorsHistory"] db_weight = data_weight ["стойност"] 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: Кодиране на сензора за вода

import timeimport threading from repositories. DataRepository импортиране на DataRepository от RPi внос GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) клас WaterSensor (threading. Thread): def _in 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 [" status "] действие = вода [" действие "] DataRepository.insert_water (str (състояние), действие) data_water = DataRepository.get_data_sensor (2) historyId = data_water [" SensorsHistory "] стойност = data_water [" стойност "] ако стойност == "0": value = "te weinig water" else: value = "genoeg water" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": стойност, "Time": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) с изключение на Exception as ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.input (GPIO_Wate r) if self.vorige_status == 0 и 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 и status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 и 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 и status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

Стъпка 6: Кодиране на сензора за близост

import timeimport threading from repositories. DataRepository импортиране на DataRepository от RPi внос GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup (GPIO_Trig, GPIO. OUT) GPIO.setup (GPIO_ IN socket def run (self): try: last_reading = 0 interval = 5000 while True: if current_milli_time ()> last_reading + interval: dist = self.distance () print ("Измерено разстояние = %.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 разстояние (самостоятелно): # задайте Trigger на 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 () # запазване на StartTime, докато 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: Кодиране на стъпкови двигатели

импортиране на RPi. GPIO като GPIOимпортиране на време на импортиране на нишки GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] за пин в control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.output (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]) клас LCDWrite: def message (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') с изключение: print ("грешка LCDWrite")

Стъпка 9: Краят

Край
Край
Край
Край

краен резултат: как го съставихме срещу как завърши.

Препоръчано: