[solved]save string read from serial com into eeprom

hi, Arduino forum

for a project of mine with an esp32, I would like to read a string (in mine case a mac address) from serial monitor and copy that into EEPROM.
once the esp32 reboots or starts up looks for this mac address in EEPROM and stores it in a var. so the esp32 could later send to that mac address.

I'm new to reading from serial and storing it for later retrieval.
where is a great place to start?
i already have experience with espnow so that isn't an issue.

Do it in two stages.
Read the 6 byte mac address into a variable via the serial console:
https://forum.arduino.cc/index.php?topic=396450.0

Then see this library "Preferences" for the EEPROM equivalent in ESP8266:

Thank you 6v6gt for that information.
the first thing I have tried is changing example 3 to my liking.
I don't fully understand how the "Preferences" library would work. it's a bit over my head.
so added EEPROM commands for reading and writing to EEPROM.
tried it to compile it but got a:

invalid conversion from 'char*' to 'uint8_t {aka unsigned char}'

I know what it means. i can't get my head around how to convert a char to an int. I
s here where the "Preferences" library comes into play?

// the current address in the EEPROM (i.e. which byte
// we're going to write to next)
#include "EEPROM.h"
int addr = 0;
#define EEPROM_SIZE 32


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

boolean newData = false;

void setup() {
  Serial.begin(115200);
  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }

  Serial.print("this has been written to EEPROM");
  Serial.println(EEPROM.read(0));
  Serial.println();
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
}

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.print("writing to EEPROM");
    EEPROM.write(0, receivedChars);
    EEPROM.commit();
    delay(100);

    Serial.print("this has been written to EEPROM");
    Serial.println(EEPROM.read(0));
    newData = false;
  }
}

so I wanted to do a little update. (also linked the code below.

I have come further with saving the mac address to EEPROM and later retrieving it. This is now successful without checking if the mac address is valid. send a example mac address with ma:cA:dr:es:s1

the next challenge I can't really wrap my head around it.

get this example mac address (B4:E6:2D:FB:29:31) into this array:

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

I'm a bit thrown off with how to get the mac numbers or/ and letters where FF are placed.

saveMacAddressEEPROM.ino (3.93 KB)

Robin's Serial Input Basics also contains an example parsing received data using strtok(); in your case you need to split on the colon ( : ).

Next you can use strtoul() to convert each result of strtok() to the number and store it in successive elements of broadcastAddress.

Hi sterretje
I kinda get what you're trying to say but I don't really know how to use these functions.
Is it possible that I could get an example?

in your case, you need to split on the colon "( : )"

so how could the code "identify" a colon? use a for loop in combination with an if statement?

Look at Robin's example how he splits on the comma using strtok instead of on the colon.

Try it out and see if you can print the numbers. After that we can help you further.

Here is another example that is going to be more in line with what you need and splits on dash.

Please note that it was written for a PC so you need to replace

printf( " %s\n", token );

by

Serial.println(token);

hi,

i have got it almost working. entered the mac address and got a "loadprohibited" and strtoul() is causing it.
it's probably a wrong address pointer.
the only thing i have added to the code is this void:

char *token;
char *ptr;

void axe() {  
int a = 0;//counter for printing what's inside broadcastAddress[]
  const char s[2] = ":";

  /* Serial.print("before STRTOK: ");
    for(int i; i< 6; i++) Serial.print(broadcastAddress[i]);
    Serial.println(" before STRTOK");*/

  /* get the first token */
  token = strtok(read_eeprom, s);

  /* walk through other tokens */
  while ( token != NULL ) {

    Serial.println(token);
    token = strtok(NULL, s);

    broadcastAddress[a] = strtoul(token, &ptr, 2);// here is where the LoadProhibited is comming from.
    Serial.print(a);   Serial.print(" ");
    Serial.println(broadcastAddress[a]);
    a++;
  }
  /* Serial.print("after STRTOK: ");
     for(int i; i< 6; i++) Serial.print(broadcastAddress[i]);
     Serial.println(" after STRTOK");*/

  Serial.print("Choping it up done"); * /
}

i have found something else than EEPROM, SPIFFS. this could be much easier and its almost the same as eeprom.
this way the esp32 could save the mac address in a text doc.
this option is also there.

Can you post your complete code?

    broadcastAddress[a] = strtoul(token, &ptr, 2);// here is where the LoadProhibited is comming from.

The two indicates base 2, so binary text representation. Change that to 16 (hex text representation) as shown below

    broadcastAddress[a] = strtoul(token, &ptr, 16);// here is where the LoadProhibited is comming from.

Note: I don't have an ESP so can only verify / demonstrate with AVR code.

yeah sorry, let me upload the complete code!

sterretje:
Note: I don't have an ESP so can only verify / demonstrate with AVR code.

no problem then if I would use spiffs I would move to the esp32 forum. but first, let's get this code working!

saveMacAddressEEPROM.ino (4.96 KB)

Your code is small enough to fit inside a post; please only attach if your code is over approx. 9000 characters.

#include "EEPROM.h"
//#include <WiFi.h>
//#include <esp_now.h>

#define EEPROM_SIZE 32


const byte numChars = 32;
char receivedChars[numChars];
char read_eeprom[numChars];
char MacAddress[numChars];
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//B4:E6:2D:FB:29:31 and sending works just fine.


//uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};


boolean newData = false;
//void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status);
  char *token;
  char *ptr;

void axe() {
  int a = 0;//counter for printing what's inside broadcastAddress[]
  const char s[2] = ":";

  /* Serial.print("before STRTOK: ");
    for(int i; i< 6; i++) Serial.print(broadcastAddress[i]);
    Serial.println(" before STRTOK");*/

  /* get the first token */
  token = strtok(read_eeprom, s);

  /* walk through other tokens */
  while ( token != NULL ) {

    Serial.println(token);
    token = strtok(NULL, s);

    broadcastAddress[a] = strtoul(token, &ptr, 2);// here is probably where the LoadProhibited is comming from.
    Serial.print(a);   Serial.print(" ");
    Serial.println(broadcastAddress[a]);
    a++;
  }
  /* Serial.print("after STRTOK: ");
     for(int i; i< 6; i++) Serial.print(broadcastAddress[i]);
     Serial.println(" after STRTOK");*/

  Serial.print("Choping it up done");
}



void setup() {
  Serial.begin(115200);
  delay(6000);

  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }



  EEPROM.get(0, MacAddress);
  Serial.print("this has been written to EEPROM ");
  Serial.println(MacAddress);

  /*
    //Setting some espNOW stuff up.
    WiFi.mode(WIFI_STA);
    initESPNow();
    esp_now_register_send_cb(OnDataSent);
    Serial.print("STA MAC: ");  Serial.println(WiFi.macAddress());

    esp_now_register_send_cb(OnDataSent);





    // Register peer
    esp_now_peer_info_t peerInfo;
    memcpy(peerInfo.peer_addr, broadcastAddress, 6);
    peerInfo.channel = 0;
    peerInfo.encrypt = false;

    // Add peer
    if (esp_now_add_peer(&peerInfo) != ESP_OK) {
      Serial.println("Failed to add peer");
      return;
    }*/
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
}

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;
    }
  }
}
int Read = 12;
void showNewData() {
  if (newData == true) {

    Serial.print("I recieved this: ");
    Serial.println(receivedChars);

    Serial.println("writing to EEPROM ");
    EEPROM.writeString(0, receivedChars);
    EEPROM.commit();
    delay(100);

    Serial.print("this has been written to EEPROM ");
    EEPROM.get(0, read_eeprom);
    Serial.println(read_eeprom);

    axe();
    // MacAddress = read_eeprom;
    newData = false;
    //   Read=random8(0,255);
    // sendVal(Read);
    //    Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  }
}


/*






  String success;
  void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  if (status == 0) {
    success = "Delivery Success :)";
  }
  else {
    success = "Delivery Fail :(";
  }
  }

  void initESPNow()
  {
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  else
  {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
  }


  void sendVal(uint8_t data) {
  //esp_err_t result = esp_now_send(MacAddress, (uint8_t *) &Read, sizeof(Read));
  esp_err_t result = esp_now_send(broadcastAddress, &data, sizeof(data));
  Serial.print("Send Status: ");
  if (result == ESP_OK) {
    Serial.println("Success");
  } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
    // How did we get so far!!
    Serial.println("ESPNOW not Init.");
  } else if (result == ESP_ERR_ESPNOW_ARG) {
    Serial.println("Invalid Argument");
  } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
    Serial.println("Internal Error");
  } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
    Serial.println("ESP_ERR_ESPNOW_NO_MEM");
  } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
    Serial.println("Peer not found.");
  } else {
    Serial.println("Not sure what happened");
  }

  }*/

Here is a fixed version, tested on a Nano. I think that there were two problems
1)
See reply #8
2)
In the while loop, you immediately called a strtok() again; that should have been done after you did process the initial token (so at the end of the while-loop).

You can harden the code to reject invalid characters in the input and add a warning.

Instead of storing the text in EEPROM, it might be better to store the 6 bytes in EEPROMl saves some space.

#include <EEPROM.h>

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

boolean newData = false;
char read_eeprom[numChars];

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//B4:E6:2D:FB:29:31 and sending works just fine.

void setup()
{
  Serial.begin(57600);
}

void loop()
{
  recvWithStartEndMarkers();
  showNewData();
}

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;
    }
  }
}

int Read = 12;

void showNewData()
{
  if (newData == true)
  {
    Serial.print("I recieved this: ");
    Serial.println(receivedChars);

    Serial.println("writing to EEPROM ");
    EEPROM.put(0, receivedChars);
    delay(100);

    Serial.print("this has been written to EEPROM ");
    EEPROM.get(0, read_eeprom);
    Serial.println(read_eeprom);

    axe();
    newData = false;
  }
}

void axe()
{
  Serial.println(F("Entering axe"));
  char *token;
  char *ptr;

  int a = 0;//counter for printing what's inside broadcastAddress[]
  const char s[2] = ":";

  Serial.println(read_eeprom);

  /* get the first token */
  token = strtok(read_eeprom, s);

  /* walk through other tokens */
  while ( token != NULL )
  {
    Serial.println(token);
    broadcastAddress[a] = strtoul(token, &ptr, 16);// here is probably where the LoadProhibited is comming from.
    Serial.print(a); Serial.print(" > ");
    Serial.println(broadcastAddress[a], HEX);
    a++;

    token = strtok(NULL, s);
  }
  Serial.print("Choping it up done");
}

Output:

I recieved this: B4:E6:2D:FB:29:31
writing to EEPROM 
this has been written to EEPROM B4:E6:2D:FB:29:31
Entering axe
B4:E6:2D:FB:29:31
B4
0 > B4
E6
1 > E6
2D
2 > 2D
FB
3 > FB
29
4 > 29
31
5 > 31
Choping it up done

i have found something else than EEPROM, SPIFFS. this could be much easier and its almost the same as eeprom.

In my experience, using eeprom.h with .put() and .get() is more simple.

I tested the code posted by @sterretje on an ESP32, and it works as intended after the necessary changes for the esp32 you previously used in your code-- reserving a size, using that size in .begin() and using .commit() on the write.

hi all, thank you so much for helping me so far!

Since sterretje has made a post. I have tested and added some commands just like cattledog did and the code works without an issue.

now the next thing on my list is to add a check if receivedChars is a valid MAC address and if it's not the same as stored in EEPROM or read_eeprom. (sorry if I'm a bit too demanding....)

i would like to have a little help with this.

also here below I have posted the code that worked for me.

#include <EEPROM.h>

#define EEPROM_SIZE 32

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

boolean newData = false;
char read_eeprom[numChars];
//< 34:7d:f6:b2:01:1f > here is a test mac address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//B4:E6:2D:FB:29:31 and sending works just fine.

void setup()
{
  Serial.begin(115200);
  delay(2000);
  Serial.println(" ");
  Serial.println("Entering setup");
  
  if (!EEPROM.begin(EEPROM_SIZE)) {
    Serial.println("failed to initialise EEPROM");
    delay(1000000);
  }

  EEPROM.get(0, read_eeprom);
  Serial.print("this has been Stored EEPROM: ");
  Serial.println(read_eeprom);

  axe();
  Serial.println("Setup done");
}

void loop()
{
  recvWithStartEndMarkers();
  showNewData();
}

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("I recieved this: "); Serial.print(receivedChars);
    Serial.print(" And this has been written to EEPROM: ");
    EEPROM.get(0, read_eeprom); Serial.println(read_eeprom);
    delay(100);
     // later add a check if receivedChars and read_eeprom are different.
    Serial.print("writing to EEPROM: "); Serial.println(read_eeprom);
    EEPROM.writeString(0, receivedChars);
    EEPROM.commit();
    delay(100);

      axe();
   
    Serial.println(" ");
    newData = false;
  }
}

void axe()
{
  Serial.println("Entering axe");
 // later add a check if the mac Address is valid
    char *token;
    char *ptr;

    int a = 0;//counter for printing what's inside broadcastAddress[]
    const char s[2] = ":";

    Serial.println(read_eeprom);

    // get the first token
    token = strtok(read_eeprom, s);

    // walk through other tokens
    while ( token != NULL ) {
      //Serial.println(token);
      broadcastAddress[a] = strtoul(token, &ptr, 16);
      Serial.print(a); Serial.print(" > ");
      Serial.print(broadcastAddress[a], HEX);
      Serial.print(" | ");
      a++;
      token = strtok(NULL, s);
    }
    Serial.println("");
    Serial.println("Choping it up done");
}

now the next thing on my list is to add a check if receivedChars is a valid MAC address and if it's not the same as stored in EEPROM or read_eeprom. (sorry if I'm a bit too demanding....)

I would like to have a little help with this.

What are the criteria that make receivedChars a valid MAC address?

Both receivedChars and read_eeprom are null terminated character arrays (c-strings) and you can compare them with
strcmp() or strncmp()

What is the purpose of what you are trying to do?

One issue with comparing the strings is that you are exposed issues like b4 is not equal to B4, and you are sensitive to extra blank spaces added by error. You may want to do more error checking on length or conditioning on receivedChars[] with toupper or tolower.

You could also test the numerical byte broadcastAddress[] arrays generated by the stored and entered data.

There are some checks

A valid MAC address always has a length of 17 bytes (6x2 plus 5 colons).
2)
A token has a length of two bytes.
3)
After you retrieved a token, you can use isHexadecimalDigit() to check if the characters in the token are valid hex characters.
4)
The (end)ptr in the call to strtoul() can give an indication; based on man strtol (same applies to strtoul).

if (endptr == token)
{
  // error, no hex digits
}
if (*endptr != '\0')
{
  // warning, there is more data in the token
}

This is what I had in mind; please note that the below code stores the 6 bytes of the mac address in eeprom, not the text that was received.

I think that I've implemented every single check that I can think of.

#include <EEPROM.h>

const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//B4:E6:2D:FB:29:31 and sending works just fine.

void setup()
{
  Serial.begin(57600);

  Serial.print("[setup]broadcastAddress from EEPROM: ");
  EEPROM.get(0, broadcastAddress);
  for (byte cnt = 0; cnt < sizeof(broadcastAddress); cnt++)
  {
    Serial.print(broadcastAddress[cnt], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

void loop()
{
  recvWithStartEndMarkers();
  if (newData == true)
  {
    bool rv = newMacToBroadcastAddress();
    if (rv == false)
    {
      Serial.println("An error occured while processing the received MAC address");
    }
    else
    {
      Serial.print("[loop]updated broadcastAddress from EEPROM: ");
      EEPROM.get(0, broadcastAddress);
      for (byte cnt = 0; cnt < sizeof(broadcastAddress); cnt++)
      {
        Serial.print(broadcastAddress[cnt], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
  }
}

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;
    }
  }
}

/*
  Process received mac address and store in EEPROM
  Returns:
    true on success else false
*/
bool newMacToBroadcastAddress()
{
  // array to store received and converted MAC address before saving to EEPROM
  byte eepromMac[sizeof(broadcastAddress)];
  // index where to write next byte in eepromMac array
  byte idx = 0;

  // tokeniser and converter
  char *token;
  char *ptr;
  const char s[2] = ":";

  if (newData == true)
  {
    newData = false;

    Serial.print("I received this: '");
    Serial.print(receivedChars);
    Serial.println("'");

    // check the length
    if (strlen(receivedChars) != 17)
    {
      Serial.println("Expected 17 characters for MAC address");
      return false;
    }

    /* parse data */
    token = strtok(receivedChars, s);
    while ( token != NULL )
    {
      Serial.print("Token: '");
      Serial.print(token);
      Serial.println("'");

      // check if there were more MAC bytes than needed; basically redundant
      if (idx >= sizeof(broadcastAddress))
      {
        Serial.println("Too many tokens");
        return false;
      }

      // token should be 2 bytes
      if (strlen(token) != 2)
      {
        Serial.println("[strlen]Expected 2 characters for Mac byte");
        return false;
      }

      // check if values in token are hexadecimal
      for (byte cnt = 0; cnt < strlen(token); cnt++)
      {
        if (isHexadecimalDigit(token[cnt]) == false)
        {
          Serial.println("[isHexadecimalDigit]Expected a hexadecimal Mac byte");
          return false;
        }
      }

      // convert token
      byte b = strtoul(token, &ptr, 16);

      // the two tests below are basically redundant but demonstrate how ptr can be used to check the result of the conversion
      if (ptr == token)
      {
        Serial.println("[strtoul]Expected a hexadecimal Mac byte");
        return false;
      }
      if (*ptr != '\0')
      {
        Serial.println("[strtoul]Still characters available");
        return false;
      }

      eepromMac[idx] = b;
      Serial.print(idx); Serial.print(" > ");
      Serial.println(b, HEX);
      idx++;

      token = strtok(NULL, s);
    }

    Serial.println("writing to EEPROM ");
    EEPROM.put(0, eepromMac);
    delay(100);

  }

  return true;
}

// Late edit:
Forgot to add a note though it is in the code; the checks of ptr in are basically redundant; I left them in for demo purposes.

Hi all!
First of all, Thank you all for your help! For the last few days, I didn't have time to work and debug the code. Today I did and didn't get it working. it has some conflicts and eventually gave up.

So wanted to get some help again and saw Sterretjes last post. This is precisely what I wanted!

My only concern is writing to EEPROM too much will damage it. Could it be possible to look at what MAC address is inside EEPROM and compare it to the received MAC address? If there are the same don't go further.

I totally loved this challenge of using new functions I never heard of! (btw thanks for writing down these checks it really helped me!)

sterretje:
There are some checks

A valid MAC address always has a length of 17 bytes (6x2 plus 5 colons).
2)
A token has a length of two bytes.
3)
After you retrieved a token, you can use isHexadecimalDigit() to check if the characters in the token are valid hex characters.
4)
The (end)ptr in the call to strtoul() can give an indication; based on man strtol (same applies to strtoul).

This is what I came up with the help of these 4 testings points:
Don't mind running it. it WON'T compile or run. i have learned myself to code so.
i will use Sterretje genius, organised and working code.

#include <EEPROM.h>

#define EEPROM_SIZE 18

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

boolean newData = false;
char read_eeprom[numChars];
//<34:7d:f6:b2:01:1f> here is a test mac address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//B4:E6:2D:FB:29:31 and sending works just fine.

void setup()
{
  Serial.begin(115200);
  delay(2000);
  Serial.println(" ");
  Serial.println("Entering setup");

  if (!EEPROM.begin(EEPROM_SIZE)) {
    Serial.println("failed to initialise EEPROM");
    delay(1000000);
  }

  EEPROM.get(0, read_eeprom);
  Serial.print("this has been Stored EEPROM: ");
  Serial.println(read_eeprom);

  axe();
}

void loop()
{
  recvWithStartEndMarkers();
  showNewData();
}

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;
    }
  }
}

int Read = 12;


void showNewData()
{
  if (newData == true)
  {
    int counter = 0;
    newData = false;
    Serial.print("I recieved this: "); Serial.println(receivedChars);

    for (byte i = 0; i < sizeof(receivedChars); i++) if (receivedChars[i] != '\0') counter++;
    //  Serial.println(counter);

    if (counter == 17) {

       axe();
      // later add a check if receivedChars and read_eeprom are different.

      
      Serial.print(" This has been written to EEPROM: ");
      EEPROM.get(0, read_eeprom); Serial.println(read_eeprom);
      delay(100);


      Serial.println(" ");
    } else Serial.println("Expected 17 characters length for MAC address");
  }
}

void axe()
{
  Serial.println("Entering axe");
  // later add a check if the mac Address is valid
  char *token;
  char *ptr;
  int a = 0;//counter for printing what's inside broadcastAddress[]
  const char s[2] = ":";

    Serial.print("I received this: '");
    Serial.print(receivedChars);
    Serial.println("'");

  // get the first token
  token = strtok(receivedChars, s);

  // walk through other tokens
  while ( token != NULL ) {
    //Serial.println(token);
  if (strlen(token) != 2){
    Serial.println("Expected 2 characters for Mac length"); 
    return;
    }

    Serial.print(" | ");
    broadcastAddress[a] = strtoul(token, &ptr, 16);
    Serial.print(a); Serial.print(" > ");
    Serial.print(broadcastAddress[a], HEX);

    if (isHexadecimalDigit(token[a])) {Serial.print(" Yes");} else {Serial.print(" No");}

    Serial.print(" | ");
    a++;
    token = strtok(NULL, s);
  }

    Serial.println("writing to EEPROM: "); Serial.println(broadcastAddress);
    EEPROM.writeString(0, broadcastAddress);
    EEPROM.commit();

  Serial.println("");
  Serial.println("Choping it up done");
}

How often are you planning to update? Flash memory has a life of 10,000 write cycles (AVR, check the spec of the ESP).

The put in my code will not update an eeprom cell if it does not change; that applies to AVR, I don't know if the ESP works in similar fashion.

But yes, you can implement it yourself; you just need an other variable to store the MAC that is read from the eeprom and the MAC that you received and want to store. Use memcmp to compare the two and decide based on that.

not much to nothing. it's practical however more of a feature creep.

so i will update the subject with [solved]

thank you all for the help!