Table des matières:
- Fournitures
- Étape 1: Câblage
- Étape 2: Rendez votre cellule de charge utilisable
- Étape 3: Base de données normalisée
- Étape 4: Codage de la cellule de charge
- Étape 5: Codage du capteur d'eau
- Étape 6: Codage du capteur de proximité
- Étape 7: Codage des moteurs pas à pas
- Étape 8: Codage de l'écran LCD
- Étape 9: La fin
Vidéo: DISTRIBUTEUR AUTOMATIQUE DE NOURRITURE POUR ANIMAUX DE COMPAGNIE : 9 étapes
2025 Auteur: John Day | [email protected]. Dernière modifié: 2025-01-13 06:57
Avez-vous déjà eu envie de perdre trop de temps à nourrir votre animal de compagnie ? Avez-vous déjà dû appeler quelqu'un pour nourrir vos animaux de compagnie pendant vos vacances ? J'ai essayé de résoudre ces deux problèmes avec mon projet scolaire actuel: Petfeed !
Fournitures
Framboise Pi 3b
Cellule de charge à barre (10kg)
Amplificateur de cellule de charge HX711
Capteur de niveau d'eau (https://www.dfrobot.com/product-1493.html)
Capteur de proximité à ultrasons
LCD 16 broches
2x moteur pas à pas 28byj-48
2x pilote de moteur pas à pas ULN2003
Étape 1: Câblage
beaucoup de câblage ici. Sortez vos câbles de démarrage et commencez à épingler !
Étape 2: Rendez votre cellule de charge utilisable
pour utiliser la cellule de charge, nous devons d'abord l'attacher à deux plaques: une plaque inférieure et une plaque sur laquelle nous allons peser nos aliments.
Les vis dont vous avez besoin sont une paire de vis M4 avec des boulons assortis et une paire de vis M5 avec des boulons assortis. J'ai utilisé une petite perceuse pour faire les trous.
(photo:
Étape 3: Base de données normalisée
les données de nos capteurs doivent être enregistrées dans une base de données. Pour les fichiers python à connecter à la base de données: voir ci-dessous.
alors vous avez également besoin d'un fichier de configuration:
[connector_python]user = *yourusername* host = 127.0.0.1 #if local port = 3306 password = *yourpassword* database = *yourdb* [application_config] driver = 'SQL Server'
Étape 4: Codage de la cellule de charge
importer RPi. GPIO en tant que GPIOimporter l'heure d'importation du filetage depuis hx711 importer HX711 depuis helpers.stepperFood importer StepperFood depuis helpers. LCDWrite importer LCDWrite depuis des référentiels. DataRepository importer DataRepository
Après avoir importé toutes nos bibliothèques (notez que nous utilisons la bibliothèque HX711 pour piloter la cellule de charge), nous pouvons commencer à écrire notre code réel
TARRA_CONSTANTE = 80600
GRAM_CONSTANT = 101
Pour connaître nos constantes, définissez d'abord TARRA_CONSTANT = 0 et GRAM_CONSTANT = 1.
Ensuite, nous devons trouver la valeur que lit notre cellule de charge lorsqu'il n'y a rien à peser. Cette valeur sera TARRA_CONSTANT.
En ce qui concerne GRAM_CONSTANT, prenez simplement un objet dont vous connaissez le poids (j'ai utilisé un paquet de spaghettis), pesez-le et divisez la lecture de la cellule de charge avec le poids réel de l'objet. Pour moi, c'était 101.
classe 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 = écran LCD
ici, nous initialisons la classe LoadCell et mappons les broches.
def run(self):
try: while True: self.hx711.reset() # Avant de commencer, réinitialisez le HX711 (non obligatoire)measures_avg = sum(self.hx711.get_raw_data()) / 5 weight = round((measures_avg - TARRA_CONSTANT) / GRAM_CONSTANT, 0) print("poids: {0}".format(poids)) DataRepository.insert_weight(poids) 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 moetenemiten") writeWeight = "weight: " + str(db_weight) msg = "PETFEED" LCDWrite.message() if int(db_weight[:-2]) <= 100: StepperFood.run() time.sleep(20) sauf exception comme e: print ("Erreur de pesée" + str(e))
Étape 5: Codage du capteur d'eau
import timeimport threading depuis les référentiels. DataRepository import DataRepository depuis 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": valeur, "Time": DataRepository.serializeDateTime(actionTime), "action": action}) time.sleep(5) sauf exception comme ex: print(ex) print('error bij watersensor') def is_water(self): status = GPIO.input(GPIO_Wate r) if self.vorige_status == 0 et 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 et status == 1: print('water aanwezig') sensorData = {"status": status, "action": "water aanwezig"} status = GPIO.input(GPIO_Water) if self.vorige_status == 1 et 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 et status == 0: print('startpositie') status = GPIO.input(GPIO_Water) sensorData = {"status": status, "action": "startpositie"} return sensorData
Étape 6: Codage du capteur de proximité
import timeimport threading depuis les référentiels. DataRepository import DataRepository depuis 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() sauf exception comme ex: print(ex) de f distance(self): # définir Trigger sur HIGH GPIO.output(GPIO_Trig, True) # définir Trigger après 0.01ms sur LOW time.sleep(0.00001) GPIO.output(GPIO_Trig, False) StartTime = time.time() StopTime = time.time() # enregistre StartTime while GPIO.input(GPIO_Echo) == 0: StartTime = time.time() # enregistre l'heure d'arrivée tandis que GPIO.input(GPIO_Echo) == 1: StopTime = time.time() # différence de temps entre le départ et l'arrivée TimeElapsed = StopTime - StartTime # multiplier par la vitesse sonique (34300 cm/s) # et diviser par 2, car distance aller et retour = (TimeElapsed * 34300) / 2 distance retour
Étape 7: Codage des moteurs pas à pas
importer RPi. GPIO en tant que GPIOimport time import threading GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) control_pins = [12, 16, 20, 21] pour la broche dans control_pins: GPIO.setup(pin, GPIO. OUT) GPIO.output(pin, 0) halfstep_seq =
Ce code est réutilisable pour l'autre moteur pas à pas, il suffit de définir les numéros de broche de contrôle sur leurs broches respectives et de renommer la classe en StepperWater:
Étape 8: Codage de l'écran LCD
Beaucoup de code, mais nous avons presque terminé.
La classe LCD est incluse dans le fichier LCD.py
de 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]) classe LCDWrite: def message(msg): try: print("try") lcd.init_LCD() lcd.send_instruction(12) lcd.clear_display() lcd.write_message(msg, '1') sauf: print("erreur LCDWrite")
Étape 9: La fin
résultat final: comment nous l'avons élaboré par rapport à la façon dont il s'est terminé.