Issue when displaying data from a text file to a 8x8 led matrix

edited May 2017 in Arduino

So i'm actually making a little project with arduino and processing. Basically i'm using a C++ program to draw on a 8x8 matrix. This program saves your drawing into a text file in this format :

  00000000
  00111000
  00010000
  00111000
  00000000
  00000000
  00000000
  00000000

And displays it to a led 8x8 matrix connected to an arduino.

So first in processing, I load this file into a string and then send it to the serial port line by line. Then in arduino i read the serial port and store the data into a string, i convert each line of this string to decimal for exemple if the value of string[0] is "00111100" the conversion will return 60. And then i store each decimals into the led matrix and display it.

The content of the text file is successfully displayed on the LED matrix but the issue is that after a few seconds, my entire drawing is shifting before returning to its place, it does not stay at the same place it should be. For exemple if i display the letter A this is the result (links to the pictures) : 'A' displayed | 'A' shifting

I think the issue is a synchronization problem between arduino and processing, processing sends the data in the text file continously and arduino doesn't read the correct data in time. But honestly i have no clue on how to fix that so i'm asking you guys help.

I might have to send only new data in Processing, for example we read the file if there is no new data we don't send anything to the serial port, if there is new data we send the new data to the serial port. I tried to create a second array that takes data from the string lines to compare it but it doesn't work because at each loop, the second array always equals to the first ...

Thank you for your time !

Here is my code :

Processing :

import processing.serial.*;
import java.io.*;
Serial myPort;

void setup() {
  //Make sure the COM port is correct
  myPort = new Serial(this, "COM5", 9600);
  myPort.bufferUntil('\n');
}

void draw() {
  String[] lines = loadStrings("matrice.txt");
  for (int a = 0 ; a < (lines.length) ; a++) {
    myPort.write(lines[a]);
    //println(lines.length);
  }
  delay(1000);
} 

Arduino :

unsigned char j;
unsigned char i;
unsigned char k;
unsigned char l;

String inChar[8];
String inCharTemp[8];
int ligne[8];

//Cablage du module (gnd et +V) utilise 3 pins
int Max7219_pinCLK = 10;
int Max7219_pinCS = 9;
int Max7219_pinDIN = 8;

//Définition des pixels a eclairer
//0-9 puis A-Z soit 10+26 = 36 caractères
char disp1[38][8];

//Autre exemple, caracteres speciaux (a definir soi meme)
//Voir explications sur http://tiptopboards.com/arduino_tutoriel/posting.php?mode=edit&f=2&p=6
//{0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55},  //damier1
// {0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA},  //damier2

//Ecriture d'un caractere 8x8
void Write_Max7219_byte(unsigned char DATA)
{
  unsigned char i;
  digitalWrite(Max7219_pinCS, LOW);
  for (i = 8; i >= 1; i--)
  {
    digitalWrite(Max7219_pinCLK, LOW);
    digitalWrite(Max7219_pinDIN, DATA & 0x80); // Extracting a bit data
    DATA = DATA << 1;
    digitalWrite(Max7219_pinCLK, HIGH);
  }
}

//Ecriture elementaire d une seule rangee
void Write_Max7219(unsigned char address, unsigned char dat)
{
  digitalWrite(Max7219_pinCS, LOW);
  Write_Max7219_byte(address);           //address,code of LED
  Write_Max7219_byte(dat);               //data,figure on LED
  digitalWrite(Max7219_pinCS, HIGH);
}

//Initialisation du module Max 7219
void Init_MAX7219(void)
{
  Write_Max7219(0x09, 0x00);       //decoding :BCD
  Write_Max7219(0x0a, 0x03);       //brightness
  Write_Max7219(0x0b, 0x07);       //scanlimit;8 LEDs
  Write_Max7219(0x0c, 0x01);       //power-down mode:0,normal mode:1
  Write_Max7219(0x0f, 0x00);       //test display:1;EOT,display:0
}

int convertir(String ligne)
{
  String sample_str = ligne;
  uint32_t result = 0;
  for (unsigned int i = 0; i < sample_str.length(); ++i)
  {
    result = result << 1;
    result = result | (sample_str[i] & 1);
  }
  return result;
}

//Le programme d affichage
void setup()
{
  //Pins a utiliser
  pinMode(Max7219_pinCLK, OUTPUT);
  pinMode(Max7219_pinCS, OUTPUT);
  pinMode(Max7219_pinDIN, OUTPUT);
  delay(50);  //Initialiser
  Serial.begin(9600);
  Init_MAX7219();
  for (int i = 0; i < 8; i++)
  {
    ligne[i] = 0;
  }
}

void loop()
{
  for (int a = 0; a < 8; a++)
  {
    for (int b = 0; b < 8; ++b)
    {
      if (Serial.available())
      {
        inChar[a] += Serial.read() - 48;

        ligne[a] = convertir(inChar[a]);
        Serial.println(ligne[a]);
      }
    }
  }

  // Boucle for qui assigne a chaque case de disp la ligne en décimal
  for (int a = 0; a < 38; a++)
  {
    for (int b = 0; b < 8; b++)
    {
      disp1[a][b] = ligne[b];
      inChar[b] = "";
    }
  }

  for (j = 0; j < 38; j++)
  {
    for ( i = 0; i < 9; i++)
    {
      Write_Max7219(i, disp1[j][i - 1]); // Affiche la matrice
    }
  }
}

Answers

  • edited February 2018

    This is a question that should be asked in an arduino forum. One thing I can see is that you send the data but it is not clear if you are sending a signal to tell when the data transmission has ended. You are also sending 8 bytes per line, times 8 lines, 64 bytes in total. You could send one byte per line, times 8 lines, a total of 8 bytes per file. However, to do that, you need to change your code. Before I attempt this quest, I have few of questions:

    Doesn't your arduino scream at you on your last arduino line?

    Write_Max7219(i, disp1[j][i - 1]);

    Notice i is looped from 0 to 9, so you are trying to access an invalid array position. To be explicit, if i=0 then Write_Max7219(0, disp1[j][ - 1]); so this is a bug in your program. Did you write this code yourself?

    Before making any big changes, I will suggest making this small change in the processing side: myPort.write(lines[a]); delay(20);

    Related to your comment:

    for example we read the file if there is no new data we don't send anything to the serial port, if there is new data we send the new data to the serial port. I tried to create a second array...

    I believe it is a good idea. However, since you are sending data every second, it should not be a problem and the ardunio should be able to handle the new data, even if there was no change. It will be a good exercise though.

    Could you also comment on how the data from processing (the 8x8 bytes) gets processed in your Ardunio loop? I was trying to figure out why you receive 8x8 bytes and then you do a nested loop of size 38 and 8.

    Kf

  • edited May 2017 Answer ✓

    Hi kfrajer, first thank you for your answer !

    I took the code from this website : >here

    I finally managed to make it work !!! You were right after looking the code from the website above, i saw that he uses a 38x8 array to display 0-9 and A-Z with a delay so a 38x8 is required. Since my drawing is only stored in one line, i changed the disp1 array to : char disp1[1][8];All the other loops where changed.

      for (int b = 0; b < 8; b++)
      {
        disp1[0][b] = ligne[b];
        inChar[b] = "";
    
      }
    
      for ( i = 1; i < 9; i++)
      {
    
        Write_Max7219(i, disp1[0][i - 1]); // Affiche la matrice
      }
    

    You were right for this part i forgot to start i from 1.

    I modified the processing code to send only new data this is the final code :

    import processing.serial.*;
    import java.io.*;
    Serial myPort;
    
    String[] lines = {
      "00000000", 
      "00000000", 
      "00000000", 
      "00000000", 
      "00000000", 
      "00000000", 
      "00000000", 
      "00000000", 
      ""
    };
    
    
    void setup() {
      //Make sure the COM port is correct
      myPort = new Serial(this, "COM5", 9600);
      myPort.bufferUntil('\n');
    }
    
    int counter=0;
    
    void draw() {
    
    
    
      String[] linesTemp =  loadStrings("C:/Users/Julien/Desktop/Pste 2 prototype final V2/matrice.txt");
    
      //println("lines: ",lines.length);
      //println("linesT: ",linesTemp.length);
    
    
      for (int a=0; a<(linesTemp.length); a++)
      {
    
        if (linesTemp[a].equals(lines[a]) == true)
        {
        } else {
    
          for (int b = 0; b<linesTemp.length; b++)
          {
    
            lines[b] = linesTemp[b];
            myPort.write(linesTemp[b]);
            //delay(15);
          }
          delay(1000);
        }
      }
    
      delay(1000);
    }
    

    Thanks you very much for you help kfrajer !! I pressed the button "this doesn't answer my question" but in fact it helped me a lot is there any way to change that?

    Here is a photo of the final result !

    C++ program Led matrix display)

  • @Taalik I am glad to hear you got it working there and that it was rather a simple solution. The final picture is just fantastic. Good luck!

    Kf

Sign In or Register to comment.