Obsah:

AUTOMATICKÝ VÝDEJNÍK POTRAVIN: 9 kroků
AUTOMATICKÝ VÝDEJNÍK POTRAVIN: 9 kroků

Video: AUTOMATICKÝ VÝDEJNÍK POTRAVIN: 9 kroků

Video: AUTOMATICKÝ VÝDEJNÍK POTRAVIN: 9 kroků
Video: Моя работа наблюдать за лесом и здесь происходит что-то странное 2024, Červen
Anonim
AUTOMATICKÝ VÝDEJNÍK POTRAVIN
AUTOMATICKÝ VÝDEJNÍK POTRAVIN

Už jste někdy měli pocit, že ztrácíte příliš mnoho času krmením svého domácího mazlíčka? Už jste někdy museli někomu zavolat, aby nakrmil vaše domácí mazlíčky, když jste byli na dovolené? Oba tyto problémy jsem se pokusil vyřešit pomocí mého aktuálního školního projektu: Petfeed!

Zásoby

Raspberry Pi 3b

Zátěžový článek tyče (10 kg)

Zesilovač zatížení buňky HX711

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

Ultrazvukový senzor přiblížení

LCD 16 pinů

2x krokový motor 28byj-48

2x ovladač krokového motoru ULN2003

Krok 1: Zapojení

Elektrické vedení
Elektrické vedení
Elektrické vedení
Elektrické vedení

tady spousta kabeláže. Vytáhněte propojovací kabely a začněte připínat!

Krok 2: Zajistěte použitelnost buňky zatížení

Zajistěte, aby byla vaše zatěžovací buňka použitelná
Zajistěte, aby byla vaše zatěžovací buňka použitelná

abychom mohli použít siloměr, musíme jej nejprve připevnit ke dvěma deskám: spodní desce a desce, na kterou budeme vážit jídlo.

Potřebné šrouby jsou pár šroubů M4 s odpovídajícími šrouby a pár šroubů M5 s odpovídajícími šrouby. Na vytvoření otvorů jsem použil malý vrták.

(obrázek:

Krok 3: Normalizovaná databáze

Normalizovaná databáze
Normalizovaná databáze

data z našich senzorů je třeba uložit do databáze. Soubory pythonu pro připojení k databázi: viz níže.

pak také potřebujete konfigurační soubor:

[konektor_python] uživatel = * vaše uživatelské jméno * hostitel = 127.0.0.1 #if místní port = 3306 heslo = * vaše heslo * databáze = * yourdb * [application_config] ovladač = 'SQL Server'

Krok 4: Kódování zatěžovací buňky

importovat RPi. GPIO jako GPIOimportovat čas importu z hx711 importovat HX711 od pomocníků.stepperFood importovat StepperFood od pomocníků. LCDWrite importovat LCDWrite z úložišť. DataRepository importovat DataRepository

Po importu všech našich knihoven (všimněte si, že k pohonu snímače zatížení používáme knihovnu HX711) můžeme začít psát náš skutečný kód

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Pro zjištění našich konstant nejprve nastavte TARRA_CONSTANT = 0 a GRAM_CONSTANT = 1.

Dále musíme zjistit hodnotu, kterou náš siloměr přečte, když se nic neváží. Tato hodnota bude TARRA_CONSTANT.

Pokud jde o GRAM_CONSTANT, jednoduše vezměte předmět, jehož hmotnost znáte (použil jsem balíček špaget), odvážte jej a vydělte odečet snímače zatížení skutečnou hmotností předmětu. Pro mě to bylo 101.

třída 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

zde inicializujeme třídu LoadCell a mapujeme piny.

def run (vlastní):

try: while True: self.hx711.reset () # Než začneme, resetujte HX711 (nezávazné) 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) except Exception as e: print („Chyba při vážení“+ str (e))

Krok 5: Kódování snímače vody

importovat vlákno timeimport z úložišť. DataRepository importovat DataRepository z RPi import GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) třída 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) kromě Exception jako ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.input (GPIO_Wate r) if 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 a 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ódování senzoru přiblížení

importovat vlákno timeimport z úložišť. DataRepository importovat DataRepository z RPi importovat 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 = běh soketu def (vlastní): zkuste: last_reading = 0 interval = 5000 while True: if current_milli_time ()> last_reading + interval: dist = self.distance () print ("Measured Distance = %.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 () kromě výjimky jako ex: print (ex) de f vzdálenost (self): # nastavit 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ý rozdíl mezi začátkem a příjezdem TimeElapsed = StopTime - StartTime # vynásobte zvukovou rychlostí (34300 cm / s) # a vydělte 2, protože vzdálenost tam a zpět = (TimeElapsed * 34300) / 2 návratová vzdálenost

Krok 7: Kódování krokových motorů

importovat RPi. GPIO jako GPIOimport čas importovat vlákno GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] pro pin in control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.output (pin, 0) halfstep_seq =

Tento kód je opakovaně použitelný pro druhý krokový motor, stačí nastavit čísla ovládacích pinů na jejich příslušné piny a přejmenovat třídu na StepperWater:

Krok 8: Kódování LCD

Spousta kódu, ale jsme téměř hotovi.

Třída LCD je zahrnuta jako soubor LCD.py

od pomocníků. 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]) třída LCDWrite: def zpráva (zpráva): zkus: tisk ("zkus") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') kromě: print ("chyba LCDWrite")

Krok 9: Konec

Konec
Konec
Konec
Konec

konečný výsledek: jak jsme to nakreslili vs. jak to skončilo.

Doporučuje: