Arduino Forum

Forum 2005-2010 (read only) => Software => Syntax & Programs => Topic started by: meg on Sep 21, 2009, 06:02 pm

Title: problem with conditional statement
Post by: meg on Sep 21, 2009, 06:02 pm
hi there!
i'm new to C and would love it someone could help me out by taking a look at this code snippet:

Code: [Select]

void test() {
 intVal = analogRead(intPin);
 Serial.println(intVal);
 if (intVal < 301) {
   ...do something...
 }
 // if i remove the following conditional statement, the code runs ok!
 else if (intVal > 300 && intVal < 701) {
   ...do something else...
 }
 else if (intVal > 700) {
   ...do another thing...
 }
}


this code works ok if i run it with only the first and last conditions, but as soon as i add (intVal > 300 && intVal < 701) to the mix, the whole thing gets stuck and crashes.

i'm hoping this will be a really obvious error to someone and i'd be so grateful of any help!  even if the code above looks fine, please let me know and i'll go further with debugging.  :)
Title: Re: problem with conditional statement
Post by: mike_pa on Sep 21, 2009, 06:34 pm
Hi,

the preference of && is higher than > or <. Change your code as follows:

Code: [Select]
void test() {
 intVal = analogRead(intPin);
 Serial.println(intVal);
 if (intVal < 301) {
   ...do something...
 }
 // if i remove the following conditional statement, the code runs ok!
 else if ((intVal > 300) && (intVal < 701)) {
   ...do something else...
 }
 else if (intVal > 700) {
   ...do another thing...
 }
}



Mike
Title: Re: problem with conditional statement
Post by: mike_pa on Sep 21, 2009, 06:39 pm
Hi,

sorry, I'm wrong (preference is different is Pascal but not in C), the code seemd to be ok. Try the following (i do not know. how the compiler optimates the code, maybe there is the problem:

Code: [Select]
void test() {
 intVal = analogRead(intPin);
 Serial.println(intVal);
 if (intVal <= 300) {
   ...do something...
 }
 // if i remove the following conditional statement, the code runs ok!
 else if (intVal > 300 && intVal <= 700) {
   ...do something else...
 }
 else  {
   ...do another thing...
 }
}



Mike
Title: Re: problem with conditional statement
Post by: meg on Sep 21, 2009, 06:46 pm
thanks for your help, mike_pa!

i tried those adjustments, but the code still jams.  so then i tried it with a different function than the one i'm calling (where i've written "...do something...") and it seems to work ok.

so i guess it's not a problem with the conditional statements after all.  i'll do some more debugging - thanks! :)
Title: Re: problem with conditional statement
Post by: ahdavidson on Sep 21, 2009, 07:20 pm
How do you declare intval?

Have you put in other println statements in each branch of the cascading if .. else statement to try to track it down?

What is the exact nature of the crash?

It might be helpful for you to post the entire program, plus the exact crash information. (E.g., does the println of the data just before the crash look ok?)
Title: Re: problem with conditional statement
Post by: meg on Sep 21, 2009, 08:48 pm
Quote
It might be helpful for you to post the entire program, plus the exact crash information. (E.g., does the println of the data just before the crash look ok?)


the program prints the following two lines before crashing:
1
885
the first number is the position of the swtich and the second number is the reading from the potentiometer.

here's my code (some explanation below):

Code: [Select]

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"

SdReader card;
FatVolume vol;
FatReader root;
FatReader f;
uint8_t dirLevel; // indent level for file/dir names
dir_t dirBuf;     // buffer for directory reads
WaveHC wave;      // only one!

int ledPin = 13;              // LED
int inputPin = 14;           // on/off switch
int val = 0;                    // variable for reading the pin status

// debounce stuff
int state = HIGH;          // the current state of the output pin
int reading;                  // the current reading from the input pin
int previous = LOW;     // the previous reading from the input pin
long time = 0;             // the last time the output pin was toggled
long debounce = 200;  // the debounce time, increase if the output flickers

// potentiometer
int intPin = 3;
int intVal = 0;

// play recursively - possible stack overflow if subdirectories too nested
void play(FatReader &dir)
{
 FatReader file;
 while (dir.readDir(dirBuf) > 0) {

   // skip . and .. directories
   if (dirBuf.name[0] == '.') continue;
   Serial.println();
   for (uint8_t i = 0; i < dirLevel; i++) Serial.print(' ');
   if (!file.open(vol, dirBuf)) {
     Serial.println("file.open failed");
     while(1);
   }

   if (file.isDir()) {
     putstring("Subdir: ");
     dirLevel += 2;
     // play files in subdirectory
     play(file);
     dirLevel -= 2;    
   }
   else {
     putstring("Playing ");
     if (!wave.create(file)) {
       putstring(" Not a valid WAV");
     }
     else {
       Serial.println();
       wave.play();

       while (wave.isplaying) {
         putstring(".");
         delay(100);
       }
     }
   }
 }
}

void setup() {
 // set up serial port
 Serial.begin(9600);

 // set up waveshield pins
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);

 pinMode(ledPin, OUTPUT);      // declare LED as output
 pinMode(inputPin, INPUT);     // declare switch as input
 digitalWrite(inputPin, HIGH);

 if (!card.init()) {//play with 8 MHz spi
   putstring_nl("Card init. failed!");
   while(1);
 }
 // enable optimize read - some cards may timeout
 card.partialBlockRead(true);

 uint8_t part;
 for (part = 0; part < 5; part++) {
   if (vol.init(card, part)) break;
 }
 if (part == 5) {
   putstring_nl("No valid FAT partition!");
   while(1);
 }

 if (!root.openRoot(vol)) {
   putstring_nl("Can't open root dir!");
   while(1);
 }

 dirLevel = 0;
}

void test() {
 intVal = analogRead(intPin);
 Serial.println(intVal);
 if (intVal <= 300) {
   playcomplete("SOUND1.WAV");
 }
 else if (intVal > 300 && intVal <= 700) {
   playcomplete("SOUND2.WAV");
 }
 else if (intVal > 700) {
   playcomplete("SOUND3.WAV");
 }
}

void loop(){
 reading = digitalRead(inputPin);
 if (reading == HIGH && previous == LOW && millis() - time > debounce) {
   // ... invert the output
   if (state == HIGH)
     state = LOW;
   else
     state = HIGH;

   // ... and remember when the last button press was
   time = millis();    
 }

 Serial.println(reading);

 if (previous != reading) {
   digitalWrite(ledPin, HIGH); // turn LED ON
   test();
 }
 previous = reading;

}

void playcomplete(char *name) {
 playfile(name);
 while (wave.isplaying);
}

void playfile(char *name) {
 if (wave.isplaying) {// already playing something, so stop it!
   wave.stop(); // stop it
 }
 if (!f.open(root, name)) {
   putstring("Couldn't open file ");
   Serial.print(name);
   return;
 }
 if (!wave.create(f)) {
   putstring_nl("Not a valid WAV");
   return;
 }
 // ok time to play!
 wave.play();
}


this code is for lady ada's wave shield using the WaveHC library.  i've been coaxing this code into doing new things for me, step-by-step, so i'm pretty sure the error is of my own doing.

in case it helps, or anyone is interested here is the original code to generate a sound when a button is pressed. (http://forums.adafruit.com/viewtopic.php?f=31&t=12591&sid=8252ffd1c4d5e932ed2319bffbc1edea)

what i'm trying to do is generate a sound when a switch is flipped, the sound will be different depending on the value of the potentiometer.

specifically, the software problem seems to be with the test() function, however, i also had problems when using a switch statement instead of conditionals, so if there's nothing really wrong with my code, maybe it's to do with the heaviness of the wav files?
Title: Re: problem with conditional statement
Post by: ahdavidson on Sep 22, 2009, 12:28 am
I don't have any experience with the wave code, but if you suspect that test routine, I would do something like this:

Code: [Select]
void test() {
 intVal = analogRead(intPin);
 Serial.println(intVal);
 if (intVal <= 300) {
   Serial.print ("val < 300 found: ");
   Serial.println (intval);
   playcomplete("SOUND1.WAV");
 }
 else if (intVal > 300 && intVal <= 700) {
   Serial.print ("val between 300 and 700 found: ");
   Serial.println (intval);    
   playcomplete("SOUND2.WAV");
 }
 else if (intVal > 700) {
   Serial.print ("val > 700 found: ");
   Serial.println (intval);    
   playcomplete("SOUND3.WAV");
 }
 else {
   Serial.print ("val ???: ");
   Serial.println (intval);    
 }
}


and see what happens.

I'd be wondering about memory usage also for a failure like what you described, but again, I'm not familiar with the details of the application.
Title: Re: problem with conditional statement
Post by: Grumpy_Mike on Sep 22, 2009, 01:34 am
Drop the else .. if .. else .. construct you have it wrong. The difficulty is knowing what if the else belongs to

As you have it the testing is wrong because for example if the first if fails then intVal has to be greater than 300 so there is no need to test it again. in the second if.

Just use a separate if for each condition and keep the comparisons very much as they are only put brackets round each >
if ((intVal > 300) && (intVal <= 700) )
Title: Re: problem with conditional statement
Post by: mfm9 on Sep 22, 2009, 02:24 am
Here's how I would write it:
Code: [Select]
void test() {
 intVal = analogRead(intPin);
 Serial.println(intVal);
 if (intVal <= 300) {
   playcomplete("SOUND1.WAV");
 }
 else if (intVal <= 700) {      /* 301 - 700 */
   playcomplete("SOUND2.WAV");
 }
 else {                               /* > 700 */
   playcomplete("SOUND3.WAV");
 }
}


-Mike
Title: Re: problem with conditional statement
Post by: meg on Sep 22, 2009, 11:17 am
thanks for all the suggestions!

mike and grumpy_mike, i tried your adjustments, but still got the same error...

andy, i tried you code and something curious came up.  when clicked "verify", i got the following error:
In function 'void test()':
error: 'intval' was not declared in this scope

the first occurrence of this line is highlighted by the program:
[glow]Serial.println (intval);[/glow]
Title: Re: problem with conditional statement
Post by: AWOL on Sep 22, 2009, 11:22 am
You spelled "intVal" wrong?
Title: Re: problem with conditional statement
Post by: meg on Sep 22, 2009, 11:23 am
doh!

ok, if i run that code with the playcomplete("SOUND1.WAV"); function calls in, i don't get any feedback whatsoever...

when i comment out the three calls to playcomplete, this happens:

1
1
1í1
215
val < 300 found: 215
1
1
1
1
1
...etc, etc, looping intVal...

...until i adjust the pot and flip the switch...
1
1
0
204
val < 300 found: 214
0
0

so i guess it is a problem with calling the wav files.  how frustrating!  these file play fine if used with a simple switch statement and three separate buttons, but as soon as i use a potentiometer it all turns to custard.  i'm going to run some tests with switches instead of a pot...
Title: Re: problem with conditional statement
Post by: ahdavidson on Sep 22, 2009, 03:59 pm
This is why it's called debugging!

Fun, huh?

>:(
Title: Re: problem with conditional statement
Post by: meg on Sep 22, 2009, 04:50 pm
pure joy. :)
Title: Re: problem with conditional statement
Post by: ahdavidson on Sep 22, 2009, 06:20 pm
I actually greatly enjoy the software debugging process; there is a very real satisfaction from figuring things out and unraveling mysteries.

Good luck!
Title: Re: problem with conditional statement
Post by: lefstin on Sep 22, 2009, 09:09 pm
Might this be a problem with running out of RAM, rather than a problem with your code?  (that seems to be the usual answer when otherwise inoffensive code clobbers your application)
Title: Re: problem with conditional statement
Post by: meg on Sep 23, 2009, 09:03 am
the RAM theory is interesting.  i went back to my original code with the switch case for three buttons.  works fine.  as soon as i wrap the switch case in a conditional statement (perhaps heresy in the c world, i'm used the the squishy reality of javascript) the board chokes again.

at the moment i'm using a lilypad but for my final project i'll be using a mini 328 which has a whopping 2KB of RAM - i'll post back here if it works!

thanks everyone for the help!  i've learnt so much in this thread!  :D
Title: Re: problem with conditional statement
Post by: meg on Oct 05, 2009, 11:22 am
just in case anyone is searching for the solution to a similar problem, this was solved by using a board with more RAM!  :)