SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By lyndon
#198865
DanV addressed my concern in item #3: concatenation.

However if the code you show is really all there is, then it's working from sheer dumb luck and will eventually crash or cause hard-to-find problems. You need to allocate memory for the command[] array, not just initialize it to ""

e.g.,
Code: Select all
// Declare command buffer for 20 character length
#define COMMAND_BUFFER_LEN 20
char command[COMMAND_BUFFER_LEN ];
// Initialize to all zeros
memset(command, 0, COMMAND_BUFFER_LEN );
By mdancer
#198866
While I mostly agree with DanV and jremington, I also slightly disagree - let me explain. What you are effectively asking is can a library use a callback function. When used in a library, a callback function gives the library user the option of modifying some part of the functionality provided by the library. But take note, there are two key words in the previous sentence - "option" and "some". If you force the user to specify all the behavior of the library, then what's the point of the library in the first place? I believe this is, to some extent, the point DanV and jremington are making (sorry, if I misread your posts).

In your case, I don't think you're forcing the user to specify all of the functionality provided by the library, but I think there are things you could do a little better. It appears to me your library does two things - store a fixed, pre-defined block of data onto an SD card and then store a user defined string after that. So the real functionality your library offers is storing this standard block of data - i.e. the user doesn't have to "reinvent the wheel" each time they want to do this. The part I think you're missing, is making the user-defined string, that's stored after, optional. Right now, anyone that uses your library as is and forgets to define SampleDataString() will get compile errors. This will happen even if all they care about is storing the standard block of data. What I would recommend is having your library (weakly) define SampleDataString() to provide a default string (or no string), then if the user wants, they can override your definition of SampleDataString() with their own. If your library defines a class that the user instantiates, you can do this another way by having a constructor that takes a function pointer as an argument, stores it, and then your library uses this pointer to "call back" to the user code when the time is right.

As an example, look at the Arduino IDE's use of the serialEvent() function. In the main program loop that the IDE creates, after it calls your loop() function, it then checks if serialEventRun is defined (which will be if you include HardwareSerial.h), and if so calls serialEventRun() which in turn calls serialEvent() whenever serial data is available. By default this function is weakly defined in HardwareSerial.cpp to do nothing, but the weak attribute, __attribute__((weak)), allows the user, in their sketch, to override this function, if they wish. So the Arduino IDE, a library of sorts (if you allow me to view it that way), provides the core functionality we all know and love - call setup() then repeatedly call loop() - as well as additional, and optional, functionality of alerting the user whenever serial data is available. To use this additional functionality, though, requires the user to define the serialEvent() function.

Anyway, I hope this helps or perhaps provides some alternate vantage point.

Mike
User avatar
By RocketNut
#198868
The project is for a high power rocketry flight computer . The library is all the core code to read the sensors (Acc,Alt,GPS, ETC) along with logging the info to the SD card and sending Radio data. I am just tiring to make it as simple as possible to the end user,

As of right now ( work in process) the core code is over 1000 lines of code. Having the user to copy or enter the core code will lead to a lot of typos and/or syntax errors. So placing all the core code into library means the user does not have to create a sketch to do the core operations and only needs to write the code for the required functions. Thus making the user sketch more reliable and easy to use (not mentioning easier to debug).