DMD or P10 32x16 - UNO - Blue Tooth - Goto, Libraries and other Stuff.

Hi there, new member here,

First Post,
First Arduino project.
But I do have a lot of experience in many areas including electronics.

Background, I bought my first UNO R3 (clone) about three weeks ago, I have three now including an original Arduino-cc,
UNO and a lot of extras to play with.

So C or C++ is all Greek to me at the moment, though I have had past experience using modified BASIC but that was all
over 10 years ago, and I have trouble even working out WTH was that I wrote back there on that part of previous code ?.

Iv'e downloaded 8Gig or more of information and data sheets, pdf's, tutorials and saved hundreds of pages from forums
and similar web sites, And NO, most (95%) of it wasn't You-Tube videos, though I do have quite a few from places
like educ8s.tv, https://educ8s.tv/ and How To Mechatronics https://howtomechatronics.com/arduino-projects/ and others, although that
little Greek man does rush things a bit, but better than a bloated, bad video of uselessness.

So far, stumbling around blind I've managed to get a 2.8in Touch Screen working and playing my modified BMP files
off an SD Card, got an HC-05 Bluetooth module going, modified with AT commands, had a play with an 8x8 Dot Matrix
MAX2719 module. My first project attempt will be a DMD 32x16 panel sign with fixed and a Blue Tooth input.

The project I've chosen is based on Ashru Abhijit Pattnaiks web page, Wireless Notice Board (Arduino UNO + DMD) © GPL3+
https://create.arduino.cc/projecthub/abhijitbrain/wireless-notice-board-arduino-uno-dmd-9ff29e?ref=tag&ref_id=wireless%20communication&offset=1

And here's where I need help, as I still have not written a single line of original code yet and don't even understand
how most of the syntax is even formed or put together,Yet. I'll get there, slowly.
I'll paste the code below and explain along the way.

/*

-----------
 - Download the DMD library here: https://github.com/freetronics/DMD
 - Place the DMD library folder into the "arduino/libraries/" folder of your Arduino installation.
 - Get the TimerOne library from here: http://code.google.com/p/arduino-timerone/downloads/list
   or download the local copy from the DMD library page (which may be older but was used for this creation)
   and place the TimerOne library folder into the "arduino/libraries/" folder of your Arduino installation.
 - Restart the IDE.

*/

#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 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);
//number max of characters in your message
#define max_char 100
char message[max_char];    // stores you message
//char mess[max_char];
char r_char;               // reads each character
byte index = 0;            // defines the position into your array
int i;            
char greeting[] = "Abhijit Pattnaik";
/*--------------------------------------------------------------------------------------
  Interrupt handler for Timer1 (TimerOne) driven DMD refresh scanning, this gets
  called at the period set in Timer1.initialize();
--------------------------------------------------------------------------------------*/
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(9600);
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<99; 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();
     }
   }
}

Q: Is there a way to include Line Numbers inside the Code Tags above ?

Anyway if you look at that code in the IDE, on line 30, it says, char greeting[] = "Abhijit Pattnaik";
When the program runs you get that message repeated across the DMD panel.

But I wanted to include a second message or third or fourth or fifth e.g ~
char greeting1[] = "Hello World";
char greeting2[] = "Merry Christmas";
char greeting3[] = "Happy Halloween"; , etc.

Now, that first message will just repeat until it gets a different input from the Blue Tooth module, via a Phone App etc.
And then the DMD panel it will just repeat whatever was input via Bluetooth.

I wanted to jump out of the BT Loop and go back to the original message (or messages) and continue from there.
Looking at the code as is, it is not structured to do things that way, so I tried ~
A Label and a Goto, opps ! half the purists just fell of their chairs and the other half are reaching for their Heart Pills.

It didn't work, the compiler refused to accept a Label: saying " 'Label' does not name a type " or some other error.
1: I thought a Label: was valid syntax
and
2: goto Label; also, though despised by most.
Look I'm bare bones new at this and had it gotten me an end result that worked, I would have been happy.
I don't tell people what Religion or Football team to support so if "goto" had worked for me that's all that matters.

Anyway why didn't it work ?, I'm using IDE 1.8.9 and had seen examples of other instances using goto that seemed
to work so why was I getting errors ?. I tried inserting it inside the Loop, outside the Loop and 50 variations of.
Then I thought something may have changed in the IDE, so I went back to 1.6.12 but nothing changed.
I did rename my original Arduino Folders, so they were saved from the un-install, pre backdating to the older IDE.

So I'm asking (nicely) is there anyone willing to point out the correct direction I should be heading in to either
restructure the above code or modify it to suit what I need it to do and in very simple terms.
Use Comments, use lots of Comments so I can follow along and anyone else who may be learning also.
Please don't just plonk a solution on the screen and just say this will work, as I'll have learned nothing ~ :o)

To recap ~
I'd like to get the DMD to come On with a message or consecutive messages and repeat them.
(at the moment only a single message is available)
But if an input was provided from the Blue Tooth source it would then just repeat that message.
(up until now that all happens anyway)

What I need to do is to be able to jump back to the start message/s after any Blue Tooth message is received.
(this is where I need advice)

And I'm really curious to know why "goto" didn't work. Even though everybody hates the use of it.

And Library files, very annoying, half of them don't work or won't add to the collection due to some error,
but we won't go there for now.

After all of that I think I need a sandwich and a coffee.

And I promise not to make such a long post in the future.

Cheers, B0B

No, you cannot have line numbers in an embedded code block.

The message displayed appears to be controlled by this line in the setup code:

strcpy(message,greeting);

The function strcpy() is part of the standard library for the C language, look it up on the web and don’t move on until you understand what it does and C strings in general, they’re key for dealing with text strings on an Arduino.

As a side note, beware of the “String” class type (note the upper case S) that finds its way into Arduino code from the world of C++. While it may look like an easy way to deal strings, it will come back to haunt/bite you as it’s not practical for micro controllers with only a few thousand bytes of ram like most Arduinos. Stick with the classic C character arrays and learn the functions for dealing with them.

Earlier, I said “appears” to be because you only posted a portion of the actual code which is extremely bad form when posting code and then asking for help with that code. It’s akin to showing someone one page from a book then asking about the plot line. It just doesn’t work.

If you’re simply reusing exsisting code from a web posting without modification, post a link to the code rather than duplicating that code as it saves us from trying to figure out what you’ve possibly changed.

In your case, posting a fragment of code as you’ve done and then going on a rant about what you’ve tried that didn’t work without actually showing what didn’t work is pointless. No one can help with something they cannot see. Clairvoyant we’re not. We’re happy to help but we need to see the code to understand and explain why it doesn’t work.

Honestly, I doubt if anyone really cares if you use a goto. There are a few rare cases where it’s the best solution but this isn’t one of them. Most will just show or explain a better way to do the same thing. Given that you’ve stated what you’re attempting to do, pursuing a solution using a goto would just turn this into a classic x-y problem. Best to drop that line of thinking, it’s your Basic spaghetti code background popping out and it will not serve you well in the structured world of C and C++.

Hello BOB,

1.) We can't tell why your code doesn't work because you haven't posted it (the code that actually threw the compile-time error)
2.) You don't have to be a purist to hate gotos. Although I can't say that I hate them, in all the projects I've done, I've never had a reason to use them. Tbh, I only recently learned about them, and yeah...they're pretty useless

All that being said, we really need to see the sketch that's throwing the errors to be of use to you.

Thanks for the replies,

The Code I posted was the entire un-modified code from the web page linked.

I posted the entire code and the full web link and hyperlink for it, just in case people wanted to see what they were
actually clicking on, and for lazy people that couldn't be bothered even clicking. I tried to cover everyone.

At line 30 (in my IDE) is where the original Message is written.
But I want 2 or 3 or 4 Messages there that will display one-after-the other and then repeat, else if a blue tooth message
arrives.
Currently if and when a Blue Tooth message does arrive (loop), it replaces the original message and repeats it.
I want a way to make it go back to the original message or messages and display them and wait for any Blue Tooth input again.

I didn't post where I was having trouble with the Label: or goto Label; because it was everywhere that I tried to
insert it in that entire code, Up the top, Down the bottom, inside the Loop, outside the Loop it didn't matter, I got
the same error.
That's why I wondered if the usage of a, any, Label: or goto Label; had been removed from the IDE in some change
or revision. I get some sort of error always.

AdlAdsBoB:
I didn't post where I was having trouble with the Label: or goto Label; because it was everywhere that I tried to
insert it in that entire code, Up the top, Down the bottom, inside the Loop, outside the Loop it didn't matter, I got
the same error.
That's why I wondered if the usage of a, any, Label: or goto Label; had been removed from the IDE in some change
or revision. I get some sort of error always.

Pick the first place you tried it and post that code. Please.

I've recreated as best I could of what I was seeing as an error, But !
Here is the full original code, with my modifications, line 30 to 33 Label:, 57, 58 and goto Label; line 101. ~

/*

-----------
 - Download the DMD library here: https://github.com/freetronics/DMD
 - Place the DMD library folder into the "arduino/libraries/" folder of your Arduino installation.
 - Get the TimerOne library from here: http://code.google.com/p/arduino-timerone/downloads/list
   or download the local copy from the DMD library page (which may be older but was used for this creation)
   and place the TimerOne library folder into the "arduino/libraries/" folder of your Arduino installation.
 - Restart the IDE.

*/

#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 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);
//number max of characters in your message
#define max_char 100
char message[max_char];    // stores you message
//char mess[max_char];
char r_char;               // reads each character
byte index = 0;            // defines the position into your array
int i; 
This_Place:                                      // I added a Label "This_Place" here.        
char greeting[] = "Merry Christmas";             // This was originally "Abhijit Pattnaik"
//char greeting1[] = "Happy Halloween";          // My Added experimental text.
//char greeting2[] = "Happy Birthday";           // My Added experimental text.



/*--------------------------------------------------------------------------------------
  Interrupt handler for Timer1 (TimerOne) driven DMD refresh scanning, this gets
  called at the period set in Timer1.initialize();
--------------------------------------------------------------------------------------*/
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(9600);
strcpy(message,greeting);
//strcpy(message,greeting1);                  // My Added experimental text.
//strcpy(message,greeting2);                  // My Added experimental text.


}
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<99; 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();
goto This_Place;       
     }
   }
}

And the error I was getting was this ~

Arduino: 1.6.12 (Windows 7), Board: "Arduino/Genuino Uno"

sketch_jul06b:30: error: 'This_Place' does not name a type

 This_Place:                                      // I added a Label "This_Place" here.          

 ^

C:\Users\Username\AppData\Local\Temp\arduino_modified_sketch_574860\sketch_jul06b.ino: In function 'void setup()':

sketch_jul06b:56: error: 'greeting' was not declared in this scope

 strcpy(message,greeting);

                ^

C:\Users\Username\AppData\Local\Temp\arduino_modified_sketch_574860\sketch_jul06b.ino: In function 'void loop()':

sketch_jul06b:101: error: label 'This_Place' used but not defined

 goto This_Place;       

      ^

exit status 1
'This_Place' does not name a type

Here's the But !, until just now I didn't realize I was only seeing half of the error, the rest was above ^ ^ ^ and I missed it,
all I was seeing was this part ~

sketch_jul06b:101: error: label 'This_Place' used but not defined

 goto This_Place;    
      ^
exit status 1
This_Place' does not name a type

And now this code tag is telling me to go set verbose settings for a better result.
It never ends lol. That reminds me, I have to un-install 1.6.12 and put IDE 1.8.9 back on.

So my Label, This_Place; is not defined, and when I did try to define it, it threw up even more errors.
How do I define it correctly ?, will it even work then ? Am I using the correct syntax even, or is it simply
being used in the wrong place. I'm the beginner remember, and have no clue, but I'm giving it a go at least.

And I will go get those strcpy() notes, at a quick glance there are limitations to investigate it seems.

As I attempted to state in my original reply, pursuing the goto is complete waste of time and it has nothing to do with the stigma surrounding the use of the language feature. It’s like trying to run before you even know how to crawl.

Imagine tying to pound a square peg into a round hole, that’s all you’re doing. If and when it compiles, it’s got 99.999% chance it will not do what you want it to and you’ll be no further towards solving the problem than you are right now. You’re attempting to place a label in a data space which is meaningless. You already have the correct information to specify the text string with the identifier of “greeting” which has a type of a character with a length indirectly associated with it.

It’s very, very important to learn what a structured and strongly typed language like C (and even more so for C++) is all about. Basic is an unstructured language and many implementations are untyped. Since Basic is all you know, you have some unlearning to do as the things you learned with a language created in 1964 don’t translate well to what you attempting today, even though C is almost as old. But, it was created for different reasons and many aspects of its creation were to prevent the mess that Basic code becomes.

Attempting to understand why you’re unable to make goto compile at this stage of learning is completely without merit. If you want to do something useful, please tell us your perceived limitations with the strcpy function.

Placing a label here is a BIG no-no:

This_Place:                                      // I added a Label "This_Place" here.        
char greeting[] = "Merry Christmas";             // This was originally "Abhijit Pattnaik"
//char greeting1[] = "Happy Halloween";          // My Added experimental text.
//char greeting2[] = "Happy Birthday";           // My Added experimental text.

You should honestly learn how to use break statements and if statements. Using these two building blocks, you can add the functionality you desire - and in a way that is a whole lot easier to understand/follow than a goto.

Thanks,

Well I have no perceived Limitations of the strcpy function as I only ever heard of it yesterday.
First answer to my post was basically "go read about the strcpy() and don't come back until you know it"
And the first two pages I came across on the subject (probably here) were discussing the reasons not to use it
as it can have overflow ramifications. In fact I think I've even seen this on my project where mysterious text appeared.
I have an idea where it may have come from, but long story. Anyway I'll do some more research on the strcpy() subject.

And yes I will have to un-learn a lot of things, which will make it doubly hard for myself.

"Placing a label here is a BIG no-no:", maybe so, but that teaches me nothing.

If I'm teaching a newbie or even an oldbie to e.g., solder and they are screwing it up, you tell them why.

No you can't do that !, you are doing it wrong !, you'll destroy the PCB, you'll ruin that component, nothing learned.

An inspirational teacher would say ~
For small PCB work turn your Iron down, or you run the risk of lifting the PCB track or burning the component.
For Large connectors turn your Iron way up or you'll linger and overheat everything and get a dry joint anyway.
Use Flux or it will not stick properly and you may get a dry joint or breakaway later on.
Clean your Iron tip regularly or you may get a dirty or incomplete joint.
You can't solder Aluminium, it doesn't work, but there is special solder for a hundred bucks a roll that will.
You can only solder Stainless Steel with a very hot iron and sometimes you need special flux.
etc.

I'm going off to read up on stuff, int i;, what the hell does that even mean, sigh.

A wise person once said: "The quality of the answers reflect the quality of the question."

With that being said I will give you one piece of non-technical advice: ask succinct questions while providing all relevant pieces of information (again, with brevity).

AdlAdsBoB:
"Placing a label here is a BIG no-no:", maybe so, but that teaches me nothing.

Mainly because it's worthless to teach how to use gotos when I already mentioned that you should be using break statements and if statements instead.

You are a beginner in this wonderful language of C++. Start simple, build a solid foundation, then branch out.

Give it another shot with breaks/if statements and then, if things still fail, ask us again. Researching strcpy() is also a good idea.

I've found a better place to GoTo:

You're both Fired !
For such condescending attitudes and total lack of inspiration.

And I'm taking away 50 of your Karma points each.

AdlAdsBoB:
You're both Fired !
For such condescending attitudes and total lack of inspiration.

Someone's a hypocrite, lol.