Attivare un led quando un oggetto viene scosso

Buongiorno a tutti, sto provando a costruire una scatola che quando viene scossa per almeno un secondo fa accendere un led.
Per farlo sto utilizzando un sensore tilt a sfera, ho trovato uno script che funziona ma a cui vorrei apportare delle modifiche.
Infatti lo script che ho trovato accende il led al minimo movimento cioè appena il sensore cambia stato, ho provato a cambiare il tempo shakeTime da 50 a 1000 ma non ho ottenuto il risultato voluto, cioè che la scatola debba essere shekerata per almeno un secondo prima di accendere il led.
Qualche suggerimento?

/*
  shaken sketch
  tilt sensor connected to pin 2
  led connected to pin 13
*/

const int tiltSensorPin = 2;
const int ledPin = 13;
int tiltSensorPreviousValue = 0;
int tiltSensorCurrentValue = 0;
long lastTimeMoved = 0;
int shakeTime=50;

void setup()
{
  pinMode (tiltSensorPin, INPUT);
  digitalWrite (tiltSensorPin, HIGH);
  pinMode (ledPin, OUTPUT);
}

void loop()
{
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    lastTimeMoved = millis();
    tiltSensorPreviousValue = tiltSensorCurrentValue;
  }

  if (millis() - lastTimeMoved < shakeTime){
    digitalWrite(ledPin, HIGH);
  }
  else{
    digitalWrite(ledPin, LOW);
  }
}

Innanzitutto ho una perplessità, l'utilità di questa riga: digitalWrite (tiltSensorPin, HIGH);
Mettere alto un pin di INPUT ? Mah!

Tornando a noi, modifica questo if (millis() - lastTimeMoved < shakeTime) con questo (millis() - lastTimeMoved >= shakeTime).
Metti shakeTime = 1000; e prova, dovrebbe andare. :wink:

Fammi sapere.

Brado:
Innanzitutto ho una perplessità, l'utilità di questa riga: digitalWrite (tiltSensorPin, HIGH);
Mettere alto un pin di INPUT ? Mah!

Se poni alto un input attivi la sua pullup, non c'è nulla di sbagliato in questo se serve la pull up sul pin.

il tuo loop

{
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    lastTimeMoved = millis();
    tiltSensorPreviousValue = tiltSensorCurrentValue;
  }

  if (millis() - lastTimeMoved < shakeTime){
    digitalWrite(ledPin, HIGH);
  }
  else{
    digitalWrite(ledPin, LOW);
  }
}

così non va bene infatti se il sensor pin è attivo continui ad aggiornare lastTimeMoved che prende millis. a che scopo??

prova così

/*
  shaken sketch
  tilt sensor connected to pin 2
  led connected to pin 13
*/

const int tiltSensorPin = 2;
const int ledPin = 13;
int tiltSensorPreviousValue = 0;
int tiltSensorCurrentValue = 0;
long lastTimeMoved = 0;
int shakeTime=50;
int a=0;

void setup()
{
  pinMode (tiltSensorPin, INPUT);
  digitalWrite (tiltSensorPin, HIGH);
  pinMode (ledPin, OUTPUT);
}

void loop()
{
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    tiltSensorPreviousValue = tiltSensorCurrentValue;
a++;
  }
delay(1000);
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    tiltSensorPreviousValue = tiltSensorCurrentValue;
a++;
  }
if(a==2){
digitalWrite(ledPind,HIGH);
}else{
digitalWrite(ledPind,LOW);
}
a=0;
}

astrobeed:
Se poni alto un input attivi la sua pullup, non c'è nulla di sbagliato in questo se serve la pull up sul pin.

Giusto, la pullup, non ci pensavo più. Grazie. :wink:

hard_uino:
il tuo loop

{

tiltSensorCurrentValue=digitalRead(tiltSensorPin);
 if (tiltSensorPreviousValue != tiltSensorCurrentValue){
   lastTimeMoved = millis();
   tiltSensorPreviousValue = tiltSensorCurrentValue;
 }

if (millis() - lastTimeMoved < shakeTime){
   digitalWrite(ledPin, HIGH);
 }
 else{
   digitalWrite(ledPin, LOW);
 }
}



così non va bene infatti se il sensor pin è attivo continui ad aggiornare lastTimeMoved che prende millis. a che scopo??

E' giusto.
LastTimeMoved prende millis solo al cambio di stato di tiltSensorPreviousValue rispetto a tiltSensorCurrentValue, quindi se il sensore si è mosso mi salvo il momento in cui l'ha fatto.
Dopodiché se muovo l'oggetto per meno di shakeTime attivo il led, altrimenti lo spengo.

Visto che l'oggetto va' "shakerato", non sarebbe contare quante volte il sensore si e' chiuso ?
meglio con un interrupt

hard_uino:
prova così

/*

shaken sketch
 tilt sensor connected to pin 2
 led connected to pin 13
*/

const int tiltSensorPin = 2;
const int ledPin = 13;
int tiltSensorPreviousValue = 0;
int tiltSensorCurrentValue = 0;
long lastTimeMoved = 0;
int shakeTime=50;
int a=0;

void setup()
{
 pinMode (tiltSensorPin, INPUT);
 digitalWrite (tiltSensorPin, HIGH);
 pinMode (ledPin, OUTPUT);
}

void loop()
{
 tiltSensorCurrentValue=digitalRead(tiltSensorPin);
 if (tiltSensorPreviousValue != tiltSensorCurrentValue){
   tiltSensorPreviousValue = tiltSensorCurrentValue;
a++;
 }
delay(1000);
 tiltSensorCurrentValue=digitalRead(tiltSensorPin);
 if (tiltSensorPreviousValue != tiltSensorCurrentValue){
   tiltSensorPreviousValue = tiltSensorCurrentValue;
a++;
 }
if(a==2){
digitalWrite(ledPind,HIGH);
}else{
digitalWrite(ledPind,LOW);
}
a=0;
}

Scusa se mi permetto, ma che casino! :fearful:
E poi non andrà mai, perchè dopo il delay devi controllare che gli stati siano uguali e non diversi. :wink:

E' giusto.
LastTimeMoved prende millis solo al cambio di stato di tiltSensorPreviousValue rispetto a tiltSensorCurrentValue, quindi se il sensore si è mosso mi salvo il momento in cui l'ha fatto.
Dopodiché se muovo l'oggetto per meno di shakeTime attivo il led, altrimenti lo spengo.

No, così ogni volta che muovo la scatola se arduino impiega meno di 50 millisecondi a compiere l'istruzione successiva il led si accende.

Scusa se mi permetto, ma che casino! smiley-eek-blue

Concordo sul fatto che sia un casino. (ma se hai trovato un errore non è poi così tanto incasinato :slight_smile: :slight_smile: :)).

E poi non andrà mai, perchè dopo il delay devi controllare che gli stati siano uguali e non diversi. smiley-wink

Vero anche questo. Il secondo != deve essere ==.

codice coretto:

/*
  shaken sketch
  tilt sensor connected to pin 2
  led connected to pin 13
*/

const int tiltSensorPin = 2;
const int ledPin = 13;
int tiltSensorPreviousValue = 0;
int tiltSensorCurrentValue = 0;
long lastTimeMoved = 0;
int shakeTime=50;
int a=0;

void setup()
{
  pinMode (tiltSensorPin, INPUT);
  digitalWrite (tiltSensorPin, HIGH);
  pinMode (ledPin, OUTPUT);
}

void loop(){
 tiltSensorPreviousValue = 0;
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    tiltSensorPreviousValue = tiltSensorCurrentValue;
a++;
  }
delay(1000);
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue== tiltSensorCurrentValue){
a++;
  }
if(a==2){
digitalWrite(ledPind,HIGH);
}else{
digitalWrite(ledPind,LOW);
}
a=0;
}

il led resta acceso solo se scuoti la scatola

Lui voleva che il led restasse acceso se la scatola viene scossa per almeno un secondo.
Se si scuote per meno, il led si spegne.

Scusa non avevo capito, così dovrebbe fare quello che chiede.(non ho la possibilità di provarlo quindi non ho la certezza al 100% che funzioni).

/*
  shaken sketch
  tilt sensor connected to pin 2
  led connected to pin 13
*/

const int tiltSensorPin = 2;
const int ledPin = 13;
int tiltSensorPreviousValue = 0;
int tiltSensorCurrentValue = 0;
long lastTimeMoved = 0;
int shakeTime=50;
int a=0;

void setup()
{
  pinMode (tiltSensorPin, INPUT);
  digitalWrite (tiltSensorPin, HIGH);
  pinMode (ledPin, OUTPUT);
}

void loop(){
 tiltSensorPreviousValue = 0;
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    tiltSensorPreviousValue = tiltSensorCurrentValue;
a++;
  }
delay(1000);
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue== tiltSensorCurrentValue){
a++;
  }
if(a==2){
digitalWrite(ledPind,HIGH);
}
if(a==1){
digitalWrite(ledPind,LOW);
}
a=0;
}

Dovrebbe bastare la sola modifica che ho proposto all'inizio, senza stare a rifare tutto lo sketch. :wink:

Brado:
Dovrebbe bastare la sola modifica che ho proposto all'inizio, senza stare a rifare tutto lo sketch. :wink:

c'è un errore:(commentato nel codice)

void loop()
{
  tiltSensorCurrentValue=digitalRead(tiltSensorPin);
  if (tiltSensorPreviousValue != tiltSensorCurrentValue){
    lastTimeMoved = millis();//salvaultimo movimento
    tiltSensorPreviousValue = tiltSensorCurrentValue;
  }

   if (millis() - lastTimeMoved >= shakeTime){//se il tempo che è passato dall ultimo cambio di stato è maggiore
                                         //di 1 secondo il led si accende. ma se scuoto la scatola per meno di un secondo
                                         //poi la fermo il led si accende dopo un secondo che è ferma(forse non mi sono
                                        //spiegato bene)
    digitalWrite(ledPin, HIGH);
  }
  else{
    digitalWrite(ledPin, LOW);
  }
}

ma trillius sei ancora interessato alla soluzione?
Come va attualmente il tuo progetto?