Need a little help making my code shorter

I've gone beyond my limit to track what's going on with my code. It's too long. I've used classes to separate them into several files, like buttons.h and buttons.cpp.

But the rest of my code is inter-related, sharing defined variables. It's grown over 2000 lines and very hard to work on.

I tried to separate the chunk without luck. I wonder if I could separate the main file into a few separate files so they're easy to read but still compile as one file so the hassle of includes and externs are gone.

Thank you!

Why is it hard to work with your code. Do you you have too many special cases to handle? Is there log of ugly code to handle your hardware?

Usually, if your code is confusing it's a sign that your design or the basic requirement is confusing. Before spreading the code over many files, I would first structure the file you have visually with comments or rework the basic structure.

To reduce the complexity, it sometimes helps to introduce a configuration singleton, use a state machine, use templates or some other technique. But to know which is the best to use, one need to understand the problem first.
Korman

Often when code gets long a lot is unessential or repeated, I have found that re-arranging functions into logical order in the source is a good start, and looking for similarities in code that can be placed in its own function to replace several blocks, even if the code has to be modified to make it more general.

Another thing I have done in projects is to re-write from scratch with a top down approach, where most of the main loop is calls to functions, while it may be slightly less efficient to use multiple calls it makes readability and maintainability easier. It also gives you the advantage of fore-thought by re-thinking how you achieved the result the first time, and can it be done better and clearer?

One thing the arduino environment would benefit from is a function list to be able to jump to a function, or even click on a call and go to the definition, both would be a great asset to navigating!

As for multiple files, splitting out lower level groups into a file is ok, but you end up with the same code in multiple windows at the best if you need to make changes!

I did everything I could. My project just has too many functionalities. Its structure is like this:

Main loop switches case on system state

If it is menu, run the menu, else run functions as the state indicates.

Switch case if a menu is selected (25 items and growing), after menu selection a preparation function is run to prep for each function to be run repeatedly.

State is switched to that function and Loop() hits end and next round will run the function selected until the function decides it's time to swtich back to menu state.

My problem: I just have too many items on my menu. I tried my best to combine subroutines so several functions will supply different parameters to a common subroutine, like displaying LCD messages and measuring on input pins. Still the scale of the program is too large. About 400 lines are encapsulated in include files and classes but the other 2000 lines are not able to do it.

I think, if I try to redefine some of those functions to have separate variables instead of sharing the variables, I can move them to a separate file. But to save SRAM space I can't have all of them store static variables when they need to store historical data for calculations. I can't just duplicate string literials for lcd messages either cause I'm 25K/30K on my flash ram.

I am looking for a way that makes multipel files share a name space (right term?) so they compile like one file. This way it's easy on me to find where each function is. Is it possible with arduino IDE?

Thank you!

You could remove redundancy in string literals, its a common method in assembly programs, there are various methods it depends on how much redundancy you have!

They're all removed. Everything that needs to be displayed is stored in progmem.

My Point is is there or is there not a way to split my main program.pde into two or more files and compile them as one file?

Just #include :-

void setup(){} ;

#include "C:\Users\Daz\Desktop\arduino-0019\libraries\loop.c"

loop.c

void loop(){} ;

Just make sure the #include is in the right place if it matters in the program!

Given the IDE the easiest thing might be to break it up into multiple files with, perhaps, the extension '.c'. Then in your PDE file -

#include "Segment1.c"
#include "Segment2.c"
#include "Segment....c"

You can split your program in as many sketch files as you like. They will be all combined before compiling.

http://arduino.cc/en/Hacking/BuildProcess

Thanks guys!
Especially deSilva! The link is explaining everything:

"The Arduino environment performs a few transformations to your main sketch file (the concatenation of all the tabs in the sketch without extensions) before passing it to the avr-gcc compiler. "

So I can just split my main file into several files without extension. I tried .cpp and .pde without success. This doesn't work yet, maybe I'm using 0018 and need 0019. Will try again with 0019!

Now I know why I kept trying and couldn't get it to work!

My very first function in main is:

int hmi_with_update(int current, int lower, int upper, byte inc, void (*update_function)(int))

A little involved, isn't it?

I did the following test to prove that arduino ide doesn't know how to create a declaration for function pointers:

Test 1:
main:

void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

function.pde

void go(void (*update_function)(int))
{
  (*update_function)(100);
}

No go

test_files.cpp: In function 'void loop()':
test_files:8: error: 'go' was not declared in this scope

Test 2:

One file:
main:

void go(void (*update_function)(int))
{
  (*update_function)(100);
}

void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

Passed!

Generated main.cpp:

#include "WProgram.h"
void setup();
void loop();
void del(int de);
void go(void (*update_function)(int))
{
  (*update_function)(100);
}

void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

Notice there is no declaration of go() in sight.

Test 3:

Put go() at the end of the single file:

main:

void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

void go(void (*update_function)(int))
{
  (*update_function)(100);
}

Error:

test_files.cpp: In function 'void loop()':
test_files:6: error: 'go' was not declared in this scope

Test 4:

I write my own declaration and put the function definition in the end:

void go(void (*update_function)(int));
void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

void go(void (*update_function)(int))
{
  (*update_function)(100);
}

Passed!

main.cpp

#include "WProgram.h"
void setup();
void loop();
void del(int de);
void go(void (*update_function)(int));
void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

void go(void (*update_function)(int))
{
  (*update_function)(100);
}

Yeah!

Test 5:
Keep the go() in a separate file and insert the declaration in main file.

main:

void go(void (*update_function)(int));
void setup()
{
}

void loop()
{
  go(del);
}

void del(int de)
{
  delay(de);
}

function.pde

void go(void (*update_function)(int))
{
  (*update_function)(100);
}

Passed!

main.cpp is the same as test 4!

Master programmers aren't that legendary? Maybe I spoke too soon?
Anyway I'm glad it's not me this time. ;D ;D ;D

Turn on verbose compilation or hold down "shift", to see what the compiler is actually doing. I suspect that "concatenates all files" might be a bit simplistic...

I would say you should bite the bullet, put your extern prototypes in .h files, and go the normal multiple module with includes and stuff route. It's the way things are done. If you're using pointers to functions, you can do that too...

The Arduino/Process IDE is made to bring some relief to non-expert C programmers. Alas, there seems to be still some bugs in the pre-compilation handling.
One of he better known is the C++ "call-by-reference" issue. It now seems a similar problem is also with function pointer parameters..

Thanks guys. I will submit this as a bug and hope it gets fixed soon. For now, I just have a declaration in the beginning.

For now, I just have a declaration in the beginning.

I find it to be a generally useful compromise that if I want to use "advanced" C features, I have to write code that is closer to real C. Or perhaps I just don't trust automatic prototype generation :slight_smile: