Char array not working with presence of SoftwareSerial.h

I'm writing a program to output text, word wrap it on an OLED, and then output it to a thermal printer.
I've successfully written code to work with the OLED and printer via separate sketches, but my problem is when I try and combine them.

What should happen when I upload the code to the Arduino is the screen should clear and then when I type on a connected PS/2 keyboard it will output the words on the screen.

The "problem" I'm having is nothing is happening on the OLED and the Arduino seems like its frozen because whatever text was on the screen before the new upload is still there.

When I tore apart my code to debug and find out what was, I noticed the introduction of SoftwareSerial.h made my char array: word_buffer not work.

Note: word_buffer does not depend on SoftwareSerial, as it is only for word wrapping in the OLED.

when I comment out the use of word_buffer in the code (in the area under the //word wrap comment), the program will run and I will be able to type on the OLED (of course, since I removed some code it doesn't work perfectly but at least it responds).

I know word_buffer is giving me the issues because if I substitute it for line_buffer (another char array) the code will be responsive on the OLED.

When I try and use word_buffer at all the program won't work, unless I remove the aspects of the thermal printer (libraries and setup code).

Once again, this code works if I take out the code required for the thermal printer.

I've tried to look into this for a few days and found nothing for my specific question.

Please me know if you can help,

Here is my code:

#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Adafruit_Thermal.h>
#include <PS2Keyboard.h>

#include <SPI.h>
#include <Wire.h>

#define LED_PIN 13


// OLED display
#define OLED_MOSI  A4
#define OLED_CLK   A3
#define OLED_DC    A2
#define OLED_CS    A0
#define OLED_RESET A1
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


// printer
#include "SoftwareSerial.h"
#define GND_PIN 7
Adafruit_Thermal printer(&Serial, 4);

// keyboard
const int DataPin = 8;
const int IRQpin =  3;
PS2Keyboard keyboard;


#define CHR_PER_LINE 21                    
#define HIDDEN_BUF 21                       
#define VIS_BUF 168           
#define WRD_BUF 32               

char line_buffer[HIDDEN_BUF + VIS_BUF + 1]; 
int line_start = HIDDEN_BUF;                
int line_len = 0;                           
int word_len = 0;
char word_buffer[WRD_BUF + 1];
int g = 0;
int row_len = 0;
int neg = 0;


void setup() {
  keyboard.begin(DataPin, IRQpin);

  pinMode(GND_PIN, OUTPUT);                 
  digitalWrite(GND_PIN, LOW);

  pinMode(LED_PIN, OUTPUT);                 
  digitalWrite(LED_PIN, HIGH);


  for (int i = 0; i < HIDDEN_BUF + VIS_BUF; i++) 
    line_buffer[i] = ' ';   

  line_buffer[HIDDEN_BUF + VIS_BUF] = 0;    


  for (int i = 0; i < WRD_BUF; i++) 
    word_buffer[i] = ' ';   

  word_buffer[WRD_BUF] = 0;  


 
  display.begin(SSD1306_SWITCHCAPVCC);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println(line_buffer + HIDDEN_BUF);
  display.display();
  
  Serial.begin(9600);  
  printer.begin();

  for (int i = 0; i < word_buffer; i++)
      printer.print(word_buffer[i]);   
    printer.print('\n');

}

void loop() {

  if (!keyboard.available()) return;


  char c = keyboard.read();         

  boolean newline = false;          


  if (c == PS2_ENTER) {
    newline = true;  

    for (int i = 0; i < 22 - row_len; i++)
      line_buffer[line_start + line_len + i] = ' ';
      line_len += 21 - row_len;
      row_len = 0;  
  } 
  else if (c == PS2_DELETE) {      
    if (line_len > 0) {              
      line_len--;                   
      line_buffer[line_start + line_len] = ' ';
      row_len--; 
      if (word_len > 0) 
      word_len--;  
    }
  }
 
  if (c >= 33 && c <= 126) {                 
    word_len++;
    line_buffer[line_start + line_len] = c;   
    word_buffer[word_len] = c;
    line_len++; 
    row_len++;                             
     }
     
  if (c == 32) {
    line_buffer[line_start + line_len] = c; 
    line_len++;
    for (int i = 0; i < 32; i++)
      word_buffer[i] = ' ';
    word_len = 0;
    row_len++;  
  }


  //word wrap
  if (word_len > 21 - (row_len - word_len) && row_len > 0){

    for (int i = row_len - word_len; i < 21; i++)
      g++;

//    for (int i = 0; i < word_len + 1; i++)
//    line_buffer[line_start + line_len - word_len + g - 1 + i] = word_buffer[i];  
    for (int i = 0; i < g; i++)
      line_buffer[line_start + line_len - word_len + i] = ' ';
    row_len = word_len;
    line_len += word_len - 1;
    g = 0; 
  }

  if (row_len == -1)
    neg++;

  if (word_len == 21)
    word_len = 0;

  if (neg > 0 && row_len == 0){

    if (word_len > 21 - (22 - word_len)){
   
    for (int i = 21 - word_len; i < 21; i++)
      g++;
//    for (int i = 0; i < word_len + 1; i++)
//      line_buffer[line_start + line_len - word_len + g - 1 + i] = word_buffer[i];  
    for (int i = 0; i < g; i++)
      line_buffer[line_start + line_len - word_len + i] = ' ';
    row_len = word_len;
    line_len += word_len - 0;
    g = 0; 
    neg = 0;
  }
  }
    

  // scroll up
  if (line_start + line_len > HIDDEN_BUF + VIS_BUF - 5) {                             
    for (int i = 0; i < HIDDEN_BUF + VIS_BUF - CHR_PER_LINE; i++)                    
      line_buffer[i] = line_buffer[i + CHR_PER_LINE];                                 
    for (int i = HIDDEN_BUF + VIS_BUF - CHR_PER_LINE; i < HIDDEN_BUF + VIS_BUF; i++)  
      line_buffer[i] = ' ';                                                           
    line_start -= CHR_PER_LINE;                                                       
  }                                            

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println(line_buffer + HIDDEN_BUF); 
  display.display();
}
#include <SPI.h>
#include <Wire.h>

#define LED_PIN 13

Pin 13 is the SPI Clock pin. You can't safely use the built-in LED if you use any SPI device.

Hmm, that doesn't seem to be a problem? I can run the program fine with that setup.

What I'm figuring out is I can't add any more char arrays.

When I try and make a new char array, the same result happens where if I try to use it the entire program will not work.

no1so:
I can't add any more char arrays.

When I try and make a new char array, the same result happens where if I try to use it the entire program will not work.

Where are you adding the array? You might be running out of dynamic memory.

pert:
Where are you adding the array? You might be running out of dynamic memory.

I am creating the char string where I defined the others: (char word_buffer[WRD_BUF + 1])

char line_buffer[HIDDEN_BUF + VIS_BUF + 1]; 
int line_start = HIDDEN_BUF;                
int line_len = 0;                           
int word_len = 0;
char word_buffer[WRD_BUF + 1];
int g = 0;
int row_len = 0;
int neg = 0;

and I am assigning values to it as the keys are pressed from PS/2 keyboard here:

if (c >= 33 && c <= 126) {                 
    word_len++;
    line_buffer[line_start + line_len] = c;   
    word_buffer[word_len] = c;
    line_len++; 
    row_len++;                             
     }

Where c is:

char c = keyboard.read();

so its going into both line_buffer and word_buffer.

this works fine when I am only trying to work on the OLED, but when I add the thermal printer library and SoftwareSerial no other char array works that I try to make besides line_buffer.

When I try and make a new char array, the same result happens where if I try to use it the entire program will not work.

When you compile your sketch, how much SRAM are you using?

At run time, how much memory are you using? Google FreeMemory, if you need to.

Hi @PaulS, thank you for your feedback.

I'm using about 50% of dynamic memory (SRAM?) when I compile my sketch so I thought that I would be okay. Mainly because the char arrays that I make have a predefined amount of variables, and when the program runs it just replaces characters (unless that adds up and takes SRAM?).

For example:

word_buffer[] =
 {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}

an array of 30 space characters

then when the code runs the spaces get replaced/overwritten with other characters continuously as new words are created.

word_buffer[] =
 {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', 's', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}

I've downloaded the library for FreeMemory but haven't been able to make it work within my sketch.

Do you think this could be the main issue? And if so, why is it not an issue when I omit the thermal printer code (libraries and such)?

Do you think this could be the main issue?

I think that you are running out of SRAM. If this is the issue you are talking about, yes, I do.

And if so, why is it not an issue when I omit the thermal printer code (libraries and such)?

Because that library uses SRAM, too. If you reduce the amount of SRAM needed, to below what is available, problems don't happen.

PaulS:
I think that you are running out of SRAM. If this is the issue you are talking about, yes, I do.
Because that library uses SRAM, too. If you reduce the amount of SRAM needed, to below what is available, problems don't happen.

Ok got it, thanks that makes sense.

I'm going to have to figure out specifically how to largely reduce the amount of SRAM my program uses, but are there any best practices or general suggestions I could use to improve my code and make it use less SRAM?