I'm having trouble with my code to read the state of a PWM pin.
I think there are three separate problems:
- The code in the command braces of an "if" conditional (which is itself in a "while" cycle) seems to be being run even though the conditional is not met.
- It appears that not all of the code in the command braces is being run properly.
- I can not seem to be able to read when the PWM switches between HIGH and LOW. It seems to always read either HIGH or always LOW.
(This problem is related to a question I asked in the sensor forum http://arduino.cc/forum/index.php/topic,145724.0.html).
I reduced the code down to a test problem, based on the LED fade default sketch example.
An LED is connected between digital pin 11 and ground.
In the setup the digital pin 11 is set to PWM with a value of 70.
In the loop there are two separate cycles:
The first cycle repeats until digitalRead() reads the state of the PWM pin to be HIGH, and then makes the LED bright and prints the word "high" over serial.
The second cycle repeats until digitalRead() reads the state of the PWM pin to be LOW, and then makes the LED dim and prints the word "low" over serial.
There is a 2 second delay between each cycle, in order to see the change.
It should start with a brightly lit LED, then print "high", then dim the LED and print "low", then brighten the LED and print "high" - and so on.
What actually happens is that the LED dims and brightens every 2 seconds, but only the word "low" ever gets printed across the serial.
This is odd because once the LED is dimmed, it should not be brightened again unless the conditional inside the first cycle is met - which requires digitalRead() to have read HIGH. If that conditional is met, then the word "high" should also be printed across the serial, which is it not being. Hence suggestion 2) that not all the code in the command braces is being run properly.
Also, if I remove the element in the first while cycle condition which limits the number of times that the cycle runs to 10, then it seems to just get stuck in an infinite loop. This infinite loop can only happen if the variable high_reading_taken remains set to 0, and that can only happen if the conditional which checks whether PWM is set to HIGH is never met. This either means that digitalRead() is never reading the PWM pin as HIGH, or that the code in the command braces is not being run properly. This really does not make sense, because when the loop is only allowed to run 10 times before failing then the LED cycles through dim and bright, which should only happen if the conditional inside the first cycle is met - but when the loop is not limited to 10 then the LED change never gets triggered, which it SHOULD do if the conditional inside the cycle is met as suggested by the results seen when there is no limit. Simply adding a conditional to the while cycle to allow it only to run 10 times before moving on should not affect the digitalRead() process. This all MUST therefore mean that in the scenario where the number of run throughs of the first cycle is limited to 10, then the code inside the command braces is being triggered EVEN THOUGH THE CONDITIONAL WHICH USES DIGITALREAD() TO GET THE PWM VALUE IS NOT BEING MET! Doesn't it??
Have I missed something really obvious here? Either there is a serious problem with the processing of the code, or I have something badly misunderstood. I presume the problem is me, but I can not see where I have gone wrong
The code I used:
int baud = 9600;
int PWMPin= 11; // the pin that the LED is attached to
int read_attempts_max = 10;
int high_reading_taken;
int low_reading_taken;
int read_attempt;
void setup() {
Serial.begin(baud);
pinMode(PWMPin, OUTPUT);
analogWrite(PWMPin, 70);
}
void loop() {
// HIGH cycle
high_reading_taken = 0;
read_attempt = 1;
while ( (high_reading_taken == 0) && (read_attempt <= read_attempts_max) )
{
if ( digitalRead(PWMPin) == HIGH )
{
high_reading_taken = 1;
analogWrite(PWMPin, 70);
Serial.println("high");
}
read_attempt++;
}
delay(2000);
// LOW cycle
low_reading_taken = 0;
while ( (low_reading_taken == 0) )
{
if ( digitalRead(PWMPin) == LOW )
{
low_reading_taken = 1;
analogWrite(PWMPin, 1);
Serial.println("low");
}
}
delay(2000);
}