Go Down

Topic: strange behavior with analog read (Read 1 time) previous topic - next topic

SouthernAtHeart

May 27, 2011, 03:51 am Last Edit: May 27, 2011, 03:57 am by SouthernAtHeart Reason: 1
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: [Select]
       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: [Select]

       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: [Select]

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: [Select]
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...

robtillaart

(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
Rob Tillaart

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

wildbill


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.

SouthernAtHeart

Thanks!  That fixed the problem!

robtillaart

Quote
Thanks!  That fixed the problem!

Which solution fixed it? 
Just for the people that have similar problems.
Rob Tillaart

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

SouthernAtHeart

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.

Go Up