Go Down

Topic: Having trouble tying multiple functions together (Read 1 time) previous topic - next topic

MisterResistor

Feb 03, 2013, 11:49 pm Last Edit: Feb 03, 2013, 11:55 pm by Learning Reason: 1
I've built a kluge that performs 5 functions. I can make any of the five work perfectly as standalone sketches. I'm trying to use the Serial Monitor to input a selection that through the use of a switch. The switch/case combo works except it only allows one iteration of the called function. If I send say "1111111" it will run 7  times, "2222" 4 times, etc. Anyone have an idea on a slick method to pull this off?

UKHeliBob

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

MisterResistor

#2
Feb 04, 2013, 01:01 am Last Edit: Feb 04, 2013, 03:18 am by Nick Gammon Reason: 1
Here's the basic structure. Thanks for looking at it.



Code: [Select]
static char mode;
#include <NewPing.h>
#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
int FLASH_PIN = 13;
int MIC_PIN = 0;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup()
{
 Serial.begin(115200);
 pinMode(MIC_PIN, INPUT);
 pinMode(FLASH_PIN, OUTPUT);
}
void loop()
{
 if(Serial.available())
 {
   char mode = Serial.read();
   Serial.println(mode);
   switch(mode)
   {
     case '1':
     Sound();
     break;
     
     case '2':
     Ultrasonic();
     break;
     
     case '3':
     Proximity();
     break;
     
     case '4':
     Magnetic();
     break;
     
     case '5':
     Mystery();
     break;
  }
 }
}
void Sound()
{
  Serial.print("Sound");
 // while(mode == '1')
 {
 //  if(Serial.available())
 {
   char mode = Serial.read();
 }
 int value = analogRead(MIC_PIN);
 Serial.println(value);
 {
   if (value < 120)
  {
   Serial.print ("SDFGHJKLJHGFDGHJKL:JHGFSDGHKJHGFSDSGHJKHGFSD");
   digitalWrite(FLASH_PIN,LOW);
  }
 else

 digitalWrite(FLASH_PIN,HIGH);
 }
}
}
void Ultrasonic()
{
// while(mode == '2')
 {
  // if(Serial.available())
 {
   char mode = Serial.read();
 }

  Serial.print("Ultrasonic");
  Serial.println(mode);
  delay(50);         // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM / 2.54); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)  
  Serial.println("in");
  if (uS / US_ROUNDTRIP_CM /2.54 < 3)  // 12 inch out
    {
      digitalWrite(FLASH_PIN,LOW);   // flash it!
    }
      else
    {
      digitalWrite(FLASH_PIN,HIGH);  // don't flash it!
    }
  }
}
void Proximity()
{
 // while(mode == '3')
 {
 // RF disrupter sketch here
 Serial.print("Proximity");
 Serial.print(mode);
 }
}
void Magnetic()
{
//  while(mode == '4')
 {
 // Hall effect sketch
 Serial.print("Magnetic");
 Serial.print(mode);
 }
}
void Mystery()
{
 //while(mode == '5')
 {
   // Jack Bauer special
 Serial.print("Mystery");
 Serial.print(mode);
 }
}


pYro_65


I've built a kluge that performs 5 functions. I can make any of the five work perfectly as standalone sketches. I'm trying to use the Serial Monitor to input a selection that through the use of a switch. The switch/case combo works except it only allows one iteration of the called function.

If I send say "1111111" it will run 7  times, "2222" 4 times, etc. Anyone have an idea on a slick method to pull this off?


You say it only allows one iteration, then its running 7 and 4 times.

Is your intention to only respond to one of the '1' in "1111111"?

If so, flushing the RX buffer may help after reading the value:

Code: [Select]
while( Serial.available() ) Serial.read();

Nick Gammon

Read this before posting a programming question


Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.
http://www.gammon.com.au/electronics

MisterResistor

No, the intention is to dynamically switch between functions by doing a single key entry through the serial monitor. It will 'run' the function each time it receives a number like 11111, but I want it to continue running that function until I enter another choice.

pYro_65

Maybe something like this:

Code: [Select]
void loop(){
  static char mode = '1'; //Default starting mode.

  //Get new mode if available
  if(Serial.available()){
    mode = Serial.read();
  }

  //Now your switch
  Serial.println( mode );

  switch( mode ){
    //...
  }
}

HazardsMind

#7
Feb 04, 2013, 02:03 am Last Edit: Feb 04, 2013, 03:19 am by HazardsMind Reason: 1
What about reading it from serial and then store it in a temporary variable. Now with that variable you can check if any new incoming chars are different or not. If it is different, do another function, if not, do same function.

Use a while loop to compare the variables.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

MisterResistor

Still only runs once and stops. I was pretty sure I tried this about 3 days ago, haha. Driving me nuts.

pYro_65

Well how are you sending the data, if you send a string with a null terminator you need to account for it.

You could flush all remaining characters.
Code: [Select]
//Get new mode if available
  if(Serial.available()){
    mode = Serial.read();
    while( Serial.available() ) Serial.read();
  }


Or maybe even better, check if the character is what you are looking for:

Code: [Select]
//Get new mode if available
  if(Serial.available()){

    char temp = Serial.read();

    if( ( temp >= '1' ) && ( temp <= '5' ) ){
      mode = temp;
    }
  }

MisterResistor

You could flush all remaining characters.

Code:

//Get new mode if available
  if(Serial.available()){
    mode = Serial.read();
    while( Serial.available() ) Serial.read();
  }

Yep, this was the bug! The old null character being ignored trick.  Thank you!!!

-Jim

Nick Gammon

You have multiple declarations of mode. That is bad practice:

Code: [Select]

static char mode;
...
    char mode = Serial.read();
...
    char mode = Serial.read();
...
    char mode = Serial.read();


These are all different variables. The resulting behaviour may not be what you expect.
http://www.gammon.com.au/electronics

MisterResistor


Go Up