Pages: [1]   Go Down
Author Topic: serial event in subroutine dont work?  (Read 899 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino is fun
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i see and tested some nice code http://atlas-scientific.com/_files/code/Arduino-sample-code-EZ-COM-MEGA.pdf
Code:
String inputstring = "";                                                       //a string to hold incoming data from the PC
String sensorstring3 = "";                                                      //a string to hold the data
boolean input_stringcomplete = false;                                          //have we received all the data from the PC
boolean sensor_stringcomplete3 = false;                                         //have we received all the data


  void setup(){                                                                //set up the hardware
     Serial.begin(115200);                                                      //set baud rate for the hardware serial port_0
     Serial3.begin(38400);                                                     //set baud rate for software serial port_3
     inputstring.reserve(5);                                                   //set aside some bytes for receiving data from the PC
     sensorstring3.reserve(30);                                                 //set aside some bytes for receiving data
     }
 
 
 
   void serialEvent() {                                                         //if the hardware serial port_0 receives a char              
               char inchar = (char)Serial.read();                               //get the char we just received
               inputstring += inchar;                                           //add it to the input String
               if(inchar == '\r') {input_stringcomplete = true;}                //if the incoming character is a <CR>, set the flag
              }  


  void serialEvent3(){                                                          //if the hardware serial port_3 receives a char
              char inchar = (char)Serial3.read();                               //get the char we just received
              //sensorstring3 += inchar;                                        //kll add it to the input String
              if(inchar == '\r') {sensor_stringcomplete3 = true;}               //if the incoming character is a <CR>, set the flag
              else {  sensorstring3 += inchar; }                                //kll
             }



 void loop(){                                                                   //here we go....
    
  if (input_stringcomplete){                                                   //if a string from the PC has been received fully
      Serial3.print(inputstring);                                              //send that string
      inputstring = "";                                                        //clear the string:
      input_stringcomplete = false;                                            //reset the flag used to tell if we have received a completed string from the PC
      }

 if (sensor_stringcomplete3){                                                   //if a string has been received fully
      Serial.println(sensorstring3);                                            //send that string to the PC's serial monitor
      sensorstring3 = "";                                                       //clear the string:
      sensor_stringcomplete3 = false;                                           //reset the flag used to tell if we have received a completed string
      }
 }

like for a terminal emulation ...

but when i tried to use the event in a code
like question and answers in a subroutine it did not work.

can you pls try that following code and tell me what you think?

Code:
/*
KLL serial event test
*/
String inputstring = "";                                                       //a string to hold incoming data from the PC
boolean input_stringcomplete = false;                                          //have we received all the data from the PC

  void setup(){                                                                //set up the hardware
     Serial.begin(115200);                                                     //set baud rate for the hardware serial port_0
     inputstring.reserve(5);                                                   //set aside some bytes for receiving data from the PC KLL but seems to work also for longer strings??
     }

   void serialEvent() {                                                         //if the hardware serial port_0 receives a char              
               char inchar = (char)Serial.read();                               //get the char we just received
               inputstring += inchar;               //add it to the inputString
               Serial.print(" S0: ");
               Serial.println(inchar,HEX);
               if(inchar == '\r') {input_stringcomplete = true;}                //if the incoming character is a <CR>, set the flag
              }
              
  void askquestion() {
      Serial.println("Question: do you love me? ");
      int var = 0;
      while(var < 20){  // do something repetitive times
                   delay(200);
                   var++;  Serial.print(".");
                   if (input_stringcomplete){
                       Serial.print(" askquestion loop got: ");
                       Serial.print(inputstring);                                               //send that string back
                       Serial.println();
                       inputstring = "";                                                        //clear the string:
                       input_stringcomplete = false;                                            //reset the flage used to tell if we have recived a completed string from the PC
                       break;
                                            }
                      } // end while
                    Serial.println(" timeout ");    
                    } // ask question

 void loop(){                                                                   //here we go....

  if (input_stringcomplete){                                                   //if a string from the PC has been recived in its entierty
      Serial.print(" main loop got: "); Serial.println(inputstring);
      inputstring = "";                                                        //clear the string:
      input_stringcomplete = false;                                            //reset the flage used to tell if we have recived a completed string from the PC
      }
  askquestion();    

 }

looks like a character is only catched in a main loop, ( and only one per loop).
so question - answer will never work?
 
any ideas what i do wrong?
« Last Edit: January 27, 2013, 12:42:46 am by kllsamui » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino is fun
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

found info
http://arduino.cc/en/Tutorial/SerialEvent
/* 
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */

so its correct what i see and this function is of limited use.
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4339
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What are you expecting your code to do ?
What does it actually do ?
Where is the call to serialEvent() ?
« Last Edit: January 27, 2013, 07:11:21 am by UKHeliBob » Logged

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino is fun
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

for a sub menu like operation i need several "questions AND answers" via serial link ( USB, operator ).
means i must stay inside a sub routine without going back to main loop inbetween,
or i would loose the reference, what answer is for what question.

the serialEvent is a interrupt routine, so not to be called here, ( only filled with functionality )
and it works perfect in a main loop structure like in the first example.

code example 2 is to show where the problem is only. pls try it.
it does not get anything from the serial line as long it is in the subroutine.
Code:
Question: do you love me?
.................... timeout
Question: do you love me?
.................... timeout
Question: do you love me?
.................... timeout
 S0: 79
Question: do you love me?
.................... timeout
 S0: 65
Question: do you love me?
.................... timeout
 S0: 73
Question: do you love me?
.................... timeout
 S0: D
 main loop got: yes

Question: do you love me?
.................... timeout
Question: do you love me?
.................... timeout

so instead of using this serialEvent interrupt function i must go back to the usual Serial.available()...
« Last Edit: January 27, 2013, 08:06:58 am by kllsamui » Logged

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 52
Posts: 2377
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

1. Its a function there are no routines (sub or other wise) in C/C++

2. Never use the String class with Arduino (there's a fault in it)

3.
Quote
for a sub menu like operation i need several "questions AND answers" via serial link ( USB, operator ).
means i must stay inside a sub routine without going back to main loop inbetween,
or i would loose the reference, what answer is for what question.

Completely wrong! See the blink without delay example and Finite State Machines in in the playground

4. Quit playing with serial event!

Mark
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4339
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your serialAvailable() function is only removing one character from the input buffer each time it is called and it is only called at the end of loop().  However, askQuestion() blocks loop() from running again until the delay of 4 seconds is over, by which time it is too late for serialAvailable() to get another character and add it to the string, and this includes the CR, so the input never finishes before the 4 seconds is up and even then only has one character in it.

If I were you I would leave serialEvent() alone.
Logged

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

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

Quote
However, askQuestion() blocks loop() from running again until the delay of 4 seconds is over
...by which time, the Serial input buffer could have overflowed 720 times, and you would never know.
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.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 641
Posts: 50361
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Where is the call to serialEvent() ?
The serialEvent() functions are called at the end of loop(), if there is serial data on the specific port. The user does not need to code a call to the serialEvent() functions.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino is fun
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for all the input:
i see : NOT USE STREAM, NOT USE EVENT.

@holmes4 / Mark
Quote
3. Completely wrong! See the blink without delay example and Finite State Machines in in the playground 
i understand that delay is bad, i try without, but the job:
ask a question " pls. give a setpoint; default 12.46: "
 - i must wait for operator input,
 - but check also on a timeout,
 - check if the number provided is good,
 - use a default number if not
 + and do something with that input
_____ while all this i can not go back to the main loop ( i think)
        as much i hate to block all other jobs in main loop
     thats why i started testing about the serialEvent.
and regarding this i do not understand your answer? you have seen code what can do that?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino is fun
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

pls find here ( attached ZIP ) my first working example, what combines all 3 ways to deal with serial input:

input check NO WAIT for a operator menu system ( by one character )
( what still allow the main loop to run 1000000 / 16sec. )

input question .. answer
for string / and number int/real with default number / type WAIT with time out

stream by serialEvent for sensor input from T3 (MEGA)
connected sensor: http://atlas-scientific.com/product_pages/sensors/ec-sensor.html

looks like:
Code:
KLL serial menu
 adjust terminal to AUTOSCROLL, Carriage Return, 115200
 hit [space] [ENTER] to get MENU list

 MENU:
 [space] this list
 [d] enable diagnostic
 [t] enable timecheck
 [n] test number input
 __________sensor ___________________
 [c] send measure command to sensor T3
 [e] send measure stop command to sensor T3
 [i] send ref info command to sensor T3
 select:
 sensor on T3 command I<CR>
E,V3.0,4/12
 sensor on T3 command C<CR>
2045,1104,0
2178,1176,0
2000,1080,0
 debug ON
 T3: 32 T3: 30 T3: 30 T3: 30 T3: 2C T3: 31 T3: 30 T3: 38 T3: 30 T3: 2C T3: 30 T3: D2000,1080,0
 T3: 32 T3: 30 T3: 32 T3: 32 T3: 2C T3: 31 T3: 30 T3: 39 T3: 32 T3: 2C T3: 30 T3: D2022,1092,0
 T3: 32 T3: 30 T3: 32 T3: 32 T3: 2C T3: 31 T3: 30 T3: 39 T3: 32 T3: 2C T3: 30 T3: D2022,1092,0
 debug OFF
1978,1068,0
2022,1092,0
 sensor on T3 command E<CR>

 Question numberinput, default 98.7654:
 int: -3456 real: -3456.79

 Question numberinput, default 98.7654:  no number input, use default!
 int: 98 real: 98.77

* serial_menu_T3stream.zip (4.62 KB - downloaded 14 times.)
« Last Edit: January 28, 2013, 08:12:17 am by kllsamui » Logged

Pages: [1]   Go Up
Jump to: