Hal text scrolled on Dmd

hello There!! Greetings!!

I am working on feedback machine project that is to be installed at a gas station to record customer feedback.

This system has a feedback machine having 20X4 LCD and a matrix keypad and runs on MEga2560. The mega is connected to another UNO via serial (115200) which inturn scrolls the feedbacks recorded on DMD (1X4).

I am attaching code of mega since it is too big to fit in the word limit and posting the UNO code here.

/*
#include <SPI.h>        //SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include <DMD.h>        
#include <TimerOne.h>   
#include "SystemFont5x7.h"
#include "Arial_black_16.h"

//Fire up the DMD library as dmd
#define DISPLAYS_ACROSS 4
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);
//number max of characters in your message
#define max_char 200
char message[max_char];    // stores you message

char r_char;               // reads each character
byte index = 0;            // defines the position into your array
int i;            

void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}

void setup(void)
{

   //initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
   Timer1.initialize( 5000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5s) and you can see flicker.
   Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
  
   //clear/init the DMD pixels held in RAM
   dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)
   Serial.begin(115200);
//strcpy(message,greeting);
}
void loop(void)
{
   //check if serial is avaible an before reading a new message delete's the old message
    
   if(Serial.available())
   {       
        for(i=0; i<199; i++){
            message[i] = '\0';
        } 
        //resests the index        
        index=0;
    }

    //while is reading the message 
    while(Serial.available() > 0){
       //the message can have up to 100 characters 
       dmd.clearScreen( true );
       if(index < (max_char-1)) 
       {         
           r_char = Serial.read();      // Reads a character
           message[index] = r_char;     // Stores the character in message array
           index++;                     // Increment position
          // message[index] = '\0';       // Delete the last position
             
       } 
   }
    
 //prepares the display to print our message
   dmd.selectFont(Arial_Black_16);
   //displays the message
   dmd.drawMarquee(message ,max_char,(32*DISPLAYS_ACROSS)-1 ,0);
   long start=millis();
   long timer=start;
   boolean ret=false;
   while(!ret)
   {
     if ((timer+30) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
}

My problem is whenever the scrolling begins it scrolls text only upto “service” parameter rest everything gets ignored it not scrolled on the DMD. I calculated the string length on mega side and it is of 94, So I used an array of 200 in UNO side. what changes do i need to make? Thaanks in Advance

sketch_may24b_BPCL_with_DMD_and_RTC_with_sprintf2.ino (12.8 KB)

You should be sending packets, with clearly defined start and end markers. You should be reading, and collecting, serial data until the end of packet marker arrives. When that end of packet marker arrives, you should change what is being scrolled.

Right now, you are collecting and scrolling all the serial data that is available at the moment you look (plus whatever arrives while you are reading the present data). That does NOT constitute a complete packet.

See: Serial Input Basics - updated - Introductory Tutorials - Arduino Forum

PaulS:
You should be sending packets, with clearly defined start and end markers. You should be reading, and collecting, serial data until the end of packet marker arrives. When that end of packet marker arrives, you should change what is being scrolled.

Right now, you are collecting and scrolling all the serial data that is available at the moment you look (plus whatever arrives while you are reading the present data). That does NOT constitute a complete packet.

See: https://forum.arduino.cc/index.php?topic=396450.0

i tried doing it earlier but I had to face some other problems like the parser on UNO parsed it but didn’t Scrolled it on DMD. I am attaching both the files for the refrenece please have look at it

FeedbackMachine_with_RtC_and_DMD_calculations_iteration_4.ino (14.3 KB)

DMD_receiver.ino (3.99 KB)

where m making a mistake? what do I need to change? any guesses?

PaulS:
You should be sending packets, with clearly defined start and end markers. You should be reading, and collecting, serial data until the end of packet marker arrives. When that end of packet marker arrives, you should change what is being scrolled.

Right now, you are collecting and scrolling all the serial data that is available at the moment you look (plus whatever arrives while you are reading the present data). That does NOT constitute a complete packet.

See: https://forum.arduino.cc/index.php?topic=396450.0

Since the code is very big I will post only that part which creates packets

void DmD()
{
  Serial1.print("<");
  Serial1.print("BPCL");
  Serial1.print(",");
  DateTime now = rtc.now();
  Serial1.print(now.day());
  Serial1.print(",");

  Serial1.print(now.month());
  Serial1.print(",");

  Serial1.print(now.year());
  Serial1.print(",");

  Serial1.print(TotalAirFB);//total air feedback recorded uptil now
  Serial1.print(",");
  
  Serial1.print(TotalToiletFB);// total air feedback recorded which is below appriciation level
  Serial1.print(",");

  Serial1.print(TotalServiceFB);
  Serial1.print(",");

  Serial1.print(Air_avg);
  Serial1.print(",");

  Serial1.print(toilet_avg);
  Serial1.print(",");

  Serial1.print(service_avg);
  Serial1.print(",");

  Serial1.print(total_avg);
  Serial1.println(">");

}

And this is the code at receiver side using UNO

sd#include "SPI.h"        
#include "DMD.h"        
#include "TimerOne.h"
#include "Arial_black_16.h" 

#define DISPLAYS_ACROSS 4
#define DISPLAYS_DOWN 1
DMD dmd( DISPLAYS_ACROSS , DISPLAYS_DOWN );

char incomingMessage[] = "Hello World, int1, int2, int3, int4, int5, int6, int7, int8, int9, int10";

const byte nbTokenExpected = 11;
char * ptrArray[nbTokenExpected]; // pointing at each token when we parse

const byte numChars = 135;
char receivedChars[numChars];
boolean newData = false;
bool success = false;

char scrollingText[135]; // big enough for what we want to do

void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}

void drawText( String dispString ) 
{
  Serial.println("1");
  dmd.clearScreen( true );
  dmd.selectFont( Arial_Black_16 );
  char newString[135];
  int sLength = dispString.length();
  dispString.toCharArray( newString, sLength+1 );
  dmd.drawMarquee( newString , sLength , ( 32*DISPLAYS_ACROSS )-1 ,0);
  long start=millis();
  long timer=start;
  long timer2=start;
  boolean ret=false;
  while( !ret ){
    if ( ( timer+50 ) < millis() ) {
      ret=dmd.stepMarquee( -1 , 0 );
      timer=millis();
    }
  }
}

  
bool parseIncomingMessage()
{
  char * strtokIndx;
  byte tokenCount = 1;


  for (byte i = 0; i < nbTokenExpected; i++) ptrArray[i] = NULL; // reset the list

  ptrArray[0] = (strtokIndx = strtok(incomingMessage, ","));
  while ((tokenCount < nbTokenExpected) && (strtokIndx != NULL)) {
    ptrArray[tokenCount++] = (strtokIndx =  strtok(NULL, ","));
  }

  if ((tokenCount == nbTokenExpected) && (strtokIndx != NULL)) {
    Serial.println("Got them all");
    for (byte i = 0; i < nbTokenExpected; i++) {
      Serial.print("ptrArray[");
      Serial.print(i);
      Serial.print("] --> \"");
      Serial.print(ptrArray[i]);
      Serial.println("\"");
      success = true;
    }
  }else {
    Serial.println("Not enough data");
  }
  return success;
}

void setup()
{
  Serial.begin(9600);
  Serial.println("Enter data in this style <HelloWorld, 12, 24.7>  ");
 }

void loop()
{
  recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(incomingMessage, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseIncomingMessage();
        showParsedData();
        drawText(scrollingText);
        newData = false;
    }
  }

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showParsedData()
{
  Serial.print("I got in the showParsedData Function");
  if (success == true) { // if we can successfully parse the message
    // then build our scrolling text
    char scrollingText[135]; // big enough for what we want to do

sprintf(scrollingText, "%s%s%s Total Feedback:%s Total Air:%s Total Toilet:%s Total Service:%s Average Air:%s Average Toilet:%s Average Service:%s Average total:%s",ptrArray[1],ptrArray[0],ptrArray[2],ptrArray[3],ptrArray[4],ptrArray[5],ptrArray[6],ptrArray[7],ptrArray[8],ptrArray[9],ptrArray[10]);

    Serial.println();
    Serial.println(scrollingText);
    Serial.print("The length of the scrolling text is ");
    Serial.println(strlen(scrollingText));
  }
}

I tried updating my codes with this but stilll stuck with the same problem

code at receiver

// Example 3 - Receive with start- and end-markers

#include <SPI.h>        //SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include <DMD.h>        
#include <TimerOne.h>   
#include "SystemFont5x7.h"
#include "Arial_black_16.h"

//Fire up the DMD library as dmd
#define DISPLAYS_ACROSS 4
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}


const byte numChars = 200;
char receivedChars[numChars];

boolean newData = false;

void setup()
{
      //initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
   Timer1.initialize( 5000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5s) and you can see flicker.
   Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
  
   //clear/init the DMD pixels held in RAM
   dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)

    Serial.begin(115200);
    Serial.println("<Arduino is ready>");
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}


void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        Serial.println(strlen(receivedChars));
        newData = false;
    }
}


void loop() {
    recvWithStartEndMarkers();
    showNewData();
    dmd.selectFont(Arial_Black_16);
   //displays the message
   dmd.drawMarquee(receivedChars ,200,(32*DISPLAYS_ACROSS)-1 ,0);
   long start=millis();
   long timer=start;
   boolean ret=false;
   while(!ret)
   {
     if ((timer+20) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
}