Cat feeder e millis

Ciao a tutti,
ho costruito un distributore automatico di croccantini per il gatto,
prendendo spunto da questo video:Link
sono riuscito a replicarlo senza problemi usando questo sketch:

#include <Servo.h>

Servo myservo;

const int servoPin = 9;
const int buttonPin = 12;
const int ledPin = 13;

void setup() {
  myservo.attach(servoPin);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  myservo.write(180);
  delay(1000);
  myservo.detach();
}

Funziona tutto correttamente nonostante il mese impiegato per insegnare al gatto a premere un pulsante per far uscire i croccantini.

Il problema è che adesso che ha imparato, l'ha preso come un gioco e lo preme parecchie volte al giorno riempendo la ciotola allo sfinimento, :o nonostante il delay(1000);
stavo quindi pensando di modificare lo sketch per non far scendere più i croccantini per 2 ore dopo che ha premuto la prima volta e ragionando su come modificare lo sketch, ho creato questo codice:

#define interval 720000 // se non sbaglio sono 2 ore 
#include <Servo.h>

long previousMills = 0;
Servo myservo;

const int servoPin = 9;
const int buttonPin = 12;
const int ledPin = 13;

void setup() {
  myservo.attach(servoPin);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  myservo.write(180);
  delay(1000);
  myservo.detach();
}

void loop() {
int buttonVal = digitalRead(buttonPin);
if (millis() -  previousMills > interval ){
previousMills = millis();                                                                                                                        
if(buttonVal == LOW) {
myservo.attach(servoPin);
myservo.write(50);
delay(1500);
myservo.write(180);
delay(1500);
myservo.detach();
delay(5000);
}
delay(13);
}}

non ho ancora provato se funziona perchè prima volevo un confronto dai più esperti!
saluti
Enzo

previousMillis va dichiarata anche unsigned.

Oltre a quello, così dovrai aspettare 2h anche per la prima apertura, meglio che apri anche nel caso in cui previousMillis == 0.

Ora vogliamo una foto del gatto che aziona l'aggeggio! :smiley:

Oltre a unsigned direi che non funziona come vorresti tu, manca qualche variabile di controllo.
E' quando pigi il pulsante che deve scendere la pappa e poi inibire per 2 ore il pulsante, il contatore deve partire dall'ultima pigiata, non ogni 2 ore, il gatto non ha l'orologio al polso.

Prova a mettere 1 minuto (60000) invece di 720000, fai dei test e guarda cosa succede, poi rimetti 720... quando hai modificato e verificato che faccia quello che vuoi tu.

SukkoPera:
previousMillis va dichiarata anche unsigned.

Oltre a quello, così dovrai aspettare 2h anche per la prima apertura, meglio che apri anche nel caso in cui previousMillis == 0.

Ora vogliamo una foto del gatto che aziona l'aggeggio! :smiley:

Grazie per le info carico il video su youtube e lo posto volentieri☺

pablos:
Oltre a unsigned direi che non funziona come vorresti tu, manca qualche variabile di controllo.
E' quando pigi il pulsante che deve scendere la pappa e poi inibire per 2 ore il pulsante, il contatore deve partire dall'ultima pigiata, non ogni 2 ore, il gatto non ha l'orologio al polso.

Prova a mettere 1 minuto (60000) invece di 720000, fai dei test e guarda cosa succede, poi rimetti 720... quando hai modificato e verificato che faccia quello che vuoi tu.

Ok quindi la logica più corretta è creare una variabile che legge se il pulsante viene premuto entra nel ciclo millis , dichiaro il codice per far scendere la pappa poi un delay e un servo.stop giusto?

--> http://www.bautifulbox.com/
Penso funzioni anche coi gatti.

pablos:
Oltre a unsigned direi che non funziona come vorresti tu, manca qualche variabile di controllo.
E' quando pigi il pulsante che deve scendere la pappa e poi inibire per 2 ore il pulsante, il contatore deve partire dall'ultima pigiata, non ogni 2 ore, il gatto non ha l'orologio al polso.

Prova a mettere 1 minuto (60000) invece di 720000, fai dei test e guarda cosa succede, poi rimetti 720... quando hai modificato e verificato che faccia quello che vuoi tu.

Ho provato a realizzare la tua idea cosi':

#include <Servo.h>
unsigned long interval = 10000;
unsigned long previousMillis = 0;
unsigned char buttonVal= 0;
unsigned char old_buttonVal = 0;

Servo myservo;

const int servoPin = 9;
const int buttonPin = 12;
const int ledPin = 13;

void setup() {
  myservo.attach(servoPin);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  myservo.write(180);
  delay(1000);
  myservo.detach();
}

void loop() {
unsigned long currentMillis = millis();  
buttonVal = digitalRead(buttonPin);
if (buttonVal != old_buttonVal){
old_buttonVal = buttonVal;
if(buttonVal == LOW) {
myservo.attach(servoPin);
myservo.write(50);
delay(1500);
myservo.write(180);
delay(1500);
myservo.detach();
}
delay(13);


if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;  digitalWrite(buttonPin,HIGH);                                                                                                                      
}
}}

in questa maniera dopo aver rilasciato i croccantini, buttonpin seconda la mia logica dovrebbe rimane su high per il tempo definito in millis e alla scadenza del tempo ricomincia il loop.
mi scuso se sto commettendo ancora errori ma nonosatnte la lettura di questo articolo:link
non ho ancora ben capito come integrarlo al meglio nel mio sketch usando un pulsante.
Tutti gli esempi che ho trovato in rete mostrano come far accendere o spegnere un led o più led, ma su come bloccare un pulsante per un tot di tempo, non ho trovato nessuna info utile.
Ringrazio tutti anticipatamente per aiutarmi a capire la logica della funzione millis.
Saluti
Enzo

SukkoPera:
Ora vogliamo una foto del gatto che aziona l'aggeggio! :smiley:

Come promesso ecco il video:Video

e una cosa del genere?

if((currentMillis - previousMillis > interval)&&(buttonVal == LOW))

Enzo--:
Come promesso ecco il video:Video

Bella la scioltezza con cui clicca il pulsante, e bella l'idea del tubo di Pringles! 8)

SukkoPera:
Bella la scioltezza con cui clicca il pulsante, e bella l'idea del tubo di Pringles! 8)

Si nonostante il mese impiegato a insegnargli a farlo, adesso che lo fà, è veramente una soddisfazione :slight_smile:
stavo provando la soluzione di uwefed creando una mia logica ma sbaglio ancora qualcosa :o

#include <Servo.h>
unsigned long interval = 10000;
unsigned long previousMillis = 0;
unsigned char buttonVal= 0;
unsigned char old_buttonVal = 0;


Servo myservo;

const int servoPin = 9;
const int buttonPin = 12;
const int ledPin = 13;

void setup() {
  Serial.begin(9600);
  myservo.attach(servoPin);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  myservo.write(180);
  delay(1000);
  myservo.detach();
}

void loop() {
int buttonVal = digitalRead(buttonPin);
Serial.println(buttonVal);
unsigned long currentMillis = millis();
if (buttonVal != old_buttonVal){
old_buttonVal = buttonVal;
if (buttonVal == LOW) 
{ 
myservo.attach(servoPin);
    myservo.write(50);
    delay(1500);
    myservo.write(180);
    delay(1500);
    myservo.detach();
}

if ((currentMillis - previousMillis >= interval)&&(buttonVal == LOW)){
previousMillis = currentMillis;
digitalWrite(buttonPin,HIGH);
Serial.println("pulsante premuto");
 
}
 } }

Veramente @UWE diceva di mettere il tutto condizionato

void loop() {
  if ((millis() - previousMillis >= interval) && (digitalRead(buttonPin) == LOW)) {
    previousMillis = millis() ;
    Serial.println("pulsante premuto");
    myservo.attach(servoPin);
    myservo.write(50);
    delay(1500);
    myservo.write(180);
    delay(1500);
    myservo.detach();
  }
}

Brunello:
Veramente @UWE diceva di mettere il tutto condizionato

void loop() {

if ((millis() - previousMillis >= interval) && (digitalRead(buttonPin) == LOW)) {
    previousMillis = millis() ;
    Serial.println("pulsante premuto");
    myservo.attach(servoPin);
    myservo.write(50);
    delay(1500);
    myservo.write(180);
    delay(1500);
    myservo.detach();
  }
}



Ciao Brunello,
in questa maniera arduino deve aspettare 10 sec dalla prima pigiata,
invece come suggeriva @Pablos : "E' quando pigi il pulsante che deve scendere la pappa e poi inibire per 2 ore il pulsante, il contatore deve partire dall'ultima pigiata."
Per questo avevo messo l'istruzione servo fuori dal millis.

inoltre come mai impostando il:

unsigned long interval = 728000;

Funziona solo per 15 minuti e non per 2 ore?

Per questo avevo messo l'istruzione servo fuori dal millis.

Come lo avevi impostato tu, non fa assolutamente niente.

digitalWrite(buttonPin,HIGH);

quel digitalWrite non è che abilita o disabilita il pulsante

comunque, per non aspettare il tempo x all'avvio ci sono atnti modi, uno è il seguente:

Dichiarare all'inizio

unsigned long interval = 0 ;

e nell' *if * dichiarare il tempo di intervallo

if ((millis() - previousMillis >= interval) && (digitalRead(buttonPin) == LOW)) {
    previousMillis = millis() ;
    interval = 10000; // assegnazione ritardo
    Serial.println("pulsante premuto");
    myservo.attach(servoPin);
    etc etc etc

Enzo--:
inoltre come mai impostando il:

unsigned long interval = 728000;

Funziona solo per 15 minuti e non per 2 ore?

perchè sono 728 secondi

Grazie Brunello adesso ho capito come funziona :wink:

Spero di non sparare una C.... quindi 7200000 equivale a 2 ore giusto?

7200 000 ms = 7200 secondi = 120 minuti = 2 ore

Brunello:
7200 000 ms = 7200 secondi = 120 minuti = 2 ore

Grazie mille per la conferma.