Sending data to Arduino from Visual Studio C#

I need some help because I don't know what to do. The concept of my project is to send a data from VS to Arduino to get the current date so I can print it in a thermal printer connected to arduino. I am able to print the date directly but I want to store this information to the Arduino through SerialPort when the program starts.

port.Write("#TEXT" + System.DateTime.Now.ToString("yyyy/MM/dd") + "#\n");

How can I make the arduino store it in a variable so I can print the current date?
Here is my code for Arduino:

#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"

#define TX_PIN 13 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 12 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor


String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String commandString = "";

boolean isConnected = false;

void setup() {
  Serial.begin(19200);
  mySerial.begin(19200);
  printer.begin();
}

void loop() {

if(stringComplete)
{
  stringComplete = false;
  getCommand();
  
  if(commandString.equals("STAR"))
  {
    printer.println("Starting...");
  }    
  else if(commandString.equals("TEXT"))
  {
    String text = getTextToPrint();
    printText(text);
  }
  inputString = "";
}
}

void getCommand()
{
  if(inputString.length()>0)
  {
     commandString = inputString.substring(1,5);
  }
}

String getTextToPrint()
{
  String value = inputString.substring(5,inputString.length()-2);
  return value;
}

void printText(String text)
{
    if(text.length()<16)
    {
      printer.feed();
      printer.justify('C');
      printer.setSize('M');
      printer.println(text);
      printer.feed();
      printer.feed();
      printer.feed();
      printer.feed();
      printer.feed();
      printer.feed();
    }
}

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

And here is my code for my Visual Studio.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace ComputerToArduino
{
    public partial class Form1 : Form

    {
        bool isConnected = false;
        String[] ports;
        SerialPort port;

        public Form1()
        {
            InitializeComponent();
            disableControls();
            getAvailableComPorts();

            foreach (string port in ports)
            {
                comboBox1.Items.Add(port);
                Console.WriteLine(port);
                if (ports[0] != null)
                {
                    comboBox1.SelectedItem = ports[0];
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (!isConnected)
            {
                connectToArduino();
            } else
            {
                disconnectFromArduino();
            }
        }

        void getAvailableComPorts()
        {
            ports = SerialPort.GetPortNames();
        }

        private void connectToArduino()
        {
            isConnected = true;
            string selectedPort = comboBox1.GetItemText(comboBox1.SelectedItem);
            port = new SerialPort(selectedPort, 19200, Parity.None, 8, StopBits.One);
            port.Open();
            button1.Text = "Disconnect";
            enableControls();
        }

        private void disconnectFromArduino()
        {
            isConnected = false;
            port.Close();
            button1.Text = "Connect";
            disableControls();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (isConnected)
            {
                port.Write("#TEXT" + System.DateTime.Now.ToString("yyyy/MM/dd") + "#\n");
            }
        }

        private void enableControls()
        {
            button2.Enabled = true;
            groupBox3.Enabled = true;

        }

        private void disableControls()
        {
            button2.Enabled = false;
            groupBox3.Enabled = false;
        }
        

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

Also, I need help with sending data the other way around. I want to send data from the arduino to VS and store it in a variable.

I really need help. I am sending a string consisting of the current date from Visual Studio C# and print it in my thermal printer. When I click the VS button, it should send the date to the Arduino. But when the Arduino receives it, it only saves it once and removes it after the loop. I have to click the button again to print out the date. I really need help as to how to save the string in the Arduino without always clicking the button. I only want to use the button as some sort of updater for the date. When I want to click the button, it should remove the old date data and save the new date data. I really need help. I don't know what to do.

#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"

#define TX_PIN 13 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 12 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String commandString = "";

boolean isConnected = false;

String textOLD = "";

// Radio Buttons!
const int button1 =  2;
const int button2 =  3;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;

//for numbers to increment
int numberCECST = 1;
int numberCEBM = 1;

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    { 
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() { 
  pinMode(button1, INPUT);  
  pinMode(button2, INPUT);         
  
  //Thermal====
  Serial.begin(19200);
  mySerial.begin(19200);
  printer.begin();
}

void loop() {
  stringComplete = false;
  getCommand();
  String text = getTextToPrint(); 
  // Select LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
      Serial.print("CECST number ");
      Serial.print(numberCECST);
      Serial.print("\n");
      Serial.println(text);
       
      printer.justify('C');
      printer.setSize('M');
      printer.feed();
      printer.println("CECST");
      printer.justify('C');
      printer.setSize('M');
      printer.println("NUMBER:");
      printer.justify('C');
      printer.setSize('M');
      if (numberCECST<100) printer.print('0');
      if (numberCECST<10) printer.print('0');
      printer.println(numberCECST);
      numberCECST++;
      printer.feed();printer.feed(); 
      printer.feed();
      printer.println(text);
      printer.feed();printer.feed();
      printer.feed();printer.feed();
      printer.feed();
      delay(500);
      inputString = "";      
      textOLD = text;
  }
  
  // Select LED if button debounced
  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )){
    Serial.print("CEBM number");
    Serial.print(numberCEBM);
    Serial.print("\n");    
    Serial.println(text);
        
    printer.justify('C');
    printer.setSize('M');
    printer.feed();
    printer.println("CEBM");
    printer.justify('C');
    printer.setSize('M');
    printer.println("NUMBER:");
    printer.justify('C');
    printer.setSize('M');
    if (numberCEBM<100) printer.print('0');
    if (numberCEBM<10) printer.print('0');
    printer.println(numberCEBM);
    numberCEBM++;
     printer.feed();
    printer.feed();
    printer.feed();
    printer.println(text);
    printer.feed();
    printer.feed();
    printer.feed();
    printer.feed();
    printer.feed();
    delay(500);    
    inputString = "";    
    textOLD = text;
  }
}
void getCommand()
{
  if(inputString.length()>0)
  {
     commandString = inputString.substring(1,5);
  }
}
String getTextToPrint()
{
  String value = inputString.substring(5,inputString.length()-2);
  return value;
}

void printText(String text)
{
    if(text.length()<16)
    {
      printer.feed();
      printer.justify('C');
      printer.setSize('M');
      printer.println(text);
      printer.feed();
    }
}

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

Thank you in advance.

Do you know how to use char arrays to store text strings rather than wastey, no-goo heap shotgunning String objects?

Because for me, reading serial text into globally defined char arrays is a no-brainer and the data stays.

Strings may be okay on PC's with tons of RAM but on systems with 64K or less RAM I've found that they SUCK RAM.

Beyond that --- char arrays allow me complete access to my text data in ways that String would rather I could not so they SUCK there too!

So an array of char is the way to go? I'm kinda new with Arduino so I have no idea how to handle strings in Arduino. So how do I approach it?

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

The parse example makes a copy of the received string before parsing it. You can use the technique for other purposes.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

You have an idea and way to handle text in Arduino. It is just a way that will limit what you can do with Arduino.
I'd like you to be aware of that and working to save yourself from becoming time-invested in such a method.

A C string is a char array with ASCII text chars stored in the elements with a string-terminator element with value = 0.

char myStr[ 20 ] = "this is text";

In the myStr array the values are

myStr[0] == 't' // evaluates to a number but 't' is easier to read
myStr[1] == 'h'
myStr[2] == 'i'
myStr[3] == 's'
myStr[4] == ' '
myStr[5] == 'i'
.....
myStr[10] == 'x'
myStr[11] == 't'
myStr[12] == 0 // as in zero, NULL, end of string, you can print this array using Serial.print()

myStr[13] to myStr[19] --- it does not matter what is in these elements, that 0 ends the string.
HOWEVER -- since I made the array with 20 elements I can change the string to be up to 19 text values plus the 0.

I can get at any element by its number, [0] to [19]. Copy, write over, compare, whatever, they're just char variables that I can do char things with and I have total freedom in that. Simple, simple, simple.

If you're not up on arrays I suggest that you spend time arming yourself with such knowledge. You can make arrays of arrays, have multiple strings that you can address which string by number as well as which element of that string by number.

I look at your code and see you're not up to the do many things at once phase, that cuts the tutorial page I'd link you to.
Sorry, here's the link but I think you might not be ready for reading w/o blocking.

The many things at once lesson that explains the basic of non-blocking in simple terms:

I'd go the 2nd one first to have a solid footing. The lesson itself is very powerful in that it teaches how to not write slow code in a simple way.

The read serial w/o blocking page has a state machine example. You use one in your debounce routine. That is the next key to automating right after not blocking.

Okay... Now I understand how strings work for Arduino. Apparently, I've been straining my Arduino by making it carry a heavy load :frowning: . I changed the string variable to an array that can hold char data. But the data wont last. After I clicked the button and printed my output by pressing a button, the date will show. But if I print another output again, the date is gone. How can I make the data stay there, like make the date available as I print more papers without clicking the button again?

Dan015:
How can I make the data stay there, like make the date available as I print more papers without clicking the button again?

You need to post the latest version of your program so we can see exactly what you have done.

...R

Oh. My bad. I forgot to insert the updated code.

#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"

#define TX_PIN 13 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 12 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

const byte numberArray = 32; //Array Size
char receivedChars[numberArray]; //Variable that stores the char

boolean new_Data = false;

// Radio Buttons!
const int button1 =  2;
const int button2 =  3;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;

//for numbers to increment
int numberCECST = 1;
int numberCEBM = 1;

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    { 
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() { 
  pinMode(button1, INPUT);  
  pinMode(button2, INPUT);         
  
  //Thermal====
  Serial.begin(19200);
  mySerial.begin(19200);
  printer.begin();
}

void loop() {
  recieveDate();
  // Select LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
      Serial.print("CECST number ");
      Serial.print(numberCECST);
      Serial.print("\n");
       
      printer.justify('C');
      printer.setSize('M');
      printer.feed();
      printer.println("CECST");
      printer.justify('C');
      printer.setSize('M');
      printer.println("NUMBER:");
      printer.justify('C');
      printer.setSize('M');
      if (numberCECST<100) printer.print('0');
      if (numberCECST<10) printer.print('0');
      printer.println(numberCECST);
      numberCECST++;
      printer.feed();printer.feed(); 
      printer.feed();printer.feed();
      showDate();
      printer.feed();printer.feed();
      printer.feed();printer.feed();
      delay(500);    
  }
  
  // Select LED if button debounced
  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )){
    Serial.print("CEBM number");
    Serial.print(numberCEBM);
    Serial.print("\n");    
        
    printer.justify('C');
    printer.setSize('M');
    printer.feed();
    printer.println("CEBM");
    printer.justify('C');
    printer.setSize('M');
    printer.println("NUMBER:");
    printer.justify('C');
    printer.setSize('M');
    if (numberCEBM<100) printer.print('0');
    if (numberCEBM<10) printer.print('0');
    printer.println(numberCEBM);
    numberCEBM++;
    printer.feed();printer.feed();
    printer.feed();printer.feed();
    showDate();
    printer.feed();printer.feed();
    printer.feed();printer.feed(); 
    delay(500);
  }
}

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

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

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

void showDate() {
    if (new_Data == true) {
        printer.println(receivedChars);
        new_Data = false;
    }
}

Its basically the communication in your form with the one that start and end markers.

You seem to have made changes to my code. In general I don't care what you do with it, but if you want it to work then follow the maxim "if it works don't fix it"

Also, it is much easier to help when the code is unchanged.

And I suggest that you start testing your communication with my program and with none of your project code added. When the communication works you can then start adding in the other stuff.

...R
PS ... you need to brush up your spelling - especially when you are copying the word "receive" incorrectly.

Dan015:
Okay... Now I understand how strings work for Arduino. Apparently, I've been straining my Arduino by making it carry a heavy load :frowning: .

Don't be a clown. I gave you the reasons why, biggest is that it will limit what you can do with Arduino.

port.Write("#TEXT" + System.DateTime.Now.ToString("yyyy/MM/dd") + "#\n");

Serial text takes a while for each character to transfer at 10 bits sent 1 at a time per char. Arduino moves hundreds to more than a thousand times faster than even 115200 baud serial. When you serial print the text you want to send goes into a circular buffer that gets 1 char at a time sent from while your code can fill that 64 char buffer in nothing flat.
So instead of "needing" to concatenate a big string in a buffer array then print it to the serial buffer it's much easier to print each part in sequence and let print buffer the text for you.

Doing this will run faster than pre-buffering a string to print by the time it takes to pre-buffer.

port.Write("#TEXT");
port.Write(System.DateTime.Now.ToString("yyyy/MM/dd");
port.Write("#\n");

It's better to not overthink these things. Take a simple view and see what is actually necessary.

Your updated code is has loads of execution-blocking code. How do you expect to catch and debounce button presses with all those delays and closed loops? Oh yeah, they take turns?
I gave you a link to the answers already.

I apparently did it. Idk why but the new_Data was the one screwing me. In the showDate() and in recieveDate(), I removed them. But I don't know why it worked. And now, I can print the date when I press the buttons as long as I clicked the button to send the date.

#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"

#define TX_PIN 13 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 12 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

const byte numberArray = 32; //Array Size
char receivedChars[numberArray]; //Variable that stores the char

boolean new_Data = false;

// Radio Buttons!
const int button1 =  2;
const int button2 =  3;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;

//for numbers to increment
int numberCECST = 1;
int numberCEBM = 1;

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(button1, INPUT); 
  pinMode(button2, INPUT);         
 
  //Thermal====
  Serial.begin(19200);
  mySerial.begin(19200);
  printer.begin();
}

void loop() {
  // Select LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
      recieveDate();
      Serial.print("CECST number ");
      Serial.print(numberCECST);
      Serial.print("\n");
       
      printer.justify('C');
      printer.setSize('M');
      printer.feed();
      printer.println("CECST");
      printer.justify('C');
      printer.setSize('M');
      printer.println("NUMBER:");
      printer.justify('C');
      printer.setSize('M');
      if (numberCECST<100) printer.print('0');
      if (numberCECST<10) printer.print('0');
      printer.println(numberCECST);
      numberCECST++;
      printer.feed();printer.feed();
      printer.feed();printer.feed();
      showDate();
      printer.feed();printer.feed();
      printer.feed();printer.feed();
      delay(500);   
  }
 
  // Select LED if button debounced
  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )){
    recieveDate();
    Serial.print("CEBM number");
    Serial.print(numberCEBM);
    Serial.print("\n");   
       
    printer.justify('C');
    printer.setSize('M');
    printer.feed();
    printer.println("CEBM");
    printer.justify('C');
    printer.setSize('M');
    printer.println("NUMBER:");
    printer.justify('C');
    printer.setSize('M');
    if (numberCEBM<100) printer.print('0');
    if (numberCEBM<10) printer.print('0');
    printer.println(numberCEBM);
    numberCEBM++;
    printer.feed();printer.feed();
    printer.feed();printer.feed();
    showDate();
    printer.feed();printer.feed();
    printer.feed();printer.feed();
    delay(500);
  }
}

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

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

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

void showDate() {
        printer.println(receivedChars);
}

GoForSmoke:
It's better to not overthink these things. Take a simple view and see what is actually necessary.

Thanks for the tip. Yeah I stared at the code for hours trying to visualize the flow.

Robin2:
Also, it is much easier to help when the code is unchanged.

Sorry if I made some changes. I usually misread variables so I try to change them to something clearer. I'm really sorry.

Also, thank you for bearing with me even and for the trouble that I may have caused. I am very grateful. Also, thanks for the links. I bookmarked them in-case I want to touch serial communications again.

What may help is to trace the flow using print statements. You want to know which path of an if-else executed, print '@' in one branch and '&' in the other then watch serial monitor during a run. We call those debug prints.

Dan015:
I apparently did it. Idk why but the new_Data

Maybe when you added to the program you did not reset newData back to false at the correct place? That should happen after you have used the data, or taken a copy of it. As soon as it is set to false there is a risk that it will be overwritten by a new message.

...R