Accepting input from Serial monitor to display it on DMD display

The Dot Matrix Display (DMD) is a 32x16 array of high-brightness LEDs for visually striking effects. [Product Page]
Post Reply
CrazzyElectron
Posts: 3
Joined: Sat Apr 13, 2019 4:46 am

Accepting input from Serial monitor to display it on DMD display

Post by CrazzyElectron » Mon May 06, 2019 6:42 am

Hello there!

I am working on project where I need to send the data to DMD from Serial monitor. I am using the code below.

Code: Select all

// Example 5 - Receive with start- and end-markers combined with parsing

#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 );

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

      // variables to hold the parsed data
char messageFromPC[numChars] = {0};
int integerFromPC = 0;
float floatFromPC = 0.0;

boolean newData = false;

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

//============

void setup() {
    Serial.begin(9600);
    Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
    Serial.println("Enter data in this style <HelloWorld, 12, 24.7>  ");
    Serial.println();
       Timer1.initialize( 5000 );           
   Timer1.attachInterrupt( ScanDMD );  
   dmd.clearScreen( true );            

}


void drawText( String dispString ) 
{
  dmd.clearScreen( true );
  dmd.selectFont( Arial_Black_16 );
  char newString[256];
  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();
    }
  }
}

//============

void loop() {
    recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        drawText(messageFromPC);
        delay(1000);
        drawText(integerFromPC);
        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 parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,",");      // get the first part - the string
    strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");
    floatFromPC = atof(strtokIndx);     // convert this part to a float

}

//============

void showParsedData() {
    Serial.print("Message ");
    Serial.println(messageFromPC);
    Serial.print("Integer ");
    Serial.println(integerFromPC);
    Serial.print("Float ");
    Serial.println(floatFromPC);

    String mac = String(integerFromPC);
    Serial.print("Mac:");
    Serial.println(mac);
}
The user is expected to enter the data to be displayed on DMD in following format
<HelloWorld,12, 99.9>. When I run the above sketch only "HelloWorld" can be seen scrolling through DMD. What changes do I need to make in my code so that I can get the remaining integer and float values on the Dmd as well. Any suggestions thanks in advance.

Brissieboy
Posts: 180
Joined: Fri Sep 20, 2013 7:25 am

Re: Accepting input from Serial monitor to display it on DMD display

Post by Brissieboy » Mon May 06, 2019 10:09 am

Convert the variables to a string then append them to your original string.

CrazzyElectron
Posts: 3
Joined: Sat Apr 13, 2019 4:46 am

Re: Accepting input from Serial monitor to display it on DMD display

Post by CrazzyElectron » Mon May 06, 2019 12:15 pm

I don't now if I am doing it right or not bt I tried that doing it in the function showparseddata(), with trying to convrt in integerFromPC to string using String mac = String(integerFromPC). if it is wrong then what should i be doing for it?

User avatar
stryker
Posts: 281
Joined: Sat Jan 14, 2012 2:44 pm

Re: Accepting input from Serial monitor to display it on DMD display

Post by stryker » Mon May 06, 2019 12:48 pm

Hi

The type of 'string' passed to the DMD drawMarquee() function is actually an array of char, rather than a String (with a capital S) type.

You'll see one simple method of printing numbers onto the DMD in the example sketch dmd_clock_readout. To convert the time to text is to take each digit in turn and add '0' to it, elevating it to the correct ASCII character to display. You could do something similar taking each digit and loading it into a character array, and passing that to drawMarquee. Remember to null terminate the string and pass the correct length.

Alternatively since you've already introduced the String type and have the number in there correctly formatted and ready to go, String types have a function c_str() which will produce the contents into a char array. Something like this...

Code: Select all

String mac = String(integerFromPC); // you already have this line
messageFromPC = mac.c_str(); // reusing the existing global variable
There are always multiple ways to skin a cat. But since you've already introduced the String and you're not up against memory limitations yet with the size of this code it might be the simplest way to go.

Cheers!
Geoff

Post Reply