Problem with 3 Serial Ports on UNO

Hi all,

I wrote a wrapper for this APRS Modem/BeRTOS firmware ( MicroAPRS | unsigned.io ) ...
The Arduino wrapper are located at GitHub - stanleyseow/ArduinoTracker-MicroAPRS: Arduino Tracker (SVTrackR) for MicroAPRS modem

I wanted to write something similar to Radio Shield 2 Radio Shield 2 for Arduino, Argent Data Systems but completely open source ...

I needed 3 Serial port for the following functions :-

Pin 0,1 ( 9600) - connect to the APRS Modem to send commands and received decoded APRS packets from the radio
Pin 2,3 (9600) - connect to GPS module for GPS coordinates ( SoftwareSerial )
Pin 8,9 (57600) - connect to a FTDI Serial USB module for Debugging and send in commands purposes...

Things that are not working (yet) are :-

  • I could not copied the entire decoded APRS packet into a String or char array

I want to display the CALLSIGN ( the string after the SRC: ) and DATA: on the 20x4 LCD but I could not grab the entire row or only partial of the sample string below..

I suspect there are too many calls to other serial port ( e.g. GPS on Software Serial or Debug ) and therefore blocking this..

How shall I solve this Serial port issue with 3 Serial ports running at the same time...

Thanks

Stanley

The output of decoded messages from the APRS modem are as below :-

SRC: [9W2BBB-12] PATH: [9M2KKK-3] [WIDE1-1] [WIDE2-2] DATA: !/Lq@Yh1usP?DG/A=000273 13.6V 32CAPRS
SRC: [9M2CCC-3] PATH: [WIDE2-1] DATA: !/Lqluh1'q# st 11.8V  33C MAAAS VHF 144.3900MHz
SRC: [9W2AAA-0] PATH: [9M4RRR-3] [9M2TTT-1] [9M2KKK-3] [WIDE1-0] DATA: @050418z0300.35N/000004.61Ez 
SRC: [9M2KKK-3] PATH: [WIDE2-1] DATA: !/Lqluh1'q# st 11.8V  33C MAAAS VHF 144.3900MHz

The decodeAPRS functions, the entire source codes are at the github URL stated above ...

void decodeAPRS() {
      char c;
      char endChar = '\n';
      char endChar2 = '\r';
      boolean storeString = true;
      char callsign[12];
      char path[60];
      char data[100];

      debug.println();
      debug.print("Entering decodeAPRS (");
      debug.print(millis());
      debug.println(")");
      while ( Serial.available() > 0 ) {
         c = Serial.read();
         // For debugging only 
         debug.print(c);
         
         // If MAXBUFFER is reach, NULL terminate the string
         if ( bufferIndex > maxBuffer ) {
               charBuffer[maxBuffer] = 0;
               storeString = false;          
         }
         
         // Check for endChar and NULL terminate the string
         if ( c == endChar || c == endChar2 ) {
             charBuffer[bufferIndex] = 0;
             storeString = false;    
         }
         
         if ( storeString ) {
              charBuffer[bufferIndex++] = c;
         }
      }
      
      // Save buffers into Strings if charBuffer is not blank
      if ( !storeString  && (!charBuffer[0] == 0) ) { 
            inBuffer = charBuffer;
      }
      
      if ( inBuffer != "" && !storeString ) {
        debug.println();
        debug.print("RF(");
        debug.print(inBuffer.length());
        debug.print("):");
        debug.println(inBuffer);
        
        // Check for first 3 char is SRC
        if ( inBuffer.substring(0,3) == "SRC" ) {
      
        int firstBracket = inBuffer.indexOf('[');  // Anything in between [ and ] is the callsign & ssid
        int secondBracket = inBuffer.indexOf(']');

        //int secondColon = inBuffer.indexOf(':',secondBracket+1);  
        int secondColon = secondBracket+6;
        // Do not use lastindexOf as the messaging uses : too 
        int thirdColon = inBuffer.indexOf(':',secondColon+1);
        
        // Get the callsign
        String decoded2 = inBuffer.substring(firstBracket+1,secondBracket); // Substring the callsign
        decoded2.toCharArray(callsign,secondBracket+1-firstBracket-1);      // Convert to char array
        
        // Get the path
        String decoded3 = inBuffer.substring(secondColon+2,thirdColon-5);
        decoded3.toCharArray(path,decoded3.length()+1);
        
        // Get the data
        String decoded4 = inBuffer.substring(thirdColon+2,inBuffer.length());
        decoded4.toCharArray(data,decoded4.length()+1);

        debug.print("Callsign (");
        debug.print(strlen(callsign));
        debug.print("):");
        debug.println(callsign);    
             
        debug.print("Path (");
        debug.print(strlen(path));
        debug.print("):");
        debug.println(path);    

        debug.print("Data (");
        debug.print(strlen(data));
        debug.print("):");
        debug.println(data);    
        
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(callsign);
        
        lcd.setCursor(0,1);
        lcd.print("                    ");        
        lcd.setCursor(0,1);
        for ( int i=0;i<20;i++ ) { lcd.print(data[i]); }

        // Print on Line 2
        lcd.setCursor(0,2);
        lcd.print("                    ");        
        lcd.setCursor(0,2);        
        if ( strlen(data) < 40 ) {
            for ( int i=20;i<strlen(data);i++ ) { lcd.print(data[i]); }
        } else {
            for ( int i=20;i<40;i++ ) { lcd.print(data[i]); } // Truncate data till 40 bytes
        }
                 
        firstBracket, secondBracket, secondColon, thirdColon = 0;
        
       } // endif SRC check
       
        // clear the buffers after saving out all the variables like callsign, path and data
        inBuffer = "";      // Clear the buffers
        charBuffer[0] = 0;  // Clear the buffers
        bufferIndex = 0;    // Reset the index
        callsign[0] = 0;
        path[0] = 0;
        data[0] = 0;
       
      } // end storeString
}

I do not understand everything you wrote, but I doubt if combining both the SoftwareSerial and AltSoftSerial will work.
Do you use any libraries that use the same timer as AltSoftSerial ?
Normally the SoftwareSerial can be used for a few serial ports. You select one port and sent something and wait for the respose. After that select another serial port and so on. I think that is okay for the GPS module, but I don't know how your modem behaves.

The Arduino Leonardo has the same size as the Arduino Uno, and the Leonardo might be able to do this. When you use the usb connection for debugging and commands (and upload a sketch), and use the hardware serial at pin 0 and 1 for the modem, and the SoftwareSerial library for the GPS.
The Leonardo uses an internal software/hardware serial port for the usb, and the hardware serial port at pin 0 and 1 is free available for your own use.

The Arduino Mega 2560 has 4 hardware serial ports.