Coding The Arduino – Comments

By Andy Joel

This is some comments and observations that people may find useful; stuff I learned along the way that is general to coding an Arduino, rather than specific to our project. I am not a coder by trade, but have nevertheless used several languages, so much of this is things I found surprising coming to C++.

Binary and Hexadecimal

Computers work in binary, or base 2, while people use base 10.

In base ten, we have ten digits, from 0 to 9. When you count up, when you reach ten, instead of using a different digit, we revert back to zero, and increment the digit to the left. So at 28 goes to 29, but then the units go back to zero, and we increment the tens, to give 30. At 99, the units again go to zero, adding one to the tens, but now that has to go zero, and we add one to the hundreds, to get to 100.

In binary, we have only two digits, 0 and 1. This is because computers work in off or on; off is 0, on is 1. What happens when we count? Just the same as base ten, except we stop at 1, not 9. So 0, 1… but then the units go back to zero, and we increment the next column, to give 10, then 11. At 11, the units again go to zero, adding one to the next column, but now that has to go zero, and we add one to the column after that, to get to 100.

In hexadecimal, we have 16 digits! to pad them out, the letters A to F are used. After 9, we go A, B, C, D, E, F and then, we before we go back to zero, adding one to the column to the left.

10       2    16
 1       1     1
 2      10     2
 3      11     3
 4     100     4
 5     101     5
 6     110     6
 7     111     7
 8    1000     8
 9    1001     9
10    1010     A
11    1011     B
12    1100     C
13    1101     D
14    1110     E
15    1111     F
16   10000    10

The advantage of hexadecimal is that it aligns moderately well to binary. At 16, both hexadecimal and binary are nice round numbers.

Hexadecimal numbers are usually denoted by having a zero and an x at the start. So 0x40 is different to 40, it is actually 64, and 0x41 is 65. This is cart of C++, so the compiler will under 0x40 to be 64 too.

More on hexadecimal here

Functions (and methods)

Functions are blocks of code that we think we might want to use several times. Rather than copy-and-paste each time, create a single function. Functions can be sent values, called arguments or parameters. They can also return values. In C++ you can only return one or zero values. A function that returns zero values has “void” before the name.

 

Convert to String

C++ is strongly ytyped, which means the compiler will complain if you use an integetrwhere is expects a string. If you want a number inserted into a string, you must first convert it to a string.

To convert a number to a string, use:

String(n)

 

Length of Array

To get the length of an array (in this example servo_configs):

sizeof(servo_configs)/sizeof(servo_configs[0]);

I find this utter ridiculous. Any halfway decent language has a simple mechanism to get the length of an array. And C++ know how long it is, because it can iterate over an array with no problem.

 

Assign of data structures

This creates a copy. This is not at all what most people would expect.

Say we have an arrange of servos, called servos; they are of the type ServoData. Each servo has an attribute, current_angle.

In any normal language, you can assign the servo to a temporary variable, and then do stuff with that.

ServoData s = servos[count];
s.current_angle = 90;

That does not work in C++. In C++ s is a copy of the data, not the data itself. Setting current_angle on the copy has no effect on the original data.

 

Preprocessor directives

The first part of a C++ program is the “preprocessor directives”. This is a hang over from the seventies, when computers were slow. Code was run through the pre-processor first, then it would go through the compiler.

Nowadays it is just an acronym, but we are stuck with it.

Preprocessor directives can be used to set up constants and to handle libraries.

And handling libraries is awful… Firstly, libraries have to be split into two parts, the header and the content. The header gives the compiler the first line of all the the functions in the body, but you have to give them again in the body! Again a hang-over from the seventies.

Libraries can include libraries too, and it two libraries both include a third, the compiler will not handle it, so libraries – and possibly code too – have to use further preprocessor directives to check if another library has already been included, and to include if if it has not, and then to flag that it has included it so other libraries do not. Modern languages handle that for you.

In fairness, modern languages do it because they have learnt from the mistakes made in the design of C++, but…

 

Classes are private