user9953: I am now programming for two Arduinos. One is used as Tx and the other is Rx. Of course they are programmed by different codes, but they share some same .h files I programmed(let's say 'share.h'), which are not libraries and shouldn't be put in Arduino's 'library' folder. 
So I put 'share.h' and main.ino in one folder, and the ino is like:
#include "share.h"
#define TX
#ifdef TX
void setup(){...something for Tx...}
void loop(){...}
#else
void setup(){...something for Rx...}
void loop(){...}
#endif

The shortage is that every time I want to update my code to the two unos, I have to: first change the board port to 40(the Tx uno) in ide, add the #define line, and upload. Then I have to change port to 42(the Rx one), comment the #define line and upload. So inconvenient! 
So do you have any good ideas? Much appreciation!

user4143: Because you're using Windows there is no easy way of doing what you want to do.
If you were on Linux or OS X you would be able to create a symbolic link so that your shared file can exist in more than one location:
$ ln -s /path/to/real/share.h share.h

On Windows there is then just two options that I can think of:

Turn your shared file into a library.  I don't know why you are so adverse to this, since it is by far the simplest option.  Just create a folder "MyProjectShared" in your libraries folder, then name you shared header "MyProjectShared.h" within that folder.  Then #include <MyProjectShared.h>.  Of course, choose a sensible name not MyProjectShared.
Change to a different IDE that will allow you to add include locations.  One example is my UECIDE which allows you to add the line:
#pragma parameter board.flags=-IC:/Path/To/Other/Includes

to the top of your sketch, which adds another location to find header files while compiling.
Another thought has just occurred to me.  If the two sketches are side by side in a folder (say Arduino/Sketch1 and Arduino/Sketch2) then you may be able to use a relative path.
In Sketch2, do:
#include "../Sketch1/share.h"


user9953: Thanks to everybody, now I get a better solution. It is changing the build path to our working directory, and then we can use relative path!
Here are the deatiled steps:

Click IDE's File-Preferences and find where it storages preferences.txt. Mine is at C:\Users\Administrator\AppData\Roaming\Arduino15\preferences.txt
In the txt file add this line: build.path=D:\MyProject\ArduinoBuild. This means let Arduino put the temp files in this directory, such as the .h waiting to compile.
Because the .h Arduino automatically generated from our .ino is in ArduinoBuild directory, you can now use #include "./../Share/SomeShare.h" in order to include the D:\MyProject\Share\SomeShare.h

Here is the same question asked in another stackexchange board: Here

user-1: You can feed the compiler a command-line switch, -D<define_name>, so for your TX you could have a project that has -DTX and for the RX -DRX.
Then you can share the code between the two projects and you don't need to change the code when you're compiling.

user10794: I confronted this exact issue a little while back when writing some sketches that hard shared information. In particular github.com/nickgammon/arduino_sketches
Whilst another IDE may help, I wanted to make my sketches usable by people with the default IDE.
There are a few (annoying) issues here:

You can't use relative folders as suggested in another answer, because the IDE copies your current sketch folder to a temporary folder and compiles from there. It won't copy other nearby folders that happen to be mentioned in .h files.
You can make soft links (in Linux anyway) as suggested, however that makes it hard to do Git control on them. My first attempt had the link (only) appear in GitHub, which meant that the links didn't compile, once you downloaded them (via the .zip file option in GitHub).
I switched to hard links, but then had another issue. If you edit a file in the IDE, and save it, evidently this becomes a new file, and so the files in other folders, which are now hard-linked, have the older version and not the newer version.


The best solution I could come up with (and I am open to suggestions) was to have a "master" sketch - which has the "real" files you want to include. The other folders have links to them. However if you change the master folder you have to recreate the hard links. I wrote a shell script to do that, but it is still an ugly solution. However since it is a manual process anyway, under Windows you could simply make a copy of the files, when you change the master one.
The other (simpler) alternative would be to make a library, and then simply change the files in that library. That gives you better Git management. The only thing is that you have to edit the library, and then go and test the sketch. It's not that bad.

And I found that after I added the h as library, no matter how I change the content of the h, the first version is always used in ide.

That shouldn't happen unless the IDE doesn't expect the library to change in-between compiles. If that is the case, even the library idea has flaws.

user10214: Ok, first of all you have to answer this question:

How can I tell the compiler what program it should compile?

The first (and easiest) solution is to have the preprocessor to this job. It's just a matter of writing two /...
Personally, instead of wrapping everything in an ifdef, I would have done something like
#include "share.h"
#define TX
#ifdef TX
#define setup_tx() setup()
#define loop_tx() loop()
#else
#define setup_rx() setup()
#define loop_rx() loop()
#endif

void setup_tx(){...}
void loop_tx(){...}

void setup_rx(){...}
void loop_rx(){...}

This way I could put the two different setup/loop pairs in two different files (e.g. tx.ino and rx.ino). Moreover the ifdef block can be moved in an h file.
NOTE: I'm not sure wheter the function redefinition works well, because I never tried it. If it doesn't work you can try doing the opposite (i.e. #define setup() setup_tx() and so on) or, in the end, make single-line functions (i.e. void setup(){setup_tx();} and so on).
Another solution can be applied if the processors are different. For instance if you have an Arduino UNO as transmitter and an Arduino Mega 2560 as a receiver, you could write:
#ifdef __AVR_ATmega2560__
- receiver functions
#else
- transmitter functions
#endif

But this would require you to switch processor along with the port.
The third solution is to place the shared h file in an include directory. You can do this by using a common include dir:

The include path includes the sketch's directory, the target directory (/hardware/core//) and the avr include directory (/hardware/tools/avr/avr/include/), as well as any library directories (in /hardware/libraries/) which contain a header file which is included by the main sketch file.

(See here)
You can also pass the -Idir option to avr-gcc to include also dir in the include dirs list, but this requires you to change the boards.txt file.
The last solution I can think at is to compile both programs, load the same files on both arduinos and then choose at runtime what is the correct program to use by assinging a pin to the "choice of program" function.
For instance you assing pin 8 to this function. On the TX board you connect pin 8 to VCC, while on the RX board you connect it to GND. Then the program is:
#include "share.h"

// Loop function callback (to speed things up)
typedef void (*loopfunction)();
loopfunction currentloop;

const int RXTX_PIN = 8;

void setup()
{
    pinMode(RXTX_PIN,INPUT);
    if (digitalRead(RXTX_PIN))
    {
        setup_tx();
        currentloop = loop_tx;
    }
    else
    {
        setup_rx();
        currentloop = loop_rx;
    }
}

void loop()
{
    currentloop();
}

void setup_tx(){...}
void loop_tx(){...}

void setup_rx(){...}
void loop_rx(){...}

IMHO the best solution is the first one, i.e. the define one. But... You should choose the best for your particular problem.
Bye

9953: <p>I am now programming for two Arduinos. One is used as Tx and the other is Rx. Of course they are programmed by different codes, but they share some same .h files I programmed(let's say 'share.h'), which are not libraries and shouldn't be put in Arduino's 'library' folder. </p>

<p>So I put 'share.h' and main.ino in one folder, and the ino is like:</p>

<pre><code>#include "share.h"
#define TX
#ifdef TX
void setup(){...something for Tx...}
void loop(){...}
#else
void setup(){...something for Rx...}
void loop(){...}
#endif
</code></pre>

<p>The shortage is that every time I want to update my code to the two unos, I have to: first change the board port to 40(the Tx uno) in ide, add the <code>#define</code> line, and upload. Then I have to change port to 42(the Rx one), comment the <code>#define</code> line and upload. So inconvenient! </p>

<p>So do you have any good ideas? Much appreciation!</p>
 4143: <p>Because you're using Windows there is no easy way of doing what you want to do.</p>

<p>If you were on Linux or OS X you would be able to create a <em>symbolic link</em> so that your shared file can exist in more than one location:</p>

<pre><code>$ ln -s /path/to/real/share.h share.h
</code></pre>

<p>On Windows there is then just two options that I can think of:</p>

<ol>
<li><p>Turn your shared file into a library.  I don't know why you are so adverse to this, since it is by far the simplest option.  Just create a folder "MyProjectShared" in your libraries folder, then name you shared header "MyProjectShared.h" within that folder.  Then <code>#include &lt;MyProjectShared.h&gt;</code>.  Of course, choose a sensible name not MyProjectShared.</p></li>
<li><p>Change to a different IDE that will allow you to add include locations.  One example is my <a href="http://uecide.org/beta" rel="nofollow">UECIDE</a> which allows you to add the line:</p>

<p>#pragma parameter board.flags=-IC:/Path/To/Other/Includes</p></li>
</ol>

<p>to the top of your sketch, which adds another location to find header files while compiling.</p>

<p>Another thought has just occurred to me.  If the two sketches are side by side in a folder (say Arduino/Sketch1 and Arduino/Sketch2) then you may be able to use a relative path.</p>

<p>In Sketch2, do:</p>

<pre><code>#include "../Sketch1/share.h"
</code></pre>
 9953: <p>Thanks to everybody, now I get a better solution. It is changing the <code>build path</code> to our working directory, and then we can use relative path!</p>

<p>Here are the deatiled steps:</p>

<ol>
<li>Click IDE's <code>File-Preferences</code> and find where it storages <code>preferences.txt</code>. Mine is at <code>C:\Users\Administrator\AppData\Roaming\Arduino15\preferences.txt</code></li>
<li>In the txt file add this line: <code>build.path=D:\MyProject\ArduinoBuild</code>. This means let Arduino put the temp files in this directory, such as the <code>.h</code> waiting to compile.</li>
<li>Because the <code>.h</code> Arduino automatically generated from our <code>.ino</code> is in <code>ArduinoBuild</code> directory, you can now use <code>#include "./../Share/SomeShare.h"</code> in order to include the <code>D:\MyProject\Share\SomeShare.h</code></li>
</ol>

<p>Here is the same question asked in another stackexchange board: <a href="https://stackoverflow.com/questions/31357207/how-to-program-for-two-arduinos-with-different-code-but-share-one-same-h/">Here</a></p>
 -1: <p>You can feed the compiler a <a href="https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html" rel="nofollow">command-line switch</a>, <code>-D&lt;define_name&gt;</code>, so for your TX you could have a project that has <code>-DTX</code> and for the RX <code>-DRX</code>.</p>

<p>Then you can share the code between the two projects and you don't need to change the code when you're compiling.</p>
 10794: <p>I confronted this exact issue a little while back when writing some sketches that hard shared information. In particular <a href="https://github.com/nickgammon/arduino_sketches" rel="nofollow">github.com/nickgammon/arduino_sketches</a></p>

<p>Whilst another IDE may help, I wanted to make my sketches usable by people with the default IDE.</p>

<p>There are a few (annoying) issues here:</p>

<ul>
<li><p>You can't use relative folders as suggested in another answer, because the IDE copies your <em>current</em> sketch folder to a temporary folder and compiles from there. It won't copy other nearby folders that happen to be mentioned in .h files.</p></li>
<li><p>You can make soft links (in Linux anyway) as suggested, however that makes it hard to do Git control on them. My first attempt had the link (only) appear in GitHub, which meant that the links didn't compile, once you downloaded them (via the .zip file option in GitHub).</p></li>
<li><p>I switched to hard links, but then had another issue. If you edit a file in the IDE, and save it, evidently this becomes a new file, and so the files in other folders, which are now hard-linked, have the older version and not the newer version.</p></li>
</ul>

<hr>

<p>The best solution I could come up with (and I am open to suggestions) was to have a "master" sketch - which has the "real" files you want to include. The other folders have links to them. However if you change the master folder you have to recreate the hard links. I wrote a shell script to do that, but it is still an ugly solution. However since it is a manual process anyway, under Windows you could simply make a copy of the files, when you change the master one.</p>

<p>The other (simpler) alternative would be to make a library, and then simply change the files in that library. That gives you better Git management. The only thing is that you have to edit the library, and then go and test the sketch. It's not that bad.</p>

<blockquote>
  <p>And I found that after I added the h as library, no matter how I change the content of the h, the first version is always used in ide.</p>
</blockquote>

<p>That shouldn't happen unless the IDE doesn't expect the library to change in-between compiles. If that is the case, even the library idea has flaws.</p>
 10214: <p>Ok, first of all you have to answer this question:</p>

<blockquote>
  <p>How can I tell the compiler what program it should compile?</p>
</blockquote>

<p><strong>The first</strong> (and easiest) solution is to have the preprocessor to this job. It's just a matter of writing two <code>/</code>...</p>

<p>Personally, instead of wrapping everything in an <code>ifdef</code>, I would have done something like</p>

<pre><code>#include "share.h"
#define TX
#ifdef TX
#define setup_tx() setup()
#define loop_tx() loop()
#else
#define setup_rx() setup()
#define loop_rx() loop()
#endif

void setup_tx(){...}
void loop_tx(){...}

void setup_rx(){...}
void loop_rx(){...}
</code></pre>

<p>This way I could put the two different setup/loop pairs in two different files (e.g. tx.ino and rx.ino). Moreover the <code>ifdef</code> block can be moved in an h file.</p>

<p>NOTE: I'm not sure wheter the function redefinition works well, because I never tried it. If it doesn't work you can try doing the opposite (i.e. <code>#define setup() setup_tx()</code> and so on) or, in the end, make single-line functions (i.e. <code>void setup(){setup_tx();}</code> and so on).</p>

<p><strong>Another</strong> solution can be applied if the processors are different. For instance if you have an Arduino UNO as transmitter and an Arduino Mega 2560 as a receiver, you could write:</p>

<pre><code>#ifdef __AVR_ATmega2560__
- receiver functions
#else
- transmitter functions
#endif
</code></pre>

<p>But this would require you to switch processor along with the port.</p>

<p>The <strong>third</strong> solution is to place the shared h file in an include directory. You can do this by using a common include dir:</p>

<blockquote>
  <p>The include path includes the sketch's directory, the target directory (/hardware/core//) and the avr include directory (/hardware/tools/avr/avr/include/), as well as any library directories (in /hardware/libraries/) which contain a header file which is included by the main sketch file.</p>
</blockquote>

<p>(See <a href="https://www.arduino.cc/en/Hacking/BuildProcess" rel="nofollow">here</a>)</p>

<p>You can also pass the <code>-Idir</code> option to avr-gcc to include also <code>dir</code> in the include dirs list, but this requires you to change the boards.txt file.</p>

<p>The <strong>last</strong> solution I can think at is to compile both programs, load the same files on both arduinos and then choose at runtime what is the correct program to use by assinging a pin to the "choice of program" function.</p>

<p>For instance you assing pin 8 to this function. On the TX board you connect pin 8 to VCC, while on the RX board you connect it to GND. Then the program is:</p>

<pre><code>#include "share.h"

// Loop function callback (to speed things up)
typedef void (*loopfunction)();
loopfunction currentloop;

const int RXTX_PIN = 8;

void setup()
{
    pinMode(RXTX_PIN,INPUT);
    if (digitalRead(RXTX_PIN))
    {
        setup_tx();
        currentloop = loop_tx;
    }
    else
    {
        setup_rx();
        currentloop = loop_rx;
    }
}

void loop()
{
    currentloop();
}

void setup_tx(){...}
void loop_tx(){...}

void setup_rx(){...}
void loop_rx(){...}
</code></pre>

<p>IMHO the best solution is the first one, i.e. the define one. But... You should choose the best for your particular problem.</p>

<p>Bye</p>
