Indentation: indent everything at 2 SPACES. Again, SPACES. DO NOT USE TABS. This is important (and fortunately pretty easy to remember :) ).
There are too many examples where tabs completely destroyed the readability of source code. Most editors have an "insert
spaces instead of tabs" option; use it, and set your "tab size" to 2.
Also, indent "{" and "}" on their own lines:

if( i == 2 )
{
// some code here
}
else
{
// some other code here
}

Or:

void f( int i )
{
// function code
}

Do not enclose single statements in {} when given a choice. For example, do this:

if( i == 2 )
return;

instead of this:

if( i == 2 )
{
return;
}

Also, follow the "one statement per line" rule. In other words, don’t do this:

if( i == 2 ) return;

Do this instead:

if( i == 2 )
return;

Note that eLua code does not use a space between the function name and its parameter list when calling/defining it (like in the Lua code, for example). So do this:

void f( int i )
{
// function code here
}
f( 2 ); // function call

instead of this:

void f ( int i )
{
// function code here
}
f ( 2 ); // function call

line terminators: THIS IS IMPORTANT Use UNIX style (LF) line terminators, not DOS (CR/LF) or old Mac (CR) line terminators.

identifier names: use a "GNU-style" here, with underlines and all lowercase:

DO NOT USE HUNGARIAN NOTATION (like iNumber, sString, fFloat … if you don’t know what that is, it’s fine, as it means that we don’t need to worry about it :) ). It has its advantages
when used properly, it’s just not for eLua.

You can see in this example an accepted violation of the "one statement per line" rule: it’s OK to write "else if (newcondition)" on the same line.

use specific data types as much as possible. In this context, specific data types refers to generic types that have the same size on all
platforms. They are defined by each platform in turn and their meaning is given below:

s8: signed 8-bit integer

u8: unsigned 8-bit integer

s16: signed 16-bit integer

u16: unsigned 16-bit integer

s32: signed 32-bit integer

u32: unsigned 32-bit integer

s64: signed 64-bit integer

u64: unsigned 64-bit integer

By writing your code to take advantage of these specific data types you ensure high portability of the code amongst different hardware platforms. Don’t
overuse this rule though. For example, a for loop has generally an int index, which is perfectly fine. But when you specify a timeout that
must fit in 32 bits, definitely declare it as u32 instead of unsigned int.

comments: we generally favor C++ style comments (//), but it’s perfectly OK to use C style (/\**/) comments. The use of automatic documentation generators like Doxygen isn’t encouraged,
since they tend to make the programmer over-document the code to the point where it becomes hard to read because of the documentation alone. Ideally, you’d neither over-document, nor
under-document your code; just document it as much as you think is needed, without getting into too much details, but also without omitting important information. In particular, DON’T do this:

When something is self-obvious from the context, documenting it more is pointless and decreases readability.

pseudo name-spaces: since we don’t have namespaces in C, I like to "emulate" them by prefixing anything (constants, variables, functions) in a file with something that identifies that
file uniquely (most likely its name, but this is not a definite rule). For example, a file called "uart.c" would look like this:

Also, if you’re using 3rd party code (from a library/support package for example) making it follow the above rules is nice, but not mandatory. Focus on functionality and writing your own
code properly, and come back to indent other people’s code when you really don’t have anything better to do with your time.