Sommario:
- Forniture
- Passaggio 1: cablaggio
- Passaggio 2: rendi utilizzabile la tua cella di carico
- Passaggio 3: database normalizzato
- Passaggio 4: codifica della cella di carico
- Passaggio 5: codifica del sensore dell'acqua
- Passaggio 6: codifica del sensore di prossimità
- Passaggio 7: codifica dei motori passo-passo
- Passaggio 8: codifica del display LCD
- Passaggio 9: la fine
Video: DISTRIBUTORE AUTOMATICO DI PET FOOD: 9 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:00
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
un sacco di cavi qui. Tira fuori i cavi dei ponticelli e inizia a fissare!
Passaggio 2: 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
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
risultato finale: come l'abbiamo disegnato e come è finito.
Consigliato:
Distributore automatico di farmaci: 5 passaggi
Distributore automatico di farmaci: questo progetto è destinato all'uso in campo medico, in cui i pazienti anziani devono disporre di un modo affidabile per porzionare e dispensare i farmaci. Questo dispositivo consente di porzionare i farmaci fino a 9 giorni in anticipo e di essere dispensati automaticamente a piacimento
Distributore automatico di caramelle: 5 passaggi
CandyVendingMachine: il distributore automatico di caramelle funziona davvero
Distributore automatico fai da te: 8 passaggi
Distributore automatico fai-da-te: tre anni fa, ho iniziato a studiare in un istituto tecnico elettronico. Uno dei fatti che mi ha sorpreso in quel momento era il numero di fumatori perché durante le pause, metà degli studenti lasciava le mura della scuola per scaricare le proprie emozioni dopo
Come realizzare un distributore automatico di sapone: 6 passaggi
Come realizzare un distributore automatico di sapone: CIAO, in questo tutorial ti mostrerò come realizzare un distributore automatico di sapone senza contatto completamente fai-da-te. Se ti piace, considera di supportarmi iscrivendoti al mio canale ARDUINO MAKER. Quindi preparati ad essere ispirato…..! puoi anche guardare
Distributore automatico di carte: 7 passaggi
Distributore automatico di carte: ho scelto un distributore di smart card come mio primo progetto perché mi piace giocare a un gioco di carte. La cosa che non mi piace di più è distribuire le carte. Devi ricordare per ogni partita quante carte riceve ogni persona. Questo diventa confuso quando conosci un lo