Softserial buffer location and using softserial with interrupts

Hi,

I have arduino pro mini and I need to connect several serial modules to it. I know about arduino mega - the sizes just don't suit me.

So I have a questions about serial buffers in arduino. I know that on-board Serial has 64byte buffer. So if data comes and I haven't received it to ram, it's got stored in that buffer. If new data comes and it overflows - previous data get's dropped.

So here is my question list:

  1. But what happens with software serial? Where it's got stored? On the serial buffer of sender?
  2. What happens if there is no serial on the other side (device is powered off)? Does data drops, or it's waiting in some kind of buffer until receiver appears?
  3. Is it OK to use several software serials in my code? What problems can I get stuck into? (As I know there is a single buffer for all softwareserials, but again I can't imagine where does that buffer located)
  4. I have an ability to disable unneded serials, should I do the SoftwareSerial.end() and then again SoftwareSerial.start() when I need? (I know when I need and when I dont need serials working, according to design there can be just one serial and one software serial running active at a time, and I can enable/disable them on-demand).
  5. I will use interrupts and SLEEP_MODE_PWR_DOWN in my code. Is it ok to use SoftwareSerial with sleep function? (I heard there is some problems with timing on interrupts&softwareserial)
  6. I am going to make my arduino power on by Serial interrupt. I will connect the 220ohm resistor to 0(rx) pin of my arduino and 2nd pin, and attach an interrupt on 2nd pin. So when the data is being sent to my arduino by serial it get's powered on and does it's job. Can the Serial data be damaged because of that resistor? Should I put a diode?
  7. Also havent found: What power saving mode does not freeze millis()? I am thinking what will be more energy cheap: use power mode with millis or buy RTC.

I really appreciate your help,
Thanks

  1. afaik SW serial has no buffer, it sends immediately and you must read and store immediately
  2. drops, it is send into oblivion.
  3. Yes; many as only one SWS can be active at the time; So it is only suitable for polling.
  4. no
  5. yes
    (too little time to answer them all, better go through the code yourself, it is not that complex.
    most of the questions are easy to find out by creating a minimal sketch

afaik SW serial has no buffer, it sends immediately and you must read and store immediately

I just can't imagine this. What is immediately? How many milliseconds I have to read the data? So if I put delay for 1 second in code and I will have the data on softserial's rx that time, I wont get the data?

Nevermind, I found this.

Seems like arduino has 64byte buffer in RAM for software serial, however it can be activated only for one SoftwareSerial. Other data will be discarded. However this configuration suit my needs.

Thanks

However this configuration suit my needs.

Does it? What are the serial devices? Will they never try to send data except in (somewhat delayed) response request from your Arduino?

So if data comes and I haven't received it to ram, it's got stored in that buffer. If new data comes and it overflows - previous data get's dropped.

No. The previous data stays in the buffer. New data is discarded until there is room. Then, the incoming data is added until the buffer is full again. Note that this may result in parts of packets being in the buffer, with no way for you to know that the buffer does not contain complete packets.

  1. What happens if there is no serial on the other side (device is powered off)? Does data drops, or it's waiting in some kind of buffer until receiver appears?

If there is nothing sending data, there is no data to be concerned about, is there?

  1. Is it OK to use several software serials in my code? What problems can I get stuck into? (As I know there is a single buffer for all softwareserials, but again I can't imagine where does that buffer located)

As long as you understand that the non-listening instances will never see any more data. The data that is in the instance's buffer stays there until you read it, but no new data will arrive until the instance is made active again (by calling it's available(), read(), or listen(), print(), println(), or write() methods).

  1. I will use interrupts and SLEEP_MODE_PWR_DOWN in my code. Is it ok to use SoftwareSerial with sleep function? (I heard there is some problems with timing on interrupts&softwareserial)

SoftwareSerial uses pin change interrupts. They do not wake up the sleeping Arduino.

  1. I am going to make my arduino power on by Serial interrupt.

SoftwareSerial won't do that.

As long as you understand that the non-listening instances will never see any more data. The data that is in the instance's buffer stays there until you read it, but no new data will arrive until the instance is made active again (by calling it's available(), read(), or listen(), print(), println(), or write() methods).

If arduino is busy by doing some other stuff, for example delay for 5 mins, will it receive incoming data on software serial and hold it in the buffer assuming that there is only one software serial instance and the data do not exceeds 64 bytes?

If there is nothing sending data, there is no data to be concerned about, is there?

No. For example there is 2 arduinos and one is sending another one data by serial for example every 5 seconds, but the second arduino is switched off. After some time it gets powered on. What happens with the data and serial buffers in this case? Will the data be queued in some kind of tx buffer, or just get's dropped? (Question not only about softwareserial, but about serial in common)

SoftwareSerial uses pin change interrupts. They do not wake up the sleeping Arduino.

But if I connect a 220 ohm resistor to softserial rx pin and pin2 I will be able to wake it up on LOW interrupt on pin2. I found that in some tutorial on internet, I will check that but I think that should work. "SLEEP_MODE_PWR_DOWN" is the best power saving mode, however serial interrupts are only allowed in MODE_IDLE. But this configuration allows to use the best power saving mode and still wake up by data on serial (but maybe with this configuration first bytes will be garbled or missed). This configuration should also allow waking up arduino by data on software serial, because no matter what serial is used, this configuration uses only LOW interrupt on pin2 or pin3. The question was if this resistor can damage the serial data during usual serial usage. Maybe I should put a transistor to allow this resistor pass signal only during sleeping. I am going to check that in some time and will write the result here.

Does it? What are the serial devices? Will they never try to send data except in (somewhat delayed) response request from your Arduino?

I have 2 devices that I should not miss data from. One of them will be connected to Serial, the second one to SoftwareSerial with listen(). As I understand I wont miss the data because even if arduino will be in delay() for 5 minutes data will be held in buffers (data wont exceed 64 bytes).
Also I have 2 devices that I should just transmit to by SoftwareSerial,nothing to receive. So I think theese 2 buffers suit my needs (one hardware and one software).

Also quick question:

void loop() {
softwareserial1.listen()
// do stuff with softwareserail1
softwareserial2.println("Line");

//Should I do softwareserial1.listen() again here and every time I work with other software serial or does it still listening after println on another serial?
}

If arduino is busy by doing some other stuff, for example delay for 5 mins, will it receive incoming data on software serial and hold it in the buffer assuming that there is only one software serial instance and the data do not exceeds 64 bytes?

Yes, but... A delay() of 5 minutes is NOT "busy doing some other stuff". It is a failure to read, understand, and embrace the blink without delay philosophy.

What happens with the data and serial buffers in this case?

What data? Data doesn't exist on the receiving Arduino until it is powered on and ready to receive data.

Will the data be queued in some kind of tx buffer, or just get's dropped?

No. Data is not magically collected in the ether somewhere, waiting for your particular Arduino to be powered on to read it.

But if I connect a 220 ohm resistor to softserial rx pin and pin2 I will be able to wake it up on LOW interrupt on pin2.

If there is something holding the software serial rx pin HIGH while the Arduino is asleep, this would work. I don't believe that this is the case when software serial is controlling the pins.

Note that the hardware serial pins are a special case, and what applies to them, with respect to serial data and sleep modes, does not necessarily apply to software serial pins.

//Should I do softwareserial1.listen() again here and every time I work with other software serial or does it still listening after println on another serial?

Any action by a SoftwareSerial instance makes it the active instance. If you want another instance active, you must make it active (by calling it's listen method).

Ok, everything got clearer to me. Thanks a lot!

Yes, but... A delay() of 5 minutes is NOT "busy doing some other stuff". It is a failure to read, understand, and embrace the blink without delay philosophy.

Just the last thing I didn't understood. Do you mean that "Doing other stuff" will interrupt on data on SoftwareSerial (and this data will be saved to RAM buffer), but if the data comes when delay is being executed - data will be dropped?

Do you mean that "Doing other stuff" will interrupt on data on SoftwareSerial (and this data will be saved to RAM buffer), but if the data comes when delay is being executed - data will be dropped?

The delay() can be (and will be) interrupted by serial data arriving, on the hardware port or on software serial pins. Data will not be lost using delay(). The opportunity to deal with it as soon as it arrives will be.

PaulS:
The delay() can be (and will be) interrupted by serial data arriving, on the hardware port or on software serial pins. Data will not be lost using delay(). The opportunity to deal with it as soon as it arrives will be.

Data most certainly will be lost if the buffer overflows.