Spisu treści:

AUTOMATYCZNY DOZOWNIK KARMY DLA ZWIERZĄT: 9 kroków
AUTOMATYCZNY DOZOWNIK KARMY DLA ZWIERZĄT: 9 kroków

Wideo: AUTOMATYCZNY DOZOWNIK KARMY DLA ZWIERZĄT: 9 kroków

Wideo: AUTOMATYCZNY DOZOWNIK KARMY DLA ZWIERZĄT: 9 kroków
Wideo: Pet Fan Automatyczna miska elektroniczna Podajnik do karmy 2024, Listopad
Anonim
AUTOMATYCZNY DOZOWNIK KARMY DLA ZWIERZĄT
AUTOMATYCZNY DOZOWNIK KARMY DLA ZWIERZĄT

Czy kiedykolwiek miałeś ochotę marnować zbyt dużo czasu na karmienie swojego zwierzaka? Czy kiedykolwiek musiałeś zadzwonić do kogoś, aby nakarmił twoje zwierzęta, gdy byłeś na wakacjach? Próbowałem rozwiązać oba te problemy w moim obecnym projekcie szkolnym: Petfeed!

Kieszonkowe dzieci

Raspberry Pi 3b

Ogniwo obciążnikowe pręta (10 kg)

Wzmacniacz tensometryczny HX711

Czujnik poziomu wody (https://www.dfrobot.com/product-1493.html)

Ultradźwiękowy czujnik zbliżeniowy

LCD 16 pinów

2x silnik krokowy 28byj-48

2x sterownik silnika krokowego ULN2003

Krok 1: Okablowanie

Okablowanie
Okablowanie
Okablowanie
Okablowanie

dużo okablowania tutaj. Wyjmij kable rozruchowe i zacznij przypinać!

Krok 2: Spraw, aby Twoje ogniwo obciążnikowe było użyteczne

Spraw, aby Twoje ogniwo obciążnikowe było użyteczne
Spraw, aby Twoje ogniwo obciążnikowe było użyteczne

aby użyć ogniwa obciążnikowego, musimy najpierw przymocować go do dwóch talerzy: dolnego talerza oraz talerza, na którym będziemy ważyli nasze jedzenie.

Potrzebne śruby to para śrub M4 z pasującymi śrubami i para śrub M5 z pasującymi śrubami. Do wykonania otworów użyłem małego wiertła.

(zdjęcie:

Krok 3: Znormalizowana baza danych

Znormalizowana baza danych
Znormalizowana baza danych

dane z naszych czujników muszą być zapisane w bazie danych. Pliki Pythona do połączenia z bazą danych: patrz poniżej.

wtedy potrzebujesz również pliku konfiguracyjnego:

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

Krok 4: Kodowanie ogniwa obciążnikowego

import RPi. GPIO jako GPIOimport wątków import czasu z hx711 import HX711 z helpers.stepperFood import StepperFood z helpers. LCDWrite import LCDWrite z repozytoriów. DataRepository import DataRepository

Po zaimportowaniu wszystkich naszych bibliotek (uwaga, używamy biblioteki HX711 do sterowania ogniwem obciążnikowym) możemy zacząć pisać nasz rzeczywisty kod

TARRA_CONSTANT = 80600

STAŁA GRAM = 101

Aby znaleźć nasze stałe, najpierw ustaw TARRA_CONSTANT = 0 i GRAM_CONSTANT = 1.

Następnie musimy dowiedzieć się, jaką wartość odczytuje nasze ogniwo obciążnikowe, gdy nic nie jest ważone. Ta wartość to TARRA_CONSTANT.

Jeśli chodzi o GRAM_CONSTANT, po prostu weź przedmiot, którego wagę znasz (użyłem paczki spaghetti), zważ go i podziel odczyt ogniwa obciążnikowego z rzeczywistą wagą przedmiotu. Dla mnie było to 101.

class LoadCell(threading. Thread):

def _init_(self, socket, lcd): threading. Thread._init_(self) self.hx711 = HX711(dout_pin=5, pd_sck_pin=6, kanał='A', wzmocnienie=64) self.socket = gniazdo self.lcd = LCD

tutaj inicjujemy klasę LoadCell i mapujemy piny.

def run(self):

try: while True: self.hx711.reset() # Zanim zaczniemy, zresetuj HX711 (nieobowiązkowo)measures_avg = sum(self.hx711.get_raw_data()) / 5 weight = round((measures_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) z wyjątkiem wyjątku jako e: print („Błąd z ważeniem” + str(e))

Krok 5: Kodowanie czujnika wody

import timeimport wątków z repozytoriów. DataRepository import DataRepository z RPi import GPIOGPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) GPIO_Water = 18 GPIO.setup(GPIO_Water, GPIO. IN) class WaterSensor(threading. Thread): def self, socket): threading. Thread._init_(self) self.socket = gniazdo 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) z wyjątkiem wyjątków np: print(ex) print('error bij watersensor') def is_water(self): status = GPIO.wejście (GPIO_Wate r) if self.vorige_status == 0 i 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 and status == 1: print('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input(GPIO_Water) if self.vorige_status == 1 and status == 0: print('wagę wody') sensorData = {"status": status, "action": "wagę wody"} self.vorige_status = status status = GPIO.input(GPIO_Water) if self.vorige_status == 0 i status == 0: print('startpositie') status = GPIO.input(GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

Krok 6: Kodowanie czujnika zbliżeniowego

importuj timeimport wątków z repozytoriów. DataRepository importuj DataRepository z RPi import GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup(GPIO_Trig, GPIO. OUT) GPIO_Echo(False). 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("Zmierzona odległość = %.1f cm" % dist) DataRepository. insert_proximity(dist) data_prox = DataRepository.get_data_sensor(1) historyId = data_prox["SensorsHistory"] prox = data_prox["wartość"] actionTime = data_prox["actionTime"] self.socket.emit('data_proximity', { "id": historyId, "Proximity": prox, "Time": DataRepository.serializeDateTime(actionTime)}) last_reading = current_milli_time() z wyjątkiem wyjątku jak np. print(ex) de f distance(self): # ustaw Trigger na HIGH GPIO.output(GPIO_Trig, True) # ustaw Trigger po 0.01ms na LOW time.sleep(0.00001) GPIO.output(GPIO_Trig, False) StartTime = time.time() StopTime = time.time() # save StartTime while GPIO.input(GPIO_Echo) == 0: StartTime = time.time() # save start time while GPIO.input(GPIO_Echo) == 1: StopTime = time.time() # różnica czasu między startem a przyjazdem TimeElapsed = StopTime - StartTime # pomnóż przez prędkość dźwięku (34300 cm/s) # i podziel przez 2, ponieważ odległość tam i z powrotem = (TimeElapsed * 34300) / 2 odległość powrotu

Krok 7: Kodowanie silników krokowych

import RPi. GPIO jako GPIOimport czasu import wątków GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) control_pins = [12, 16, 20, 21] for pin w control_pins: GPIO.setup(pin, GPIO. OUT) GPIO.output(pin, 0) halfstep_seq =

Ten kod jest wielokrotnego użytku dla drugiego silnika krokowego, wystarczy ustawić numery pinów sterujących na odpowiednie piny i zmienić nazwę klasy na StepperWater:

Krok 8: Kodowanie wyświetlacza LCD

Dużo kodu, ale prawie skończyliśmy.

Klasa LCD jest zawarta jako plik LCD.py

od pomocników. LCD import 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]) class LCDWrite: def message(msg): try: print("try") lcd.init_LCD() lcd.send_instruction(12) lcd.clear_display() lcd.write_message(msg, '1') z wyjątkiem: print("błąd LCDWrite")

Krok 9: Koniec

Koniec
Koniec
Koniec
Koniec

efekt końcowy: jak to sporządziliśmy a jak to się skończyło.

Zalecana: