Sommario:

DISTRIBUTORE AUTOMATICO DI PET FOOD: 9 passaggi
DISTRIBUTORE AUTOMATICO DI PET FOOD: 9 passaggi

Video: DISTRIBUTORE AUTOMATICO DI PET FOOD: 9 passaggi

Video: DISTRIBUTORE AUTOMATICO DI PET FOOD: 9 passaggi
Video: DADYPET Distributore Automatico di Alimenti, Distributore facile da programmare e che si alimenta a 2024, Giugno
Anonim
DISTRIBUTORE AUTOMATICO PER PET FOOD
DISTRIBUTORE AUTOMATICO PER PET FOOD

Hai mai avuto voglia di perdere troppo tempo a dare da mangiare al tuo animale domestico? Hai mai dovuto chiamare qualcuno per dare da mangiare ai tuoi animali domestici mentre eri in vacanza? Ho cercato di risolvere entrambi questi problemi con il mio attuale progetto scolastico: Petfeed!

Forniture

Raspberry Pi 3b

Cella di carico della barra (10kg)

Amplificatore per celle di carico HX711

Sensore di livello dell'acqua (https://www.dfrobot.com/product-1493.html)

Sensore di prossimità ad ultrasuoni

LCD a 16 pin

2x motore passo-passo 28byj-48

2x driver per motore passo-passo ULN2003

Passaggio 1: cablaggio

Cablaggio
Cablaggio
Cablaggio
Cablaggio

un sacco di cavi qui. Tira fuori i cavi dei ponticelli e inizia a fissare!

Passaggio 2: rendi utilizzabile la tua cella di carico

Rendi utilizzabile la tua cella di carico
Rendi utilizzabile la tua cella di carico

per utilizzare la cella di carico, dobbiamo prima fissarla a due piatti: un piatto inferiore e un piatto su cui peseremo il cibo.

Le viti necessarie sono una coppia di viti M4 con bulloni corrispondenti e una coppia di viti M5 con bulloni corrispondenti. Ho usato un piccolo trapano per fare i fori.

(foto:

Passaggio 3: database normalizzato

Database normalizzato
Database normalizzato

i dati dei nostri sensori devono essere salvati in un database. Per i file python da connettere al database: vedi sotto.

allora hai anche bisogno di un file di configurazione:

[connector_python]user = *yourusername* host = 127.0.0.1 #if porta locale = 3306 password = *yourpassword* database = *yourdb* [application_config] driver = 'SQL Server'

Passaggio 4: codifica della cella di carico

import RPi. GPIO as GPIOimport threading import time from hx711 import HX711 from helpers.stepperFood import StepperFood from helpers. LCDWrite import LCDWrite from repository. DataRepository import DataRepository

Dopo aver importato tutte le nostre librerie (nota, stiamo usando la libreria HX711 per pilotare la cella di carico) possiamo iniziare a scrivere il nostro codice effettivo

TARRA_COSTANTE = 80600

GRAM_COSTANTE = 101

Per scoprire le nostre costanti, imposta prima TARRA_CONSTANT = 0 e GRAM_CONSTANT = 1.

Quindi dobbiamo scoprire il valore che legge la nostra cella di carico quando non viene pesato nulla. Questo valore sarà TARRA_CONSTANT.

Per quanto riguarda GRAM_CONSTANT, prendi semplicemente un oggetto di cui conosci il peso (ho usato un pacco di spaghetti), pesalo e dividi la lettura della cella di carico con il peso effettivo dell'oggetto. Per me questo era 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

qui inizializziamo la classe LoadCell e mappiamo i pin.

def run(self):

try: while True: self.hx711.reset() # Prima di iniziare, reimposta l'HX711 (non obbligatorio) measure_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 moeten emitten") writeWeight = "weight: " + str(db_weight) msg = "PETFEED" LCDWrite.message() if int(db_weight[:-2]) <= 100: StepperFood.run() time.sleep(20) tranne Eccezione come e: print ("Errore con la pesatura" + str(e))

Passaggio 5: codifica del sensore dell'acqua

import timeimport threading da repository. DataRepository import DataRepository da RPi import GPIOGPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) GPIO_Water = 18 GPIO.setup(GPIO_Water, GPIO. IN) class 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) tranne Eccezione come es: 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 e status == 1: print('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input(GPIO_Water) if self.vorige_status == 1 e 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

Passaggio 6: codifica del sensore di prossimità

import timeimport threading from repository. DataRepository import DataRepository da 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_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 = 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() tranne Eccezione come es: print(ex) de f distance(self): # imposta Trigger su HIGH GPIO.output(GPIO_Trig, True) # imposta Trigger after 0.01ms su LOW time.sleep(0.00001) GPIO.output(GPIO_Trig, False) StartTime = time.time() StopTime = time.time() # salva StartTime while GPIO.input(GPIO_Echo) == 0: StartTime = time.time() # salva l'ora di arrivo while GPIO.input(GPIO_Echo) == 1: StopTime = time.time() # differenza di tempo tra l'inizio e l'arrivo TimeElapsed = StopTime - StartTime # moltiplicare per la velocità del suono (34300 cm/s) # e dividere per 2, perché distanza di andata e ritorno = (TimeElapsed * 34300) / 2 distanza di ritorno

Passaggio 7: codifica dei motori passo-passo

import RPi. GPIO come GPIOimport time import threading GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) control_pins = [12, 16, 20, 21] per pin in control_pins: GPIO.setup(pin, GPIO. OUT) GPIO.output(pin, 0) halfstep_seq =

Questo codice è riutilizzabile per l'altro motore passo-passo, basta impostare i numeri dei pin di controllo sui rispettivi pin e rinominare la classe in StepperWater:

Passaggio 8: codifica del display LCD

Un sacco di codice, ma abbiamo quasi finito.

La classe LCD è inclusa come file LCD.py

da helpers. 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]) class LCDWrite: def message(msg): try: print("try") lcd.init_LCD() lcd.send_instruction(12) lcd.clear_display() lcd.write_message(msg, '1') tranne: print("errore LCDWrite")

Passaggio 9: la fine

La fine
La fine
La fine
La fine

risultato finale: come l'abbiamo disegnato e come è finito.

Consigliato: