sostituzione sensore vibrazione da digitale ad analogico con piezoelettrico

salve, ho voluto cambiare per questioni di sensibilità il sensore di vibrazione da digitale ad analogico con un sensore piezo collegando tra il i cavi di quest ultimo una resistenza da 1Mohm.
Problema: non riesco ad impostare una soglia ad di sopra del quale cambi stato. Per realizzare questo programma, mi siete stati di grande aiuto, cosa sto sbagliando adesso? grazie

Ecco il programma:

#define       pinSensore  A0
#define       pinPiezo   11
byte          statoPiezo = LOW;
byte          sensStat = 0;
unsigned long sensTime;
byte          soundStat = 0;
unsigned long soundTime;

const int threshold = 9;
int sensorReading = 0;  
//-----------------------------------------------------------------------------
void setup()
{
    delay(1000);
    Serial.begin(9600);
    Serial.println("avvio programma");
    pinMode(pinPiezo, OUTPUT);
}
//-----------------------------------------------------------------------------
void loop()
{   sensorReading = analogRead(pinSensore);
    gestSens();
    gestSound();
}
//-----------------------------------------------------------------------------
void gestSens()
{
    byte sens = analogRead(pinSensore);
    if (sensorReading >= threshold) {
      sensStat=!sensStat;
    switch (sensStat)
    {
        case 0:  // attende sensore HIGH
            if (sens)
            {
                sensTime = millis();  // memorizza tempo attuale
                sensStat = 1;         // passa a stato 1
            }
            break;

        case 1:  // conteggio 4 sec, torna a stato zero se sens LOW
            if (!sens)
                sensStat = 0;
            else if (millis() - sensTime >= 5000)  // se timeout 5 secondi
            {
                statoPiezo = HIGH;
                Serial.println("Stato high");
                sensStat = 3;
            }
            break;

        case 3:  // attende sensore LOW, poi torna a stato zero
            if (!sens)
            {
                statoPiezo = LOW;
                Serial.println("Stato low");
                sensStat = 0;
            }
    }
}}
//-----------------------------------------------------------------------------
void gestSound()
{
    switch (soundStat)
    {
        case 0:
            if (statoPiezo) { soundStat = 3; break; }
            tone(pinPiezo, 1397, 600);
            soundTime = millis();
            soundStat = 1;
            break;

        case 1:
            if (statoPiezo) { soundStat = 3; break; }
            if (millis() - soundTime >= 600)
            {
                tone(pinPiezo, 1175, 600);
                soundStat = 2;
            }
            break;

        case 2:
            if (statoPiezo) { soundStat = 3; break; }
            if (millis() - soundTime >= 15000) soundStat = 0;
            break;

        case 3:
            if (!statoPiezo) { soundStat = 0; break; }
            tone(pinPiezo, 1175, 600);
            soundTime = millis();
            soundStat = 4;
            break;

        case 4:
            if (!statoPiezo) { soundStat = 0; break; }
            if (millis() - soundTime >= 600)
            {
                tone(pinPiezo, 1175, 600);
                soundStat = 5;
            }
            break;

        case 5:
            if (!statoPiezo) { soundStat = 0; break; }
            if (millis() - soundTime >= 2500) soundStat = 3;
    }
}

Mi sono spiegato? O devo spiegarmi meglio?

magari se metti un link del vecchio sensore digitale e del nuovo analogico e a come li hai collegati qualcuno potrebbe darti una mano più facilmente :wink:

Certo, questo è il link di quello vecchio https://www.amazon.it/gp/aw/d/B01MDP1XKS/ref=mp_s_a_1_2/262-4819302-3367759?__mk_it_IT=ÅMÅZÕÑ&qid=1505714993&sr=1-2&pi=AC_SX236_SY340_QL65&keywords=sensore+vibrazione+arduino&dpPl=1&dpID=51afHffugDL&ref=plSrch

Questo schema illustra il piezo e il collegamento effettuato
https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTyXggKctPT7Guw6-6yrocqtpj9QQK0amF0uwt-5Lvz0a4ot-Sx

in quel modo dubito possa mai funzionare, la tensione generata da un piezo mi sa che è troppo bassa per essere misurata da arduino, andrebbe amplificato con un operazionale o qualcosa di simile.

-zef-:
in quel modo dubito possa mai funzionare

Beh però quel circuito è identico a quello del tutorial Arduino Knock ed anche il codice mi sembra direttamente ricavato da questo, quindi credo che funzioni.

Non ho capito quindi quale problema abbia riscontrato Emanuele, la "sensibilità" è determinata dal threshold, secondo me gli basta caricare quell'esempio Knock e sperimentare con quello, e poi integrare il suo codice.

L'esempio del knock e' formalmente sbagliato (come del resto tutti quelli che mostran la connessione diretta di una cialda piezoelettrica ad un'ingresso logico) ... un dischetto piezo puo arrivare, se sollecitato con una certa energia, a generare diverse decine di volt, e questa uscita e' "alternata", quindi sia positiva che negativa ... passi per la scarsa corrente generata che puo essere chiusa a massa dal diodo interno, ma non e' certo una cosa buona da fare, proprio a livello di principio ... :wink:

Etemenanki:
L'esempio del knock e' formalmente sbagliato (come del resto tutti quelli che mostran la connessione diretta di una cialda piezoelettrica ad un'ingresso logico) ...

Infatti anche per me quel circuito non è il massimo, ma immagino/spero che quando hanno messo quel tutorial sul sito abbiano pensato che almeno per iniziare possa anche andare :wink:
Io ci metterei anche almeno uno zener, e magari, a seconda dell'uso reale che se ne vuole fare (es. una batteria elettronica "picchia" parecchio) anche una seconda resistenza in serie e un condensatore per smorzare i picchi e rimbalzi meccanici... Confermi?

Infatti collegare un piezo direttamente ad un pin di Arduino è una tavanata galattica, è allo stesso livello di collegare direttamente un carico induttivo ad un pin. :slight_smile:

Uno zener da 5V (o esagerando un TVS da 5V) fra pin e massa, con il catodo al pin, sarebbe il minimo indispensablie ... se si vuole fare un sistema piu preciso, un ponte di diodi, anche solo 1N4148, ed un piccolo condensatore da 47n o 100n al massimo, ma anche meno se serve piu reattivita' (ma sempre con lo zener sul pin)

Se poi deve rilevare vibrazioni molto lievi, serve per forza usare almeno un'operazionale o alla peggio un paio di transistor (l'operazionale e' meglio e piu semplice) ... ed in tutti i casi sarebbe sempre meglio collegare una resistenza, anche se di alto valore, in parallelo alla cialda, perche' elettricamente si comporta come un condensatore, ed e' meglio tenerla "scarica"

(per provare questo fatto il modo piu semplice e' collegare un'alimentatore da 12V o simile alla cialda ... la prima volta si sente un "tic", poi basta, a meno che non si invertano le polarita' ogni volta, perche' la cialda e' "carica" e non si flette piu ... ora se si scollega la cialda dall'alimentatore e si mettono in corto i fili, si sente un secondo "tic", e' il disco che ritorna a riposo scaricando l'energia che aveva immagazzinato)

Infatti vedendo su eBay ci sono breakout board come QUESTA che hanno solamente un diodo (voglio sperare Zener) e una resistenza 1M Ohm, suppongo entrambi in parallelo al piezo vista anche l'assenza di +5V, ed altre come QUESTA ben più completa, dove mi sembra di vedere sicuramente un operazionale ed altri componenti SMD.

La seconda è quella che acquisterei...

La seconda consente anche di regolare la sensibilita', sia della soglia dell'uscita TTL che dell'uscita analogica (almeno a quanto si capisce dalla scarsa descrizione) ... :wink:

Ragazzi, allora mi spiego meglio...il progetto consiste in un oggetto che nel momento in cui subisce vibrazioni emetta due suoni (amplificati da un transistor) di frequenza diversa con intervallo di 15 sec (es. 2 suoni-15 sec- 2 suoni) ,se non subisce vibrazioni due suoni di frequenza uguale ad intervallo di 2,5 sec( 2 suoni -2,5 sec- 2 suoni)... Ovviamente quando l oggetto non subisce vibrazioni, deve accertarsi per 5 sec che non ci siano vibrazioni per cambiare di stato...il tutto è stato fatto con il sensore digitale e funziona correttamente ( se volete vi metto il programma). Il problema che il sensore digitale è poco sensibile e quindi con quello analogico( che ho testato tramite gli sketch di Arduino stesso) il risultato sarebbe ottimale.. Il problema è che non riesco ad inserire il sensore analogico nel programma di quello digitale pur cambiando porte e impostazioni, mi aiutate?dove sbaglio? Grazie per le numerose risposte

Cioè non riesco ad integrare lo sketch knock nel mio programma, sbaglio sicuramente nella scrittura...volete che vi alleghi lo sketch con il sensore digitale? Non riesco ad inserire questo esempio,tutto qui...e poi Scusate.... Voi mi dite che il collegamento cosi come l ho fatto, può portare a bruciare la porta perché accumula energia?

Emanuele1993:
volete che vi alleghi lo sketch con il sensore digitale? Non riesco ad inserire questo esempio,tutto qui..

Se il problema è questo, si, posta lo sketch ma dicci anche (visto che hai scritto "quello analogico che ho testato tramite gli sketch di Arduino stesso") quali valori leggi per il pin analogico quando lo colpisci con l'intensità che prevedi essere sufficiente per il tuo scopo, e vediamo.

Va bene appena arrivo a casa vi posto tutto...la soglia deve essere di 5...molto basso...grazie ancora

Ecco il programma:

#define       pinSensore 9
#define       pinPiezo   11
byte          statoPiezo = LOW;
byte          sensStat = 0;
unsigned long sensTime;
byte          soundStat = 0;
unsigned long soundTime;
//-----------------------------------------------------------------------------
void setup()
{
    delay(1000);
    Serial.begin(9600);
    Serial.println("avvio programma");
    pinMode(pinSensore, INPUT);
    pinMode(pinPiezo, OUTPUT);
}
//-----------------------------------------------------------------------------
void loop()
{
    gestSens();
    gestSound();
}
//-----------------------------------------------------------------------------
void gestSens()
{
    byte sens = digitalRead(pinSensore);
    switch (sensStat)
    {
        case 0:  // attende sensore HIGH
            if (sens)
            {
                sensTime = millis();  // memorizza tempo attuale
                sensStat = 1;         // passa a stato 1
            }
            break;

        case 1:  // conteggio 4 sec, torna a stato zero se sens LOW
            if (!sens)
                sensStat = 0;
            else if (millis() - sensTime >= 4000)  // se timeout 4 secondi
            {
                statoPiezo = HIGH;
                Serial.println("Stato high");
                sensStat = 3;
            }
            break;

        case 3:  // attende sensore LOW, poi torna a stato zero
            if (!sens)
            {
                statoPiezo = LOW;
                Serial.println("Stato low");
                sensStat = 0;
            }
    }
}
//-----------------------------------------------------------------------------
void gestSound()
{
    switch (soundStat)
    {
        case 0:
            if (statoPiezo) { soundStat = 3; break; }
            tone(pinPiezo, 1397, 600);
            soundTime = millis();
            soundStat = 1;
            break;

        case 1:
            if (statoPiezo) { soundStat = 3; break; }
            if (millis() - soundTime >= 600)
            {
                tone(pinPiezo, 1175, 600);
                soundStat = 2;
            }
            break;

        case 2:
            if (statoPiezo) { soundStat = 3; break; }
            if (millis() - soundTime >= 18000) soundStat = 0;
            break;

        case 3:
            if (!statoPiezo) { soundStat = 0; break; }
            tone(pinPiezo, 1175, 600);
            soundTime = millis();
            soundStat = 4;
            break;

        case 4:
            if (!statoPiezo) { soundStat = 0; break; }
            if (millis() - soundTime >= 600)
            {
                tone(pinPiezo, 1397, 600);
                soundStat = 5;
            }
            break;

        case 5:
            if (!statoPiezo) { soundStat = 0; break; }
            if (millis() - soundTime >= 2000) soundStat = 3;
    }
}[code]

Anziché inserire il pin sensore 9, voglio inserire il sensore piezo A0

Emanuele1993:
...la soglia deve essere di 5...

... metri ? ... litri ? ... chili ? ... giri ? ... arance ? ...

Cinque "cosa" ? ... cinque e basta, e' leggermente vago ... :wink:

Comunque dato che ti serve gestito come on/off, se prendi il secondo linkato da docdoc, ha anche l'uscita digitale, e la sensibilita' e' regolabile ... :wink:

Etemenanki:
Comunque dato che ti serve gestito come on/off, se prendi il secondo linkato da docdoc, ha anche l'uscita digitale, e la sensibilita' e' regolabile ... :wink:

Eh, si, e a quel punto lo sketch resta praticamente identico.. :wink: