INHOUDSOPGAWE:
Video: AUTOMATIESE VOEDSELDISPENSOR: 9 stappe
2025 Outeur: John Day | [email protected]. Laas verander: 2025-01-13 06:56
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
baie kabels hier. Haal jou springkabels uit en begin vasmaak!
Stap 2: 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
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
eindresultaat: hoe ons dit opgestel het teenoor hoe dit beland het.