INHOUDSOPGAWE:

AUTOMATIESE VOEDSELDISPENSOR: 9 stappe
AUTOMATIESE VOEDSELDISPENSOR: 9 stappe

Video: AUTOMATIESE VOEDSELDISPENSOR: 9 stappe

Video: AUTOMATIESE VOEDSELDISPENSOR: 9 stappe
Video: TRIXIE Automatic Feed Dispenser TX8 Smart: Feeding via App! 2024, Junie
Anonim
AUTOMATIESE VOEDSELDISPENSOR
AUTOMATIESE VOEDSELDISPENSOR

Het u al ooit gevoel dat u te veel tyd mors om u troeteldier te voed? Het u ooit iemand gebel om u troeteldiere te voed terwyl u op vakansie was? Ek het probeer om albei hierdie probleme op te los met my huidige skoolprojek: Petfeed!

Voorrade

Framboos Pi 3b

Bar Load Cell (10kg)

HX711 Load Cell Versterker

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

Ultrasoniese nabyheidssensor

LCD 16-penne

2x stapmotor 28byj-48

2x stapmotorbestuurder ULN2003

Stap 1: Bedrading

Bedrading
Bedrading
Bedrading
Bedrading

baie kabels hier. Haal jou springkabels uit en begin vasmaak!

Stap 2: Maak u vragsel bruikbaar

Maak u vragsel bruikbaar
Maak u vragsel bruikbaar

Om die laaisel te gebruik, moet ons dit eers aan twee borde heg: 'n onderplaat en 'n bord waarop ons ons voedsel sal weeg.

Die skroewe wat u benodig, is 'n paar M4 -skroewe met bypassende boute en 'n paar M5 -skroewe met bypassende boute. Ek gebruik 'n klein boor om die gate te maak.

(foto:

Stap 3: Genormaliseerde databasis

Genormaliseerde databasis
Genormaliseerde databasis

data van ons sensors moet in 'n databasis gestoor word. Sien die python -lêers om aan die databasis te koppel:

dan benodig u ook 'n config -lêer:

[connector_python] gebruiker = * u gebruikersnaam * host = 127.0.0.1 #if plaaslike poort = 3306 wagwoord = * u wagwoord * databasis = * yourdb * [application_config] driver = 'SQL Server'

Stap 4: Kodering van die laaisel

invoer RPi. GPIO as GPIO invoer ingevoerde tyd vanaf hx711 invoer HX711 vanaf helpers.stepperKos invoer StepperKos van helpers. LCDWrite invoer LCDWrite uit bewaarplekke. DataRepository invoer DataRepository

Nadat ons al ons biblioteke ingevoer het (let wel, ons gebruik die HX711 -biblioteek om die laaisel te dryf) kan ons ons werklike kode begin skryf

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Stel eers TARRA_CONSTANT = 0 en GRAM_CONSTANT = 1 in om ons konstante uit te vind.

Vervolgens moet ons uitvind watter waarde ons laadsel lees as daar niks geweeg word nie. Hierdie waarde sal TARRA_CONSTANT wees.

Wat GRAM_CONSTANT betref, neem eenvoudig 'n voorwerp waarvan u die gewig ken (ek het 'n pakkie spaghetti's gebruik), weeg dit en verdeel die lassel met die werklike gewig van die voorwerp. Vir my was dit 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

hier initialiseer ons die LoadCell -klas en karteer die penne.

def run (self):

probeer: terwyl True: self.hx711.reset () # Voordat ons begin, moet u die HX711 (nie verplig nie) meet_avg = som (self.hx711.get_raw_data ()) / 5 weight = round ((maatregels_avg - TARRA_CONSTANT) / GRAM_CONSTANT, terugstel, 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 moet emitten") writeWeight = "weight:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [:-2]) <= 100: StepperFood.run () time.sleep (20) behalwe Uitsondering as e: print ("Weegfout" + str (e))

Stap 5: Kodering van die watersensor

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): probeer: terwyl 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 [" waarde "] as waarde == "0": value = "te weinig water" else: value = "genoeg water" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": value, "Tyd": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) behalwe Uitsondering as ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.invoer (GPIO_Wate r) as self.vorige_status == 0 en status == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water) as self.vorige_status == 1 en status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 en status == 0: print ('water weg') sensorData = {"status": status, "action": "water weg"} self.vorige_status = status status = GPIO.input (GPIO_Water) as self.vorige_status == 0 en status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} stuur sensorData terug

Stap 6: Kodering van die nabyheidssensor

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 (GPIOE. 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): probeer: last_reading = 0 interval = 5000 terwyl 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 () behalwe Uitsondering as ex: print (ex) de f afstand (self): # stel Trigger in op HIGH GPIO.output (GPIO_Trig, True) # stel Trigger na 0.01ms op LOW time.sleep (0.00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # bespaar StartTime terwyl GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # bespaar aankomstyd terwyl GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # tydsverskil tussen begin en aankoms TimeElapsed = StopTime - StartTime # vermenigvuldig met die soniese snelheid (34300 cm / s) # en deel met 2, want daar en terug = = (TimeElapsed * 34300) / 2 retourafstand

Stap 7: Kodering van die stapmotors

invoer RPi. GPIO as GPIO invoer tyd invoer threading GPIO.setmode (GPIO. BCM) GPIO.setwarnings (Onwaar) control_pins = [12, 16, 20, 21] vir pin in control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.output (pen, 0) halfstep_seq =

Hierdie kode is herbruikbaar vir die ander stapmotor, stel net die kontrolepennommers in op hul repektiewe penne en hernoem die klas na StepperWater:

Stap 8: Kodering van die LCD

Baie kode, maar ons is amper klaar.

Die LCD -klas is ingesluit as lêer LCD.py

van helpers. LCD invoer 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]) klas LCDWrite: def -boodskap (msg): try: print ("probeer") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') behalwe: print ("fout LCDWrite")

Stap 9: Die einde

Die einde
Die einde
Die einde
Die einde

eindresultaat: hoe ons dit opgestel het teenoor hoe dit beland het.

Aanbeveel: