7.13 KB
Newer Older
Patrick's avatar
Patrick committed
1 2 3
Intermediate Microcontrollers

Patrick's avatar
Patrick committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
This course follows on from [introduction to Microcontrollers](
and extends the inital learning about what microcontrollers are, how to program
them (Arduino in particular), and how to connect up other basic pieces of electronics
to them, and toggle the pins, read the pins, vary the output voltage, and read
a variable voltage back in.

Next, we'll be using the course-specific shield called "Red-Peg" to connect more
advanced ICs, read voltages with greater resolution, attach 4-20mA sensors,
store and keep track of time, and record readings onto an on-board SD card.

You will need:

 * a recent version of the Arduino IDE (>1.6.5) (from [](,
 * an Arduino Uno and USB cable,
 * a Red-Peg shield with battery and SD card,
 * a TMP36 temperature sensor,
 * a 4-20mA calibration unit,
 * the most recent version of this document from: [](

Patrick's avatar
Patrick committed
23 24
# Recap

Patrick's avatar
Patrick committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
In the last course, we covered:

 * installing the Arduino integrated development environment (IDE),
 * the 3 parts of an Arduino sketch:

   - Global variable scope,
   - `void setup() {}`,
   - `void loop() {}`

 * Inbuilt functions such as:

   - `pinMode(pin,INPUT/OUTPUT);``
   - `digitalWrite(pin, HIGH/LOW);`
   - `result = digitalRead(pin);`
   - `analogWrite(pin, value);`
   - `value = analogRead(pin);`

 * and inbuilt libraries, such as the Serial connection,

   - `Serial.begin(BAUD);`
   - `Serial.print(value);`
   - `Serial.print("String");`
   - `Serial.println("with new-line");`

# Libraries

Libraries are just snippets of code that you can re-use in your own sketches to
give an easy way of doing something. Rather that writing your own functions, you
can re-use something that someone else has written.

For common activities this makes a lot of sense, and you've already used libraries
without even realising it. The "Arduino Programming language" is really a set of
helper functions that make it easier to program the boards. Typing `digitalWrite(2, HIGH);`
in your code is a lot easier than finding the lookup for the byte array that
controls the setting of pin 2, making a bitwise `and` to shift your byte in and
setting it to `1`.

Library functions wrap up or abstract away the lower level commands and enable you
to focus on the program flow. As long as you trust the library author!

Using library functions means you can toggle a pin, send data over the serial port,
pick a very random number, receive a morse code signal, talk to another chip to set
and get data and write to an SD card, all without having to know all the low level
operations used to do that.

## Installing Libraries

There are two ways to install libraries, the manual way, and the newer automatic
downloader. You can use the manual way to install any library that you find on
the internet, but if you have an Arduino IDE version of 1.6.5 or newer (check
the title bar in the window) you can use the automatic downloader to get any
libraries that have been submitted for inclusion.

Just adding the library folder to the `ArduinoSketchbook/libraries/` folder on
your computer and restarting the IDE is enough to make the library available
for inclusion in your sketch. If the library is formatted correctly, it will
make a number of example files available too.

For newer IDE versions and submitted, versioned libraries, just going to the
Library Manager and searching for the name or function of the library and clicking
`install` is enought to set everything up.

## Lewis

A while ago, I wrote a library that takes input and output pins, and allows you
to send and recive morse code signals by using the same `print()` and `read()`
functions as are in the Serial library.

Rather than creating functions that flash a pin at the right rate (say `dot()`
and `dash()`), then writing those in a list to flash out `"SOS"`, you can just
use the function `Morse.write("SOS");`. Then changing the message is easy, just
change the string.

It also means you can receive messages and change the microcontroller's behaviour.

char c =;
if (c == 'k') {
  // if the incoming letter is a 'k',
  // reply by saying 'y'
You can install *Lewis* either by downloading the zip file from
[]( and restarting the
Arduino IDE; or by going to the
`Sketch` → `Include Library` → `Libraries Manager`, searching for `Lewis` and
installing the most recent version.

After installing the library, you should be able to go to;
`File` → `Examples` → `Lewis` and select and example sketch to try.

## Using a library

Although your new functionallity is installed for the IDE to access, you still
have to include the library code in your particular sketch to make it work. This
means you only use the code you intend for your particular application, and
there's no clashing with other, unused libraries that might not work together.

Including a library means using a compiler function which says, "Put the whole
contents of this file in the sketch at this point". You can include any file
that you like (although any other `.ino, .pde` and `.h` files in the sketch
directory will already be included automatically), but just the *header* files
for the library will include the definitions, variables and functions that you
need to make it work.

To include the Lewis library, at the top of your sketch, in the global scope, use:

#include <Lewis.h>

Then you may (normally) need to instantiate the library, to give it a function
definition, though some libraries do this automatically; just check the documentation
for your chosen library to be sure — it does have some documentation right?!.

For *Lewis* you need to create a named object that refers to the library, so we
can use that name to call the Lewis version of `print()`, rather than the Serial
version. To do this, after the `#include` but still in the global scope, call:

Lewis Morse;

That sets a Lewis object called `Morse` we can refer to. You can have points if
you realised why the library is called Lewis by this point!

Typically the use of library needs some standard variables setting, or some
specific choises of settings. In Arduino sketches, this is normally done through
a `begin()` function. `Serial.begin(BAUD)` take the baud rate at which to clock
out and listen to the data. As this only needs to happen once, the begin call
is normally placed in the `setup()` function.

For *Lewis*, there are a couple of options. For the standard settings on pin `9`,


Or for more options, you can set:

Morse.begin(rx_pin, tx_pin, wpm_rate, use_interrupts);

With your library begun, you can start to use the functions. For Lewis, you can:

 * `Morse.print("A string"); // send out some characters`
 * `Morse.print(variable); // print the number in a variable`
 * `Morse.write('c'); // one character`
 * `char c =; // receive the next character`
 * `int num_chars = Morse.available(); // are there any characters already received?`

Patrick's avatar
Patrick committed
180 181 182 183
# 4–20mA Sensors

# Real time clock

Patrick's avatar
Patrick committed
# The Red-Peg library
Patrick's avatar
Patrick committed

Patrick's avatar
Patrick committed
# Logging to SD card