Оглавление:
- Запасы
- Шаг 1. Подключение
- Шаг 2: сделайте свой датчик веса пригодным для использования
- Шаг 3: нормализованная база данных
- Шаг 4: Кодирование тензодатчика
- Шаг 5: Кодирование датчика воды
- Шаг 6: Кодирование датчика приближения
- Шаг 7: Кодирование шаговых двигателей
- Шаг 8: Кодирование ЖК-дисплея
- Шаг 9: Конец
Видео: АВТОМАТИЧЕСКИЙ ДОЗАТОР ДЛЯ ЖИВОТНЫХ: 9 шагов
2024 Автор: John Day | [email protected]. Последнее изменение: 2024-01-30 11:48
Вы когда-нибудь чувствовали, что тратите слишком много времени на кормление своего питомца? Вам когда-нибудь приходилось звать кого-нибудь, чтобы покормить ваших питомцев, пока вы были в отпуске? Я попытался исправить обе эти проблемы в моем текущем школьном проекте: 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: Конец
конечный результат: как мы это сделали, и чем все закончилось.
Рекомендуемые:
Проект автоматизированной миски для корма для домашних животных: 13 шагов
Проект «Автоматизированная кормушка для домашних животных»: в этом руководстве будет показано и объяснено, как построить автоматизированную программируемую кормушку для домашних животных с прикрепленными мисками для корма. Я прикрепил сюда видео, показывающее, как работает продукт и как он выглядит
Автоматический дозатор дезинфицирующего средства для рук: 3 шага
Автоматический дозатор дезинфицирующего средства для рук: Этот автоматический дозатор дезинфицирующего средства для рук был разработан как относительно недорогой вариант, который легко собрать. Большинство необходимых предметов можно приобрести у местных розничных продавцов оборудования и электроники. Есть возможность распечатать
Автоматический дозатор воды для отслеживания расхода: 6 шагов
Автоматический дозатор воды для отслеживания потребления: Привет! Пару месяцев назад я был в своей комнате и думал о том, какой проект я хотел бы сделать для школьного задания. Я хотел сделать что-то, что подошло бы мне и принесло бы пользу в будущем. Внезапно в комнату вошла мама и
Автоматический дозатор корма для кошек: 7 шагов (с изображениями)
Автоматический дозатор корма для кошек: если вы не контролируете количество корма, которое ест ваша кошка, это может привести к перееданию и проблемам с лишним весом. Это особенно актуально, если вы находитесь вдали от дома и оставляете кошке лишнюю еду, чтобы она могла есть по ее собственному графику. В других случаях вы можете
Автоматический дозатор для собак: 10 шагов
Автоматический дозатор для собак: в моем проекте я убеждаюсь, что когда вы оставляете свою собаку дома одну, она никогда не останется без еды. Устройство автоматической подачи будет "взломано". из дозатора кукурузных хлопьев. Диспенсер - это резервуар для собачьего корма, колесико внизу