Arduino-Tiny Attiny85 Funzione mills

Salve ragazzi , ho flashato su attiny uno sketch e ora devo fare il reset dopo 2 secondi dalla non ricezione HIGH di un ingresso. Su arduino si usa mills ma provando qui non funziona...
Ho cambiato i fuse ed uso attiny85 a 8mhz il delay(1000) conta un secondo , ma se ad esempio io metto timer=mills(); if mills == 4000 digitalwrite ec ecc non funziona , dove sbaglio o nel caso come posso fare ilr eset se non ricevo dopo tot tempo su attiny?

waterseven:
... io metto timer=mills(); if mills == 4000 digitalwrite ec ecc non funziona , dove sbaglio o nel caso come posso fare il reset se non ricevo dopo tot tempo su attiny?

Forse è meglio se posti il codice completo, da quel poco che scrivi mi sembra errato. Manca qualcosa nel confronto e difficilmente la differenza tra millis() precedente e l'attuale può dare una cifra esatta come 4000.

tempo=0;  nel setup
...
if ( millis()-tempo > 4000 )  
{ tempo=millis();
  // qui codice per quando scatta il tempo
}

O ancora meglio (più completo) guarda l'esempio "blink without delay"
http://arduino.cc/en/Tutorial/BlinkWithoutDelay

millis() (non mills) funziona perfettamente sui Tiny.
Usa il core Tiny preso da qui:
http://code.google.com/p/arduino-tiny/downloads/list

Il reset come intendi farlo? Spero non collegando un pin digitale direttamente al pin di reset e mettendolo low. Non funziona. Devi usare il watchdog.

nid69ita:

waterseven:
... io metto timer=mills(); if mills == 4000 digitalwrite ec ecc non funziona , dove sbaglio o nel caso come posso fare il reset se non ricevo dopo tot tempo su attiny?

Forse è meglio se posti il codice completo, da quel poco che scrivi mi sembra errato. Manca qualcosa nel confronto e difficilmente la differenza tra millis() precedente e l'attuale può dare una cifra esatta come 4000.

tempo=0;  nel setup

...
if ( millis()-tempo > 4000 )  
{ tempo=millis();
  // qui codice per quando scatta il tempo
}



O ancora meglio (più completo) guarda l'esempio "blink without delay"
http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Grazie funziona, errore mio allora nella sintassi della funzione.

Questo è il codice che ho fatto, in pratica si preme il pulsante la prima volta [0] e la i diventa 1 , si preme una seconda volta per piu' di 2 secondi e la i diventa 2 , quando la i è due il cancello si apre. Solo che non mi funziona dove sbaglio ?

const int  buttonPin = 4;
const int cancello = 3;       

// Variables will change:
int i=0;
int buttonState = 0;         
int lastButtonState = 0;    
double time;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(cancello, OUTPUT);
}


void loop() {
  buttonState = digitalRead(buttonPin);
 
  if (buttonState != lastButtonState) {

     if (buttonState == HIGH) { 
        if(i==0){
           i++;
        }
        else{
           reg();
        }
     } 
    
     check();
  }

  lastButtonState = buttonState;

}

void reg(){
  time= millis();   
  if ((buttonState == HIGH)&&(millis()-time > 2000 ))  {
   i++;
  }
}

void check(){
  if(i == 2){
    digitalWrite(cancello, HIGH);
  }

}

Sbagli nel fatto che dentro alla funzione reg() devi continuare a leggere lo stato e solo quando l'utente lo ha premuto per più di 2 secondi, agire di conseguenza.
Tu invece entri in reg() e controlli se la pressione è durata più di 2 secondi ma la pressione non è durata più di 2 secondi perché dal loop, non appena hai premuto il pulsante, vai a verificare i tempi.

Rimodificata cosi ma non funziona...

void reg(){
  time= millis();   
    buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) {
  if ( (buttonState == HIGH)&&(millis()-time > 2000 ))  {
   i++;
  }
  }
}

Ti do una dritta. Usa un while da cui esci solo per timeout (quindi pressione maggiore di 2 secondi) oppure per rilascio pulsante.
Dopo la while controlli se sei uscito per timeout (quindi l'utente ha premuto il pulsante per più di 2 secondi) oppure per rilascio del pulsante, in questo caso sicuramente prima dei 2 secondi ed ignori la cosa.
Altra dritta, usa una variabile aggiuntiva da impostare prima del while, modificare dentro al while e controllare dopo il while.

Di più non posso, il programma sennò te lo scrivo io :wink:

Ho modificato un po del tutto il codice aggiungendo anche i tempi (Avevo fatto un sketch per il clapper e l ho riadattato) per avere ulteriori precauzioni "antiladro" :smiley: , Il mio intento è di fare una combinazione ("per ora di 3") quando nel caso non ho le chiavi suonando il citofono si apre da solo. La combo ora è , primo push , secondo push lungo 2 secondi , terzo push.
Ora ho 2 problemi:

  1. Posso resettare la funzione di millis facendo ripartire da 0 nuovamente con il reset (è possibile il reset dell' attiny85 da software) ?
  2. Non riesco a capire come posso implementare il push del secondo bottone per 2 secondi qui:
 if ( combo[1]==0 ) { 
    combo[1] = time; 
    return; 
  }

Questo è il codice completo:

const int pinButton = 4; // Pin bottone
const int pinGate = 3; // Pin 3 Cancello
int lastState=0;
double combo[3]; // Combinazione di 3 push
double lastPush; // Ultimo push


void setup() 
{
  pinMode(pinGate, OUTPUT); // Dichiaro pinGate come OUTPUT
  pinMode(pinButton, INPUT); // Dichiaro pinGate come INPUT
}




void loop() 
{
        
  // Leggo stato bottone citofono
  int buttonCit = digitalRead(pinButton);    
 
  // Se il bottone è in stato diverso dal precedente
  if (buttonCit != lastState) 
  {
    //Controllo se è in stato alto
     if (buttonCit == HIGH ){
    Reg(); // Registro in combo il momento in cui viene avvertito il push
    Check(); // Controllo se la sequenza e' completa*/
    delay(400);  // Aspetto per non sovraccaricare il buffer
    }
  }
 
  // Sequenza cominciata ma oltre 4 secondi di silenzio: resetto
  if ( combo[0] && millis()-lastPush > 4000 ) {
    reset(); 
  }
  
}


// Registro il momento in cui viene premuto il bottone
void Reg()
{
  double time = millis();
  lastPush = millis();
  
  if ( combo[0]==0 ) {
  combo[0] = time; 
  return;
  }
  
  if ( combo[1]==0 ) {  //QUI DEVO AGGIUNGERE IL CODICE DEL PUSH PER 2 SECONDI SE VERO FAI IL RETURN ALTRIMENTI RESET
    combo[1] = time; 
    return; 
  }
  
  if ( combo[2]==0 ) { 
  combo[2] = time;
  return; 
}

}


void Check()
{
  // Se c'e' il numero corretto di push registrati
  if ( combo[2] > 0 )
  {   
    // Verifica il "ritmo" della sequenza di battiTO
    if ( combo[1]-combo[0] >= 500 && combo[1]-combo[0] <= 1000 ) // 250{
    if ( combo[2]-combo[1] >= 500 && combo[2]-combo[1] <= 1000 ) // 250
      success();

    // Resetto la combo ogni volta che ha completato la sequenza
    reset();
  }
}



//Resetto tutto 
void reset()
{
  for ( int n=0; n<=2; n++ ) { combo[n] = 0; }
  digitalWrite(pinGate,LOW);
  
}


void success()
{
        digitalWrite(pinGate,HIGH);
        delay(1000);
        reset();
}

waterseven:
Ora ho 2 problemi:

  1. Posso resettare la funzione di millis facendo ripartire da 0 nuovamente con il reset (è possibile il reset dell' attiny85 da software) ?

Se resetti il micro, millis riparte da zero. Per resettare il micro puoi usare il watchdog.
Ma perché vuoi resettare il micro? Per far ripartire il programma dall'inizio? Allora il reset è l'ULTIMA delle tue necessità. Io vedo nel tuo caso l'uso del reset come un GOTO, vuoi cioè uscire da un blocco di codice saltando l'esecuzione del resto. Ma allora if..else, do..while a cosa li hanno inventati a fare? :wink:

  1. Non riesco a capire come posso implementare il push del secondo bottone per 2 secondi qui:

Te l'ho spiegato nel post precedente come implementare un controllo per verificare se una pressione avviene per più o meno di un certo tempo (il codice non te lo scrivo, altrimenti non serve a nulla. Sei tu che devi imparare, non io :wink: ).

No io voglio resettare solo il millis non riavviare completamente il pic , watchdog non so proprio dover metter mani haha , domani vedo un po online qualche guida ! :grin: :grin:

In poche parole devo perdere una giornata per capire come funziona il push per 2 secondi ho capito hahahahaha :smiley:

Non serve neanche resettare millis, se fai il programma come si deve. :wink:
Ti passo un link per studiare un pò millis:
http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/

waterseven:
No io voglio resettare solo il millis non riavviare completamente il pic

AVR!!
:grin: :grin: :grin: :grin:

Eh eh eh XD

Fatto , ora funziona era una cagata farlo .... Mi ero inceppato con la logica ... Troppe cose per la testa :smiley:

Ecco il codice completo:

const int pinButton = 4; // Pin bottone
const int pinGate = 3; // Pin 3 Cancello
int lastState=0;
double combo[3]; // Combinazione di 3 push
double lastPush; // Ultimo push
long duration;

void setup() 
{
  pinMode(pinGate, OUTPUT); // Dichiaro pinGate come OUTPUT
  pinMode(pinButton, INPUT); // Dichiaro pinGate come INPUT
}




void loop() 
{
        
  // Leggo stato bottone citofono
  int buttonCit = digitalRead(pinButton);    
 
  // Se il bottone è in stato diverso dal precedente
  if (buttonCit != lastState) 
  {
    //Controllo se è in stato alto
     if (buttonCit == HIGH ){
    Reg(); // Registro in combo il momento in cui viene avvertito il push
    Check(); // Controllo se la sequenza e' completa*/
    delay(400);  // Aspetto per non sovraccaricare il buffer
    }
  }
 
  // Sequenza cominciata ma oltre 4 secondi di silenzio: resetto
  if ( combo[0] && millis()-lastPush > 4000 ) {
    reset(); 
  }
  
}


// Registro il momento in cui viene premuto il bottone
void Reg()
{
  double time = millis();
  lastPush = millis();
  
  if ( combo[0]==0 ) {
  combo[0] = time; 
  return;
  }
  
  if ( combo[1]==0 ) {  //QUI DEVO AGGIUNGERE IL CODICE DEL PUSH PER 2 SECONDI SE VERO FAI IL RETURN ALTRIMENTI RESET
    combo[1] = time; 
   while(digitalRead(pinButton) == HIGH){ // wait while the switch is still pressed
       duration = millis() - combo[1] ;
     }
     if(duration > 1000){ 
    return; 
    }
    else{
      reset();
    }
  }
  
  if ( combo[2]==0 ) { 
  combo[2] = time;
  return; 
}

}


void Check()
{
  // Se c'e' il numero corretto di push registrati
  if ( combo[2] > 0 )
  {   
    // Verifica il "ritmo" della sequenza di battiTO
    if ( combo[1]-combo[0] >= 500 && combo[1]-combo[0] <= 2000 ) // 250{
    if ( combo[2]-combo[1] >= 500 && combo[2]-combo[1] <= 5000 ) // 250
      success();

    // Resetto la combo ogni volta che ha completato la sequenza
    reset();
  }
}



//Resetto tutto 
void reset()
{
  for ( int n=0; n<=2; n++ ) { combo[n] = 0; }
  digitalWrite(pinGate,LOW);
  
}


void success()
{
        digitalWrite(pinGate,HIGH);
        delay(1000);
        reset();
}

Grazie a tutti !!!
leo72 :wink: Non voglio la pappa pronta ! :smiley:

waterseven:
leo72 :wink: Non voglio la pappa pronta ! :smiley:

Tranne che in rari casi, da me non la ottieni. :wink: Non hai idea di quanto MALE faccia farsi fare il codice da altri:

  1. non lo capisci
  2. dato che non lo capisci, ti porta apprendimento pari a 0,1
  3. dato che non ti ha insegnato nulla, domani sarai nuovamente a chiedere aiuto.

Sulle cose bisogna sbatterci il proprio capo, non quello degli altri, solo così le si imparano pian piano.

Sisi pienamente d'accordo 8)

Ahhhhhh, che brutte tutte quelle righe vuote!!! E a che serve indentare ? :smiley:

Quella è la versione comprensibile da tutti :wink: , poi ho la versione min senza commenti e quant'altro :smiley:

No, no i commenti mai toglierli !!! Quelli vanno bene, anzi sono fondamentali. Tra 1 anno voglio vederti a leggere il tuo codice senza commenti e rammentarti che cavolo fa. :grin: