Questions about functions and datatypes

I have a few questions about functions. Can anyone tell me why when I remove the line ' Serial.println("About to return true for int");' from my function 'validateDataType', that the serial out freezes and does not get past the area where I have 'Serial.println("Freeze Before");' ?

Also, can anyone see any issues with my function itself?

function validateDataType

bool validateDataType(String dataType, char* data)
{
    if (dataType == "string")
    {
        for (int i = 0; i < strlen(data); i++)
        {
            if (isAlpha(data[i]))
            {
                // continue
            }
            else
            {
                return false;
            }
        }

        return true;
    }    
    else if (dataType == "int")
    {
        for (int i = 0; i < strlen(data); i++)
        {
            if (isDigit(data[i]))
            {
                // continue
            }
            else
            {
                return false;
            }
        }
        Serial.println("About to return true for int"); // This line stops it from freezing???

        return true;
    }
    else if (dataType == "float")
    {
        int decimalPointCount = 0;
        for (int i = 0; i < strlen(data); i++)
        {
            if (isDigit(data[i]))
            {
                // continue
            }
            else if (data[i] == '.')
            {
                decimalPointCount++;
                if (decimalPointCount > 1)
                {
                    return false;
                }
            }
            else
            {               
                return false;
            }
        }

        if (decimalPointCount != 1)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}

Code to test/call function validateDataType


String stringToTest = "isthisanactualstring";
    bool isDataType = validateDataType("string", stringToTest.c_str()); // true is indeed 1, and false is 0.    
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");
    stringToTest = "isthisanactual1string";
    isDataType = validateDataType("string", stringToTest.c_str());
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");
    stringToTest = "isthisanactu*lstring";
    isDataType = validateDataType("string", stringToTest.c_str());
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");
    stringToTest = "isthisan actualstring";
    isDataType = validateDataType("string", stringToTest.c_str());
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");

    String intToTest = "123456789101112";
    Serial.println("Freeze Before");
    isDataType = validateDataType("int", intToTest.c_str()); // true is indeed 1, and false is 0.
    Serial.println("Freeze After");
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");
    intToTest = "12345678910!112";
    isDataType = validateDataType("int", intToTest.c_str());
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");
    intToTest = "123A56789101112";
    isDataType = validateDataType("int", intToTest.c_str());
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");
    intToTest = "123456 789101112";
    isDataType = validateDataType("int", intToTest.c_str());
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");

    String floatToTest = "12345.6789";
    isDataType = validateDataType("float", floatToTest.c_str()); // true is indeed 1, and false is 0.
     Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "123456789";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "12345.67.89";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "12345.67A89";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "12345*6789";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "123 45.6789";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");

Lastly, I need to validate data saved in EEProm addresses, which is why I'm writing this function. I need to be able to read the values, determine if they are legitimate/expected and then send them over a Bluetooth module to a receiver. Although I still want critiques on my function, is there a better way to do this?

The code below with the function 'readFromEEPROMAll' gives this output

00:22:27.351 -> **
00:22:27.351 -> ***
00:22:27.384 ->
00:22:27.384 -> **
00:22:27.384 -> 3|1023|-�
00:22:27.384 -> ***
00:22:27.384 ->

function readFromEEPROMAll and code to call

    Serial.println(" ** ");
    readFromEEPROMAll();
    Serial.println(" *** ");

    Serial.println("");
    writeToEEProm("11", "Test");

    Serial.println(" ** ");
    Serial.println(readFromEEPROMAll());
    Serial.println(" *** ");
    Serial.println("");
    Serial.println("");


float Target;
String readFromEEPROMAll()
{
        int address = 11;
        int EEPromValue11 = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        Target = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        if (isnan(Target))
        {
            Serial.println("EEPromValue11 was empty");
        }

        address = 12;
        int EEPromValue12 = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        Target = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        if (isnan(Target))
        {
            Serial.println("EEPromValue12 was empty");
        }
   
        address = 13;
        int EEPromValue13 = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        Target = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        if (isnan(Target))
        {
            Serial.println("EEPromValue13 was empty");
        }
    
    

    String returnValue = String(EEPromValue11) + "|" + String(EEPromValue12) + "|" + String(EEPromValue13);
    return returnValue;
}

Can you please put your queries about data types and functions in the form of direct questions referring to the codes you have posted? For example: what kind of data type is the String?

  1. Can anyone tell me why when I remove the line ' Serial.println("About to return true for int");' from my function 'validateDataType'?

  2. How does my function look in general?

  3. I need to validate data saved in EEProm addresses and to be able to read the EEProm values, determine if they are legitimate/expected and then send them over a Bluetooth module to a receiver. Is my function a good approach to this?

1 Like

You have three pieces of codes in post #1. Please, you make a single sketch with setup() and loop() functions and post it along with your statements about what you are expecting from the sketch and what it is delivering?

Data Types

.

make a working sketch with your function and all necessary things to make it compile in the IDE.
Then post it and one might be able to answer your question.

Your idea looks weired. if you want to "validate" your eeprom data, you should consider some kind of CRC / checksum.

and also your EEPROM access ... it will get much more easier if you would use .put and .get

  1. I'd like to know why I get the EEProm values circled. I have not written to the 2nd and 3rd places (separated by the pipe symbol) yet there is still values residing there. I have written the validateDataType function to try and compensate for that, so that I can determine when the values are garbage or when they are written by my code. I even get differing values from one read to the next.

  2. I'd like to know if my function looks reliable/robust, or if there is a library already written on handling garbage EEProm values? I don't believe I am the only one that has encountered this issue, unless I'm doing something incorrectly.

  3. Although relatively unimportant, I am wondering why I get the long row of rectangular boxes at the start


#include <EEPROM.h>

String readFromEEPROMAll()
{
        int address = 11;
        int EEPromValue11 = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        
        address = 12;
        int EEPromValue12 = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        
        address = 13;
        int EEPromValue13 = ((EEPROM.read(address) << 8) + EEPROM.read(address + 1));
        
    String returnValue = String(EEPromValue11) + "|" + String(EEPromValue12) + "|" + String(EEPromValue13);
    return returnValue;
}

String writeToEEProm (String settingName, String settingValue)
{
    if (settingName == "dm")
    {
        int setting = NULL;
        if (settingValue == "E")
        {
            setting = 1;
        }
        else if (settingValue == "St")
        {
            setting = 2;
        }
        else if (settingValue == "Sp")
        {
            setting = 3;
        }
        else if (settingValue == "C")
        {
            setting = 4;
        }

        int address = 11;
        EEPROM.write(address, setting >> 8);
        EEPROM.write(address + 1, setting & 0xFF);
    }
    else if (settingName == "tc")
    {
        int setting = NULL;
        if (settingValue == "E")
        {
            setting = 1;
        }
        else if (settingValue == "D")
        {
            setting = 2;
        }

        int address = 12;
        EEPROM.write(address, setting >> 8);
        EEPROM.write(address + 1, setting & 0xFF);
    }
    else if (settingName == "ts")
    {
        int setting = NULL;
        if (settingValue == "F")
        {
            setting = 1;
        }
        else if (settingValue == "R")
        {
            setting = 2;
        }
        else if (settingValue == "T")
        {
            setting = 3;
        }
        
        int address = 13;
        EEPROM.write(address, setting >> 8);
        EEPROM.write(address + 1, setting & 0xFF);
    }
          
    return "1";
}

bool validateDataType(String dataType, char* data) // true is indeed 1, and false is 0.
{
    if (dataType == "string")
    {
        for (int i = 0; i < strlen(data); i++)
        {
            if (isAlpha(data[i]))
            {
                // continue
            }
            else
            {
                return false;
            }
        }
        return true;
    }    
    else if (dataType == "int")
    {
        for (int i = 0; i < strlen(data); i++)
        {
            if (isDigit(data[i]))
            {
                // continue
            }
            else
            {
                return false;
            }
        }
        return true;
    }
    else if (dataType == "float")
    {
        int decimalPointCount = 0;
        for (int i = 0; i < strlen(data); i++)
        {
            if (isDigit(data[i]))
            {
                // continue
            }
            else if (data[i] == '.')
            {
                decimalPointCount++;
                if (decimalPointCount > 1)
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        if (decimalPointCount != 1)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    return false;
}

void setup() {
    Serial.begin(9600);
    
    while (!Serial)
    {
      ; // Wait for serial to connect
    }
   
    delay(1000);

    Serial.println("");
    Serial.println("    ***** Start *****    ");
    Serial.println("");

    Serial.println("");
    writeToEEProm("dm", "E");

    Serial.println(" ** ");
    Serial.println(readFromEEPROMAll());
    Serial.println(" *** ");

    Serial.println("");
    writeToEEProm("dm", "St");

    Serial.println(" **** ");
    Serial.println(readFromEEPROMAll());
    Serial.println(" ***** ");
    Serial.println("");

    String stringToTest = "isthisanactualstring";
    bool isDataType = validateDataType("string", stringToTest.c_str()); // true is indeed 1, and false is 0.    
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");
    stringToTest = "isthisanactual1string";
    isDataType = validateDataType("string", stringToTest.c_str());
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");
    stringToTest = "isthisanactu*lstring";
    isDataType = validateDataType("string", stringToTest.c_str());
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");
    stringToTest = "isthisan actualstring";
    isDataType = validateDataType("string", stringToTest.c_str());
    Serial.print(stringToTest);
    Serial.print(" isDataType of (string): ");
    Serial.println(isDataType);
    Serial.println("");

    String intToTest = "123456789101112";
    isDataType = validateDataType("int", intToTest.c_str()); // true is indeed 1, and false is 0.
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");
    intToTest = "12345678910!112";
    isDataType = validateDataType("int", intToTest.c_str());
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");
    intToTest = "123A56789101112";
    isDataType = validateDataType("int", intToTest.c_str());
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");
    intToTest = "123456 789101112";
    isDataType = validateDataType("int", intToTest.c_str());
    Serial.print(intToTest);
    Serial.print(" isDataType of (int): ");
    Serial.println(isDataType);
    Serial.println("");

    String floatToTest = "12345.6789";
    isDataType = validateDataType("float", floatToTest.c_str()); // true is indeed 1, and false is 0.
    //bool isDataType = isAlphaNumerAndPeriod("isthisanactualstrg");
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "123456789";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "12345.67.89";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "12345.67A89";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "12345*6789";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");
    floatToTest = "123 45.6789";
    isDataType = validateDataType("float", floatToTest.c_str());
    Serial.print(floatToTest);
    Serial.print(" isDataType of (float): ");
    Serial.println(isDataType);
    Serial.println("");

}

void loop() {
  // put your main code here, to run repeatedly:

}

The below tells me everything is a string, because I'm sending it inside of quotes or as a string data type initially. I'm not sure how I could adjust my code to read and write without the use of strings.

void types(String a) { Serial.println("it's a String"); }
void types(int a) { Serial.println("it's an int"); }
void types(char *a) { Serial.println("it's a char*"); }
void types(float a) { Serial.println("it's a float"); }
void types(bool a) { Serial.println("it's a bool"); }

Would you mind explaining to me the advantages of put and get over

((EEPROM.read(address) << 8) + EEPROM.read(address + 1))
and
EEPROM.write(address, setting >> 8);
EEPROM.write(address + 1, setting & 0xFF);

Maybe I'm not understanding, but my issue is that when I read the value from the EEProm (I'm getting values in memory locations that have not been written to ever), I need to know if it is the expected data type/format for that memory location and within an expected range, and if not I discard it and I do not transmit it via Bluetooth but consider the value null.

I believe what you are referring to is for when I write to the EEProm?

really?

what make your lines of code easier than a simple

EEPROM.get(address, setting);

and

EEPROM.put(address, setting);

No bit shifting, masking, OR necessary,
will also work with complex types, structures....

have you read the Arduino reference already?

https://wiki-content.arduino.cc/en/Tutorial/LibraryExamples/EEPROMPut

https://wiki-content.arduino.cc/en/Tutorial/LibraryExamples/EEPROMGet

Which Arduino you are using -- I have uploded your sketch of post #7 in Arduino UNO R3, and I have not seen the boxes appearing on the Serial Monitor?

If your intention is to learn the procedures of storing/retrieving (into/from EEPROM) data of various types (built-in, user-defined, array, struct), then start with small examples for which you can explore Arduino Reference Manual.

I see the obvious advantages now and will switch over. I had not read that, I'm less than a week into this and still trying to find all of the informational sources/documentation. I appreciate what you've shown me as it allows me to see other functions/procedures as well.

I am using the Arduino Mega 2560 (pcb by Elegoo).

That is part of my intention, the other part is validating the data to ensure it is the expected data type and within expected ranges. Are you seeing the varying EEProm read values coming from 'virgin' EEProm addresses that have not been written to yet? I've notated them in the code below with " < --This "

1:30:34.716 ->     ***** Start *****    
11:30:34.750 -> 
11:30:34.750 -> 
11:30:34.781 ->  ** 
11:30:34.781 -> 1|511|-1  < --This
11:30:34.781 ->  *** 
11:30:34.781 -> 
11:30:34.781 ->  **** 
11:30:34.781 -> 2|767|-1  < --This
11:30:34.814 ->  ***** 
11:30:34.814 ->

I have changed over to EEPROM.put and EEPROM.get (thank you noiasca) and I am now getting the same results each read and write for the unwritten to memory blocks, so that's resolved.

I also changed delay(1000); to delay(2000); and now I am not getting the rectangles printed across the screen, so that's also been resolved.

13:09:39.969 -> 
13:09:39.969 ->  **** 
13:09:39.969 -> 2|-256|-1
13:09:39.969 ->  ***** 
13:09:40.001 -> 
13:09:40.001 -> 
13:09:40.001 ->  **** 
13:09:40.001 -> 3|-256|-1
13:09:40.001 ->  ***** 
13:09:40.034 -> 
13:09:40.034 -> 
13:09:40.034 ->  **** 
13:09:40.034 -> 4|-256|-1
13:09:40.034 ->  ***** 
13:09:40.067 ->

It's going to take me a bit to digest your code and how it ties together on a detailed level. I love the idea of creating a struct object, this is my first time doing that as with c# that isn't used often and I have had limited exposure to it. It's more familiar to me with the dot notation as well.

Some issues I'm working with is that my input configuration communication comes from an app and although some of the app's fields are binary switches, some are text boxes with floating point numbers and I'd like to validate that the correct data was input in the correct format, or have the Arduino dispose of it as invalid. I'm sure there are better ways to do this, however I'm sending the input data over Bluetooth as text and want to validate that data format on the Arduino. It's also not sent as a batch, but rather real time when a specific value is changed within an app.

Here is my current progress, do I have to declare strct_settings as a global variable somehow? The compiler is not recognizing the data type it appears.

error: 'strct_settings' was not declared in this scope
bool isStructSettingsValid(strct_settings *settings)

error: 'strct_settings' was not declared in this scope
void setSettingsChecksum(strct_settings *settings)

struct strct_settings 
{   
  int checkSum = 0x42;
  int dm;
  int tc;
  int ts;
  int imt;
  float pFloor;
  float pCeiling;
  int tr;
  int trw;
  String lowerVal;
  String upperVal;
  int32_t sum = 0;
} ;

bool isStructSettingsValid(strct_settings *settings)
{
    int32_t sum = settings->checkSum;
    if (sum != 0x42)
    return false;

    sum += settings->dm;
    sum += settings->tc;
    sum += settings->ts;
    sum += settings->imt;
    sum += settings->pFloor;
    sum += settings->pCeiling;
    sum += settings->tr;
    sum += settings->trw;
    sum += settings->lowerVal;
    sum += settings->upperVal;

    return (settings->sum == sum);
}

void setSettingsChecksum(strct_settings *settings)  // Update the bias store checksum
{
  int32_t sum = settings->header;
  sum += settings->dm;
    sum += settings->tc;
    sum += settings->ts;
    sum += settings->imt;
    sum += stsettingsre->pFloor;
    sum += settings->pCeiling;
    sum += settings->tr;
    sum += settings->trw;
    sum += settings->lowerVal;
    sum += settings->upperVal;
    settings->sum = sum;
}

typedef struct strct_settings strct_Settings;

It's going into an INO file, I'll think on that

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.