Pages: [1] 2 3   Go Down
Author Topic: Arduino-Tiny Attiny85 Funzione mills  (Read 1832 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 57
Posts: 3485
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... 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.
Code:
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
« Last Edit: July 02, 2013, 01:26:46 am by nid69ita » Logged

my name is IGOR, not AIGOR

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 312
Posts: 21606
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... 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.
Code:
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.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Questo è il codice che ho fatto, in pratica si preme il pulsante la prima volta
  •   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 ?
Code:
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);
  }

}
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 312
Posts: 21606
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rimodificata cosi ma non funziona...
Code:

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

Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 312
Posts: 21606
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-wink
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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-grin , 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:
Code:
if ( combo[1]==0 ) {
    combo[1] = time;
    return;
  }


Questo è il codice completo:
Code:
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();
}
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 312
Posts: 21606
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?  smiley-wink

Quote
2) 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  smiley-wink ).
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ! smiley-mr-green smiley-mr-green

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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 312
Posts: 21606
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Cagliari, Italy
Online Online
Tesla Member
***
Karma: 102
Posts: 6544
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

AVR!!
 smiley-mr-green smiley-mr-green smiley-mr-green smiley-mr-green
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 312
Posts: 21606
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Eh eh eh  smiley-lol
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Ecco il codice completo:
Code:
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   smiley-wink  Non voglio la pappa pronta !  smiley-grin
« Last Edit: July 03, 2013, 05:32:55 pm by waterseven » Logged

Pages: [1] 2 3   Go Up
Jump to: