Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Contact microphone pinMode problem

  1. #1
    Junior Member
    Join Date
    Nov 2017
    Posts
    3

    Contact microphone pinMode problem

    I'm trying to use the "knock" example code on a Teensy 3.2. It works as expected unless I include "pinMode(knockSensor, INPUT);" in the setup in which case the pin hangs on a higher value (different every time) and does not return to 0. Ultimately I'd like to use this in a situation where a single pin will sometimes be used as a button and sometimes as a contact mic input which means I will need to switch the pin mode between INPUT and INPUT_PULLUP otherwise I guess I don't even need to set the pinMode initially.

    What am I doing wrong?

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    1,875
    As the forum rules say: give enough information (code, schematics, etc.) so that others may easily reproduce your problem. IMHO, it is basically not a good idea using one pin with different peripherals and changing the pin configuration “on the fly”. PinMode(x, INPUT) will put the pin into a high Z CMOS logic input which expects defined signals (LOW <=0.3V or HIGH >= 2.7V) fed from outside. If these conditions aren’t satisfied, undefined behavior is the logical consequence.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,300
    Quote Originally Posted by bryan5555 View Post
    What am I doing wrong?
    Maybe you're using analogRead()? That's just a blind guess, but if so, use INPUT_DISABLE to put the pin back to a mode where the digital circuitry (with slight leakage current) is turned off.

    Otherwise, as Theremingenieur explained, the way we work here involves questions that give a complete & clear picture of what you're really doing. Don't "tell" us, actually "show" what you're really doing. We can help much more when we can see what's really going on.

  4. #4
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,583
    I have used this knock example, https://www.arduino.cc/en/Tutorial/Knock, with piezo vibration sensor to an analog pin with 1 Mohm resitor in parallel to ground. the example works on UNO and T3.2. you have to tap the piezo or place some mass on sensor (e.g., stapler) to detect taps on the table. You don't want to use any pinMode() for the analog pin. (for debugging you could print out the analog value each time through loop() to see how sensitive sensor/mic is)
    vibration sensor: https://www.sparkfun.com/products/10293

    what "mic" are you using?

  5. #5
    Junior Member
    Join Date
    Nov 2017
    Posts
    3
    You're absolutely right - I'll try to provide better information.

    The circuit is as manitou described it- the piezo is between PIN17 and GRD with a 1Mohm resistor between GRD and PIN17. Here's the slightly modified Knock code I'm using which works great

    Code:
    const int ledPin = 13;      // led connected to digital pin 13
    const int knockSensor = 17; // the piezo is connected to analog pin 0
    const int threshold = 100;  // threshold value to decide when the detected sound is a knock or not
    
    
    // these variables will change:
    int sensorReading = 0;      // variable to store the value read from the sensor pin
    int ledState = LOW;         // variable used to store the last LED status, to toggle the light
    
    void setup() {
      pinMode(ledPin, OUTPUT);
    //  pinMode(knockSensor, INPUT);// declare the ledPin as as OUTPUT
      Serial.begin(9600);       // use the serial port
    }
    
    void loop() {
      
      sensorReading = analogRead(knockSensor);
      Serial.println(sensorReading);
    
      if (sensorReading >= threshold) {
        ledState = !ledState;
        digitalWrite(ledPin, ledState);
        Serial.println("Knock!");
      }
      delay(100);  // delay to avoid overloading the serial port buffer
    }
    Here's the code that's not working. The only change is that I added in the commented out line " pinMode(knockSensor, INPUT);"

    Code:
    
    const int ledPin = 13;      // led connected to digital pin 13
    const int knockSensor = 17; // the piezo is connected to analog pin 0
    const int threshold = 100;  // threshold value to decide when the detected sound is a knock or not
    
    
    // these variables will change:
    int sensorReading = 0;      // variable to store the value read from the sensor pin
    int ledState = LOW;         // variable used to store the last LED status, to toggle the light
    
    void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(knockSensor, INPUT);// declare the ledPin as as OUTPUT
      Serial.begin(9600);       // use the serial port
    }
    
    void loop() {
      
      sensorReading = analogRead(knockSensor);
      Serial.println(sensorReading);
    
      if (sensorReading >= threshold) {
        ledState = !ledState;
        digitalWrite(ledPin, ledState);
        Serial.println("Knock!");
      }
      delay(100);  // delay to avoid overloading the serial port buffer
    }
    This time analogRead does not return to 0- it stays at 893 but it's a slightly different number each time.

    --serial window
    1
    1
    2
    3
    2
    1
    7
    1
    1
    1
    888
    Knock!
    893
    Knock!
    893
    Knock!
    893
    Knock!
    893
    Knock!
    893
    Knock!
    893
    Knock!
    --end serial window

    This is not a real world example. I'll make a simple circuit and some code that better illustrates what I'm trying to do and post it here soon. This INPUT_DISABLE business Paul mentioned might be just what I'm looking for.

  6. #6
    Hi,
    as mentioned you don't need to use <<pinMode(knockSensor, INPUT)>> if you use just analogread().

    pinMode(knockSensor, INPUT_DISABLE) is the right way to put pin back to high state before using it for an other purpose.

    Maybe you can also change <<const int knockSensor = 17; // the piezo is connected to analog pin 0>>
    into <<const int knockSensor = A3; // the piezo is connected to analog pin A3 on teensy 3.2>>

  7. #7
    Junior Member
    Join Date
    Nov 2017
    Posts
    3
    Thanks for everyone's help! Here's some test code I came up with using (or trying to use since I don't really understand it) INPUT_DISABLE instead of INPUT. In the end, I may not use this method but I thought I'd put it here for others.

    Code:
    // testing switching pinMode when using a contact microphone
    // if I indicate pinMode INPUT the values from analogRead stay high.
    // actually if I only tap the mic slightly things are okay but if I 
    // give it a good tap it stays around 893 or something high
    
    int incoming = 0;   // for incoming serial data
    int previousIncoming;
    int reading;
    int ledPin = 13;
    int knockSensor = A1;
    int n0;
    int var = 0;
    
    void setup() {
            pinMode(ledPin, OUTPUT);
            Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
    }
    
    void loop() {
    // This code uses serial input from the serial window
    // 1 switched pinMode to INPUT_PULLUP
    // 2 switches pinMode to INPUT
            if (Serial.available() > 0) {
                    reading = Serial.read();
                    if (reading > 20){
                      incoming = reading;
                    } 
            }
    
    // default position -- no pinMode specified
    if (incoming == 0){
      digitalWrite(ledPin, LOW);
    
      n0 = analogRead(knockSensor);
      Serial.println(n0);
    }        
    
    // Serial input 1 -- pinMode INPUT_DISABLE
    if (incoming == 49){
      if (incoming != previousIncoming){
        digitalWrite(ledPin, LOW);
    //    pinMode(knockSensor, INPUT); // this didn't work
        pinMode(knockSensor, INPUT_DISABLE); // this works!
        previousIncoming = incoming;
        var = 0;
      }
      var++;
      if (var > 1){ // filter out the first reading when the pinMode is changed because I was still getting a high number
         n0 = analogRead(knockSensor);    
      }
    }
    
    // Serial input 2 -- pinMode INPUT_PULLUP as though I want to use this pin with a button instead of a contact mic now
    if (incoming == 50){
        if (incoming != previousIncoming){
        digitalWrite(ledPin, HIGH);
        previousIncoming = incoming;
        }
      pinMode(knockSensor, INPUT_PULLUP);
      n0 = digitalRead(knockSensor);
    }
    
    Serial.println(n0);
    delay(100); 
      
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •