Sketch name as PreProcessor value?

Hi,
I've found that once I upload code into my Arduino, and run it for days, weeks, months, I usually forget what the name of the running sketch is.
Would it be possible to add a few pre-precessor reserved words, something like the #defines (all caps below) to allow us to have the sketch name and modification timestamp auto-inserted at compile time?

If I were to include in the setup() code something like:

Serial.print("You are running sketch: ");
Serial.print( THIS_SKETCH_NAME );
Serial.print(" modified: ");
Serial.println( THIS_SKETCH_TIMESTAMP );

Then I could take my Arduino offline, plug it into USB, hit the reset button, check the serial monitor, and have it tell me the name of the sketch it's running!

I do the same thing right now by manually entering that information, but it would be cool to have it auto-fill.

Maybe this is already possible?

Thanks for reading!
J

I'm posting from my phone, so can't try anything, but have you tried FILE ?

Thanks, I'll give that a try.

Where could I find a list of available macros or predefined "defines" like that? I'm not very familiar with the use of the compiler flags, settings, or (clearly) available variables.

Thanks!

or similar.

Thanks again AWOL for the tip.

I threw together this little function to display what I need. Maybe someone else will find it helpful as well.

// displays at startup the Sketch running in the Arduino
void display_Running_Sketch (void){
  String the_path = __FILE__;
  int slash_loc = the_path.lastIndexOf('/');
  String the_cpp_name = the_path.substring(slash_loc+1);
  int dot_loc = the_cpp_name.lastIndexOf('.');
  String the_sketchname = the_cpp_name.substring(0, dot_loc);

  Serial.print("\nArduino is running Sketch: ");
  Serial.println(the_sketchname);
  Serial.print("Compiled on: ");
  Serial.print(__DATE__);
  Serial.print(" at ");
  Serial.print(__TIME__);
  Serial.print("\n");
}

I call it like this in setup()

void setup() {      
  Serial.begin(9600);
  display_Running_Sketch();
}

My output in the Serial Monitor looks like this:

Arduino is running Sketch: MyTestSketch_ver_2
Compiled on: Aug 15 2012 at 09:36:27

(It could, of course, be used without the function, just copy/paste directly into setup() )

Just be aware that PATH is going to resolve to something like:

C:\DOCUME~1\user\LOCALS~1\Temp\build5844727131377394186.tmp\MyTestSketch_ver_2.cpp

and that entire string will be allocated as RAM, so is not cheap in that regard.

I'd probably consider writing my own substring extraction fn as well to avoid the overhead of linking in the string lib fns (unless I was already using them in the program in any case.)

Edit: Oh well, you've made me go and do it now! :stuck_out_tongue:

/*** Pico's version of a src file/compilation details lister ***/

#include <avr/pgmspace.h>

int pgm_lastIndexOf(uint8_t c, const char * p)
{
  int last_index = -1; // -1 indicates no match
  uint8_t b;
  for(int i = 0; true; i++) {
    b = pgm_read_byte(p++);
    if (b == c)
      last_index = i;
    else if (b == 0) break;
  }
  return last_index;
}

// displays at startup the Sketch running in the Arduino

void display_srcfile_details(void){
  const char *the_path = PSTR(__FILE__);           // save RAM, use flash to hold __FILE__ instead

  int slash_loc = pgm_lastIndexOf('/',the_path); // index of last '/' 
  if (slash_loc < 0) slash_loc = pgm_lastIndexOf('\\',the_path); // or last '\' (windows, ugh)

  int dot_loc = pgm_lastIndexOf('.',the_path);   // index of last '.'
  if (dot_loc < 0) dot_loc = pgm_lastIndexOf(0,the_path); // if no dot, return end of string

  Serial.print("\nSketch: ");

  for (int i = slash_loc+1; i < dot_loc; i++) {
    uint8_t b = pgm_read_byte(&the_path[i]);
    if (b != 0) Serial.print((char) b);
    else break;
  }

  Serial.print(", Compiled on: ");
  Serial.print(__DATE__);
  Serial.print(" at ");
  Serial.print(__TIME__);
  Serial.print("\n");
}
  String the_path = __FILE__;
  int slash_loc = the_path.lastIndexOf('/');
  String the_cpp_name = the_path.substring(slash_loc+1);
  int dot_loc = the_cpp_name.lastIndexOf('.');
  String the_sketchname = the_cpp_name.substring(0, dot_loc);

Wasting a boatload of resources just so the Arduino can tell you which sketch is running is hardly going to win you any friends.

Nothing that you are doing here requires the String class. Lots of text processing was done in the 40 years before the String class came along.

If you don't remember the sketch name, and you have to connect it to the PC to check, what is the point of doing this? If the board is already connected and the IDE opened should take couple of seconds to upload any script

For the heck of it, I gave it a shot to extract the sketch name without using the dreaded String class.

    char fullPath[] = __FILE__;
    char *slash;
    slash = strrchr(fullPath, '/');
    slash++;
    strcpy(fullPath, slash);
    byte length = strlen(fullPath);
    char fileName[20] = "";
    strncpy(fileName, fullPath, (length - 4));
    strcat(fileName, ".ino");
    Serial.print(fileName);

I don't know if my non-String version is much better (I don't really get C), or if the whole excercise is pointless, but there it is.

eried:
If you don't remember the sketch name, and you have to connect it to the PC to check, what is the point of doing this? If the board is already connected and the IDE opened should take couple of seconds to upload any script

I think it is more an exercise in version control. Coming back to a device that has been in use for some time and trying to determine exactly which version of the program it has on it currently can be tricky, unless you have an extremely good memory or are organised to keep meticulous records.

Or automatically write some key info into the sketch itself, as this is doing.

Edit: I recall seeing a write-up a few months ago on a website a fellow has set-up to use as a "repository" of sketches, with a serial number system of some sort that ties an Arduino to a particular sketch. I had a quick look but can't remember enough of the details to find it... I seem to recall his motivation was to address the problem "orphan" devices that had lost their source code over time.

tape a sticker to the chip ....easy

Good idea about the sticker :slight_smile:

Yes, revision control is a lot of it. Also, as a hobbyist, I currently have only one Arduino. So, if I "borrow" it from one project, tinker, then want to put it back the way it was, that is why it would be nice to have it echo back the sketch name before I re-upload an alternate sketch. But, yeah, I'd already be connected and in the IDE.

So - given the numerous ways this could be accomplished, both efficiently and inefficiently, I return to my original idea of there being an "easy" way to include the sketch name.

It would be great if the functionality were something like a reserved word that the Arduino IDE uses, so the IDE handles any filename or path manipulation, and then simply injects the sketch name into the sketch as if it were hand typed by the developer. That way, the IDE does the work, and the sketch is only bloated by 30 or so bytes to contain the sketch name. I don't think there is a dynamic (programatic) way to do the same task in less space than that. (And yes, the concept would possibly break in alternate IDE like XCode or Eclipse)

Thanks to everyone for your input. This is great stuff.

An old thread, but it didn't seem to reach a satisfactory conclusion, so how about this quick suggestion which I'm now using:

Maintain a short macro in the code, along with a very few words referencing the change:

#define SKETCH_VERSION "03c"
// 2018_01_03 07:52 03c Humidity
// 2018_01_02 18:13 03b WiFi.macAddress

And then at the start of setup() print it to the Serial Monitor:

  Serial.println(SKETCH_VERSION);

For what it's worth, I do use stickers on the chips with just an index number.
In a spreadsheet, I keep information on the chip e.g. "raw", with bootloader, etc.
Out of habit and the ability of losing track of changes to sketches, I comment lines with with at least a date and use "save as" a lot.
I like to put the sketch name in the setup area and print it.
The easiest way I've found to get the sketch name is go to the tab dropdown (top right), select rename and copy (CTRL + C). I add this because the IDE does not have a contextual copy for this. It's also a pain not being able to highlight stuff in the serial monitor and do a copy without using CTRL + C