Turinys:

AUTOMATINIS PET MAISTO DOZATORIUS: 9 žingsniai
AUTOMATINIS PET MAISTO DOZATORIUS: 9 žingsniai

Video: AUTOMATINIS PET MAISTO DOZATORIUS: 9 žingsniai

Video: AUTOMATINIS PET MAISTO DOZATORIUS: 9 žingsniai
Video: How to BATTLE the SUMMER HEAT with an Aquarium in 2023? 2024, Birželis
Anonim
AUTOMATINIS PET MAISTO DOZATORIUS
AUTOMATINIS PET MAISTO DOZATORIUS

Ar kada nors jautėte, kad eikvojate per daug laiko maitindami savo augintinį? Ar jums kada nors teko skambinti kam nors, kad pamaitintų jūsų augintinius, kai atostogavote? Aš bandžiau išspręsti abi šias problemas savo dabartiniame mokyklos projekte: „Petfeed!

Prekės

Raspberry Pi 3b

Strypo apkrovos ląstelė (10 kg)

HX711 apkrovos elementų stiprintuvas

Vandens lygio jutiklis (https://www.dfrobot.com/product-1493.html)

Ultragarsinis artumo jutiklis

LCD 16 kontaktų

2x žingsninis variklis 28byj-48

2x žingsninio variklio vairuotojas ULN2003

1 žingsnis: laidų prijungimas

Laidai
Laidai
Laidai
Laidai

čia daug kabelių. Išimkite trumpiklius ir pradėkite tvirtinti!

2 veiksmas: padėkite naudoti savo apkrovos langelį

Padarykite savo apkrovos langelį tinkamu naudoti
Padarykite savo apkrovos langelį tinkamu naudoti

norėdami naudoti apkrovos matuoklį, pirmiausia turime jį pritvirtinti prie dviejų lėkščių: apatinės plokštelės ir lėkštės, ant kurios sversime maistą.

Jums reikalingi varžtai yra pora M4 varžtų su atitinkamais varžtais ir pora M5 varžtų su atitinkamais varžtais. Skylėms padaryti naudoju nedidelį grąžtą.

(nuotrauka:

3 žingsnis: normalizuota duomenų bazė

Normalizuota duomenų bazė
Normalizuota duomenų bazė

mūsų jutiklių duomenys turi būti išsaugoti duomenų bazėje. Norėdami prijungti „Python“failus prie duomenų bazės: žr.

tada jums taip pat reikia konfigūracijos failo:

[connector_python] user = * jūsų vartotojo vardas * host = 127.0.0.1 #if local port = 3306 password = * yourpassword * database = * yourdb * [application_config] driver = 'SQL Server'

4 veiksmas: apkrovos elemento kodavimas

importuoti RPi. GPIO kaip GPIO importuoti sriegių importavimo laiką iš „hx711“importuoti HX711 iš pagalbininkų.stepperFood importuoti „StepperFood“iš pagalbininkų. LCD rašyti importuoti LCD rašyti iš saugyklų. DataRepository importuoti duomenis

Importavę visas savo bibliotekas (atkreipkite dėmesį, kad įkrovos elementui vairuoti naudojame HX711 biblioteką), galime pradėti rašyti savo tikrąjį kodą

TARRA_CONSTANT = 80600

GRAM_KONSTANTAS = 101

Norėdami sužinoti mūsų konstantas, pirmiausia nustatykite TARRA_CONSTANT = 0 ir GRAM_CONSTANT = 1.

Toliau turime sužinoti vertę, kurią nuskaito mūsų apkrovos matuoklis, kai nieko nesveriama. Ši vertė bus TARRA_CONSTANT.

Kalbant apie GRAM_CONSTANT, tiesiog paimkite objektą, kurio svorį žinote (aš naudoju spagečių pakuotę), pasverkite jį ir padalinkite apkrovos elemento rodmenį su faktiniu objekto svoriu. Man tai buvo 101.

„LoadCell“klasė (sriegimas. Siūlai):

def _init _ (self, socket, lcd): sriegimas. Siūlas._ init _ (self) self.hx711 = HX711 (dout_pin = 5, pd_sck_pin = 6, channel = 'A', gain = 64) self.socket = socket self.lcd = LCD

čia inicijuojame „LoadCell“klasę ir priskiriame kaiščius.

def bėgti (savarankiškai):

try: while True: self.hx711.reset () # Prieš pradedant, iš naujo nustatykite HX711 (neprivaloma) 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), išskyrus išimtis kaip e: print („Klaida sveriant“+ str (e))

5 žingsnis: vandens jutiklio kodavimas

importuoti laikąimporto sriegį iš saugyklų. 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 = vanduo [" 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, "Laikas": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5), išskyrus išimtį, pvz..input (GPIO_Wate r) jei self.vorige_status == 0 ir status == 1: print ('water gedetecteerd') sensorData = {"status": status, "action": "water gedetecteerd"} self.vorige_status = status status = GPIO.input (GPIO_Water), jei self.vorige_status == 1 ir status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 ir 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 ir status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

6 žingsnis: artumo jutiklio kodavimas

importuoti laikąimporto sriegį iš saugyklų.. 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 ("Išmatuotas atstumas = %.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 (), išskyrus išimtį, pvz.: print (ex) de f atstumas (savarankiškai): # nustatykite trigerį į HIGH GPIO.output (GPIO_Trig, True) # nustatykite aktyviklį po 0,01 ms į LOW time.sleep (0,00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # išsaugoti pradžios laiką, kol GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # išsaugoti atvykimo laiką, o GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # laiko skirtumas tarp pradžios ir atvykimo laiko.

7 žingsnis: žingsninių variklių kodavimas

importuoti RPi. GPIO kaip GPIO importuoti laiko importavimo gijas GPIO.setmode (GPIO. BCM) GPIO.setwarnings (klaidinga) control_pins = [12, 16, 20, 21] kaiščiui į „control_pins“: GPIO.setup (PIN, GPIO. OUT) GPIO. išvestis (kaištis, 0) halfstep_seq =

Šis kodas gali būti pakartotinai naudojamas kitam žingsniniam varikliui, tiesiog nustatykite valdymo kaiščių numerius į atitinkamus kaiščius ir pervardykite klasę į „StepperWater“:

8 veiksmas: LCD kodavimas

Kodo daug, bet mes beveik baigėme.

LCD klasė yra įtraukta į failą LCD.py

iš pagalbininkų. LCD importo 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ės LCD Rašymas: def pranešimas (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1'), išskyrus: spausdinti ("klaida LCDWrite")

9 žingsnis: pabaiga

Pabaiga
Pabaiga
Pabaiga
Pabaiga

galutinis rezultatas: kaip mes jį parengėme ir kaip tai baigėsi.

Rekomenduojamas: