Software Serial Library - 328P, Tx only, Debug only, Small

Hi All

Can I get recommendations for a light weight Software Serial Library please. It is for the 328P, I need Tx only and it is only for Debug. Light weight is the key - otherwise SoftwareSerial would be fine, but looking to save every byte of code space I can.

I found tinySerialOut, which would have been perfect but it looks to only be for the ATtiny, (I guess the clue is in the name!)

Thanks very much
Kevin

Do you want a buffer and send the data with interrupts ?
The most simple Serial output is putting data in the TX register and wait until it is sent. You have to select a very high baudrate, and it will slow things down.

What is going on ? Is your sketch filling the Flash or the SRAM ? When using the Flash for 99%, that is no problem at all.
Is your sketch too large ? Maybe you can write a better sketch.

Hi Koepel

No buffer / interrupts needed as long as I can send at a reasonable speed 56k or so. A bit of slow down is fine.

Sketch is filling Flash and I want to add more functionality so hence looking for areas to save.

I'm sure I can save space in other areas too, but this is one...

Cheers
Kev

So you want a send only software serial ?

How about send only software serial;

You can go a lot more low level than that when you want to send debug messages to the serial monitor on the computer.

With a hardware serial port of the Arduino Uno, it is like this: Set the baudrate in the register UBRR0, enable the TX bit, and send data in UDR0 while waiting for the UDRE0 bit.
Then you get this: USART Programming : Arduino / ATmega328p - Arnab Kumar Das.

Why do you need SoftwareSerial ? Where is that going ?

Trick that you may (not) like:

  • You can put data in EEPROM, even text strings.
  • Debug messages don't need to be very long, if you see "X", then you can look up in the sketch what error X means.
  • When you have a table of 24-bits values stored into 32-bits variables in PROGMEM, then you might be able to reduce it to 24-bits (with bytes or a struct).
  • Compressing data in PROGMEM is an option. For an Arduino Uno it is often trivial: the code to decompress it might take more Flash memory.
  • During development you can turn on and off parts of the code with #define #ifdef and #if defined. For example to remove a sensor to be able to debug an other part.
  • More lines in the code does not mean that the Flash usage increases. A Finite State Machine can be efficient.
  • There are smaller versions of some libraries, sometimes they are faster and better as well.
  • Going a great length to optimize code and variables might make the sketch harder to read, and it might not help. Use the "Verify" button a lot to check if the code gets smaller. The compiler might be able optimize simple code better than highly "optimized" code.
  • There is an option to reduce the precision for floating point. You probably won't notice it.

Are you sending to the hardware serial pins? In that case, the suggestions above for writing the data register and waiting for it to send are the best (smallest) approach.

DrAzzy:
Are you sending to the hardware serial pins? In that case, the suggestions above for writing the data register and waiting for it to send are the best (smallest) approach.

Hi, This is software serial, as the hardware serial pins are already used, but I will look at the hardware serial code size too, thanks.

srnet:
So you want a send only software serial ?

How about send only software serial;

GitHub - nickgammon/SendOnlySoftwareSerial: Arduino library for sending (only) of serial data

I'll have a look, thank you for the pointer. I wonder if it will be any smaller compared to the normal software serial library, where I dont use any transmit functions, and the code is compiled with optimise on...
I was hoping for something more like tiny Serial but for a wider chip range..

KevWal:
I was hoping for something more like tiny Serial but for a wider chip range..

Wider chip range ?

Your first post says "It is for the 328P"

Hi,

Sorry if I have confused, to be clear I am looking for something that only needs to work on the 328p. My 'wider chip range' comment was in relation to TinySerial, that looks to only work on the ATtiny chips. So I would like tinySerial to work on a wider chip range, ie to work on a 328p.

Thanks very much
Kevin

Shouldn't you just be able to bit-bang it ? Not that i've managed to do so, but just flicking a pin HIGH/LOW is all it really is, isn't it ?

If someone has some bit bang code that has some #define timings for some different clock speeds that would be great I think? Unless I am missing some complexities?

Cheers
Kev

Look at transmitting the bits in the SendOnlySoftwareSerial, it uses a tuned delay and outputs the bits. That is what you want and there is not much that can be removed from that code.

I think that SendOnlySoftwareSerial is a good choice. You have to look at other things to shrink.

Koepel:
You can go a lot more low level than that when you want to send debug messages to the serial monitor on the computer.

Thanks @Koepel, great post with lots of ideas and detail.
The web link for Hardware serial is great, as I use Hardware serial as well for talking to the GPS.
Software serial is just for debug messages back to the PC or logic analyser.
Putting text strings into EEPROM or compressing them is an idea I had not considered. Do you have any good implementation examples for that?
Thanks very much
Kevin

Koepel:
Look at transmitting the bits in the SendOnlySoftwareSerial, it uses a tuned delay and outputs the bits. That is what you want and there is not much that can be removed from that code.

I think that SendOnlySoftwareSerial is a good choice. You have to look at other things to shrink.

I prejudged SendOnlySoftwareSerial poorly, just tried it and saved my self 1kb vs the full SoftwareSerial even with the RX buffer reduced to almost nothing. Thanks very much for the sugestion.

Reading text from EEPROM requires extra code and the EEPROM handling functions will be added to your code. It depends on your sketch and how the EEPROM will be used.

Can you show your sketch ? Maybe most of your Flash usage is in a library for a OLED font or so.

Hi @Koepel

Sorry for the delay, I was continuing to work on some things. Please find attached the code as it stands. 29.8KB with debugging, 23.3Kb without debugging included.

I still need to do some work on my digital write replacements to make them a bit more manageable. I am thinking I should be able to get the same code size reductions but using some Macros to save me hard coding registers and bit settings in the code?

Suggestions for further size reductions welcome, I have a set of RTTY routines that I would like to implement but don't have the code space for right now.

Thanks very much
Kevin

Code.zip (677 KB)

Without DEBUG, I get 23492 bytes (72%) Flash and 971 bytes (47%) SRAM for an Arduino Uno.
That is not so bad. That means there is still some memory to add functions.
Can you turn off certain pieces of code with #ifdef and #if defined and debug the new part as I wrote before ?

At first I thought: "it is not that much code", but with the libraries it becomes a lot.
It is what it is. Trying to squeeze a few bytes here and there in your own code does not help.
If you want to add more functionality then you have to upgrade to a Arduino board with more memory.

This is what I did:
Arduino IDE 1.8.13 and selected Arduino Uno.
I copied the *.h files of your project to *.ino files and remove from each file the part that should not belong there.
Then I added: #include <avr/power.h>
In KW_HF.h the DEBUG and DEBUGNOTUK were commented out.
Because Timing-NOPPP.ino was added to the project, I removed the contents by adding #ifdef NONOPPP at the top and #endif at the bottom.
I might have fixed a few other thing, just follow the compiler output for problems.

Never declare a variable in a *.h file.
Never put a function in a *.h file.

They belong in a *.ino or *.cpp file.
In a *.h file can be the #define or function prototyping or class definitions and so on. But not variables and not functions.

Which macros do you mean ?

KevWal:
Suggestions for further size reductions welcome, I have a set of RTTY routines that I would like to implement but don't have the code space for right now.

There is a point where you cannot continue to re-write code and make it ever smaller.
How much space do the RTTY routines take, a simple example will tell you, and how much space have you actually got left ?
What else do you intend to add ?

Kopel - Re "Which macros do you mean ?" I am not sure, I need to research that, I just mean I should be able to be more intelligent (more maintainable) than hard coded statements like PORTD |= 1 << 4; whilst not increasing the code size, because ultimately the macro would result in the producing the same code.

Thanks
Kevin