Problem with NewSoftSerial and two MCUs

Hi, I am trying to communicate between an ATMEGA2560 and an ATMEGA328P.

Since ATMEGA328P only has an UART and I need two communication ports, used NewSoftSerial library to emulate the extra port.

With NewSoftSerial I managed to send information to ATMEGA2560 but cannot receive data.

This is the code running in ATMEGA2560:

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  
  Serial.println("Listening to MCU2...");
}

void loop()
{
  Serial1.println("TEST");
  delay(1000);
  
  while(Serial1.available())
  {
    Serial.print((char)Serial1.read());
  }
}

and this is the code running in ATMEGA328P

#include <NewSoftSerial.h>

#define MCU1_TXD1 2 
#define MCU1_RXD1 3

NewSoftSerial mySerial(MCU1_TXD1, MCU1_RXD1);
char ch[5];

void setup()
{
  delay(3000);
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop()
{
  uint8_t ii = 0;
  memset(ch,'\0',5);
  
  mySerial.println("testing MCU2...");
  delay(2000);

  while(mySerial.available())
  {
    ch[ii] = mySerial.read();
    ii++;
  }
    
  mySerial.println(ch);
}

My idea was to receive a string from ATMEGA2560 and then send it back. Unfortunately, no information is being received.

Is there any hint?

Many thanks.

Two questions:

  1. Did you connect the grounds of each MCU together?
  2. In the 328P code, what happens when if ii gets to 6?

You're sending 6 bytes ("TEST" plus CR/NL) but on the receiving side you have reserved memory for only 4 (plus NULL byte). You should limit the number of bytes you accept if your array is limited.

Yes, the grounds are connected together.

Please note that I am unable to receive information from ATMEGA2560 hence, while(mySerial.available()) is never a valid condition and the allocated space is enough. I tried "TEST" and smaller strings like "AT", for instance.

Thanks for your replies :slight_smile: .

Have you tried echoing each character immediately without storing it in an array? How do you know that the 328 does not receive anything from the 2560? If it freezes because of a programming error it never returns anything exactly as it would if it never received anything.

pylon:
Have you tried echoing each character immediately without storing it in an array? How do you know that the 328 does not receive anything from the 2560? If it freezes because of a programming error it never returns anything exactly as it would if it never received anything.

I cannot print received characters because I don't receive any.

while(mySerial.available()) is never a valid condition. However I can send data to ATMEGA2560 with mySerial.println("STRING");

My guess is that my problem has something to do with interruptions (because I can send data but can't receive)...

You're using a pre-1.0 IDE (NewSoftSerial.h) I guess. I suggest switching to 1.0 or better 1.0.1 where the library is simply called SoftwareSerial.h, maybe some fixes have found their way into the code in the meantime.

pylon:
You're using a pre-1.0 IDE (NewSoftSerial.h) I guess. I suggest switching to 1.0 or better 1.0.1 where the library is simply called SoftwareSerial.h, maybe some fixes have found their way into the code in the meantime.

Yes, you're right, I'm using Arduino 0023. Tomorrow I'll try Arduino 1.0.
I'm still using a downgraded version due to compatibility with libraries and old code. Maybe that's the right moment to upgrade :wink: .

I just tried the code with Arduino 1.0.1 but the problem still occurs...

I am able to send data from ATMEGA328P to ATMEGA2560 but can't receive from ATMEGA2560. According to datasheet, ATMEGA328P 's PD2 and PD3 (pins that software serial library uses to emulate the communication port) should support interruptions (PCINT18 and PCINT19, respectively).

UPDATE:
I used an Arduino UNO, opened its Serial port and created/opened two NewSoftSerial objects (mySerial and mySerial2). The problem persists: mySerial transmits to mySerial2 and mySerial2 is able to transmit to mySerial, as well. However, neither mySerial nor mySerial2 can receive/read data.

I think I don't understand your update. If mySerial2 is able to transmit to mySerial, you have received data on that interface. Do you have the possibility to connect an oscilloscope (better) or a logic analyzer to the port to see what's going on?

Have you also checked that you selected the correct board type while compiling your code? The library uses different lookup tables with timings depending on the CPU's frequency.

Both mySerial and mySerial2 transmit data (I checked with an oscilloscope) and the pin also receives data (again, checked with an oscilloscope).
The issue is that I can't read the buffer. mySerial.available() is always 0 so, I can't use mySerial.read();

I read that when using multiple NewSoftSerial instances, listen() method should always be called. I tried it but, again, I had no luck.

Thanks for all your replies.

The SoftwareSerial implementation allows for only one active object at a time. You can have several instances but only one receiving data at a given moment.

Just to check: You're using SoftwareSerial now and not NewSoftSerial, aren't you?

Because you have an oscilloscope you can activate the DEBUG feature of SoftwareSerial. In SoftwareSerial.cpp change the line

#define _DEBUG 0

to

#define _DEBUG 1

Then you can connect your scope to pin 11 and 13. You should see a pulse on pin 13 for the start bit and for every bit received (also for the 0). If you see a spike on pin 11, your buffer has an overrun.

Since I am using Arduino 0023, I am including NewSoftSerial.

I also tried Arduino 1.0.1 and officially supported SoftwareSerial but got the same (bad) results.

Thanks for your suggestions. I'll try again with the oscilloscope as soon as possible.

I don't know if the old versions support this feature. Maybe you have to try with the new IDE. You can still use the old one for your other projects but I'd suggest using only the newest version for this project as there are relevant changes in the code of SoftwareSerial.

Yes, I think your are right. I really should port my code to the new IDE... Still, after checking Arduiniana page NewSoftSerial | Arduiniana , NewSoftSerial should work without any trouble.

Well, this is very strange...

Today I tried PCInt library to ensure an interruption routine could be called when receiving characters (it worked), activated and deactivated #define _DEBUG in NewSoftSerial and... it started working properly!

I really don't know what happened because the code I'm running is the same I posted here...

Many thanks for all your replies!