Go Down

Topic: Strange voltage readings using my potato (Read 3024 times) previous topic - next topic

kayle

#15
Feb 09, 2013, 04:29 pm Last Edit: Feb 09, 2013, 04:48 pm by kayle Reason: 1
OK. I set the circuit up as shown in the circuit diagram I posted in my last posting (February 03, 2013, 05:05:04 PM). The only difference is that I am using a 10uF electrolytic capacitor instead of a 1uF ceramic capacitor.

However, there now seems to be a problem reading the analog input when the PWM pin is on the LOW part of its cycle. I'm not sure if this is a hardware problem, or a code problem. I'll happily move this question to the code section if this is the wrong place for it - but I am guessing it is best to ask it here first, on the thread it is most associated with.

I am setting the PWM pin to < 0.5 V (because apparently skin resistance only behaves linearly below 0.5V). So the PWM is set to 20. (I have tried it at higher values as well).
I am trying to take a reading from the analog input (A0) when the PWM pin is HIGH and then again when it is LOW.
If the reading from the analog pin when the PWM pin is HIGH and when it is LOW together count as one "set" of readings, then I am trying to take a set of readings about each second or so.
To do this there is a "main" cycle which runs every second or so, and prints the results to serial at the end of each cycle.
Within this "main" cycle there are two separate (not nested within each other) mini cycles.
The first mini cycle checks to see when the PWM pin is set to HIGH, and then records the reading from the analog input at that point to an integer variable for use later.
The second mini cycle does the same for when the PWM pin is set to LOW, recording the analog input at that point to a different integer variable.

The problem is that the PWM pin never seems to be set to LOW. The cycle that checks for when the PWM pin is set to HIGH works fine, but the cycle that checks for when the PWM pin is set to LOW never completes - presumably because it is never seeing the PWM pin as LOW via digitalRead().

Also, the analog reading (taken when the PWM pin is HIGH) is always around 1020. This seems WAY too high - especially when the PWM pin is only set to 20 and there is a 3.3K resistor.

I have gone through the info on PWM, digitalRead() and analogWrite() many times, and I still have no idea why this is happening. The summary of the code I am using is:

Code: [Select]

int PWMPin = 11;
int PWMValue = 20;
int sensor_high;
int sensor_low;
int high_reading_taken;
int low_reading_taken;
int read_attempt;
int read_attempts_max = 10;

void setup{
pinMode(PWMPin, OUTPUT);
}

void loop{

// "main" cycle
while ( x,y,z .... )
      {

       sensor_high = -1;
       sensor_low = -1;
             
       // first mini cycle, checks for when PWM pin is set to HIGH
       high_reading_taken = 0;
       read_attempt = 1;
       while ( (high_reading_taken == 0) && (read_attempt <= read_attempts_max) )
             {
             if ( digitalRead(PWMPin) == HIGH ) { sensor_high = analogRead(0); high_reading_taken = 1; }
             read_attempt++;
             }
             
       delay(100);     // delay here to allow analog pin to recover, as suggest in the documentation.
             
       // second mini cycle, checks for when PWM pin is set to LOW
       low_reading_taken = 0;
       read_attempt = 1;
       while ( (low_reading_taken == 0)  && (read_attempt <= read_attempts_max)  )
             {
             if ( digitalRead(PWMPin) == LOW ) { sensor_low =  analogRead(0); low_reading_taken = 1; }
             read_attempt++;
             }
       
       // followed by code to print the results to serial and/or SD card.

       delay(1000); // main cycle runs roughly once per second
       }

}


The use of "attempts" to limit the cycles is only there to stop it from going into an infinite loop. I've tried it without that limit, and the problem is still there.
(I have not posted my full code because that would take me over the word limit, but I could post it if anyone would like).
I've tried using integer values of 1 or 0 respectively for the conditionals which check whether digitalRead() is HIGH or LOW.
I have also tried using different PWM pins ( such as 9 and 3). I'm using an arduino uno. Can't use pin 10 because that is reserved for SD functions. (5 and 6 apparently experience interference, so I am avoiding them).

When this code runs, it prints the "sensor_high" value as 1020 or 1021, and the "sensor_low" value as -1.
Am I making a really obvious error? Is this even a code problem?


dc42

1. Change the PWM to 128. The whole point of the arrangement with the capacitor is to feed balanced AC to the skin electrodes, which you are not doing. If you want to restrict the voltage to 0.5V then either increase the 3.3K resistor to a higher value, or increase the 3.3K resistor to 15K and connect 3.3K from the resistor-capacitor junction to ground (this will give you a maximum of +/- 0.5V peak at the electrodes).

2. Get rid of that delay(100) call, it isn't necessary and it's screwing up the timimg.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

kayle

Thanks again!

I understand now about the PWM being set to half. I didn't twig that it needs to be that way in order to balance the voltage in both directions.
I have used the voltage divider method you described to get the voltage down, and now the analog input pin reads about 180 - which equates to about 0.88V I think.
(The resistors I am using are cheap though, and I measured the 15k resistor to be more like 14.5k, so I guess that is to be expected. I shall tweak them to get it to 0.5V).

I am still struggling to take analog readings when the PWM is outputting LOW. I shall ask that question in the programming forum http://arduino.cc/forum/index.php/topic,148353.0.html, because I'm pretty sure it is my coding error.

Go Up