user14471: I faced a problem in my graduation project and I hope you can help me to solve it :)  

My project is connecting Arduino Uno to 16x32 Dot Matrix Display(DMD) and display messages on it from VB.net program. I wrote my VB.net program to convert the input text into 2D binary array. The number of columns depend on the text width.
as we know Arduino Uno SRAM is too small just 2 KBytes, so can't receive all the columns and display it.
I tried to receive 100 columns in the Arduino code and display it, then send star * to computer to receive the second 100 columns and display it and so on but it didn't work. I see the RX and TX of Arduino LEDs flicker but then nothing gets displayed on the DMD. 
Can anyone tell me where is the error part in the code, or if you have another idea to solve this problem :) 
VB.net Code for sending the 2D array ar(,)
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        SerialPort2.Open()
        Dim la As String
        If CheckBox1.Checked Then
            la = "arabic"
        Else
            la = "english"
        End If
        SerialPort2.Write("#" + cols.ToString + "#" + "*" + la + "*")
        Dim INDEX As Integer = 0

        While INDEX <= cols
            Dim see As String = SerialPort2.ReadLine().ToString()
            If see = "*" Then
                Dim BUFFER(16) As Byte
                For I = INDEX To INDEX + 100
                    If I < cols Then
                        For J = 0 To rows - 1
                            BUFFER(J) = ar(I, J)
                        Next
                        SerialPort2.Write(BUFFER, 0, 16)
                    End If
                Next
                INDEX += 100
            End If
        End While
        SerialPort2.Close()
End Sub

C++ Code for receiving 100 columns and display them:
#include <SPI.h>
#include <DMD2.h>

SoftDMD dmd(1,1);
void setup() {
  Serial.begin(9600);
  dmd.setBrightness(255); 
  dmd.begin();
}
long Wid;
void loop() {
  if(Serial.available()){
    String st = String(Serial.readString());
    Wid = (st.substring(st.indexOf('#')+1, st.lastIndexOf('#'))).toInt();
    //String Language = st.substring(st.indexOf('*')+1, st.lastIndexOf('*'));
  }
  long ind = Wid ;
  while(ind >= 0 ){
    Serial.println("*");
    if(Serial.available()>1 ){
      boolean pixls[16][100];
      getArray(pixls);
      displayArray(pixls);
      ind-=100;
    }
    if(ind >=Wid){
      ind = wid ;
    }
  }
}

void getArray(boolean arr[16][100]){
  byte serialData[16];  
  for(int k = 0 ; k < 100 ; k++){
    Serial.readBytes(serialData,16);
    for(int i = 0 ; i < 16 ; i++){
      arr[i][k]= serialData[i];
    }
  }
}


void displayArray(boolean arr[16][100]){
  for(int h = 0 ; h <= 100-33 ; h++){
    for (int i = 0 ,g=h; i < 32 ,g<h+32; i++ ,g++){
      for (int j = 0 ; j < 16 ; j++){
        dmd.setPixel(i,j,(arr[j][g] == 1) ? GRAPHICS_ON : GRAPHICS_OFF);
      }
    }  
    delay(100); 
  }
}

This VB code works for me when sending just 100 columns of the array:
SerialPort2.Open()

        Dim BUFFER(16) As Byte
        For J = 0 To 100
            For I = 0 To rows - 1
                BUFFER(I) = ar(J, I)
            Next
            SerialPort2.Write(BUFFER, 0, 16)
        Next
        SerialPort2.Close()

C++ code: 
#include <SPI.h>
#include <DMD2.h>
SoftDMD dmd(1,1);

void setup() {
  Serial.begin(9600);
  dmd.setBrightness(255);
  dmd.begin();
}
void loop() {
    boolean pixls[16][100];
    for(int i=0 ;i<100 ; i++){
      for(int j=0 ;j<16 ; j++){
        pixls[j][i]=0;
      }
    }
    if(Serial.available()>0){
      getArray(pixls); 
      for(int i=0 ; i<100 ; i++)
      {
        displayArray(pixls);
      }
    }
}
void getArray(boolean arr[16][100]){
  byte serialData[16];  
  for(int k = 0 ; k < 100 ; k++){
    Serial.readBytes(serialData,16);
    for(int i = 0 ; i < 16 ; i++){
      arr[i][k]= serialData[i];
    }
  }
}


void displayArray(boolean arr[16][100]){
  for(int h = 0 ; h <= 100-33 ; h++){
    for (int i = 0 ,g=h; i < 32 ,g<h+32; i++ ,g++){
      for (int j = 0 ; j < 16 ; j++){
        dmd.setPixel(i,j,(arr[j][g] == 1) ? GRAPHICS_ON : GRAPHICS_OFF);
      }
    }  
    delay(100); 
  }
}


user19409: You have likely run out of RAM.
The following use up large chunks of your SRAM:

pixls array = 1600 bytes
Serial = 170 bytes
DMD > 64 bytes 

This is in addition to all your other variables and function calls. 
The problem is that the compiler promotes boolean variables to bytes. So where you need 1600 pixels it takes 1600 bytes. Alternatively, you could pack 8 pixels into that byte. This method would only consume 200 bytes instead of 1600.
Also, I don't understand why you have a 16 by 100 array. From the code I can see that you are using a single DMD which has 32 pixels wide by 16 pixels high. Why send/buffer more pixels than needed? A single DMD would only need an array of 64 bytes. 
The Arduino Uno only has 2KB of SRAM.
Solutions:

I suggest sending the ASCII text to the Arduino and then letting the font library within SoftDMD convert it to pixels. That is why you are using the DMD2 library.

However if you want to stick to the approach you have taken: 

Pack 8 pixels into every byte in the array. This will save 1400 bytes of precious SRAM.
Only send one DMD word of data at a time. This will save 1536 bytes of precious SRAM.
You could use an Arduino with a greater amount of SRAM. 

Arduino Mega  - 8KB SRAM  
Arduino ZERO  - 32KB SRAM  
Arduino Due   - 96KB SRAM  
Arduino MKR 1000/1010/1400/ZERO - 32KB SRAM



user10794:   boolean pixls[16][100];

You are running out of RAM, amongst other possible problems.
That array alone takes 1600 bytes out of 2048 on the Uno. Since you are using Serial that also takes:

34 bytes for the HardwareSerial instance (Serial)
64 bytes for the Serial transmit buffer
64 bytes for the Serial receive buffer
4 bytes for the Serial transmit buffer head and tail pointers
4 bytes for the Serial receive buffer head and tail pointers

That's another 170 bytes.
SoftDMD dmd(1,1);

I presume that also uses RAM.
You need to rework. You don't need to store 100 bytes before displaying. How about reading each byte and displaying it? That saves almost 1600 bytes.

14471: <p>I faced a problem in my graduation project and I hope you can help me to solve it :)  </p>

<hr>

<p>My project is connecting Arduino Uno to 16x32 Dot Matrix Display(DMD) and display messages on it from VB.net program. I wrote my VB.net program to convert the input text into 2D binary array. The number of columns depend on the text width.
as we know Arduino Uno SRAM is too small just 2 KBytes, so can't receive all the columns and display it.</p>

<p>I tried to receive 100 columns in the Arduino code and display it, then send star <code>*</code> to computer to receive the second 100 columns and display it and so on but it didn't work. I see the RX and TX of Arduino LEDs flicker but then nothing gets displayed on the DMD. </p>

<p>Can anyone tell me where is the error part in the code, or if you have another idea to solve this problem :) </p>

<p><strong>VB.net Code for sending the 2D array <code>ar(,)</code></strong></p>

<pre><code>Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        SerialPort2.Open()
        Dim la As String
        If CheckBox1.Checked Then
            la = "arabic"
        Else
            la = "english"
        End If
        SerialPort2.Write("#" + cols.ToString + "#" + "*" + la + "*")
        Dim INDEX As Integer = 0

        While INDEX &lt;= cols
            Dim see As String = SerialPort2.ReadLine().ToString()
            If see = "*" Then
                Dim BUFFER(16) As Byte
                For I = INDEX To INDEX + 100
                    If I &lt; cols Then
                        For J = 0 To rows - 1
                            BUFFER(J) = ar(I, J)
                        Next
                        SerialPort2.Write(BUFFER, 0, 16)
                    End If
                Next
                INDEX += 100
            End If
        End While
        SerialPort2.Close()
End Sub
</code></pre>

<p><strong>C++ Code for receiving 100 columns and display them:</strong></p>

<pre><code>#include &lt;SPI.h&gt;
#include &lt;DMD2.h&gt;

SoftDMD dmd(1,1);
void setup() {
  Serial.begin(9600);
  dmd.setBrightness(255); 
  dmd.begin();
}
long Wid;
void loop() {
  if(Serial.available()){
    String st = String(Serial.readString());
    Wid = (st.substring(st.indexOf('#')+1, st.lastIndexOf('#'))).toInt();
    //String Language = st.substring(st.indexOf('*')+1, st.lastIndexOf('*'));
  }
  long ind = Wid ;
  while(ind &gt;= 0 ){
    Serial.println("*");
    if(Serial.available()&gt;1 ){
      boolean pixls[16][100];
      getArray(pixls);
      displayArray(pixls);
      ind-=100;
    }
    if(ind &gt;=Wid){
      ind = wid ;
    }
  }
}

void getArray(boolean arr[16][100]){
  byte serialData[16];  
  for(int k = 0 ; k &lt; 100 ; k++){
    Serial.readBytes(serialData,16);
    for(int i = 0 ; i &lt; 16 ; i++){
      arr[i][k]= serialData[i];
    }
  }
}


void displayArray(boolean arr[16][100]){
  for(int h = 0 ; h &lt;= 100-33 ; h++){
    for (int i = 0 ,g=h; i &lt; 32 ,g&lt;h+32; i++ ,g++){
      for (int j = 0 ; j &lt; 16 ; j++){
        dmd.setPixel(i,j,(arr[j][g] == 1) ? GRAPHICS_ON : GRAPHICS_OFF);
      }
    }  
    delay(100); 
  }
}
</code></pre>

<p><strong>This VB code works for me when sending just 100 columns of the array:</strong></p>

<pre><code>SerialPort2.Open()

        Dim BUFFER(16) As Byte
        For J = 0 To 100
            For I = 0 To rows - 1
                BUFFER(I) = ar(J, I)
            Next
            SerialPort2.Write(BUFFER, 0, 16)
        Next
        SerialPort2.Close()
</code></pre>

<p><strong>C++ code:</strong> </p>

<pre><code>#include &lt;SPI.h&gt;
#include &lt;DMD2.h&gt;
SoftDMD dmd(1,1);

void setup() {
  Serial.begin(9600);
  dmd.setBrightness(255);
  dmd.begin();
}
void loop() {
    boolean pixls[16][100];
    for(int i=0 ;i&lt;100 ; i++){
      for(int j=0 ;j&lt;16 ; j++){
        pixls[j][i]=0;
      }
    }
    if(Serial.available()&gt;0){
      getArray(pixls); 
      for(int i=0 ; i&lt;100 ; i++)
      {
        displayArray(pixls);
      }
    }
}
void getArray(boolean arr[16][100]){
  byte serialData[16];  
  for(int k = 0 ; k &lt; 100 ; k++){
    Serial.readBytes(serialData,16);
    for(int i = 0 ; i &lt; 16 ; i++){
      arr[i][k]= serialData[i];
    }
  }
}


void displayArray(boolean arr[16][100]){
  for(int h = 0 ; h &lt;= 100-33 ; h++){
    for (int i = 0 ,g=h; i &lt; 32 ,g&lt;h+32; i++ ,g++){
      for (int j = 0 ; j &lt; 16 ; j++){
        dmd.setPixel(i,j,(arr[j][g] == 1) ? GRAPHICS_ON : GRAPHICS_OFF);
      }
    }  
    delay(100); 
  }
}
</code></pre>
 19409: <p>You have likely run out of RAM.</p>

<p>The following use up large chunks of your SRAM:</p>

<ul>
<li><code>pixls</code> array = 1600 bytes</li>
<li>Serial = 170 bytes</li>
<li>DMD > 64 bytes </li>
</ul>

<p>This is in addition to all your other variables and function calls. </p>

<p>The problem is that the compiler promotes boolean variables to bytes. So where you need 1600 pixels it takes 1600 bytes. Alternatively, you could pack 8 pixels into that byte. This method would only consume 200 bytes instead of 1600.</p>

<p>Also, I don't understand why you have a 16 by 100 array. From the code I can see that you are using a single DMD which has 32 pixels wide by 16 pixels high. Why send/buffer more pixels than needed? A single DMD would only need an array of 64 bytes. </p>

<p>The Arduino Uno only has 2KB of SRAM.</p>

<p><strong>Solutions:</strong></p>

<ol>
<li><strong>I suggest sending the ASCII text to the Arduino and then letting the font library within SoftDMD convert it to pixels. That is why you are using the DMD2 library.</strong></li>
</ol>

<p>However if you want to stick to the approach you have taken: </p>

<ol start="2">
<li><p>Pack 8 pixels into every byte in the array. This will save 1400 bytes of precious SRAM.</p></li>
<li><p>Only send one DMD word of data at a time. This will save 1536 bytes of precious SRAM.</p></li>
<li><p>You could use an Arduino with a greater amount of SRAM. </p>

<ul>
<li>Arduino Mega  - 8KB SRAM  </li>
<li>Arduino ZERO  - 32KB SRAM  </li>
<li>Arduino Due   - 96KB SRAM  </li>
<li>Arduino MKR 1000/1010/1400/ZERO - 32KB SRAM</li>
</ul></li>
</ol>
 10794: <pre><code>  boolean pixls[16][100];
</code></pre>

<p>You are running out of RAM, amongst other possible problems.</p>

<p>That array alone takes 1600 bytes out of 2048 on the Uno. Since you are using Serial that also takes:</p>

<ul>
<li>34 bytes for the HardwareSerial instance (Serial)</li>
<li>64 bytes for the Serial transmit buffer</li>
<li>64 bytes for the Serial receive buffer</li>
<li>4 bytes for the Serial transmit buffer head and tail pointers</li>
<li>4 bytes for the Serial receive buffer head and tail pointers</li>
</ul>

<p>That's another 170 bytes.</p>

<pre><code>SoftDMD dmd(1,1);
</code></pre>

<p>I presume that also uses RAM.</p>

<p>You need to rework. You don't need to store 100 bytes before displaying. How about reading each byte and displaying it? That saves almost 1600 bytes.</p>
