LED Won't display Real Text [Advanced Knowledge Required]

Hey everyone,
I’ve been working on this project and it’s giving me a headache right now. I have everything working perfectly except for one minor issue. I had LED strips set out 66x8 Neopixel strips connected on pins 22 through 29 PORTA of an Arduino Mega. I have a HC-06 Bluetooth connected to it along with everything else. I send data to the bluetooth and it sends it both to the serial monitor and the LED’s. However, instead of it being actual readable text, it just shows me lines and boxes. This might be a font error? I have no idea. I’ve tried everything in my knowledge to fix it. In the code, it says “getMessage” which is the String I use to get message inputted from my phone to the HC-06. I send actual messages like “hello”. But it just shows me boxes and lines. Everything else works.
I have the code attached as both txt or ino. Feel free to take a look.

Anything helps.
Thank you,
revengedeath.

LEDCONTROL2.ino (18.3 KB)

LEDCONTROL2.ino (18.3 KB)

Hi,
I presume this bit of code:

void loop() {
  // Check if a message has been received
    String msg = getMessage();
    if(msg!=""){
      Serial.println(msg);
    }

is meant to get a message from your software serial port and print it to the usual Serial port.
then the code seems to output whatever is in 'conn' to the display

Forget the LEDs for a while and just get your code to Serial.println() whatever message you want to appear on the LEDS.

This is completely wrong:

String getMessage(){
  String msg = "";
  
  while(mySerial.available()) {
      strcat(conn, mySerial.read());
      msg+=conn;
  }
  return msg;
}
  • the function strcat( dest, src ), adds the string 'src' to the end of 'dest'
    both 'dest' and 'src' must be 0-terminated strings ( not a single character from mySerial.read() )
  • "msg+=conn;" seems an attempt to add the whole of 'conn' to the end of 'msg'
    for every character read by mySerial.read()
  • you return 'msg', but then in 'loop()' you use 'conn'

Yours,
TonyWilk

Yes, i have a few loose stragelers in my code that i need tidying up but im literally stuck at this part of my code. Can you help me out by showing me what needs to be done?

Thank you.

  • the function strcat( dest, src ), adds the string 'src' to the end of 'dest'
    both 'dest' and 'src' must be 0-terminated strings ( not a single character from mySerial.read() )
  • "msg+=conn;" seems an attempt to add the whole of 'conn' to the end of 'msg'
    for every character read by mySerial.read()
  • you return 'msg', but then in 'loop()' you use 'conn'

I have also tried to strcat msg into bf using

strcat( bf, msg);

but it says it cannot convert String to a const char*. I've also tried to use strcpy, but I need the sp char to be right before the actual message.
Thanks again.

You can not strcat() a single character to a character array. Read Serial Input Basics - updated to get ideas how to populate a character array.

Also, why do you use SoftwareSerial if you have 3 extra hardware serial ports available on a Mega? Use Serial1, Serial2 or Serial3 for your HC-06 instead of mySerial.

PS
strcat works on strings (lower case s), not on Strings (uppercase S) or characters.

sterretje:
Also, why do you use SoftwareSerial if you have 3 extra hardware serial ports available on a Mega? Use Serial1, Serial2 or Serial3 for your HC-06 instead of mySerial.

I have plugged my bluetooth cables into TX1 and RX1 and am trying to use Serial1 i'm guessing, but I cannot figure out how to use the hardware serials to make it wait for a new "text" i enter through the bluetooth using my phone so that it displays on the LED's.

Thank you.

I have also made some changes. It now outputs whatever I write back to my phone's bluetooth terminal app. for example if I write "hello", it sends back "hello".
However, i don't know how to make this work with my LED's because my LED's only accept a char* instead of a string and i'm not sure how to convert it or anything.

Read the article I linked. Replace Serial in that article by Serial1 for the bluetooth.

Don't use String, use character arrays for everything, will make life a lot easier.

Hey man, I got everything to work, but it just concatenates onto the first string i send through the bluetooth. I want it to compeletely replace until i send another one.

revengedeath:
Hey man, I got everything to work, but it just concatenates onto the first string i send through the bluetooth. I want it to compeletely replace until i send another one.

It sounds like you need to clear what is there before and set the output position back to the start before writing to the display again. Are you sending any indication that a new message is being sent ?

Please post your code as it is now

UKHeliBob:
It sounds like you need to clear what is there before and set the output position back to the start before writing to the display again. Are you sending any indication that a new message is being sent ?

Please post your code as it is now

Yes, I have thought exactly about this, although I don’t know how to go about clearing the displays. If you can help, my project will have become complete. Thank you.
Attachments are my new code as of now.

LEDCONTROL2.ino (18.5 KB)

LEDCONTROL2.ino (18.5 KB)

I don't know how to go about clearing the displays.

How about sending a series of spaces or simply turning each LED off ?

I'm trying to accomplish this right now, but it keeps the receivedChars char. I cannot find a way to completely wipe everything inside the receivedChars char while keeping its numChars or technically its "buffer" as for example 500 or 30 or whatever.

UKHeliBob:
How about sending a series of spaces or simply turning each LED off ?

Ya I really cant figure it out. I've added another void called gggc that's supposed to clear all the pixels, but it still continues to loop the same text because it is stored within char bf. I need this char to be completely wiped basically each time i send a new code.

      receivedChars[ndx] = '\0'; // terminate the string

In your code this terminates the string, which is the right thing to do.

If you were to do this before receiving a new string

ndx = 0;
receivedChars[ndx] = '\0';

you would set the index back to zero and terminate the string at position zero. As far as the program is concerned it would be an empty string.

I've added another void called gggc

NO YOU HAVEN'T

You may have added a new function that does not return a value and is therefore of type void.

Please get the terminology right

UKHeliBob:

      receivedChars[ndx] = '\0'; // terminate the string

In your code this terminates the string, which is the right thing to do.

If you were to do this before receiving a new string

ndx = 0;

receivedChars[ndx] = '\0';



you would set the index back to zero and terminate the string at position zero. As far as the program is concerned it would be an empty string.

Ok. Thank you, but I'm still a little bit confused on where I should put

ndx = 0;
receivedChars[ndx] = '\0';

It's technically already in here.

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

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

or is it supposed to be like this.

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

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

You don't have to clear receivedChars. But you might want to clear your other buffers. And change the logic; only do your stuff when you have received a complete message (newData == true).

void loop()
{
  recvWithEndMarker();

  // check if a complete message was received
  if (newData == true)
  {
    // call showNewData here is necessary
    // showNewData();

    // clear the flag so we can receive a new message
    // this was done in showNewData
    newData = false;

    if (scrolling == true)
    {
      strcpy( bf, sp );
      strcat( bf, receivedChars );
      if (colorMode1 == true)
      {
        ggg1();
        ggg2();
        ggg3();
      }
      else
      {
        ggg4();
        ggg5();
        ggg6();
      }
    }
    else
    {
      strcpy( bf, receivedChars );
      gggf();
    }
  }
}

The call to showNewData() is not strictly necessary and I have removed it in the above. It's just a demo function and you should actually do the processing of the message in there. In the below example I have renamed it to processData.

void loop()
{
  recvWithEndMarker();

  // check if a complete message was received
  if (newData == true)
  {
    // process the data
    processData();
    // clear the flag so we can receive a new message
    // this was done in showNewData
    newData = false;
  }
}

void processData()
{
    if (scrolling == true)
    {
      strcpy( bf, sp );
      strcat( bf, receivedChars );
      if (colorMode1 == true)
      {
        ggg1();
        ggg2();
        ggg3();
      }
      else
      {
        ggg4();
        ggg5();
        ggg6();
      }
    }
    else
    {
      strcpy( bf, receivedChars );
      gggf();
    }
}

If you want to echo back the received message, do it in processData using Serial1.println(); if you want to see the message on serial monitor, do it in processData using Serial.println().

sterretje:
The call to showNewData() is not strictly necessary and I have removed it in the above. It's just a demo function and you should actually do the processing of the message in there. In the below example I have renamed it to processData.

void loop()

{
  recvWithEndMarker();

// check if a complete message was received
  if (newData == true)
  {
    // process the data
    processData();
    // clear the flag so we can receive a new message
    // this was done in showNewData
    newData = false;
  }
}

void processData()
{
    if (scrolling == true)
    {
      strcpy( bf, sp );
      strcat( bf, receivedChars );
      if (colorMode1 == true)
      {
        ggg1();
        ggg2();
        ggg3();
      }
      else
      {
        ggg4();
        ggg5();
        ggg6();
      }
    }
    else
    {
      strcpy( bf, receivedChars );
      gggf();
    }
}

Hey so I just tried this code and it uploads fine but when i try to send the text over bluetooth, the LED's don't light up at all now. With my example (my last post) it would work fine but would only show the last character of the entire text.

Maybe hook it up to serial monitor, add some serial.print statements and see what is happening?

void loop()
{
  recvWithEndMarker();

  // check if a complete message was received
  if (newData == true)
  {
    // process the data
    processData();
    // clear the flag so we can receive a new message
    // this was done in showNewData
    newData = false;
  }
}

void processData()
{
    Serial.println(receivedChars);

    memset(bf,0, sizeof(bf));

    if (scrolling == true)
    {
      strcpy( bf, sp );
      strcat( bf, receivedChars );
      if (colorMode1 == true)
      {
        ggg1();
        ggg2();
        ggg3();
      }
      else
      {
        ggg4();
        ggg5();
        ggg6();
      }
    }
    else
    {
      strcpy( bf, receivedChars );
      gggf();
    }
}
[/code,]
I've added a clearing of bf as well.

I'll try this in two days, unfortunately I accidentally shorted my HC-06.