Pages: [1]   Go Down
Author Topic: strange behavior with analog read  (Read 1021 times)
0 Members and 1 Guest are viewing this topic.
South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Strange behavior, and can't figure out why.  My knock sensor is constantly picking up false knock signals (voltage?)from the piezo.  After hours of hair pulling, I've figured out that it will work fine if I comment out the line that checks my photocell:
Code:
       int senseVal = analogRead(photocellPin);  //get the pin reading
Then the knock sensor works great.  When I add back in the analogRead of the photocell into the loop, my knock sensor detects a signal everytime thru the loop.  The photocell is on pin A0 & 5 volt, with a 10 pulldown on A0.  The peizo is on A2 and ground, with a 1 meg pulldown on A0.

For troubleshooting, I've stripped down my loop:
Code:
       check_Lights();  //used here to update the level (turn them off eventually)
        check_photocell();  //Check Light Level                      
        checkknock(); //check for a secret knock

here is part of the checkknock:
Code:
void checkknock() {
  // Listen for any knock at all.
  knockSensorValue = analogRead(knockSensor);

  if (knockSensorValue >=threshold){ //is it above the minimum?
    listenToSecretKnock();  //if so, listen to it
  }
}

// Records the timing of knocks.
void listenToSecretKnock(){
      LCDclear();
    Serial.print("knock starting");  
...

Here is my photocell code:
Code:
void check_photocell(){  //sets lightLevel TRUE for light, FALSE for dark
    //THE ONLY THING THE PHOTOCELL WILL DO IS TURN ON THE LIGHTS IF:
        //1: IT'S HIBERNATING
        //2: IT'S LIGHT FOR MORE THAN 2 SECONDS (THE DOOR WAS JUST OPENED)
    if (MySettings.Enable_Photocell) { //check photocell only if enabled
        //and resets photocellMillis anytime there is a change
        boolean prevLightLevel = lightLevel;  //set the previous level
        int senseVal = analogRead(photocellPin);  //get the pin reading
        if (senseVal > MySettings.Photocell_Level + 10) {//reading is above the threshold
            lightLevel = true;  //cabinet doors are open
        }
        else if (senseVal < MySettings.Photocell_Level - 10) {
            lightLevel = false;  //cabinet doors are closed
        }
        if (lightLevel != prevLightLevel) {  // the light level has changed
            photocellMillis = millis();  //so the last lightchange time is updated  
        }
    
        if (millis() - photocellMillis > 2000){ //light has changed & stayed the same for 2 seconds
            LEDLights = lightLevel; //did it get dark? turn off the lights. did it get light? turn on the lights        
        }
    }
}




Any ideas on this?  This is probably too much to sift thru, but here's my whole code, and my eagle files of this project.

ps.  oh, and if I touch part of the board's ground, I can make the false reading on the piezo stop.  Is a 1 meg resistor too big?  That's what the sample says, and also the 'secret knock detector' online...

* arduino files.zip (19.64 KB - downloaded 2 times.)
* eagle files.zip (262.62 KB - downloaded 2 times.)
« Last Edit: May 26, 2011, 08:57:31 pm by SouthernAtHeart » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 221
Posts: 13848
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(disclaimer I'm no electrical engineer)

Quote
The photocell is on pin A0 & 5 volt, with a 10 pulldown on A0.  The piezo is on A2 and ground, with a 1 meg pulldown on A0.
Both pulldowns on A0???
you mean 10K pulldown on A0?   and a 1M on A2???

The 1M pulls down slowly, maybe too slow. Try replace it with a 10K too.

Note: The Arduino has one ADC converter which is multiplexed over the 6 lines. Adding a small delay() between the readings to give the ADC a few millis() to  "recover".

Hopes this helpes
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

New Jersey
Online Online
Faraday Member
**
Karma: 70
Posts: 3727
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Arduino has one ADC converter which is multiplexed over the 6 lines. Adding a small delay() between the readings to give the ADC a few millis() to  "recover".

For this reason, I've also seen a suggestion recently in the forums recommending that you read the ADC twice, ignoring the first reading, when you are switching it between pins.
Logged

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!  That fixed the problem!
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 221
Posts: 13848
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Thanks!  That fixed the problem!
Which solution fixed it? 
Just for the people that have similar problems.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Delay(50);

...but when I clean up my code, I may see if doing 2 readings, and skipping the first one works.  ...take away one less delay.
Logged

Pages: [1]   Go Up
Jump to: