ottenere il valore maggiore

Salve a tutti,
utilizzo un piezo come sensore di vibrazioni,
ottengo i dati con questo sketch:

const int sensorPin = A0;
int value = 0;


void setup(){
Serial.begin(9600);
}

void loop(){
value = analogRead(sensorPin);

if(value > 4 && value < 80){
  Serial.println(value); 
}
if(value > 101  ){
  Serial.println(value);
}
}

ad ogni urto ottengo almeno una quindicina di valori, è possibile di ogni urto ottenere solo il valore più altro?

grazie

Ciao, quello che ti serve si chiama debounce, solitamente si usa per letture sui pulsanti per ovviare appunto a letture false o ripetute per via dei transitori dei contatti. Puoi dare un occhiata qui
http://playground.arduino.cc//Code/Bounce
La libreria si applica a pulsanti digitali quindi il link l'ho messo solo per capire il funzionamento, dovrai replicare quello che avviene nella libreria per poterlo adattare alle tue esegenze di lettura analogica, sostanzialmente si tratta di effettuare un ciclo con dei ritardi nelle letture e delle operazioni matematiche che ritarrai più opportune (media, valore di picco, ecc.)

Grazie fabpolli per la risposta,
ho subito cercato di adattarlo al mio sketch ma ho incontrato alcuni problemi:

#include <Bounce.h>

const int sensorPin = A0;
//int value = 0;

Bounce bouncer = Bounce( sensorPin, 5 ); 
void setup(){
Serial.begin(9600);

}

void loop(){
   bouncer.update ( );
//value = analogRead(sensorPin);

//if(value > 4 && value < 80){
//  Serial.println(value);
 Serial.println(??????);
}

cosa inserisco in Serial.println?
il valore di picco come si ottiene?
la costante value è giusto eliminarla?

scusate ma è da poco che ho iniziato con Arduino, spero di non chiedere troppo.
grazie

fabpolli: lui usa un'ingresso analogico, dubito che una routine di debounce possa avere senso per un'analogread :wink:

gius: non sono sicuro di come si possa fare, ma fondamentalmente quello che ti serve e' una campionatura con controllo del valore massimo ... tipo, leggi in sequenza parecchi valori rapidamente, la prima lettura la salvi in una variabile, e ad ogni lettura successiva confronti il nuovo valore con i precedenti, se e' inferiore lo ignori, se e' superiore lo salvi al posto del precedente ... alla fine dovresti avere nella variabile solo il valore piu alto che hai letto ... (softwaristi, correggetemi se sbaglio :P)

quindi posso tralsciare la libreria Bounce?
Grazie Etemenanki per la risposta,
mi poptreste indicare uno sketch da cui estrarre il codice o modificarlo?

grazie

Dammi un minuto e ti faccio uno sketch rapido rapido..
@Etemenanki: non sbagli XD

fabpolli:
La libreria si applica a pulsanti digitali quindi il link l'ho messo solo per capire il funzionamento, dovrai replicare quello che avviene nella libreria per poterlo adattare alle tue esegenze di lettura analogica, ...

Pensavo fosse meglio che si leggesse il codice della bounce e capendone il funzionamento lo adattasse ai suoi scopi... mea culpa :wink:

Questo dovrebbe andare bene.. :slight_smile:

#define piezoPin A0
const unsigned int nRead = 5; //numero di letture da campionare
const unsigned int delRead = 1; //millisecondi di "distanza" tra le misurazioni
unsigned int value = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  value = readVal(piezoPin);
  Serial.println(value);
  delay(1);
}

unsigned int readVal(unsigned int sensorPin){
  unsigned int maxVal = 0;
  for(unsigned int x=0; x<=nRead; x++){
    unsigned int tempVal = analogRead(sensorPin);
    if(tempVal > maxVal){
      maxVal == tempVal;
    }
    delay(delRead);
  }
  return maxVal;
}

Grazie MrJacko per il grande aiuto,
ho provato subito ma mi da sempre 0 e mai un numero diverso...

Aspetta che ricontrollo il codice :stuck_out_tongue_closed_eyes:
EDIT: Strano, il codice sembra corretto..
Prova questo e dimmi se va (ho cambiato alcuni tipi di variabili..)

const int piezoPin  = A0;
const int nRead = 5; //numero di letture da campionare
const int delRead = 1; //millisecondi di "distanza" tra le misurazioni
int value = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  value = readVal(piezoPin);
  Serial.println(value);
  delay(1);
}

int readVal(int sensorPin){
  int maxVal = 0;
  for(int x=0; x<=nRead; x++){
    int tempVal = analogRead(sensorPin);
    if(tempVal > maxVal){
      maxVal == tempVal;
    }
    delay(delRead);
  }
  return maxVal;
}

A livello hardware, come hai collegato il sensore ?

Puoi usare le funzione max e min

maxVal = max(maxVal, tempVal);
minVal = min(minVal, tempVal);

--> http://arduino.cc/en/Reference/Max

MrJacko:
Questo dovrebbe andare bene.. :slight_smile:

unsigned int readVal(unsigned int sensorPin){

unsigned int maxVal = 0;

La variabile maxVal o la definisci come globale oppure la devi definire come static ("static unsigned int maxVal = 0;") all'interno della funzione altrimenti ogni volta che esci dalla stessa viene distrutta e ricreata a 0 ogni volta che entri nella funzione.

Ma in quel caso non importa che quella variabile si azzeri quando si esce dalla funzione, perchè tanto la riporto manualmente a 0 all'inizio della stessa..

non funziona, mi dispiace....

#define piezoPin A0
const unsigned int nRead = 2; //numero di letture da campionare
const unsigned int delRead = 10; //millisecondi di "distanza" tra le misurazioni



int value = 0;
void setup(){
  Serial.begin(9600);
}

void loop(){
  
  value = readVal(piezoPin);
  if( value < 80){
    Serial.println(value); 
  }
  if(value > 101  ){
    Serial.println(value);
  }
  delay(1);
}

unsigned int readVal(unsigned int sensorPin){

  static unsigned int maxVal = 0;
  for(unsigned int x=0; x<=nRead; x++){
    unsigned int tempVal = analogRead(sensorPin);
    if(tempVal > maxVal){
      maxVal == tempVal;
    }
    delay(delRead);
  }
  return maxVal;
}

mi da sempre 0, in continuazione.
il sensore è collegato nel seguente modo:

se utilizzo il mio iniziale sketch funziona.
cosa posso fare?

grazie

Hai provato anche il secondo sketch che ho postato?
Non trovo l'errore :stuck_out_tongue_closed_eyes:

gius:
...
il sensore è collegato nel seguente modo:
...

Scusa, i due pin a cui sono connessi il filo di massa e la resistenza da 1M sono entrambi masse ? ... perche' se e' cosi, non dovrebbe funzionare un gran che, la resistenza da 1M andrebbe al +5V :wink:

Poi un'altra cosa, suggerirei di mettere un diodo 1N4148 fra il pin di ingresso e la massa (catodo al pin di ingresso ed anodo a massa), cosi taglia la parte negativa del segnale e non rischia di danneggiare il micro ( lo so che le correnti sono basse, ma un piezo genera alternata, in fondo, quindi e' sempre meglio non rischiare :wink: )

gius:
non funziona, mi dispiace....

c'e' qui in errore:

    if(tempVal > maxVal){
      maxVal == tempVal;              // errore, usare = per assegnare
    }

deve essere:

    if(tempVal > maxVal){
      maxVal = tempVal;              
    }

nid69ita:
c'e' qui in errore:

    if(tempVal > maxVal){

maxVal == tempVal;              // errore, usare = per assegnare
   }




deve essere:


if(tempVal > maxVal){
     maxVal = tempVal;              
   }

Che dire..quando le cose si fanno di fretta :stuck_out_tongue_closed_eyes:

#define piezoPin A0
const unsigned int nRead = 5; //numero di letture da campionare
const unsigned int delRead = 1; //millisecondi di "distanza" tra le misurazioni
unsigned int value = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  value = readVal(piezoPin);
  Serial.println(value);
  delay(1);
}

unsigned int readVal(unsigned int sensorPin){
  unsigned int maxVal = 0;
  for(unsigned int x=0; x<=nRead; x++){
    unsigned int tempVal = analogRead(sensorPin);
    if(tempVal > maxVal){
      maxVal = tempVal;
    }
    delay(delRead);
  }
  return maxVal;
}

si, Mr Jacko, non funziona con entrambi....

Tutto risolto grazie al comsiglio di nid69ita, grazie!!!

per Etemenanki
ho preso lo schema da questo link http://www.arduino.cc/en/Tutorial/Knock

ora per comodità sto usando questo schema
http://learning.codasign.com/index.php?title=Piezos_and_Arduino

del diodo non trovo traccia, perchè?

ancora grazie a tutti