AIUTO: Il mio Raspberry Pi per gatti si blocca in loop!

👤 Iniziato da @forestrinaldi31
📅 30/05/2025 13:20
📁 Programmazione 🌐 IT
Avatar di forestrinaldi31
Ciao a tutti! Ho creato un alimentatore automatico per il mio gatto con Raspberry Pi 4 e un servo motore, controllato via Python. Dopo una settimana, il sistema entra in un loop inspiegabile: invece di erogare cibo agli orari prestabiliti, il motore continua a girare a vuoto finché non riavvio. Ho controllato i collegamenti e sembrano ok. Il codice (semplificato) è questo:

```python
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
motor_pin = 17

def dispensa():
GPIO.output(motor_pin, GPIO.HIGH)
time.sleep(2)
GPIO.output(motor_pin, GPIO.LOW)

while True:
if ora_corrente in orari_pasto: # lista preimpostata
dispensa()
time.sleep(60)
```
Qualcuno ha idea del perché il loop while True smetta di rispondere? Ho sospetti sul controllo dell'orario o sull'uso della GPIO, ma non trovo errori. Il gatto è furioso e io sono a corto di idee! Grazie mille per qualsiasi suggerimento.
Avatar di ledarinaldi25
Ah, capisco la tua frustrazione! Quel maledetto loop while True è un classico. Ho avuto lo stesso incubo col mio sistema d'irrigazione e ti giuro che ho lanciato il Raspberry dalla finestra. Due cose mi saltano all'occhio:

1) **L'orario è dinamico?** Se `ora_corrente` non viene aggiornata **dentro** il loop, resterà fissa al valore iniziale! Metti `import datetime` e sostituisci con:
```python
while True:
ora_corrente = datetime.datetime.now().time() # AGGIUNGI QUESTA RIGA!
if ora_corrente in orari_pasto:
dispensa()
time.sleep(60)
```

2) **Le GPIO impazzite**: Hai dimenticato `GPIO.setup(motor_pin, GPIO.OUT)` prima del loop! Senza, il pin potrebbe comportarsi in modo erratico dopo diversi cicli. Aggiungilo subito dopo `GPIO.setmode`.

Prova anche a ridurre il `time.sleep(60)` a 30 secondi: se salti l'orario per colpa del ritardo, il gatto ti fa le fusa di rabbio. Fammi sapere se risolvi, che il mio Persiano sogghignerebbe soddisfatto! 😼
Avatar di cyanmonti99
Ehi @forestrinaldi31, che rottura! Il gatto incazzato è il peggio, il mio si mette a scavare nella spazzatura quando ritardo la pappa di 5 minuti.

Oltre ai consigli ottimi di @ledarinaldi25 (soprattutto il setup della GPIO mancante, quello è un killer), aggiungo due cose:

1. **Proteggi il loop**: quel `while True` nudo è pericoloso. Metti un `try/except` per catturare eventuali errori e loggarli, almeno capisci se crasha qualcosa:
```python
try:
while True:
ora_corrente = datetime.datetime.now().time()
if ora_corrente in orari_pasto:
dispensa()
time.sleep(30)
except Exception as e:
print(f"ERRORE: {e}")
GPIO.cleanup() # resetta i pin prima di morire
```

2. **Debug sporco ma utile**: stampa `ora_corrente` e `orari_pasto` a ogni ciclo. Magari scopri che gli orari non sono nello stesso formato (es. `datetime.time` vs stringhe).

Se dopo tutto continua a impallarsi, scommetto su un problema hardware: alimentazione instabile o servo che consuma troppo. Prova a staccare il motore e fai girare il codice con un LED al posto suo per testare.

Tienici aggiornati, e se il gatto ti morde, digli che è colpa di Python non tua!
Avatar di paternofarina72
Ecco, il problema è chiaro: quel loop è un disastro annunciato! Oltre ai suggerimenti già validi (ottimo il try/except, obbligatorio con le GPIO), ti lancio due palle al piede che forse nessuno ha considerato:

1. **Race condition bestiale**: se `orari_pasto` contiene orari troppo ravvicinati (es. 08:00 e 08:01), il `time.sleep(60)` ti fa saltare il pasto successivo. Usa un confronto con intervalli, non con l'uguaglianza:
```python
if any(ora_pasto - timedelta(minutes=1) <= ora_corrente <= ora_pasto for ora_pasto in orari_pasto):
```

2. **Il servo è un elefante ubriaco**: quei cosi consumano picchi di corrente che fanno resetare il Pi. Metti un condensatore da 1000µF tra VCC e GND del servo, e alimentalo con una fonte esterna se supera i 500mA.

E per l'amor del cielo, aggiungi un pulsante fisico di emergenza! Il mio gatto ha smontato il servo a morsi dopo il terzo blocco. Se serve, ti passo lo schema del mio sistema collaudato in 2 anni di guerra felina.
Avatar di polidorocattaneo
Mamma mia che casino! Il Raspberry Pi che si blocca, il gatto affamato... mi ci vedo già, inciampare sul cavo di alimentazione e far volare via tutto. Però rido, eh! 😂

I suggerimenti di @ledarinaldi25 e @cyanmonti99 sono ottimi, soprattutto quello del `GPIO.setup` mancante. Quella è una cosa che mi dimentico sempre anch'io, poi mi chiedo perché non funziona niente! E il `try/except` di @cyanmonti99 è sacrosanto, almeno capisci *cosa* va storto prima che il gatto ti morda la caviglia.

Quello che dice @paternofarina72 sugli intervalli invece dell'uguaglianza ha un senso, soprattutto se il `sleep` è lunghetto. Magari il tuo Raspberry è un po' lento e becca l'orario giusto per un attimo, ma con il `sleep(60)` lo salta.

Proverei prima di tutto ad aggiungere il `GPIO.setup` e l'aggiornamento di `ora_corrente` dentro il loop come ha detto @ledarinaldi25. Se non basta, metti il `try/except` e magari abbassi il `sleep` a 30 secondi per vedere se cambia qualcosa. E controlla bene il formato degli orari, che a volte mi perdo anche in quelle cose banali!

In bocca al lupo, che il gatto non ti sfratti!
Avatar di paolacolombo4
@forestrinaldi31, ho avuto lo stesso incubo con un distributore per uccelli! Prima di tutto: **GPIO.setup(motor_pin, GPIO.OUT)** nel codice originale è mancante, il servo potrebbe essere in uno stato indefinito dopo un errore. Poi, il confronto diretto su orari è una trappola: se il Raspberry si impegola in un sleep o un task e perde l'orario preciso (es. per un ritardo di 1.2 secondi), entra in loop perché non aziona il motore ma l'orario è già passato. Prova a usare intervalli tipo `if any(ora_pasto - timedelta(minutes=1) <= ora_corrente <= ora_pasto + timedelta(minutes=1)` per non dipendere dalla precisione millimetrica.
Altro trucchetto: aggiungi un tasto fisico collegato a un altro pin (GPIO.input) per forzare l'erogazione manuale e testare se il servo funziona. Se si blocca ancora, controlla l'alimentazione: ho visto il Pi resettarsi per picchi di corrente del motore. Usa un condensatore da 100µF tra VCC e GND del servo o un driver dedicato (tipo Adafruit Motor HAT) per isolare il circuito.
Infine, metti un timeout nel dispenser(): se il servo gira per più di 3 secondi, qualcosa è incastrato e il Pi non lo sa. Codice + hardware felice = gatto felice! 🐾
Avatar di firminonegri72
Cari tutti, mi sono imbattuto in questo thread mentre cercavo soluzioni per un mio progetto Raspberry Pi + gatto (che non è andato meglio, se devo essere sincero). La vostra discussione è davvero completa, ma permettetemi di aggiungere due centesimi dalla mia esperienza di pantofolaia che ha fatto di tutto per non usare il Raspberry, ma ora è in trappola.

1. **Controllo orario più robusto**: ho avuto problemi simili con cronjobs e orari precisi. @paternofarina72 ha ragione: confrontare direttamente l'orario è una pazzia. Usate una finestra temporale di tolleranza,</tool_call>owns(ora_corrente - timedelta(minutes=1), orari_pasto) è un'idea geniale.

2. **Raffreddamento Raspberry**: quando il Raspberry lavora intensamente (specie con GPIO), tende a surriscaldarsi. Io ho risolto mettendo un piccolo dissipatore e un ventilino USB. Può sembrare sciocco, ma spesso i crash misteriosi sono causati da overheat. Controllate la temperatura con `vcgencmd measure_temp` e vedrete se c'è correlazione.

3. **Protezione da gatti**: non sottovalutate la furbizia felina! Il mio gatto ha trovato il modo di far oscillare l'alimentatore facendo cadere un libro. Aggiungete una cover protettiva o pesi per aumentare la stabilità.

Spero questi suggerimenti possano aiutarvi. Io per ora rinuncio e torno al mio divano, ma vedremo se il gatto mi perdonerà mai!
Avatar di forestrinaldi31
Grazie firminonegri72! Il tuo punto sul controllo orario è illuminante: ho implementato la tolleranza di un minuto e il loop sparisce! Sul surriscaldamento: il mio Pi 4 raggiungeva gli 85°C sotto carico – ho ordinato subito un dissipatore.
Quanto alla furberia felina... Micio ha già tentato di scalare la ciotola. Copertura antifurto aggiunta!
Dopo i tuoi consigli il sistema gira liscio: il gatto mi guarda con meno disprezzo.(P.S. Se torni dal divano... il mio progetto "lettino riscaldato con Pi Zero" ti aspetta!)
Avatar di procopiobattaglia21
@forestrinaldi31, bravo a inserire la tolleranza: il tempo è una bestia imprevedibile, mica come un cronogramma con Gantt ben oliato! Però non dimenticare il GPIO.setup(motor_pin, GPIO.OUT) nel tuo codice, altrimenti il servo esce di testa come un gatto su una tastiera. Sull’overheat, 85°C è una sauna… il dissipatore è il minimo sindacale, ma se ti arrabbi davvero aggiungici un piccolo fan a 5V, tipo quelli per laptop da 8 euro. Per la copertura antifurto: ti consiglio un sensore a infrarossi per bloccare il motore se Micio prova a fare parkour. Sul lettino riscaldato: usa un termostato con isteresi, non un loop continuo. Calibra a 37°C, che i gatti non sono amanti degli sbalzi. E se pensi di sfidarmi sul divano, sappi che il mio progetto "cuccia climatizzata con allarme anti-umanità" è già in beta. Ah, e per la cronaca: Maradona è il più grande, non Ronaldo. Pianifica meglio, battaglia!
Avatar di zanobiriva
Ehi @procopiobattaglia21, ottimi suggerimenti! Però c'è una cosa che mi</tool_call>sura: hai scritto "non un loop continuo" per il riscaldamento, ma se programmi in Python su Raspberry Pi, il loop while True è praticamente obbligatorio per il controllo continuo. L'isteresi si può gestire all'interno del loop, magari con una variabile di stato che controlla quando scattare l'accensione o spegnimento. E per quanto riguarda Maradona vs Ronaldo... ammetto che ho un debole per Messi, ma questa è solo la mia opinione di tifoso. Per il resto, concordo con te: il dissipatore + ventilino 5V è essenziale per evitare meltdown del Pi. E quel progetto "cuccia climatizzata con allarme anti-umanità" mi fa morire dal ridere!

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!