détecteur de choc sw-18030P

Bonjour

J'essaye désespérément de faire fonctionner un détecteur de choc, j'ai suivi plein de tuto, qui disent a peut pret tous la meme chose ... et ça fait pas comme dans les tuto.
Alors déja voici le capteur
et voici un des tuto que j'ai suivi (y a pas plus simple je crois) et un autre

A lire ces deux tuto, on doit avoir 1023 a l'état de repos et une valeur inférieur a l'état d'excitation.

Mais si j'ai bien compris le principe d'une entrée analogique, ça mesure un courant : 0 étant 0V et 1023 5V.
si j'ai bien compris comment est monté mon capteur (et ceux des tuto) au repos, le circuit est ouvert et il devient fermé quand il y a vibration. donc on passe d'une valeur de bruit électronique (je suis a 440 je sais pas si c'est normal ou non) a 1023. et pas l'inverse comme expliqué dans les tuto.

Est ce que je suis completement a coté de la plaque ?

merci

ewaca:
... si j'ai bien compris comment est monté mon capteur (et ceux des tuto) au repos, le circuit est ouvert et il devient fermé quand il y a vibration. donc on passe d'une valeur de bruit électronique (je suis a 440 je sais pas si c'est normal ou non) a 1023. et pas l'inverse comme expliqué dans les tuto. ...

Vous avez bien compris et c'est le tuto qui dit des bêtises. En effet s'il n'y a pas de vibration, le capteur présente un circuit ouvert et votre entrée Arduino est ce qu'on appelle "en l'air" et prend n'importe quelle valeur entre 0 et 1023. S'il y a vibration, le capteur présente un circuit fermé et comme une des broches est au +5 V, l'autre aussi et donc votre entrée est au +5 V et indique 1023.

Cela dit, ce montage n'et pas ce qu'il y a de plus correct. Il faudrait placer une résistance de rappel entre l'entrée de l'Arduino et le GND pour mieux fixer la valeur de l'entrée lorsque le capteur est ouvert.
Une autre solution est encore préférable, c'est de relier le capteur entre le GND et l'entrée de l'Arduino et de déclarer cette entrée comme suit :

pinMode (A5, INPUT_PULLUP);

De cette manière, vous bénéficiez de la résistance de rappel interne à l'Arduino. Vous aurez 1023 hors vibration et 0 en vibration.

Cordialement.

Pierre

Bonsoir,

Merci pour cette réponse.
Je réponds tardivement car j'ai pas eu le temps de me remettre sur ce projet.

Voici le schema que j'ai fait suite a vos remarques :
La résistance pour le détecteur de choc est de 10KOhm (sur le schema c'est pas la bonne valeur)

Je suis pas sur du placement de ma résistance de rappel, mais en tout cas j'ai bien 0 quand il n'y a pas de choc.

J'avais donc mis dans mon code un critère >1022 pour allumer ma led. Et je remarquais que ça marchait pas tout le temps, qu'il fallait vraiment y aller fort pour que ça s'allume. J'ai tester avec le meme type de capteur mais plus sensible. C'était mieux mais ça marchait pas toujours non plus.
J'ai essayé de diminuer le critère pour voir, et suivant l'intensité du choc j'ai une valeur qui varie.
voici ce que j'ai récupéré sur le dernier test.

Sensor Value: 30
Sensor Value: 298
Sensor Value: 549
Sensor Value: 167
Sensor Value: 252
Sensor Value: 977
Sensor Value: 267
Sensor Value: 671
Sensor Value: 537
Sensor Value: 12
Sensor Value: 121
Sensor Value: 944
Sensor Value: 22
Sensor Value: 464
Sensor Value: 229
Sensor Value: 94
Sensor Value: 44
Sensor Value: 994
Sensor Value: 749
Sensor Value: 951
Sensor Value: 333
Sensor Value: 1020
Sensor Value: 1023

voici le code que j'utilise

int sensor;           //Variable to store analog value (0-1023)


void setup()
{
  Serial.begin(9600);      //Only for debugging
  pinMode(2, OUTPUT);
}

void loop()
{
  sensor = analogRead(A0);
  //While sensor is not moving, analog pin receive 1023~1024 value
  if (sensor>1){

    digitalWrite(2, HIGH);
     delay(500); //Small delay
  digitalWrite(2, LOW);
    Serial.print("Sensor Value: ");
    Serial.println(sensor);
}

Pour moi, le capteur est une sorte d'interrupteur, c'est soit 0, soit 1023. Mais là ce n'est pas le cas, ça prend plein de valeurs intermédiaires et je comprends pas pourquoi.

petit UP.
J'ai essayé de voir si la valeur récupérée en analogique était proportionnelle à la force du choc, et ça ne semble pas être le cas ("semble" car difficile de faire toujours exactement le meme choc).
Sur des petits chocs des fois j'ai 1023, alors que sur des gros choc je peux avoir 30.
Quelque part ça me parait logique que ce ne soit pas proportionnel car ce n'est pas une cellule piezo, mais juste un switch.
Je comprends toujours pas pourquoi il prend des valeurs différentes de 0 et 1023.

J'ai essayé de mettre sur une entrée digital, et tester s'il est "HIGH", mais je me retrouve comme quand je teste >1022 sur de l'analogique, c'est a dire une led qui ne s'allume pas toujours, meme après un gros choc.

ça reste encore un mystere.

Bonjour,

L'utilisation d'une entrée analogique pour mesurer un capteur n'est valable que si le dit capteur envoi une valeur analogique entre 0 et Vcc.
Ici ce n'est qu'un élément mécanique fonctionnant comme un bouton poussoir.

Pour moi , il n'y a pas lieu de faire une mesure analogique.

L'idéal c'est d'utiliser une entrée logique et y attacher une interruption.

La sensibilité du capteur déterminera l'amplitude de la vibration nécessaire à déclencher l'activation et donc la fermeture du contact interne.

hello

+1

sur la description du capteur on parle de contact "NO" ou "NF".
c'est du tout ou rien.

une patte à GND ( ou au 5V) et l'autre patte sur une entrée digitale ( interruptible éventuellement)

"leptro" et "dfgh" ont raison, il faut utiliser une entrée numérique et qui plus est une entrée sur interruption.

En effet, suite à un choc (dont l'amplitude est suffisante pour provoquer la commutation du détecteur), il va y avoir une succession de fermetures/ouvertures liées aux vibrations engendrées par le choc. Cette succession n'est pas contrôlable ni en nombre ni en fréquence, la seule chose qui soit interprétable est qu'au moins une fois il y a eu commutation. C'est celle-là qui faut enregistrer. Il n'y a qu'une interruption qui puisse le faire. Toutes autres explorations par échantillonnage risque de tomber à côté.

Cordialement.

Pierre

D'accord, merci pour vos réponses.

Si je comprend bien, je continue mes test sur des entrée digitales qui gère une interruption.
En faisant quelques recherches, sur ça, je suis tombé sur ce site qui explique ce que c'est.
Apparemment toutes les pins ne sont pas susceptible d’être utilisée pour ça.
j'ai un arduino mega, si j'en crois ce schema

je ne peux utiliser que les pins 2 et 3 pour ça ?

Bonjour,

Voir la doc de attachInterrupt() qui donne les interruptions supportées en fonction de la carte.

Merci encore pour vos réponses, je comprends mieux comment tout ça fonctionne.

J'ai encore un soucis, c'est que le capteur, suivant le choc, va faire plus ou moins de fermetures de circuit.
voici mon code :

const byte interruptPin = 2;
const byte ledPin=4;
volatile byte state=LOW;

void setup()
{
  Serial.begin(9600);      //Only for debugging
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin,INPUT_PULLUP);
  attachInterrupt(0,bla,CHANGE);
}

void loop()
{
  

}

void bla()
{
  digitalWrite(ledPin,!digitalRead(4));
  Serial.print(!digitalRead(4));

}

voila ce que je capture :

01010101010101010101010101010101

Le but de mon projet, c'est pour une épreuve de rapidité, il faut que je capte le premier contact et avec millis() j'aurais un temps .
Le soucis c'est que j'arrive pas a arreter la fonction au 1er contact.
Dans la doc ils disent que delay ne marche pas mais que delayMicroseconds() fonctionne dans un interrupt.
J'ai essayé delayMicroseconds(500000000000) à la fin de ma fonction bla, j'ai toujours une suite d'ouverture et fermeture.

J'ai essayé le detachInterrupt(), pareil ...

Du coup je ne sais pas comment faire pour arreter le systeme au premier 1.

Si vous avez des astuces, je suis preneur.

merci :slight_smile:

Voici un petit bout de code dont tu peux t'inspirer

const byte phm = 2;//entrée interruptible
volatile byte top =0;
unsigned long deb=0;
unsigned long fin =0;
void setup() {
Serial.begin(115200);  
pinMode(phm, INPUT_PULLUP);
attachInterrupt(0, isr_Phm, FALLING);

}

void loop() {
  if (top==1) {deb=millis();}
  if (top==10){fin=millis();Serial.print("10 top en : ");Serial.print(fin-deb);Serial.println(" ms");top=0;}
}


void isr_Phm()
{top++;}