Obsah:

AUTOMATICKÝ VÝDEJNÍK POTRAVÍN: 9 krokov
AUTOMATICKÝ VÝDEJNÍK POTRAVÍN: 9 krokov

Video: AUTOMATICKÝ VÝDEJNÍK POTRAVÍN: 9 krokov

Video: AUTOMATICKÝ VÝDEJNÍK POTRAVÍN: 9 krokov
Video: Моя работа наблюдать за лесом и здесь происходит что-то странное 2024, Jún
Anonim
AUTOMATICKÝ VÝDEJNÍK POTRAVÍN
AUTOMATICKÝ VÝDEJNÍK POTRAVÍN

Už ste niekedy chceli stratiť príliš veľa času kŕmením svojho domáceho maznáčika? Už ste niekedy museli niekomu zavolať, aby nakŕmil vašich miláčikov, keď ste boli na dovolenke? Oba tieto problémy som sa pokúsil vyriešiť pomocou môjho aktuálneho školského projektu: Petfeed!

Zásoby

Raspberry Pi 3b

Tyčový silomer (10 kg)

Zosilňovač zaťažovacej bunky HX711

Senzor vodnej hladiny (https://www.dfrobot.com/product-1493.html)

Ultrazvukový senzor priblíženia

LCD 16-pinový

2x krokový motor 28byj-48

2x ovládač krokového motora ULN2003

Krok 1: Zapojenie

Elektrické vedenie
Elektrické vedenie
Elektrické vedenie
Elektrické vedenie

je tu veľa kabeláže. Vytiahnite prepojovacie káble a začnite pripínať!

Krok 2: Zaistite, aby bola vaša zaťažovacia bunka použiteľná

Zaistite, aby bola vaša zaťažovacia bunka použiteľná
Zaistite, aby bola vaša zaťažovacia bunka použiteľná

Aby sme mohli použiť silomer, musíme ho najskôr pripevniť k dvom doskám: spodnej doske a doske, na ktorú budeme odvážiť jedlo.

Potrebné skrutky sú pár skrutiek M4 so zodpovedajúcimi skrutkami a pár skrutiek M5 so zodpovedajúcimi skrutkami. Na vytvorenie dier som použil malú vŕtačku.

(obrázok:

Krok 3: Normalizovaná databáza

Normalizovaná databáza
Normalizovaná databáza

údaje z našich senzorov je potrebné uložiť do databázy. Súbory pythonu, ktoré sa majú pripojiť k databáze, nájdete nižšie.

potom budete potrebovať aj konfiguračný súbor:

[konektor_python] používateľ = * vaše používateľské meno * hostiteľ = 127.0.0.1 #if lokálny port = 3306 heslo = * vaše heslo * databáza = * váš server * [application_config] ovládač = 'SQL Server'

Krok 4: Kódovanie zaťažovacej bunky

importovať RPi. GPIO ako GPIOimportovať závitový čas z hx711 importovať HX711 od pomocníkov.stepperFood importovať StepperFood od pomocníkov. LCDWrite importovať LCDWrite z úložísk. DataRepository importovať DataRepository

Po importe všetkých našich knižníc (všimnite si, že na pohon snímača zaťaženia používame knižnicu HX711) môžeme začať písať náš skutočný kód

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Na zistenie našich konštánt najskôr nastavte TARRA_CONSTANT = 0 a GRAM_CONSTANT = 1.

Ďalej musíme zistiť hodnotu, ktorú náš snímač zaťaženia číta, keď sa nič neváži. Táto hodnota bude TARRA_CONSTANT.

Pokiaľ ide o GRAM_CONSTANT, jednoducho vezmite predmet, ktorého hmotnosť poznáte (použil som balenie špagiet), odvážte ho a vydeľte snímač zaťaženia skutočnou hmotnosťou predmetu. Pre mňa to bolo 101.

trieda 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

tu inicializujeme triedu LoadCell a mapujeme piny.

def run (vlastné):

skúste: while True: self.hx711.reset () # Skôr než začneme, resetujte HX711 (nie je povinné) 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) okrem výnimky ako e: print („Chyba pri vážení“+ str (e))

Krok 5: Kódovanie senzora vody

importujte vlákno timeimport z úložísk. 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 _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) okrem výnimky ako ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.input (GPIO_Wate r) ak self.vorige_status == 0 a 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 a 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 and status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

Krok 6: Kódovanie snímača priblíženia

importujte vlákno timeimport z úložísk. DataRepository import 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.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 = spustenie soketu def (vlastné): skúste: last_reading = 0 interval = 5000 zatiaľ čo True: ak current_milli_time ()> last_reading + interval: dist = self.distance () print ("Nameraná vzdialenosť = %.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 () okrem výnimky ako ex: print (ex) de f vzdialenosť (self): # nastaviť Trigger na 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 () # save StartTime while GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # save time of příjezdu while GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # časový rozdiel medzi štartom a príchodom TimeElapsed = StopTime - StartTime # vynásobte zvukovou rýchlosťou (34300 cm / s) # a delte 2, pretože vzdialenosť tam a späť = (TimeElapsed * 34300) / 2 vzdialenosť návratu

Krok 7: Kódovanie krokových motorov

import RPi. GPIO ako GPIOimport čas importu vlákna GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] pre pin in control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.výstup (pin, 0) halfstep_seq =

Tento kód je opakovane použiteľný pre druhý krokový motor, stačí nastaviť čísla riadiacich pinov na ich príslušné kolíky a triedu premenovať na StepperWater:

Krok 8: Kódovanie LCD

Veľa kódu, ale sme takmer hotoví.

Trieda LCD je zahrnutá ako súbor LCD.py

od pomocníkov. 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]) LCDWrite: správa def: print ("chyba LCDWrite")

Krok 9: Koniec

Koniec
Koniec
Koniec
Koniec

konečný výsledok: ako sme to nakreslili vs. ako to skončilo.

Odporúča: