How to make Arduino runs continuous routines even inside a "switch case loop".

Hi,
I would like to create a sketch that execute some different function (sensor measurements) depending on which key is pressed by user. In particular I've Imagined a sketch with a "switch case loop" for the function selection. As It's wrote below, the sketch is working perfectly, especially if considering the situation in which every function returns one single value. My own huge problems start when I need to create a measurement function (in this specific case a pressure measurement, but this doesn't really matter) that when it is called it runs forever its measurement routine, until User press the key to stop it. This sketch will be used with an interface, built in Processing, that will ask Arduino to get the measurements: each value from "single measurement" (obtained from all the functions except those named "Pres()")will be represented in a "text box", whereas those from the "continuous measurements" (obtained from the "Pres()" function) will be plotted in a continuous graph (for example a graph similar to http://arduino.cc/en/Tutorial/Graph).
I've search some help for a long time (almost all use the "millis()" function,or the "time.h" and "TimeAlarm.h" library, etc...) but after some attempts I can't obtain the result I need. Could someone help me??
Maybe I would like to obtain something that is conceptually wrong. You should Consider that I'm absolutely not an expert programmer. Every help will be really appreciated.

Here is my code

//includes necessary libraries
#include <......>


//Some setup & variables/constants declaration & other stuff


void setup() {
  Serial.begin(9600);
  //arduino/sensor setup and other stuff
}

void loop(){
  if(Serial.available()){
    delay(100);
    char ch=Serial.read();
    switch(ch)
    { 
      case '1':
      SHT1();
      break;
      
      case '2':
      SHT2();
      break;
      
      case '3':
      Pres();
      break;
      
      case '4':
      LIGHT1();
      break;
      
      case '5':
      LIGHT2();
      break;
      
      default:
      Serial.print(ch);
      Serial.println(" unknown command");
    }   
}
}

void SHT1(){
  // do measurement and return ONE DATA
}

void SHT2(){
  // do measurement and return ONE DATA
}

void Pres(){
    // do measurementS and RETURN DATA AS LONG AS USER PRESS ONE KEY TO STOP MEASUREMENT
}


void LIGHT1() {
   // do measurement and return ONE DATA
}

void LIGHT2() {
  // do measurement and return ONE DATA
}

Separate the "getting the thing to do" (entering the key code) from the "doing the thing".
A simple state machine (good search term there) will help.

Get rid of "delay()"s.

Make your functions non-void, so they actually do return something.

AWOL:
Separate the "getting the thing to do" (entering the key code) from the "doing the thing".
A simple state machine (good search term there) will help.

Can you tell me how to do this?? If you would make an example with some code/pseudocode I'll really appreciate it!!Meanwhile I'll start to search something in this great forum!
Thank you very much for your soon reply!

Rather than trying to code your functions so they run 'continuously', design them so that they are called repeatedly.

Have some global variables which tell you which function(s) you should be calling. In loop(), put your code to read the input commands and update the variables to show which functions are supposed to be being called. Also in loop(), test the value of those variables to decide which function(s) need to be called, and then call them. The code will be similar to your original code, but separate out the 'reading from the serial port' from 'deciding which function to call'.

In other words, don't do this:

void loop(){
  if(Serial.available()){
    delay(100);
    char ch=Serial.read();
    switch(ch)
    { 
      case '1':
      SHT1();
      break;
      ... etc

Do this:

char ch = 0;
void loop(){
  if(Serial.available())
  {
    ch=Serial.read();
  }
  switch(ch)
  { 
    case '1':
      SHT1();
      break;
      ... etc

PeterH:
Rather than trying to code your functions so they run 'continuously', design them so that they are called repeatedly.

Have some global variables which tell you which function(s) you should be calling. In loop(), put your code to read the input commands and update the variables to show which functions are supposed to be being called. Also in loop(), test the value of those variables to decide which function(s) need to be called, and then call them. The code will be similar to your original code, but separate out the 'reading from the serial port' from 'deciding which function to call'.

In other words, don't do this:

void loop(){

if(Serial.available()){
    delay(100);
    char ch=Serial.read();
    switch(ch)
    {
      case '1':
      SHT1();
      break;
      ... etc




Do this:



char ch = 0;
void loop(){
  if(Serial.available())
  {
    ch=Serial.read();
  }
  switch(ch)
  {
    case '1':
      SHT1();
      break;
      ... etc

Hi PeterH,
thank you for your reply! I've changed my code as suggested by you, but nothing changes in the results: every routines has been executed one time only. Is there anything else that needs to be changed in the code?
Thank you. Best wishes.

Is there anything else that needs to be changed in the code?

You haven't posted any, so how can we tell?

AWOL:

Is there anything else that needs to be changed in the code?

You haven't posted any, so how can we tell?

I'm sorry AWOL. As suggested by PeterH, I've changed some of the code and below there's my code. Every function returns ONE single "value" and break from its case. I need that one function (in this case "Pres()") continues to keep the routine (to return the value everytime) untill the User give it a break (for example) pressing a key on the keyboard.

//includes necessary libraries
#include <......>


//Some setup & variables/constants declaration & other stuff
char ch=0; //global variable for Serial.read()

void setup() {
  Serial.begin(9600);
  //arduino/sensor setup and other stuff
}

void loop(){
  if(Serial.available()){
    delay(100);
    ch=Serial.read();
    switch(ch)
    { 
      case '1':
      SHT1();
      break;
      
      case '2':
      SHT2();
      break;
      
      case '3':
      Pres();
      break;
      
      case '4':
      LIGHT1();
      break;
      
      case '5':
      LIGHT2();
      break;
      
      default:
      Serial.print(ch);
      Serial.println(" unknown command");
    }   
}
}

void SHT1(){
  // do measurement and return ONE DATA
}

void SHT2(){
  // do measurement and return ONE DATA
}

void Pres(){
    // do measurementS and RETURN DATA AS LONG AS USER PRESS ONE KEY TO STOP MEASUREMENT
}


void LIGHT1() {
   // do measurement and return ONE DATA
}

void LIGHT2() {
  // do measurement and return ONE DATA
}

As suggested by PeterH, I've changed some of the code

No, you didn't change it as he suggested. Read the post again, particularly around the reading of the serial port.
If the character read is global and therefore persistent, then once read, it will trigger the appropriate action every time through "loop ()" until a new character is read.

AWOL:

As suggested by PeterH, I've changed some of the code

No, you didn't change it as he suggested. Read the post again, particularly around the reading of the serial port.
If the character read is global and therefore persistent, then once read, it will trigger the appropriate action every time through "loop ()" until a new character is read.

Holy crap!! I feel so stupid for the mistake I've done.. I'm sorry! now it works!!!!

Here is the sketch!

//includes necessary libraries
#include <......>


//Some setup & variables/constants declaration & other stuff
char ch=0; //global variable for Serial.read()

void setup() {
  Serial.begin(9600);
  //arduino/sensor setup and other stuff
}

void loop(){
  if(Serial.available()){
    ch=Serial.read();}
    switch(ch)
    { 
      case '1':
      SHT1();
      break;
      
      case '2':
      SHT2();
      break;
      
      case '3':
      Pres();
      break;
      
      case '4':
      LIGHT1();
      break;
      
      case '5':
      LIGHT2();
      break;
}
}

void SHT1(){
  // do measurement and return ONE DATA
}

void SHT2(){
  // do measurement and return ONE DATA
}

void Pres(){
    // do measurementS and RETURN DATA AS LONG AS USER PRESS ONE KEY TO STOP MEASUREMENT
}


void LIGHT1() {
   // do measurement and return ONE DATA
}

void LIGHT2() {
  // do measurement and return ONE DATA
}

Is it a correct way adding "ch=0;" inside a case to get only a value from the selected case?
something like this:

case '1':
      SHT1();
      ch=0;
      break;

Thank You all very very much!!!

Program structure is easier to follow if you indent it like this

void loop()
{
  if(Serial.available()){
    ch=Serial.read();
  }

or

void loop()
{
  if(Serial.available())
  {
    ch=Serial.read();
  }

The compiler doesn't care, but my first reading of your revised code was that nothing had changed.

AWOL:
Program structure is easier to follow if you indent it like this

void loop()

{
 if(Serial.available()){
   ch=Serial.read();
 }



or


void loop()
{
 if(Serial.available())
 {
   ch=Serial.read();
 }




The compiler doesn't care, but my first reading of your revised code was that nothing had changed.

Looking at my first post you can observe what I wrote is:

void loop(){
  if(Serial.available()){
    delay(100);
    char ch=Serial.read();
    switch(ch)
    { 
      case '1':
      SHT1();
      break;
    .......
}

Now I've changed the code:

char ch=0;

void setup(){
....}

void loop(){
  if(Serial.available()){
    ch=Serial.read(); 
    }
    switch(ch)
    { 
      case '1':
      SHT1();
      break;
      ......
      }
      }

This is pretty different! Anyway my own Arduino now works exactly as I wish!!

What you posted in reply #8 was this

void loop(){
  if(Serial.available()){
    ch=Serial.read();}
    switch(ch)

So, with the "read" and the "switch at the same level of indentation, it is difficult to spot the trailing "}"

void loop()
{
  if(Serial.available())
  {
    ch=Serial.read();
  }
  switch(ch)

is much easier on the eye, and easier to spot the program flow.

AWOL:
What you posted in reply #8 was this

void loop(){

if(Serial.available()){
    ch=Serial.read();}
    switch(ch)




So, with the "read" and the "switch at the same level of indentation, it is difficult to spot the trailing "}"


void loop()
{
  if(Serial.available())
  {
    ch=Serial.read();
  }
  switch(ch)


is much easier on the eye, and easier to spot the program flow.

Ok! thank you very much!

8bit_Biker:
Is it a correct way adding "ch=0;" inside a case to get only a value from the selected case?

That will cause the corresponding function to get called once when the command was received, and not run again until the command was sent again. If I understood your original post correctly, that's not what you wanted.

PeterH:

8bit_Biker:
Is it a correct way adding "ch=0;" inside a case to get only a value from the selected case?

That will cause the corresponding function to get called once when the command was received, and not run again until the command was sent again. If I understood your original post correctly, that's not what you wanted.

Hi PeterH!
What I wrote above is very useful to me to get the function returns only one value instead of multiple values (that's what I need to obtain from "Pres()" function).
Another time thank you very very much for you help! Really useful to me!