Innholdsfortegnelse:

AUTOMATISK PET -MATDISPENSER: 9 trinn
AUTOMATISK PET -MATDISPENSER: 9 trinn

Video: AUTOMATISK PET -MATDISPENSER: 9 trinn

Video: AUTOMATISK PET -MATDISPENSER: 9 trinn
Video: РАДУЖНЫЕ ДРУЗЬЯ — КАЧКИ?! НЕЗАКОННЫЕ Эксперименты VR! 2024, November
Anonim
AUTOMATISK PET -MATDISPENSER
AUTOMATISK PET -MATDISPENSER

Har du noen gang hatt lyst til å kaste bort for mye tid på å mate kjæledyret ditt? Har du noen gang måttet ringe noen for å mate kjæledyrene dine mens du var på ferie? Jeg har prøvd å fikse begge disse problemene med mitt nåværende skoleprosjekt: Petfeed!

Rekvisita

Raspberry Pi 3b

Barlastcelle (10 kg)

HX711 lastcelleforsterker

Vannstandssensor (https://www.dfrobot.com/product-1493.html)

Ultralyd nærhetssensor

LCD 16-pinners

2x trinnmotor 28byj-48

2x trinnmotor driver ULN2003

Trinn 1: Kabling

Kabling
Kabling
Kabling
Kabling

mye kabling her. Ta ut startkablene og begynn å feste!

Trinn 2: Gjør lastecellen din brukbar

Gjør lastecellen din brukbar
Gjør lastecellen din brukbar

For å bruke lastcellen må vi først feste den til to tallerkener: en bunnplate og en tallerken som vi skal veie maten på.

Skruene du trenger er et par M4 -skruer med matchende bolter og et par M5 -skruer med matchende bolter. Jeg brukte et lite bor for å lage hullene.

(bilde:

Trinn 3: Normalisert database

Normalisert database
Normalisert database

data fra sensorene våre må lagres i en database. For pytonfilene å koble til databasen: se nedenfor.

da trenger du også en konfigurasjonsfil:

[connector_python] user = * dittbrukernavn * host = 127.0.0.1 #if lokal port = 3306 passord = * ditt passord * database = * yourdb * [application_config] driver = 'SQL Server'

Trinn 4: Koding av lastcellen

importer RPi. GPIO som GPIOimporttråd importtid fra hx711 import HX711 fra helpers.stepperFood import StepperFood fra helpers. LCDWrite import LCDWrite fra repositories. DataRepository import DataRepository

Etter å ha importert alle bibliotekene våre (merk at vi bruker HX711 -biblioteket til å drive lastcellen) kan vi begynne å skrive vår faktiske kode

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

For å finne ut våre konstanter, sett først TARRA_CONSTANT = 0 og GRAM_CONSTANT = 1.

Deretter må vi finne ut verdien vår lastecelle leser når ingenting veies. Denne verdien vil være TARRA_CONSTANT.

Når det gjelder GRAM_CONSTANT, bare ta et objekt du kjenner vekten på (jeg brukte en pakke spaghetti), veie det og dele lastcelleavlesningen med objektets faktiske vekt. For meg var dette 101.

class 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

her initialiserer vi LoadCell -klassen og kartlegger pinnene.

def run (self):

prøv: mens True: self.hx711.reset () # Før vi starter, må du tilbakestille HX711 (ikke obligatorisk) 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 burde emitten") writeWeight = "weight:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) unntatt Unntak som e: print ("Feil med veiing" + str (e))

Trinn 5: Koding av vannsensoren

import timeimport threading from repositories. DataRepository import DataRepository from RPi import GPIOGPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) GPIO_Water = 18 GPIO.setup (GPIO_Water, GPIO. IN) class 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 "] 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 = "nok vann" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": value, "Time": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) unntatt Unntak som ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.input (GPIO_Wate r) if self.vorige_status == 0 and 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 og status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 og status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) hvis self.vorige_status == 0 og status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} returner sensorData

Trinn 6: Koding av nærhetssensoren

import timeimport threading from repositories. DataRepository import DataRepository from 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_cho. 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 ("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 () unntatt Unntak som ex: print (ex) de f distanse (selv): # sett Trigger til HIGH GPIO.output (GPIO_Trig, True) # sett Trigger etter 0,01 ms til LOW time.sleep (0,00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # lagre StartTime mens GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # lagre ankomsttid mens GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # tidsforskjell mellom start og ankomst TimeElapsed = StopTime - StartTime # multipliser med sonisk hastighet (34300 cm / s) # og divider med 2, fordi der og tilbake distanse = (TimeElapsed * 34300) / 2 returavstand

Trinn 7: Koding av trinnmotorene

importer RPi. GPIO som GPIOimport tid import tråding GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] for pin i control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.output (pin, 0) halfstep_seq =

Denne koden kan gjenbrukes for den andre trinnmotoren, bare sett kontrollpinn -tallene til de repressive pinnene og gi klassen nytt navn til StepperWater:

Trinn 8: Koding av LCD -skjermen

Mye kode, men vi er nesten ferdige.

LCD -klassen er inkludert som fil LCD.py

fra hjelpere. 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]) klasse LCDWrite: def melding (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') unntatt: print ("feil LCDWrite")

Trinn 9: slutten

Slutten
Slutten
Slutten
Slutten

sluttresultat: hvordan vi tegnet det opp mot hvordan det endte opp.

Anbefalt: