Оглавление:

АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ: 9 шагов
АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ: 9 шагов

Видео: АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ: 9 шагов

Видео: АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ: 9 шагов
Видео: 🔥ТОП-5: Лучшие автоматические кормушки для кошек и собак | Рейтинг автокормушек в 2023 году 2024, Июнь
Anonim
АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ ПИЩЕВЫХ ПРОДУКТОВ
АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ ПИЩЕВЫХ ПРОДУКТОВ

Вы когда-нибудь чувствовали, что тратите слишком много времени на кормление своего питомца? Вам когда-нибудь приходилось звать кого-нибудь, чтобы покормить ваших питомцев, пока вы были в отпуске? Я попытался исправить обе эти проблемы в моем текущем школьном проекте: Petfeed!

Запасы

Малина Pi 3b

Штанговая тензодатчик (10 кг)

Усилитель тензодатчика HX711

Датчик уровня воды (https://www.dfrobot.com/product-1493.html)

Ультразвуковой датчик приближения

LCD 16-контактный

2 шаговых двигателя 28byj-48

2x драйвер шагового двигателя ULN2003

Шаг 1. Подключение

Проводка
Проводка
Проводка
Проводка

здесь много кабелей. Вытащите соединительные кабели и начните закреплять!

Шаг 2: сделайте свой датчик веса пригодным для использования

Сделайте свой датчик веса пригодным для использования
Сделайте свой датчик веса пригодным для использования

Чтобы использовать датчик веса, нам сначала нужно прикрепить его к двум тарелкам: нижней тарелке и тарелке, на которой мы будем взвешивать нашу пищу.

Вам понадобятся пара винтов M4 с соответствующими болтами и пара винтов M5 с соответствующими болтами. Я использовал небольшое сверло, чтобы проделать отверстия.

(рис:

Шаг 3: нормализованная база данных

Нормализованная база данных
Нормализованная база данных

данные с наших датчиков должны быть сохранены в базе данных. Чтобы файлы python подключились к базе данных: см. Ниже.

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

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

Шаг 4: Кодирование тензодатчика

import RPi. GPIO as GPIOimport threading import time from hx711 import HX711 from helpers.stepperFood import StepperFood from helpers. LCDWrite import LCDWrite from repositories. 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 = ЖК-дисплей

здесь мы инициализируем класс LoadCell и сопоставляем контакты.

def run (self):

try: while True: self.hx711.reset () # Перед тем, как мы начнем, сбросим HX711 (не обязательно) sizes_avg = sum (self.hx711.get_raw_data ()) / 5 weight = round ((sizes_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) за исключением Exception as e: print («Ошибка при взвешивании» + str (e))

Шаг 5: Кодирование датчика воды

импортировать timeimport threading из репозиториев. DataRepository импортировать DataRepository из RPi import GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) class WaterSensor (threading. Thread): def _init _ (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 "] 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) за исключением Exception as ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.input (GPIO_Wate r) если self.vorige_status == 0 и status == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water), если self.vorige_status == 1 и status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water), если self.vorige_status == 1 и status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) если self.vorige_status == 0 и status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

Шаг 6: Кодирование датчика приближения

импорт timeimport threading из репозиториев. DataRepository импорт DataRepository из RPi import GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup (GPIO_Trig, GPIO. OUT) GPIO.setup (GPIO_Echo, GPIO. 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 ("Измеренное расстояние =%.1f см"% 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 () за исключением Exception as ex: print (ex) de f distance (self): # установить для триггера значение HIGH GPIO.output (GPIO_Trig, True) # установить для триггера через 0,01 мс значение LOW time.sleep (0,00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # сохранить время начала, пока 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: Кодирование шаговых двигателей

import RPi. GPIO as GPIOimport time import threading 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.py

от помощников. LCD импорт LCD

E = 26 RS = 25 D0 = 19 D1 = 13 D2 = 24 D3 = 22 D4 = 23 D5 = 8 D6 = 7 D7 = 10 ЖК = ЖК-дисплей (E, RS, [D0, D1, D2, D3, D4, D5, D6, D7]) class 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: Конец

Конец
Конец
Конец
Конец

конечный результат: как мы это сделали, и чем все закончилось.

Рекомендуемые: