Strange analogRead() behavior on ESP32 with vibration sensor

I'm seeing a behavior I don't understand using an Adafruit fast vibration sensor ( Fast Vibration Sensor Switch (Easy to trigger) : ID 1766 : $0.95 : Adafruit Industries, Unique & fun DIY electronics and kits ) wired to an analog input pin on an ESP32. When I use a delay of 10ms between reads, I get a stream of unexpected zero or near-zero readings. If I up the delay to 20ms, everything is fine. I've tried this on several input pins (25, 26, 27) with the same result. When I run the same code on a Nano, the extra delay is not needed. Can someone give me some insight into what might be happening here? Thanks!

#define VIBRATION_PIN 27    // For ESP32

void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial.println("Test vibration sensor");
}

void loop() {
  int val = analogRead(VIBRATION_PIN);
  if (val < 15)  // threshold determined through trial and error
  {
    Serial.println(val);
    delay(300);           // prevent re-triggers
  }
  delay(10);
}

Why do you read that sensor with an analogue pin.
The sensor is just a switch.
Leo..

Use a pullup resistor with a switch, otherwise the input is floating.

Ohhhhh ... that makes perfect sense! So, I treat it as a button with appropriate debouncing code. Duh! Thanks very much!

No debouncing. The code should react instantly to a closure of the switch.
If you debounce, you might miss the short activation of these switches.
Leo..

Perhaps we're talking about different usage scenarios. I'm wanting to get the initial impulse when the vibration sensor is shaken or moved. The sensor will be attached to a plastic cable, which is to be plucked like a guitar string - I'm looking for that pluck event, and wanting to avoid retriggering, hence I'm thinking debouncing. Certainly if I wanted to sense vibration rate or something of that sort, I would look for those short activations you're talking about. Hope that makes sense.

Debouncing is a delayed action or no action at all after an event, which is the opposite of what you describe. What you want is a lock-out time after an instant event.
Untested example code.
Leo..

const int sensorPin = 27;
unsigned long prevMillis, interval = 300; // lockout time in ms

void setup() {
  Serial.begin(115200);
  pinMode(sensorPin, INPUT_PULLUP); // sensor between pin and ground
  Serial.println("Test vibration sensor");
}

void loop() {
  if (millis() - prevMillis > interval) {
    if (!digitalRead(sensorPin)) { // if LOW
      Serial.println("Bingo!");
      prevMillis = millis(); // reset
    }
  }
}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.