Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Trouble passing Serial, Serial1, Serial2 as a reference

  1. #1
    Junior Member
    Join Date
    Nov 2016
    Posts
    6

    Trouble passing Serial, Serial1, Serial2 as a reference

    I'm trying to have a single project that can either send/receive strings via USB serial or Bluetooth. I have a command to switch between Serial and Serial2. It doesn't seem to work the way I expect. When I send a "BTON" command, the print statement prints to Serial, switches to Serial2 and properly prints to Serial2. But when I send the "BTOFF" command immediately after "BTON", both print statements print to Serial when I expected the 1st print command to go to Serial2. It seems as though the "Stream& MySerial = Serial2;" does not persist. Can anyone provide help?

    Thanks.

    Code:
    uint8_t argCount;
    uint8_t thisArg = 0;
    char *argv[30];
    bool BT = false;
    
    Stream& MySerial = Serial;
    
    void setup() {
    	Serial.begin(115200);
    	Serial2.begin(115200);
    }
    void loop() {
    
    	static char buffer[80];
    	if ((readline(Serial.read(), buffer, 80) > 0) || (readline(Serial2.read(), buffer, 80) > 0)) {
    		char tmpBuffer[sizeof(buffer)-2];
    		strcpy(tmpBuffer, &(buffer[2]));
    		cmd_parse(buffer);
    		if (!strcmp(argv[0],"BTON")) {
    			MySerial.println("Bluetooth Turning on");  // This properly prints to Serial
    			Stream& MySerial = Serial2;
    			MySerial.println("Bluetooth is turned on");  // This properly prints to Serial2
    		}
    		else if (!strcmp(argv[0],"BTOFF")) {
    			MySerial.println("Bluetooth Turning off");  // THIS DOES NOT PRINT TO SERIAL2
    			Stream& MySerial = Serial;
    			MySerial.println("Bluetooth is turned off");  // This prints to Serial
    		}
    	} 
    }

  2. #2
    Senior Member
    Join Date
    Jan 2013
    Posts
    184
    You have defined 3 variables named MySerial. This is probably not what you intended.

  3. #3
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,563
    I am not the greatest c++ expert, but would strongly guess that the MySerial.println("Bluetooth Turning off"); // THIS DOES NOT PRINT TO SERIAL2
    Would print to Serial and not Serial2.

    Why: as @markonian mentioned, you have defined three different MySerial objects, each have their own scope.
    In Particular: Stream& MySerial = Serial;
    Has a global scope, so it is valid everywhere in your sketch (after that point it is defined).

    And the definition:
    Code:
    	if (!strcmp(argv[0],"BTON")) {
    			MySerial.println("Bluetooth Turning on");  // This properly prints to Serial
    			Stream& MySerial = Serial2;
    			MySerial.println("Bluetooth is turned on");  // This properly prints to Serial2
    		}
    Is only valid within the code block that it is defined. That is everywhere after where it is defined up till that next }
    Within that scope it sort of masks the global definition variable, but when you exit that scope, the global version is again used...

    I know that a compiler person could explain this better than I just did, including the proper terms for the scoping...

  4. #4
    Junior Member
    Join Date
    Nov 2016
    Posts
    6
    Shoot. Of course... Now I'm not sure how to change the global reference to Serial2. I have read that you cannot change references. Do I understand this correctly or is there a way to change the global reference back and forth between Serial and Serial2?

  5. #5
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,169
    Don't redeclare MySerial. Just assign a new value to it.
    Code:
    MySerial = Serial2;
    .
    .
    .
    MySerial = Serial;
    Pete

  6. #6
    Junior Member
    Join Date
    Nov 2016
    Posts
    6
    Quote Originally Posted by el_supremo View Post
    Don't redeclare MySerial. Just assign a new value to it.
    Code:
    MySerial = Serial2;
    .
    .
    .
    MySerial = Serial;
    Pete
    I tried this and it didn't work. I don't think I am able to re-assign the reference that way as everything prints to Serial.

  7. #7
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,169
    Hmm. I'll have to ponder that.
    BTW what is readline? It looks like you are reading a line from Serial and a line from Serial2 into the same buffer. If so, that'll be quite messy.

    Pete

  8. #8
    Try this:
    Code:
    		if (!strcmp(argv[0],"BTON")) {
    			Serial.println("Bluetooth Turning on");  // This properly prints to Serial
    			Serial2.println("Bluetooth is turned on");  // This properly prints to Serial2
    		}
    		else if (!strcmp(argv[0],"BTOFF")) {
    			Serial2.println("Bluetooth Turning off");  // THIS DOES NOT PRINT TO SERIAL2
    			Serial.println("Bluetooth is turned off");  // This prints to Serial
    		}
    The usual test for data on a serial port is:
    Code:
    	if (Serial.available() > 0)
    	{
    		incomingByte = Serial.read();
                    ...
            }

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    545
    I don't think I am able to re-assign the reference that way
    Right, references can not be reassigned. This is much easier by using pointers instead of references.

    Just declare a global pointer holding the address of the Serial object you want to print to. You can change that at any time.
    Since your code snippet does not compile here a simple example which shows the principle by switching the port after each print:

    Code:
    Stream *mySerial;
    
    void setup()
    {
       Serial1.begin(9600);
       Serial2.begin(9600);
    
       // E.g. assign the address of Serial1 to mySerial for a start
       mySerial = &Serial1;
    }
    
    void loop()
    {
       // just assign any Stream address (e.g. Serial, Seria1, ....)
       // to mySerial. 
       // Here a simple example which switches ports after each print
       // replace that with your switching code
    
       if (mySerial == &Serial1)
          mySerial = &Serial2;
       else
          (mySerial = &Serial1);
    
    
      // print to the currently selected port
       mySerial->println("Hello");
    
       delay(100); // don't overrun the receiver
    }

  10. #10
    Junior Member
    Join Date
    Nov 2016
    Posts
    6
    luni,

    Thank you. I have switched to pointers and MySerial->print. This works!!

    Elf,
    Thank you for the suggestion, but I do not want to print twice everywhere as I have some timing constraints and prints take too much time already.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •