SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
User avatar
By RocketNut
#198835
Hello

I am working on a large sketch project with an eye on turning it into a library. I am not ready to turn the sketch to library right now, but I want to include what might be needed into the sketch.

The question I have is there a way to call a user sketch from inside a library . The following code shows what I am talking about


Library cpp file

SD.print(Log_Sample_Num)
SD.print(" ,)";
SD.print(Log_Time);
SD.print(" ,");
SD.println(SampleDataString());


User Sketch file

String SampleDataString()
{
String ReturnString = ""
if(GPS.fix)
{
RerurnString = GPS.Lat + GPS.Long;
}
else
{
ReturnString = "*****,*****,";
}

// Gentrate the rest of ReturnString
return ReturnString;
}

Thanks for help :-)
By jremington
#198836
It is not a good idea to use String objects with Arduino. They cause memory problems and program crashes.

Use the far more reliable C-strings (character arrays) and associated C-string manipulation functions, like strlen(), strcat(), etc. instead.
User avatar
By RocketNut
#198838
Thanks for the heads up jremington :D

I looked in the Language Reference and I could not find how to use a C-sting variable. I did find how to define a string (char string[]) I changed the user sketch using the C-strings

User Sketch file
String SampleDataString()
{
chr ReturnString[] = "" <<------------------
if(GPS.fix)
{
RerurnString = GPS_Lat + GPS_Long;
}
else
{
ReturnString = "*****,*****,";
}

// Gentrate the rest of ReturnString
return ReturnString;
}

What do you suggest to use instead the Arduino String objects as used in the above example? Also is there a website or tutorial that explains all the C-strings functions ( with examples if possible)?

I am newbie to programming an coding so please excuse stupid questions.
User avatar
By RocketNut
#198840
I could not edit my post

My bad wording
I am newbie to programming an coding so please excuse stupid questions.

Should read:
I am newbie to programming an coding so ny help would be appreciated
User avatar
By RocketNut
#198844
I to Googled and found a web page that showed me how to declear the string as a array,

We are getting off topic about a library function calling a user sketch question. Before getting back the topic question I have one last question.

In the following code sinbit I need to add a single char to a string is causing a error

while (Serial.available())
{
char c = Serial.read();
if ( c == '\n')
{
ParseCommand(command);
break;
}
else
{
command = command + c; <<< == Error happens here
}


What would be the proper C-string should it be.
By lyndon
#198847
1) It would be really, really nice if you would explicitly say what "Error happens here" when asking for help. Show actual code with actual errors.
2) What are the variable types?
3) The error is that in c/c++ you can't concatenate a character to anything like that
User avatar
By RocketNut
#198850
Sorry about that. The error message is :

Arduino: 1.8.5 (Windows 10), Board: "Arduino M0 Pro (Programming Port)"

H:\DataLogger\DataLogger Software\DataLogger_V4\DataLogger_Prgm_V2.ino\DataLogger_Prgm_V2.ino.ino: In function 'void loop()':

DataLogger_Prgm_V2.ino:230: error: incompatible types in assignment of 'char*' to 'char [1]'

command = command + c;

^

Multiple libraries were found for "SD.h"
Used: C:\Program Files (x86)\Arduino\libraries\SD
Not used: C:\Users\Rocke\Documents\Arduino\libraries\arduino_625652
exit status 1
incompatible types in assignment of 'char*' to 'char [1]'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.




Again here the code with declared variaable types:

if(USB_Enable && digitalRead(USB_PWR))
{
char command[] = ""; <<< --- "command" variable

// Check to see if it's time to send USB data
if(USB_Enable && RadioTX_Time <= millis()) Serial.println("**,**," + DataStringGen());

// Check for a recived USB command/char
while (Serial.available())
{
char c = Serial.read(); <<== "c" variable
if ( c == '\n')
{
ParseCommand(command);
break;
}
else
{
command = command + c; <<==Error statement
}
}
}


I want to thank you for the great help and suggestions :D
User avatar
By DanV
#198851
Add a new variable "index" of type int.
Then, instead of
Code: Select all
command = command + c;
Use this code
Code: Select all
index = strlen(command);
command[index++] = c;
command[index] = '\0';
Just make certain that you declare command[] large enough to hold all the characters you think will be in the string (char array) plus the null terminator.
User avatar
By RocketNut
#198852
:D That did the trick Thanks DanV

Now lets get back to topic question. Is it possible for a library function to call main sketch function? As the sketch sits right now the library will be calling 3 different main sketch functions.
User avatar
By DanV
#198856
It's my personal opinion that including a library simply makes the functions in it available anywhere in the program scope.
That pretty much puts them at the same level as the functions and code everywhere in the program.
Could a library function call a main program function? Sure, why not?

But, this kind of precludes the purpose of the library which is usually to build a set of functions that are reusable and can be included in many programs without having to rewrite them.

So, you would likely need to have your function "SampleDataString()" in more any of your programs that you plan to include your library into in order for the compiler to not ***** about the unresolved function call to "SampleDataString()" which is in your library function (whew...).

Why not put "SampleDataString()" in your library?

Now, there are possibilities of having a pointer to a function and then defining it to point to your main sketch function, but that's beyond the scope of this reply.
By jremington
#198858
As the sketch sits right now the library will be calling 3 different main sketch functions.
I agree with DanV. There is no point in writing a "library" that requires a user's program to have several different specific functions.

Who else would want to use such a thing, and why?

A library provides useful, frequently needed, well written and well documented functions.
User avatar
By RocketNut
#198860
You could look at the main sketch 3 functions as variables used in the library. Like in the following code sample. The library calls SampleDataString() which is defined in the user's main sketch. This allows the user to define what info they want to be logged onto the SD card. In this example the user wants the GPS info to be the first 2 variables, which are define in the library. All the rest of SD card writing is also done in the library. So the user only has to write code for the 3 different functions (TX_DataString , SampleDataString, and EventStep) every thing else resides in the library.
Library cpp file
SD.print(Log_Sample_Num)
SD.print(" ,)";
SD.print(Log_Time);
SD.print(" ,");
SD.println(SampleDataString());


User Sketch file
String SampleDataString()
{
String ReturnString = ""
if(GPS.fix)
{
RerurnString = GPS.Lat + GPS.Long;
}
else
{
ReturnString = "*****,*****,";
}

// Gentrate the rest of ReturnString
return ReturnString;

Side note:
I am changing the code to use C_Sting code instead of the Arduino String functions.
}
By jremington
#198861
It is easier for the user just to write code to log the data of interest to the SD card, using the reliable, well written and well documented functions provided by the SD library.
User avatar
By DanV
#198862
... using the reliable, well written and well documented functions provided by the SD library.
Agreed!

But, if it works for you, then all is good.
It's not the first time I've seen this sort of thing and I'm sure it won't be the last.