SoftwareSerial interferes with Hardware Serial

Hi,

I'm building a mobile phone based on a ATmega328p and a Click2Gsm module. I am communicating between the two on the hardware serial on 57600 baud. To monitor the software i have added a SoftwareSerial debug pin on pin 13, TX only.

I had issues causing the serial connection between the modem and the cpu being unstable, dropping characters and such.

This evening I found out that the communications became stable once I removed the SoftwareSerial debug statements.

On the prjc site for AltSoftSerial i found:

NewSoftSerial (SoftwareSerial in Arduino 1.0 & later) - Can have multiple instances on almost any pins, but only 1 can be active at a time. Can not simultaneously transmit and receive. Can interfere with other libraries or HardwareSerial if used at slower baud rates. Can be sensitive to interrupt usage by other libraries.

My problem now is this: what are my alternatives in keeping a debug port while still being able to receive data on the hardware RX reliably? I can't use AltSoftSerial because the ports are all taken by other hardware.

Thank you for your time.

This is about the 4th or 10th thread this past week asking essentially the same question. You might do a bit of leg work.

I apologise for not having taken the time to read up. I will do a search.

A TX only is even possible without any buffers or any interrupts. But it will slow down your code dramatically. Where is your RX of the SoftwareSerial ? floating ? disabled ?

Can you give a link to the Click2Gsm that you use ?

Any luck with the leg work ?

I found two posts on the topic:

Describes a similar issue but does not relate to using the SoftwareSerial in combo with HardwareSerial http://forum.arduino.cc/index.php?topic=286663.0

Describes using TWO software serials and a Listen() method, but since I am not listening on the software port it is irrelevant http://forum.arduino.cc/index.php?topic=286753.0

I am not using the RX of the SoftwareSerial because I do not need it. I passed a 0 a the port number. Here's the click2gsm module home page. The issue is not with the GSM module but the combo is Hardware UART + SoftwareSerial. I cannot block the IO because serial data may be arriving on the Hardware UART at any time. I've been trying to solve this issue for almost 6 months now (on and off) and I only realised until recently that it is caused by me using the softwareSerial for debugging output. I never thought my debugging code would have such an impact on the entire system.

Perhaps doing a bit-banged serial out on the debugging port may be the solution, thank you for suggesting that. I will investigate the solution.

With some research I decided to bit-bang my debug method. The UART should be able to buffer a few incoming bytes while I send out short debug messages on port 13 (PB5).

I would like to share the code (debug.h):

#include <arduino.h>

//use hardware port 13 (PB5) for max performance.
class debugStream
{
    public:
      debugStream()
      {
        writePin(HIGH);
      }
      void println(const char *line)
      {
        print(line);
        writeByte('\r');
        writeByte('\n');
      };
      void print(const char *line)
      {
        while(*line != 0)
        {
          writeByte(*line);
          line++;
        }
      };
      void println(int i)
      {
        char sbuf[10];
        sprintf(sbuf, "%d", i);
        println(sbuf);
      };
      
      //http://www.dnatechindia.com/Tutorial/8051-Tutorial/BIT-BANGING.html
      void writeByte(uint8_t c)
      {
         int periodMicroSecs = 104; //1/9600 interval
         
         writePin(LOW);
         delayMicroseconds(periodMicroSecs);
         for(uint8_t b = 0; b < 8; b++)
         {
           writePin(c & 0x01);
           c >>= 1;
           delayMicroseconds(periodMicroSecs);
         }
         
         //stop bit
         writePin(HIGH);
         delayMicroseconds(periodMicroSecs*2);
      };
      
      void writePin(bool value)
      {
        if(value)
        {
          PORTB |= 0b00100000;
        }
        else
        {
          PORTB &= ~0b00100000;
        }
      };
};

It isn’t the best solution, but it allows me to continue focus on getting the project finished.

That's the best way to solve this problem. Fall back to something that doesn't cause troubles.

Thanks for the link, but 44 dollars is a normal price. I would prefer a SIM900 module.

Using a '0' for RX for the SoftwareSerial, means that you select digital pin 0 for RX. That is already the RX of the hardware serial port. So every byte that is received causes two interrupts for two libraries and that results into a big avalanche of ... something. That's not good, "something" is bad.

Peter_n: That's the best way to solve this problem. Fall back to something that doesn't cause troubles.

Thanks! :D

Thanks for the link, but 44 dollars is a normal price. I would prefer a SIM900 module.

I didn't pay 44 dollars of course, much less.. The issue was, I had a EFCOM PRO with a SIM900 but the IO board was horrible. It gave me intermittent power stability issues and IO was only 3v3 (i guess the board was faulty). This board is smaller, stable and allows me to 5v IO because of the on-board level converter.

Using a '0' for RX for the SoftwareSerial, means that you select digital pin 0 for RX. That is already the RX of the hardware serial port. So every byte that is received causes two interrupts for two libraries and that results into a big avalanche of ... something. That's not good, "something" is bad.

I tried with using a different number for the RX, but I just couldn't get it working. Anyway, it is sorted now. I much more prefer my code. It is extremely lightweight, i've added a printf() parameter style API, so I guess i'll keep it like this.

Oh and by the way, if you change the periodMicrosecs, I can boost the debug speed to 38400bps.

int periodMicroSecs = 26; //1/38400 interval