Pages: [1] 2   Go Down
Author Topic: problem with conditional statement  (Read 1775 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.  smiley
« Last Edit: September 21, 2009, 11:04:30 am by meg » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 149
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

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

Code:
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
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 149
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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! smiley
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?)
Logged

.andy

0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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.

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?
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't have any experience with the wave code, but if you suspect that test routine, I would do something like this:

Code:
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.
Logged

.andy

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 597
Posts: 33328
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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) )
« Last Edit: September 21, 2009, 06:35:35 pm by Grumpy_Mike » Logged

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's how I would write it:
Code:
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
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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]
« Last Edit: September 22, 2009, 04:20:18 am by meg » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25735
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You spelled "intVal" wrong?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...
« Last Edit: September 22, 2009, 04:36:48 am by meg » Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is why it's called debugging!

Fun, huh?

 >smiley-sad
Logged

.andy

0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

pure joy. smiley
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I actually greatly enjoy the software debugging process; there is a very real satisfaction from figuring things out and unraveling mysteries.

Good luck!
Logged

.andy

Pages: [1] 2   Go Up
Jump to: