Tabla de contenido:

DISPENSADOR AUTOMÁTICO DE ALIMENTOS PARA MASCOTAS: 9 Pasos
DISPENSADOR AUTOMÁTICO DE ALIMENTOS PARA MASCOTAS: 9 Pasos

Video: DISPENSADOR AUTOMÁTICO DE ALIMENTOS PARA MASCOTAS: 9 Pasos

Video: DISPENSADOR AUTOMÁTICO DE ALIMENTOS PARA MASCOTAS: 9 Pasos
Video: Dispensador Automático de Alimento para Mascotas MiCan - Productos Higo 2024, Junio
Anonim
DISPENSADOR AUTOMÁTICO DE ALIMENTOS PARA MASCOTAS
DISPENSADOR AUTOMÁTICO DE ALIMENTOS PARA MASCOTAS

¿Alguna vez sintió ganas de perder demasiado tiempo alimentando a su mascota? ¿Alguna vez tuviste que llamar a alguien para alimentar a tus mascotas mientras estabas de vacaciones? He intentado solucionar ambos problemas con mi proyecto escolar actual: ¡Petfeed!

Suministros

Frambuesa Pi 3b

Celda de carga de barra (10 kg)

Amplificador de celda de carga HX711

Sensor de nivel de agua (https://www.dfrobot.com/product-1493.html)

Sensor de proximidad ultrasónico

LCD de 16 pines

2x motor paso a paso 28byj-48

2x controlador de motor paso a paso ULN2003

Paso 1: cableado

Alambrado
Alambrado
Alambrado
Alambrado

mucho cableado aquí. ¡Saque sus cables de puente y comience a fijar!

Paso 2: Haga que su celda de carga sea utilizable

Haga que su celda de carga sea utilizable
Haga que su celda de carga sea utilizable

Para usar la celda de carga, primero necesitamos unirla a dos platos: un plato inferior y un plato en el que pesaremos nuestra comida.

Los tornillos que necesita son un par de tornillos M4 con pernos a juego y un par de tornillos M5 con pernos a juego. Usé un pequeño taladro para hacer los agujeros.

(imagen:

Paso 3: base de datos normalizada

Base de datos normalizada
Base de datos normalizada

Los datos de nuestros sensores deben guardarse en una base de datos. Para que los archivos de Python se conecten a la base de datos: consulte a continuación.

entonces también necesitas un archivo de configuración:

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

Paso 4: codificación de la celda de carga

importar RPi. GPIO como GPIOimportar el tiempo de importación de subprocesos desde hx711 importar HX711 desde helpers.stepperFood importar StepperFood desde helpers. LCDWrite importar LCDWrite desde repositorios. DataRepository importar DataRepository

Después de importar todas nuestras bibliotecas (tenga en cuenta que estamos usando la biblioteca HX711 para controlar la celda de carga) podemos comenzar a escribir nuestro código real

TARRA_CONSTANT = 80600

GRAM_CONSTANT = 101

Para conocer nuestras constantes, primero configure TARRA_CONSTANT = 0 y GRAM_CONSTANT = 1.

A continuación, debemos averiguar el valor que lee nuestra celda de carga cuando no se pesa nada. Este valor será TARRA_CONSTANT.

En cuanto a GRAM_CONSTANT, simplemente tome un objeto cuyo peso conozca (utilicé un paquete de espaguetis), péselo y divida la lectura de la celda de carga con el peso real del objeto. Para mí esto fue 101.

clase LoadCell (threading. Thread):

def _init _ (self, socket, lcd): subproceso. Thread._ init _ (self) self.hx711 = HX711 (dout_pin = 5, pd_sck_pin = 6, canal = 'A', ganancia = 64) self.socket = socket self.lcd = lcd

aquí inicializamos la clase LoadCell y mapeamos los pines.

def ejecutar (auto):

try: while True: self.hx711.reset () # Antes de comenzar, restablezca el HX711 (no obligado) 0) print ("peso: {0}". Formato (peso)) DataRepository.insert_weight (peso) data_weight = DataRepository.get_data_sensor (3) historyId = data_weight ["SensorsHistory"] db_weight = data_weight ["valor"] actionTime = data_weight ["actionTime"] self.socket.emit ('data_weight', {"id": historyId, "Weight": db_weight, "Time": DataRepository.serializeDateTime (actionTime)}) print ("zou moeten emitten") writeWeight = "peso:" + str (db_weight) msg = "PETFEED" LCDWrite.message () if int (db_weight [: - 2]) <= 100: StepperFood.run () time.sleep (20) excepto Excepción como e: print ("Error al pesar" + str (e))

Paso 5: codificación del sensor de agua

importar timeimport threading desde repositories. DataRepository importar DataRepository desde 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 [" estado "] acción = agua [" acción "] DataRepository.insert_water (str (estado), acción) data_water = DataRepository.get_data_sensor (2) historyId = data_water [" SensorsHistory "] valor = data_water [" valor "] si valor == "0": value = "te weinig water" else: value = "genoeg water" actionTime = data_water ["actionTime"] self.socket.emit ('data_water', {"id": historyId, "value": value, "Hora": DataRepository.serializeDateTime (actionTime), "action": action}) time.sleep (5) excepto Excepción como ex: print (ex) print ('error bij watersensor') def is_water (self): status = GPIO.input (GPIO_Wate r) if self.vorige_status == 0 y 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 y status == 1: print ('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input (GPIO_Water) if self.vorige_status == 1 y 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 y status == 0: print ('startpositie') status = GPIO.input (GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData

Paso 6: codificación del sensor de proximidad

importar el subproceso de importación de tiempo de repositorios.. 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 ("Distancia medida =%.1f cm"% dist) DataRepository. insert_proximity (dist) data_prox = DataRepository.get_data_sensor (1) historyId = data_prox ["SensorsHistory"] prox = data_prox ["valor"] actionTime = data_prox ["actionTime"] self.socket.emit ('data_proximity', {"id": historyId, "Proximity": prox, "Time": DataRepository.serializeDateTime (actionTime)}) last_reading = current_milli_time () excepto Excepción como ex: print (ex) de f distancia (auto): # establecer Trigger en HIGH GPIO.output (GPIO_Trig, True) # establecer Trigger after 0.01ms en LOW time.sleep (0.00001) GPIO.output (GPIO_Trig, False) StartTime = time.time () StopTime = time.time () # guardar StartTime mientras GPIO.input (GPIO_Echo) == 0: StartTime = time.time () # guardar tiempo de llegada mientras GPIO.input (GPIO_Echo) == 1: StopTime = time.time () # diferencia de tiempo entre el inicio y la llegada TimeElapsed = StopTime - StartTime # multiplique por la velocidad sónica (34300 cm / s) # y divida por 2, porque la distancia de ida y vuelta = (TimeElapsed * 34300) / 2 distancia de retorno

Paso 7: codificación de los motores paso a paso

importar RPi. GPIO como GPIOimportar tiempo importar subprocesos GPIO.setmode (GPIO. BCM) GPIO.setwarnings (False) control_pins = [12, 16, 20, 21] para pin en control_pins: GPIO.setup (pin, GPIO. OUT) GPIO.output (pin, 0) halfstep_seq =

Este código es reutilizable para el otro motor paso a paso, simplemente configure los números de los pines de control en sus respectivos pines y cambie el nombre de la clase a StepperWater:

Paso 8: codificación de la pantalla LCD

Mucho código, pero casi hemos terminado.

La clase LCD se incluye como archivo LCD.py

desde helpers. LCD importar 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]) clase LCDWrite: def message (msg): try: print ("try") lcd.init_LCD () lcd.send_instruction (12) lcd.clear_display () lcd.write_message (msg, '1') excepto: imprimir ("error LCDWrite")

Paso 9: el final

El fin
El fin
El fin
El fin

resultado final: cómo lo redactamos vs. cómo terminó.

Recomendado: