Kazalo:

AVTOMATSKI DOSAVNIK ZA HRANO ZA Hrana za hišne ljubljenčke: 9 korakov
AVTOMATSKI DOSAVNIK ZA HRANO ZA Hrana za hišne ljubljenčke: 9 korakov

Video: AVTOMATSKI DOSAVNIK ZA HRANO ZA Hrana za hišne ljubljenčke: 9 korakov

Video: AVTOMATSKI DOSAVNIK ZA HRANO ZA Hrana za hišne ljubljenčke: 9 korakov
Video: Wir haben unser Leben verändert! Warum und wie, darüber wird in diesem Video berichtet. 2024, Junij
Anonim
AVTOMATSKI DOSAVNIK ZA HRANO ZA Hrana za hišne ljubljenčke
AVTOMATSKI DOSAVNIK ZA HRANO ZA Hrana za hišne ljubljenčke

Se vam je kdaj zdelo, da zapravljate preveč časa s hranjenjem svojega ljubljenčka? Ste kdaj morali med počitnicami poklicati nekoga, da nahrani vaše hišne ljubljenčke? Obe težavi sem poskušal odpraviti s svojim trenutnim šolskim projektom: Petfeed!

Zaloge

Malina Pi 3b

Polimerna obremenitvena celica (10 kg)

HX711 ojačevalnik obremenitvenih celic

Senzor vodnega nivoja (https://www.dfrobot.com/product-1493.html)

Ultrazvočni senzor bližine

16-pinski LCD

2x koračni motor 28byj-48

2x gonilnik koračnega motorja ULN2003

1. korak: Ožičenje

Ožičenje
Ožičenje
Ožičenje
Ožičenje

tukaj je veliko kablov. Odstranite mostične kable in začnite pripenjati!

2. korak: Naj bo vaša merilna celica uporabna

Naj bo vaša merilna celica uporabna
Naj bo vaša merilna celica uporabna

za uporabo merilne celice jo moramo najprej pritrditi na dve plošči: spodnjo ploščo in ploščo, na kateri bomo tehtali hrano.

Vijaki, ki jih potrebujete, so par vijakov M4 z ustreznimi vijaki in par vijakov M5 z ustreznimi vijaki. Za izdelavo lukenj sem uporabil majhen vrtalnik.

(slika:

3. korak: Normalizirana baza podatkov

Normalizirana baza podatkov
Normalizirana baza podatkov

podatke iz naših senzorjev je treba shraniti v bazo podatkov. Za povezavo datotek python z bazo podatkov: glejte spodaj.

potem potrebujete tudi konfiguracijsko datoteko:

[connection_python] user = * ime vašega uporabnika * gostitelj = 127.0.0.1 #if lokalna vrata = 3306 geslo = * vaša geslo * baza podatkov = * yourdb * [application_config] driver = 'SQL Server'

4. korak: Kodiranje celice za nalaganje

uvoz RPi. GPIO kot GPIOimport threading import time from hx711 import HX711 from helpers.stepperFood import StepperFood from helpers. LCDWrite import LCDWrite from repositories. DataRepository import DataRepository

Po uvozu vseh naših knjižnic (upoštevajte, da za poganjanje merilne celice uporabljamo knjižnico HX711) lahko začnemo pisati svojo dejansko kodo

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Če želite izvedeti naše konstante, najprej nastavite TARRA_CONSTANT = 0 in GRAM_CONSTANT = 1.

Nato moramo ugotoviti vrednost, ki jo bere naša merilna celica, ko nič ne tehtamo. Ta vrednost bo TARRA_CONSTANT.

Kar zadeva GRAM_CONSTANT, preprosto vzemite predmet, za katerega poznate težo (uporabil sem paket špagetov), ga stehtajte in odčitek merilne celice delite z dejansko težo predmeta. Zame je bilo to 101.

razred 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

tukaj inicializiramo razred LoadCell in preslikamo zatiče.

def run (self):

poskusite: while True: self.hx711.reset () # Preden začnemo, ponastavimo HX711 (ni obvezno) ukrepi_avg = vsota (samo.hx711.get_raw_data ()) / 5 teža = okroglo ((mere_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 () če je int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) razen izjeme kot e: print ("Napaka pri tehtanju" + str (e))

5. korak: Kodiranje senzorja vode

uvoz timeimport navojev iz skladišč. DataRepository uvoz DataRepository iz RPi uvoz GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) razred 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 "] dejanje = voda [" dejanje "] DataRepository.insert_water (str (stanje), dejanje) data_water = DataRepository.get_data_sensor (2) historyId = data_water [" SensorsHistory "] vrednost = data_water [" vrednost "] če je vrednost == "0": value = "te weinig water" else: value = "genoeg water" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": vrednost, "Time": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) razen izjeme kot ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.vhod (GPIO_Wate r) če self.vorige_status == 0 in 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 in status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 in status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) če self.vorige_status == 0 in status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

6. korak: Kodiranje senzorja bližine

uvoz časovnega uvoza navojev iz skladišč. DataRepository uvoz DataRepository iz RPi uvoz GPIO GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Trig = 4 GPIO_Echo = 17 GPIO.setup (GPIO_Trig, GPIO. OUT) GPIO.setup (GPIO_, GPIO_ IN socket def run (self): try: last_reading = 0 interval = 5000 while True: če current_milli_time ()> last_reading + interval: dist = self.distance () print ("Izmerjena razdalja = %.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 () razen izjeme kot ex: print (ex) de f razdalja (samo): # nastavite sprožilec na VISOK GPIO.izhod (GPIO_Trig, True) # nastavite sprožilec po 0,01 ms na LOW time.sleep (0,00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # shranite StartTime, medtem ko je GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # shranite čas prihoda, medtem ko GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # časovna razlika med začetkom in prihodom TimeElapsed = StopTime - StartTime # pomnožite z zvočno hitrostjo (34300 cm / s) # in delite z 2, ker je razdalja tam in nazaj = (TimeElapsed * 34300) / 2 povratna razdalja

7. korak: Kodiranje koračnih motorjev

uvoz RPi. GPIO kot GPIO čas uvoza uvoz niti nit GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] za pin v control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.output (pin, 0) halfstep_seq =

Ta koda se lahko ponovno uporabi za drugi koračni motor, samo nastavite številke kontrolnih pin na njihove odbojne zatiče in preimenujte razred v StepperWater:

8. korak: Kodiranje LCD -ja

Veliko kode, vendar smo skoraj končali.

Razred LCD je vključen kot datoteka LCD.py

od pomočnikov. LCD uvoz 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]) razred LCDWrite: def sporočilo (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') razen: print ("napaka LCDWrite")

9. korak: Konec

Konec
Konec
Konec
Konec

končni rezultat: kako smo ga sestavili v primerjavi s tem, kako se je končalo.

Priporočena: