Practical Electronics For Makers

All about Arduino and electronics

GPS Walker : Get GPS Data With Your Arduino

Introduction : Satellite Story

Back in 1977 I got my first telescope and began watching the night skies.  I trained my telescope on the moon and would stare at the moon for long periods of time trying to understand what I saw.  Next, I would try to point the telescope at various stars that I saw, but the telescope was too weak and I didn't know what I was looking at. I finally obtained a star map and tried hard to discern what I was looking at.  Where was Saturn?  If I could just get a look at those magnificent rings around Saturn I would be amazed.  

One very clear night while l lay on the ground staring at the sky I saw something moving.  It was ever so small, just a pinprick of light, smaller than many of the stars I could see.  It was racing across the sky at an amazing speed.  I wanted to leave to tell someone and show them, but I knew it would be gone so I just stared and wondered.

There Was No Internet (Available to Civilians) In 1977

Back in '77 you couldn't look something like that up.  As a 10 year old I had no idea what I had seen but it was fantastic.  Luckily, I mentioned it to one of my mom's friends who was an engineer and he told me, "You've seen a satellite which is orbiting the Earth."  

The 24 GPS satellites* that make up the system weren't placed into service until 1989** so I saw some other satellite.  I must've been pretty lucky too, since the number of satellites was much smaller back then.

*I thought GPS satellites were geostationary but they are not, they have 12-hour orbits.  

**Edit - found this which says Navstar^ first GPS satellite was put in place in 1978.

GPS Component Talks to Satellites

If you would've told me back then that some day I would be able to build my own device that ran off batteries and fit in my hand which would communicate with a satellite I would've thought you were nuts.  

This is why this little experiment is so exciting to me.  You can build this inexpensive little circuit powered off of 4 AA batteries, connect to the GPS satellites and store the data on an SD card.  

First Look At the Circuit

I got everything (Atmega328p-pu, GPS Component, SD Card reader/writer) onto a small breadboard.  It is a bit ugly because of my long wires but I built this circuit in just a few hours yesterday (Aug. 5, 2018).

 

You can see that I've put the bare Atmega328p-pu chip onto the breadboard.   After programming the chip, using my Arduino Uno board, I took the chip off so I could create a smaller footprint.  I needed to do this because I wanted to walk around with the device and carrying the Arduino Uno board around too, just doesn't make sense.

Won't Run Without the 16Mhz Crystal

As I've detailed in another article (Arduino Uno: Using Your ATMega328p-u As Stand-alone[^]) this circuit won't work properly with the Atmega328 running stand-alone without adding the 16Mhz crystal which you can see in the middle of the board, below the Atmega chip.

Since the wires look a bit jumbled up in the picture, I'll provide you with a nice schematic so you can easily build the circuit.

First, I'll list everything you need.

Project Parts List

  • 1 - 16Mhz Crystal Oscillator - 10 for $5.04 USD (https://amzn.to/2MmYPru ) You only need 1 for this project but these are very inexpensive and you'll probably use more of them for projects later.
  • 2 - 22pF ceramic capacitors (non-polarized) - for use with the Crystal  You can get 50 of them for $5.69 USD (https://amzn.to/2AM3KRz)
  • 1 - GPS Module - I was amazed when I found this for less than $20 -- only $15.66 USD (https://amzn.to/2KvA2zP) Very well made and works better (more precise) than an iPhone set on high granularity.  Amazing!
  • 1 - SD Card Reader/Writer You can get a pack of 5 of these for $8.98 USD (https://amzn.to/2vmi51C)
  • 1 - Arduino Uno You'll use your Uno to program your Atmega328 chip.  This knock-off board is inexpensive, works great and comes with the Atmeg328 installed and USB cable all less than $12 USD (https://amzn.to/2KySU0J). This is the one I use.
  • 1 - Breadboard (https://amzn.to/2vtlCLZ) pack of three for $8.20 USD.
  • AA Battery holders - I use these ones that take two batteries and I connect them serially.  12 of them for $7.99 USD (https://amzn.to/2vkjPJ4)

Now, take a look at the schematic.  You can build the circuit in just less than an hour.

Circuit Details

 

Pin Labels

I've labeled the pins on the Atmega328 by combining a few different methods.  The first number (reading left to right) on each pin is the physical pin number on the Atmega chip.  Physical pin numbers start on the upper left side of the chip and increment down to the bottom and then coninue up the right side of the chip.   I've skipped some pins to save room.  

I've also labeled the pins with their Digital pin numbers (used by the Arduino).  And I've also added their Pin bank numbers (PBx, PDx, etc) that they are referred to when examining the Atmega data sheet.  I've done it this way to insure you can tell which pin you are connecting to.

Here's a very good pin mapping diagram that will help you sort it out (provided by the official Arduino site here^).

Once you build that circuit you can upload the code, insert an SD micro card in the reader/writer and run it.

Arduino Sketch Overview

I've added the Arduino sketch to this article so you can download it.  

The first thing you're probably going to notice if you try building the sketch is that it fails because you (probably) don't have the TinGPS library that it depends on. 

What Is The TinyGPS Library?

TinyGPS is a helper library that formats the GPS data from the raw data that comes from the GPS component into something that is a bit more readable.

In our case we use it to just get the Longitude and Latitude values from the data, but there is more data that can be obtained.

You can get the library at GitHub here^.

You only need the two source files (TinyGPS.cpp, TinyGPS.h).  They need to be in a folder named TinyGPS which you will place under your Arduino IDE libaries folder.  

Since that code is open source, I've placed them in the TinyGPS folder, zipped them up and included them in this article as a download.  That means you can just download the zip, unzip it and drop the TinyGPS folder into your Arduino IDE libraries folder (probably installed under \Program Files x86\.

What The Code Does

This code is based upon a sketch that I found where the author was testing the GPS component^.  That's an informative article and it is very interesting because he found that the GPS component is far more precise than the iPhone's GPS.  However, that author only writes the data to a Bluetooth module and I wanted to write the data to an SD card for later analysis so I have altered the code quite a bit.

The basics of what it does can be summarized in the following few lines of code:

if (latitude<=90 and latitude>=-90 and longitude>-180 and longitude<180){
    dtostrf(latitude,1,4,latitude_str);
    strcat(out_data,latitude_str);
    strcat(out_data,",");
    writeToSD(out_data);

If the value read from the GPS unit is in a valid range then grab the latitude and write it to the SD card.

Then next chunk of code does the same thing longitude values.  

It writes the data every second so if you are moving it will pick up changing values.  It writes the values as float values (to four decimal places) and comma delimits them. The data is saved in a file named gps.txt and looks something like the following:

  • 39.7624,-84.0624
  • 39.7624,-84.0600

That data format is the same that Google Maps will accept and you can copy those coordinates and paste them in and they will show you the location.  Later you can upload multiple points from your SD card capture and create paths that show where the GPS Walker went.

Now, you can power it up with 4 AA batteries and go for a walk.  Of course you can throw it in your car or put in on your bike too.

Here it is running off battery power.

 

The first time you run it you should be outside to get a good signal from the GPS Satellite.  This module seemed to work very well though and it would even pick up the satellite inside my house.

The green LED will let you know when it has connected with the satellite.

Try it out.  I think you'll find it a lot of fun and amazing that you can build this thing that commuicates with a satellite that is 20,000 kilometers away.  

When you obtain your data, you can upload it into Google Maps and use their API to create routes from the data.  

Bluetooth Messenger: Learn to use the HC-05 component with your Arduino

 

Introduction

One of the most exciting things when working with Arduino is getting it to talk to other components. It is not always necessary (or preferable) to have the component connected to the Internet. That's where Bluetooth comes in nicely. There is a very inexpensive (and mostly) easy-to-use component (HC-05) that can be paired with your Arduino so you can control your Arduino remotely. Learning to use the component also provides a great entre into larger Arduino projects you may have in mind.

Background

The Bluetooth module we are going to use is very easy to use with the Arduino. You literally only need four wires to hook it up to your Arduino (VCC, GND, Tx (transmit), Rx (receive). Basically, when the module receives data, it writes it to the Tx pin, sending the data out to the Arduino (in via the Rx pin).

There are a number of things you need to work with a Bluetooth component:

  1. Bluetooth (BT) component (in this article, we are using the HC-05)
  2. A way to send messages over Bluetooth. In this article, we will use the Android app which I wrote for this specific purpose. It is named BTMessenger and I've placed the source code at my GitHub (https://github.com/raddevus/BTMessenger^). It's easy to use. You can type a message and press the [Send] button (more later).
  3. Understanding how the Bluetooth component is configured and how it can be paired with the device you will use to send messages to it. You can use the BT component straight out of the box with default settings (speed 9600 and PIN 1234, name=HC-05) but if you want to change the device to have a nice name and a different PIN, then you'll need to know how configure it. To configure the component, you have to wire it up in a special way and use a Serial app to send AT commands to it. (I will point you to an article I am writing so you'll know the ins & outs of this.)

Point of This Background

The main point I'm trying to make is:

It's very easy to get the HC-05 Bluetooth (BT) component set up and use it for the basics. However, it is quite difficult to customize the component. You will see that there is a lot of mis-information about the component out there and many of them from the numerous manufacturers work slighly different.

Why Not Bluetooth 4.x / BLE?

There are far more details to get BLE (Bluetooth Low Energy) working. I'm planning on doing a larger investigation on BLE in the future since it is wise to move to BLE so you can support iOS apps (iphone, ipad, etc.).

Parts List For This Article

  1. Arduino Uno - I use the Elegoo clone (https://amzn.to/2JOoiIp) about $11 USD
  2. I2C LCD - (https://amzn.to/2NBWl8S) I showed you how to use this in my other article (Discovering What Your Code Is Doing Using a 20x4 LCD With Your Nano[^]) about $10 USD
  3. Bluetooth component / HC-05 (https://amzn.to/2ABeAcQ) $8.99 USD
  4. Breadboard - I use these (https://amzn.to/2uVHteA) about $8.50 USD for 3
  5. Hook up wire: Here’s the wire pack I ordered and I am very happy with (https://amzn.to/2JsVKsz). About $20.

Let's get started using the HC-05 straight out of the box.

Wiring Up the HC-05 and Using It

The HC-05 can run off of 3.6V - 6V so your Uno will provide the correct power off the 5V pin. That makes things very easy. All you have to do is wire up your HC-05 like the following and connect your Uno to your USB port and you will see the HC-05 power up and start fast-blinking an LED.

Why We Used Arduino Pins 10 and 11

The first thing you may be wondering about is why we used pins 10 and 11 for the Rx (receive) and Tx (transmit) pins. You may be familiar with the Uno and understand that pin 0 is the Rx (serial receive) and pin 1 is the Tx (serial transmit).

There are actually two reasons I chose to assign other digital pins to be our Rx and Tx.

  1. Uploading From IDE will Fail: When you go to upload your program to the Uno, the Arduino IDE will use the hardware serial Rx and Tx pins. When the IDE attempts to do that and the HC-05 is connected to those pins, you will find that the upload will fail. That's because the IDE believes the pins are in use and it cannot get a connection to them. Actually, it is just the Rx (pin 1) that it won't be able to connect to. But that means it cannot upload your sketch. It's easy to fix by removing the wire each time, but it is a pain when you're doing development. Using pin 10 for our Rx alleviates this problem.
  2. Using Serial Monitor Will Fail : Also if you want to use the Arduino IDE Serial monitor, you will not be able to since the Bluetooth device would be sitting on the hardware (pin 0 and pin 1) Rx and Tx pins. Connecting to pins 10 and 11 keeps 0 and 1 free for Serial Monitor use.

Get Your Wires Crossed: Rx => Tx and Tx => Rx

It is also important to notice that for the serial communication to work between the HC-05 and the Arduino, we need to make sure:

  1. HC-05 Tx pin is connected to Arduino Uno Rx pin
  2. HC-05 Rx pin is connected to Arduino Uno Tx pin

Take another close look at the first schematic and you'll plainly see that now. I placed the pins on the devices so the wires don't actually cross each other.

What Happens When Bluetooth Message is Sent or Received

You really have to wrap your head around this and think about how it works.

Bluetooth Receive Message

When the HC-05 device receives a message over Bluetooth, it writes that message to its Tx (transmit pin).

Since we want our Uno to receive the messages, we connect the HC-05 Tx pin to the Uno Rx pin (digital 10 in our case).

Bluetooth Send Message

When we want to send a message from the Bluetooth device, we will have the Uno write serial bytes to its Tx pin (digital 11). When we write data to the Uno Tx pin, it will be received by the HC-05 on its Rx pin. The HC-05 sends the data that it receives on its Rx pin by broadcasting it on the Bluetooth signal.

Now, let's write a very simple sketch to receive data and display it in the Serial Monitor.

First Sketch: Display Data In Serial Monitor

Take a look at the HC-05 component.

You can see that it has six pins, but we only need to use four of them. There is also a button (top right of the first picture) that is used when you put the component into configuration mode.

On the back side, the pins are labeled for you. We only use the Rxd, Txd, GND and VCC.

Here's what it looks like all wired up and running.

You can see that the red LED on the HC-05 is on -- it is actually blinking fast indicating that it is ready to receive data.

Now, let's upload some code that will read bytes from Bluetooth and print them out in the Serial Monitor.

Here's the full code listing:

#include <SoftwareSerial.h>

SoftwareSerial BT_Serial(10, 11);

void setup() {
  Serial.begin(19200);
  Serial.println("BT Messenger");
  BT_Serial.begin(38400);
}

void loop() {
  String outMsg;
  int incomingByte;
  byte byteCounter = 0;
  byte words[64];
  
  if (BT_Serial.available() > 0) {
    Serial.println("got data"); 
    incomingByte = BT_Serial.read();
    while (incomingByte > 0){
        words[byteCounter++] = incomingByte;
        Serial.print(incomingByte,DEC);    
        incomingByte = BT_Serial.read();
        Serial.print(" ");
      } // while
      Serial.println("");
      for (int x = 0; x < byteCounter; x++){
        outMsg += char(words[x]);
      } // for
      Serial.println(outMsg);
    } // if (BT_Serial.available()
} // loop()

Get the Code: BTMessenger_v001.zip

Download the code and upload it to your Uno and try it out.

Once you have it running, you'll go back to the Arduino IDE and open the Serial Monitor.

It's under [Tools]...[Serial Monitor]...

When you select that menu item, the Serial Monitor window will open up. If your Uno is attached via USB cable and you've already uploaded the sketch, then it will print an initial message (BT Messenger).

In the bottom right corner of Serial Monitor, notice that we have Carriage Return and LineFeed turned on [Both NL & CR]. We also have the speed set to [19200 baud].

If You See Odd Characters

If you see some odd output, it is probably because the baud rate doesn't match what we've set up in the sketch (19200).

Here's what mine looks like when I set it to 9600 baud. See those odd backwards question marks? If you see garbled output, it is almost always because you haven't matched the baud rate properly.

Let's talk about the code now.

Software Serial

The first thing we do is include the SoftwareSerial library because we are using digital pins 10 and 11 instead of using hardware serial at pins 0 and 1.

Next, we instantiate a SoftwareSerial object by passing in the digital pin for Rx (10) and the digital pin to use for Tx (11). Keep in mind that we are configuring the Uno here.

SoftwareSerial BT_Serial(10, 11); 

We name our Software Serial object BT_Serial so we can reference it throughout the code.

In the setup() method, we initialize both of the Serial devices we will use.

Configuring Software and Hardware Serial

Whenever you see the variable Serial, we are referencing the built-in hardware serial.

This is why we have to set up the Serial Monitor to 19200 because we initialize it to that value in our code.

Serial.begin(19200); // here we set the baud rate to 19200.

Serial.println("BT Messenger"); // here we print text onto the hardware serial. Since the Serial Monitor is connected to it, it will print it out.

Next, we have to initialize the speed of our Software Serial object also. Serial timing is very exact since it is sending bytes at a specific rate. That's why this value must match the speed that the Bluetooth (HC-05) is sent to send and receive data. We initialize it to 38400 because that is the default that the HC-05 is set to.

BT_Serial.begin(38400);

Now, both the serial components are ready to go.

Next, we simply read the data off the Rx line of the Arduino and grab each byte one by one.

Before I explain the rest of the code, take a look at what the output looks like in Serial Monitor after I send a message.

Get the Android App to Send Data

Of course, to send data to the device you write a program. I wrote a very simplified Android app which will let you type data in a TextEdit box and press the [Send] button. Here's a snapshot of the app.

Download APK and Sideload BTMessenger

First, you will need to download the .apk. The easiest way to do that is point your phone or pad at the following URL on my web site: http://raddev.us/btmessenger.apk. When you point your Android device at that URL (from your browser), it will download the APK and ask you if you want to install the app. It isn't signed so it will warn you.

If you don't want to download the app, you can get the source code at my GitHub^ and build it and install it.

Pair Your Android Device With Your Bluetooth Component

After you download and install the app, don't start the app yet. First, you'll need to pair your device with the Bluetooth component. To do that, you need to:

  1. Power up your HC-05 - you have to do this so that the device can scan for the item. The item has to be on for it to find it.
  2. Next, you'll basically open the Bluetooth functionality on your device and then you may have to tell it to scan for new devices.

Here's what it looks like on my device. You can also see it is auto-scanning for new devices and their GUID (globally unique id) addresses are showing up first. After a bit, you will normally see the name of the device so you can identify it more easily.

You can also see I have a lot of paired Bluetooth devices. It's because I've been working with this Arduino Bluetooth stuff for a couple of years now off and on.

When you click one that you want to pair, then a box will come up and you'll have to type the pin. The default is 1234 so you'll type that in and you'll be paired to the device. Once you are paired, you can run the app and the device will show up at the bottom so you can select it and send data to it.

Run the App

Select the name of your Bluetooth device in the bottom spinner (droplist). Yours will probably be named HC-05 which is the default. Mine is named superblue. Type in your message in the top TextEdit field and press the [Send] button.

Check If Data Has Arrived

Of course, the sketch continuously runs the loop() and checks to see if any data has arrived with the following line:

if (BT_Serial.available() > 0)

The available() method is a SoftwareSerial function which returns a number of bytes that are in the serial buffer. There will be bytes in the serial buffer, if the Bluetooth device has received a message, because when the Bluetooth device receives a message, it writes those bytes to its Tx pin. Since the Tx pin of the Bluetooth device is connected to the Rx (receive pin) of the Uno, the Uno has bytes in its serial buffer.

The first thing the sketch does when it gets data is prints "got data" to the hardware serial output which shows up in the Serial Monitor. I do that just so I can know I'm in that part of the code, as a debugging message.

Read the Bytes Out of Serial Buffer

The serial buffer can be up to 64 bytes and we use the following line to read those bytes out and into our own byte buffer so we can do something with them.

incomingByte = BT_Serial.read();

The read() method reads one byte at a time, so I put the sketch into a loop to read all of the available bytes out of the buffer.

Then I print each byte as its byte value with:

Serial.print(incomingByte,DEC);  

That is the code that prints all of the digits on the line following the "got data" line in the Serial Monitor:

After that, I convert each byte into a character and add it to the outMsg string and finally, we print the character-based message into the serial monitor.

That's really all there is to it. But now, you can see that you can send messages to your Arduino over Bluetooth.

The Challenges You May Encounter

There are a few challenges you may encounter and they are almost always related to having the wrong speed set up on something.

It may be that your HC-05 is defaulted to 9600. If that is true, you are going to get garbage output in the Serial Monitor and you'll need to change the line that sets it to 38400 to 9600. That means that instead of the following line in setup():

BT_Serial.begin(38400);

You will have:

BT_Serial.begin(9600);

That's all there is to it. This should get you going so you can begin to communicate over Bluetooth with your Arduino and control your Arduino from your phone by sending it various messages.

Other Bluetooth Information

Other things that you'll want to know is how to change the pin code and the name of your device. There is a way to do that and it isn't terribly difficult, but it does take another circuit setup and some different code. I'll cover this soon on my blog or here at CodeProject. See you then.

History

  • 2018-08-02: First publication

 

Getting Started With Arduino Using the Small, Inexpensive Nano Board

What Do You Need To Know To Get Started With Arduino?

You don’t need any prior electronics experience.  You just need to know how to do basic things with a computer like download software and install it.  

I will walk you through each step of building the beginning circuits that are a part of the article and I will explain what you are doing and what it means as we go.  I’ll also point you toward other resources if you want to deepen your knowledge on topics we touch upon.

What Will You Learn From This Article?

This article will provide you with a walk-thru tutorial which will take you through all the steps from gathering everything you need through getting your Arduino Nano to do something.

Final Project

The final project will include a stand-alone circuit running the Nano from a battery.  This will provide the user with the complete experience of how they might design and create their project and then actually use it in the wild.

Pictorial Walk-thru Provides Experience

I will use numerous pictures in attempt to make the reading of the article a part of your experience, even before you sit down and work through the projects yourself. There are 28 images in this article to help the reader visualize what is happening.  I’m doing this in an effort to provide the reader with an easy way to determine if she wants to get involved more with Arduino development. My hope is that the article will convince the reader that the content :

  • Won’t be overwhelming
  • Will keep her interest
  • Will open up the entire idea of embedded programming so she can see how easy it really can be.

What Will You Need?

I always like to know what I’m going to need ahead of time for my projects so I’ll list all those things here for you.  That way you can get the supplies together ahead of time and have everything you need to get to the end of the article. I’ll also provide Amazon links (I’m a Prime member) so you can see the items and their prices and estimate your costs.

Supply List

Here’s what you’ll need so you can try all of the experiments in this article.

Arduino Nano - You can get three of them at Amazon (https://amzn.to/2JHO58N) for only $13.  That’s barely more than $4 a piece.  Compare that to the Arduino Uno (about  which most beginners start with.

To connect the Nano to your computer, you will need a micro usb cable.  You probably have one laying around somewhere. Here’s a cheap one you can pick up for $5 (https://amzn.to/2y0pzvg)

This cable is how we attach the Nano to our computer so we can upload our Arduino Sketches (programs) to it so the Nano can run them.  If you have an older Playstation (PS3 I believe) you may have some of these because they used Micro USB connectors.

Breadboards - These make your life much easier as you do your experiments because you don’t have to solder anything.  (https://amzn.to/2JFQtgx) About $9.  Instead, you just push the end of the wire into a hole to make a connection.

Wire - For our experiments using bread boards we prefer solid core wire (not stranded) so you can easily push the wire into the bread board.  Here’s the wire pack I ordered and I am very happy with (https://amzn.to/2JsVKsz). About $20.   It’s a good amount of wire in various colors so you can keep your connections straight.  You’ll learn how important that is when you make a project that has a lot of connections and you need to check them.

Wire cutters / strippers - You need a fast way to cut wire to appropriate lengths and to strip the wire.  Here’s a very inexpensive but nice pair of cutters / strippers : (https://amzn.to/2xW9Yg9) About $7.

Resistors : You really only need one 220 Ohm resistor but here is an inexpensive set ($7.99) which will give you numerous useful values https://amzn.to/2HJjeDY They are the ones I use for my experiments.

LEDs : Again you only need one but here is a nice set https://amzn.to/2sNoT7p ($6.49)

If you are not sure you’re going to do more in the future then maybe you just want to buy some jumper wires so you don’t have to cut or strip wires.  These are ready to be plugged into your projects (https://amzn.to/2MeoZNA) About $8.

We are going to do a bit of soldering to get your Nano ready for our experiments, but I promise it won’t be scary.  Here’s a decent soldering iron that includes various tips and some solder, all for only $17.99 : (https://amzn.to/2HDulOR)

9V battery

9V battery connectors : (https://amzn.to/2JPoOtB) $4.94

First Look At Arduino Nano

Let’s jump right in and take a look at what you’ll find when you open up your Nano after receiving it.

You will find that there are actually three additional pieces that come with the Nano.  If you’ve never seen them before it may be a bit confusing. These are called header pins.  They are specifically provided to make it easier to use your Nano on a breadboard. You solder these header pins to the Nano and then it is much easier to connect to your breadboard and then connect other things electrically to each pin on the Nano.

We Call Them Pins Even Though This Board Has Holes

Also, notice that even though we refer to the pins on the Nano, if you do not add the header pins then you basically just have those holes.  However each of the holes you see in the Nano actually leads back to a pin on that square chip in the middle of the board. That square chip on the middle of the board (see next image)  is actually the chip we are programming. On a Nano it is the ATMega328P chip.

Here’s another snapshot of the Nano that I’ve labeled to show what some of the things you are seeing are:

The Micro USB is the connector I mentioned earlier which you will use to connect to your computer.  If you were to count each one of the silver pins coming out of the ATMega328P you would find that there are 8 on each side of the square for a total of 32 pins.That format of the ATMega328P is called QFP (Quad Flat Package).  The chip also comes in other formats like the DIP (Dual Inline Package https://en.wikipedia.org/wiki/Dual_in-line_package).

Each of those pins on the chip provides an interface to control the chip -- to make the chip behave in different ways by reading input from the pin or writing output.  Each of those pins is mapped to the holes along the sides of the Nano.

That is done entirely to make the pins more accessible for your experiments.

If you count the holes on each long side (top and bottom as we are viewing the Nano in the previous picture) you will find that there are 15 on each side for a total of 30.  

There are actually a few other pins on the left side of the Nano that are also mapped to the ATMega328P chip in the middle.

That block of 6 holes (pins) also has a seperate header pin block which can be added to the Nano for easier access.

Reset Button and Indicator LEDs

You can see that the Nano also provides an extremely small button that can be pressed to reboot the chip.  When you press that button the Nano will stop running your program then repower and start your program from the beginning again.

Those extremely small LEDs are very helpful since the second one from the top one (as we are viewing the chip) is a power indicator.  That one will be red when there is sufficient power to the Nano.

The nice thing about this little board is that it will be powered from your computer’s USB port when you connect the cable.   That means while we are developing our project we don’t have to worry about having another power source. You will see that the Nano and other connected devices (like our LED in our first experiment) will be powered from the USB port.

Connect It To Your Computer

Let’s go ahead and see what the board will do when you connect it to your computer, straight out of the package.

This isn’t a great picture, but you can see that the power indicator light is on.  Most Nanos will also already be running a program from the manufacturer called Blink.  

The Blink program is running on mine and it blinks the top LED (above the power indicator) one time every two seconds.  It’s just a simple test app most manufacturers add so you can know the Nano works right out of the package.

What Is Arduino Programming?

If you’ve written software for computers you know you can write a program and run it.  That’s because the inputs (keyboard, mouse) and outputs (display, file system, etc) you need are generally available to you on any computer system.

Things are quite a bit different when programming the Arduino.

With the Nano connected to our computer, we could start up the Arduino IDE (Integrated Development Environment) and send programs to the Nano.  However, writing programs and uploading them to the Nano is only one part of the process. That’s because the Nano doesn’t provide any operating system, no file system (or hardware to capture files on) and not even a display system of any kind beyond the flashing LEDs you’ve seen.

We are actually engaging in a lower level type of programming known as embedded programming.  We will control things at a much lower level than we do when we write software on a computer system like Microsoft Windows.

There are basically two parts to developing an embedded system:

  1. Hardware - build the circuit

  2. Software - write the program which will activate or automate the circuit.

This means there are now two challenges to designing a solution.  The way to manage those challenges is to break them down into small pieces you can work on.  

Understanding Two Things Opens Up How It All Works

A lot of knowing how to design your final product or project is related to knowing:

  1. What capabilities the hardware you’re dealing with has -- what functionality does each ATMega328P pin expose, how much memory does it have, etc.?

  2. What kinds of I/O devices (sensors, displays, etc) can you attach to the pins and how do you work with them?

Everything comes back to connecting things to the pins on the Nano because that is how we can read sensors or output a signal to display something.  That’s why we want the ability to construct circuits around the Nano’s pins.

That’s why we want to solder the headers onto our Nano.

What About Those Header Pins?

The first thing you need to do to make your electronics experimenting life easier is to solder on the header pins. I know.  I know. I felt the same way just a year or two ago. I was worried I’d toast the thing because I don’t have great soldering skills.  I’m going to show you a trick that will allow you to solder the pins on in about ten minutes.

Please Note: I need to solder header pins on a different (but very similar) Arduino board (Pro Micro) so the images where I’m doing the soldering is going to include the Pro Micro board but that doesn’t matter because the way we do the soldering is all the same.

The first thing you want to do to become familiar with your header pins and the Nano is simply try sliding them into the board.  You want the shorter side of the pins to go into the bottom of the board which will expose them slightly at the top. When you have them in properly it will look like the following.  Notice that I’m not going to add the six pin block at the back at this time.

Insuring that the shorter portion of the pins is just sticking through (as it is in the picture) makes it so the pins are long enough to go into the breadboard properly and it makes it far easier to use as little solder as possible to connect the header pins to the pads (holes) on the Nano.

The First Trick To Make The Soldering Easy

The trick to making this all easy is to take the Nano on the header pins and push it into your breadboard, before you do your soldering.  This insures your pins are all aligned nicely and everything will be held nicely so your hands will be free for soldering.

You can see that the pins at the bottom are now pushed securely into the breadboard.  That’s how we’ll use it when we experiment too.

To get the pins pushed down into the breadboard, I sat the Pro Micro on the pin headers and pushed down and rocked as I did.  The Pro Micro one went in fairly easily. But the first time you try it you will probably feel like you are going to break the board.

Another Try Wasn’t So Easy

I decided to go ahead and put a Nano on this same breadboard and solder header pins on it also and I had a bit of a problem with the Nano one.

You can see that at the top there is a pin that is sticking up too far.  As I rocked the Nano a couple of pins (one on the front right also) didn’t quite go down far enough.  If this happens just take something made of metal (maybe even a coin) and push down on each pin until it is level with the others.

If they go too far, you can remove the Nano and grab them with the front of your wire strippers and pull them out a bit. The wire strippers have a nice gripping tool at the front.

None of this is difficult.  It’s all part of the experience.  It’s also a lot of stuff that you don’t see explained very often.

A Warning

It would be kind of nice if we could just start our experiments now without the soldering.  But do not try that. The connection between the pin and the pads is not clean enough before soldering and it will drive you crazy as things work and don’t work due to loose connections.

Here’s How Easy The Soldering Is Now

Here are the steps get your soldering area set up.

Gather everything you need:

  1. Solder

  2. Soldering iron

  3. Soldering iron stand

  4. Nano on breadboard.

Plug in your soldering iron and allow it to heat up.  Please use all proper safety precautions like having a proper stand for the soldering iron and never leave the iron while is it hot.

Extra Soldering Tips

Once your soldering iron is hot keep the following things in mind:

  1. You want to touch the tip of the iron to the pad and the pin and heat them both up (see next image).

  2. Next you want to touch the solder to the pad and the pin so that the pad and the pin melt the solder and “absorb” it into one complete connection.  

  3. When the drop beads up, pull your iron away immediately and the bead of solder will harden.  It should only take 1 or 2 seconds for the pin & pad to heat and solder to melt.

Keep in mind that you don’t want to keep the iron on the pin and pad for long minutes because the heat will trace back up the connections in the board and can heat up the ATMega328P chip and kill it.  Or you could simply melt through the board itself since it is so small.

If you do all of this properly (and I’m sure you will) then a drop of solder will connect the pin to the pad and that is all there is to it.

Want More Soldering Help?

Check out the fantastic SparkFun site and this resource which explains all the details of soldering.  

How to Solder: Through-Hole Soldering - learn.sparkfun.com[^]

Here’s mine. If you look closely you can see a small (duller looking) bead of solder on each pin.

I will assume that you were successful.

Here’s another snapshot of it so you can see that now the pins align with the holes in the breadboard and it’ll be easy to add the Nano to any breadboard whenever I want to do experiments.

One more hint: I like to solder outside to keep everything ventilated.  But if you cannot for some reason then you can also put a little fan pointing at your soldering area to blow the solder smoke away from you.

A Good Idea

A good idea is to take out a multimeter and set it to Continuity Test and touch one multimeter probe to the top of the pin (above the board, where you soldered) and another probe to the bottom of the same pin (under the board) to insure that every pin really is soldered properly.  If the pin is soldered properly then the multimeter will beep to indicate it is a complete connection and you never have to worry about the Nano header pins again since you’ll know they are right.

Now, we’re ready to light this thing up!

Arduino IDE (Integrated Development Environment)

The first thing you need to do is download the Arduino IDE.  It’s not too big and you can get it at the official Arduino site (http://arduino.cc) for free.   Arduino - Software[^]

Download the software and install it.  I won’t show you how to do all of that here, because it basically an installation wizard and is self explanatory.

Once you download it and install it go ahead and start it up.

You’ll see something like the following:

 

This is a basic Arduino program which they call a Sketch. Of course any program we write is going to be paired with some hardware (the Nano, LEDs, displays, potentiometers and more) that we build on our circuit board.

That’s the real power of these embedded chips -- these miniature computers. They allow us to get input from other devices (temperature sensors, etc) and to control other hardware devices like relays or LEDs and more.

Let’s Get Our Nano To Do Something

The easiest thing to get our Nano to do is to light up an LED.  The Blink program that is most likely already on your Nano blinks an on-board LED, but it’s a bit more educational to see the Nano light up an LED that is separate from the board.

The value of this first simple experiment is that the process and the result is basically the same thing you will do whenever you want to control any attached device.  There will just be more details to work through with more advanced devices.

FirstNano : First Experiment

For this first experiment we just need:

  1. your Nano on your breadboard

  2. an LED

  3. a 220 Ohm resistor.

Why Do We Need A Resistor?

Here’s why we need a resistor.  We are going to power your Nano off of the USB port.  The USB port provides 5 volts. The LED will drop that voltage approximately 1.7V.  LEDs are rated at a max current around 20mA (milliamperes).

With no extra resistor, we would have over 500mA flowing through the LED.  We use the resistor to limit the current so we don’t burn out the LED.

With the 220 Ohm resistor included we will only have 15mA of current flowing.

Using Ohm’s Law* we can calculate the current.  

5V - 1.7V = 3.3V

3.3V / 220 = 0.015 (15mA)

*We won’t go into details of Ohm’s law and all the electrical principles here but if you want to read more in depth about electronics try my series of articles here at CP starting with : Practical Electronics For Makers (Part 1 of N)[^]

You will see that we are going to be powering the LED off of one of the pins on the Nano.  That means the current will actually be flowing through that pin and the Nano itself cannot have that much current flowing through it or it will be damaged.  

The max rating for each pin is really only 40mA (milliamperes) so allowing more current to flow would also damage our Nano.

Select A Nano Pin

Now we want to create a circuit where our resistor and LED are connected to one of the pins on the Nano and routes to ground (to create a complete circuit).

We are going to choose a pin somewhat arbitrarily.  We are going to use a digital pin so we can use the Arduino function named digitalWrite().  We could use an analog pin and use the analogWrite() function but again I’m (arbitrarily) showing you how to use the digital pins and digital functions for now.

Why One Pin or The Other

The Nano has a limited number of pins, of course.  So as your projects grow and you use many or all of the available pins, part of your design is in choosing to create your circuit according to what pins are available.

Here’s a zoomed in shot of the Nano so we can take a look at the labels and see which pin is which.

 

I’ve marked one pin (at the top) with a red line that looks like it is labeled V2 or U2 but is actually D2 -- obviously some of the print was scratched off or wasn’t printed properly.  

Digital And Analog Pins

All of the Digital pins are marked DX where X is the pin number.  You can see that most of the digital pins are all on that one side.  The analog pins are marked AX where X is the pin number. You can see that you have more digital pins than analog.  There are Digital pins numbered 2 through 13 (12 total digital pins) and Analog pins numbered 0 through 8 (7 total analog pins).

We are going to use D2 for our first experiment.  We will connect our LED circuit to that pin and we will reference that pin in our Arduino Sketch.

I’ve also marked the GND (ground) pin at the bottom of the Nano (as we’re looking at it) because we are going to use that to complete our circuit.  Every circuit flows from an area of high voltage to a place of low voltage (ground) and so we need our circuit to connect to ground also.

When we connect to the ground pin, we will actually be connecting to the ground supplied by the USB port which is connected to the ground of our computer.  This is only true when we are powered off of the USB port. If we want to run the Nano from batteries (which is possible) then we would have to tie the Nano’s ground to the common ground of our battery supply.

Creating the Simplest Circuit Possible

Now I will create the simplest circuit possible by adding the LED and resistor.  By simplest, I just mean that I didn’t have to add any additional wires to get a complete circuit. I made sure I could get the legs of the LED and resistor to reach properly.

Here’s what it looks like.  

I’ve connected the positive leg of the LED to D2.  (LEDS are polarized and must be aligned properly or they will not allow current flow.)  

I’ve connected the 220 Ohm resistor to the negative leg of the LED. (Resistors are not polarized and work either way.)

I then connect the other end of the resistor to the ground pin (GND) on the Nano to complete the circuit.  

If you need more information on how breadboards work you can read my article here at CP that explains them in depth:  Practical Electronics For Makers (Part 2 of N)[^]

BEWARE : Make sure the legs of your LED and resistor do not touch any of the other pins sticking up off the Nano or you will get a short circuit and possibly strange behavior or possibly even destroy the Nano.

At This Point: Nothing

If we plug the Nano in it still will not do anything.

 

I had to cover the indicator LED up for the picture because it was shining through our separate LED and making it look like it was on.  The LED is not on, because we haven’t written a program or uploaded it to our Nano to turn on pin D2. Let’s do that now.

Back In The IDE

Go back to the Arduino IDE (Integrated Development Environment) and we will type in some code.

In the Setup() function which only runs once, we set the D2 pin for output with the following code.  Since you can read or write from a pin you have to tell it which purpose you are using it for.

void setup() {

 pinMode(2,OUTPUT);

}

We call the pinMode() function that takes a pin value and a special pre-defined constant (OUTPUT) which sets up our pin so we can write to it.  Writing to a pin means setting voltage to a high level which is 5V for the ATMega328P.

That code just sets the pin up but doesn’t do anything to make the LED turn on. For that we need to add some code into the loop() function.

The loop() function code runs continually while the Nano has power.

We want to write to the pin so we use the Arduino function called digitalWrite().

When we call that function we tell it which pin we want to write to. In our case it is D2 which is the same pin we set up for output in the setup() function, of course.  We also want to tell it that we want the pin to go high (5V). There is a pre-defined value of HIGH for that so our digitalWrite looks like the following:

digitalWrite(2, HIGH);

Next, we want to turn the LED off. To do that we will write a low (0V) to the pin.  There is also a pre-defined value for the 0V value which is LOW. These pre-defined values are case-sensitive so low will not work in the code and will give you an error.

digitalWrite(2, LOW);

However, we want to pause before we turn the LED off so we can actually see the LED go off and on so we need to call a function that can make the program pause.  That function is called delay() and it takes the number of milliseconds (thousandths of a second) that you want to pause the program.

I will pause the program ¾ of one second so I will use 750 as the value I send in to delay().

Here’ the entire code listing for the loop():

void loop() {
  digitalWrite(2,HIGH);
  delay(750);
  digitalWrite(2,LOW);
  delay(750);
}

Here’s the natural language explanation of what that code does.

  1. Turn the LED (connected to pin D2) on.

  2. Wait 750 milliseconds (ms) (LED stays on that long).

  3. Turn LED off

  4. Wait 750 ms (LED stays off that long).

  5. Back to step 1.

Go ahead and save your Arduino Sketch as NanoFirst (or download the code from the top of this article and open it with the Arduino IDE -- NanoFirst_v001.zip).

Choose the Correct Arduino Board

If this is the first time you’ve used Arduino IDE or the first time you’ve built code for a Nano, we need to set the Arduino environment so it knows to build the code for the specific board and chip (ATMega328P) we are using.

It’s very easy to do.  Just go to the Tools menu at the top of the IDE and then slide down to the [Board >] menu item.  The Nano board may already be chose, but if not when you slide over that item another menu will pop out with a large number of choices.  Slide down the Arduino Nano and click it to select it.


 

The IDE should automatically select the “Processor: ATMega328P” for that board, because it is the newer processor used on these boards.  However, you want to make sure it is selected properly.

The next image shows you how to select the proper processor.

 

These two options insure that the IDE will build the code that is correct for your board.  

Notice that the bottom status area of the IDE (shown in previous image) confirms that you are building for the Arduino Nano with an ATMega328P and the device is connected to COM1.

Now, we are ready to build the program.

Build the Program

Once you’ve got the code written and you think it is correct, you can have the Arduino IDE check it for you.  You do that by attempting to build the program. To build the program you select the Sketch menu at the top of Arduino IDE and then choose the first menu item, [Verify/Compile].

 

When you do that the Arduino IDE turns your high level language code (that you understand) into machine language instructions that the ATMega328P understands.

As the program is compiled (depending upon the speed of your computer) you will see some status information at the bottom the Arduino IDE.

When it completes successfully you will see something like the following:

 

You can see that it tells you that it is complete and there is some status info that lets you know the the size of your application and how much memory will be left on the chip.  Memory is of utmost importance because it is so limited on these little computers. Keep in mind that we’ve only built the program at this point but we still haven’t uploaded it to our Nano.  

What Happens If There Are Errors?

Programming can be a lonely endeavour and the most important thing that lonely devs can learn is what to do when you encounter an error.  The better you are at understanding errors and resolving them the better dev you are.

I’ve introduced an error on purpose so you can see what the IDE will look like when you compile and it encounters an error.

It tries to help you to show you where it thinks the error is.  In this case it highlights the problematic line in pink. Then in the output window at the bottom it gives you some error information.

Error Messages Are Sometimes Confusing

Error messages can sometimes be confusing though because at times they will give you what ends up being a guess by the compiler.  In this case it tells us:

‘DigitalWrite’ was not declared in this scope

What!?!

Basically you just have to know that it is saying, “I don’t know what DigitalWrite is and I’ve never heard of it before.”  That’s because computers and computer languages are very specific. And in the Arduino language (which is based upon C/C++) is case-sensitive.  That means when you see that error you should think, “hey do I have something typed wrong? Am I referring to something that the Arduino IDE doesn’t know about?”

Of course, all we have to do to fix it is change the capital D in DigitalWrite to a lowercase one and build the program again.

Upload the Program

To get the Nano to run our program, we need to upload the program to it.  We can compile the program separately as we’ve been doing and then upload it.  But we can also tell the IDE to compile it and send it to the Nano all in one click.  To do that you simply click the right-pointing arrow.

 

When you do that, the IDE will determine if the code has been changed and if it is it will compile it and then send it to your connected Nano.

If you click that button and your Nano is not connected the program will compile but you will get an error because the IDE cannot upload the program.

The IDE will tell you about the trouble and try to give you some hints to fix it.

 

 

You may also get that problem, if for some reason the Arduino IDE guesses incorrectly about which COM (communications) Port your Nano is connected to. This could occur in rare occasions if you have other devices connected to other USB ports and the IDE gets confused.

You can try other COM ports without hurting anything so you can just drop the menu and see what choices you have and try a different one.  

Here’s what mine looks like because I do have multiple Arduino devices connected to my computer.

 



Once you get everything working, when you click the Upload button the program will be compiled and sent to your Nano.

Once that happens your Nano will start running your program.  

The Real Code That Is Written To Your ATMega328P

Keep in mind that the IDE does not send the text you have typed into the IDE to the Nano.  It sends pure machine language program to it and writes it into the flash memory of the Nano.

Behind the scenes when the IDE builds the app it saves all the work it does to a temp folder on your computer.

The path is %localappdata%\Temp\arduino_build_<generated_number>

If you go to %localappdata%\Temp\ you can usually easily find the latest updated folder after you build and find the app if you want to.  You can copy and paste %localappdata%\Temp into your File Explorer and it will take you to that folder.

The NanoFirst.ino.hex file is that file that is uploaded to the Nano.

You can open it with a text editor and look at it.  Here’s what it looks like:

Yeah, pretty boring unless you know machine language for the ATMega328P.

Watch A Video Of It In Action

If everything went well your program is running on your Nano and your red LED is flashing on and off.

I made a very quick video and posted it to youtube to show you the circuit in action: Getting Started With Arduino Using the Small, Arduino Nano - YouTube[^]

What Next?

Now, you’ve written a program, but it may not seem that amazing, because it is still connected to your computer.  After the program is uploaded to the Nano, the Nano does not need the computer for anything except power. What I mean is that the Nano is doing all the work to turn the LED on and off and the computer doesn’t control any of that code.  That’s because the Nano is a little computer itself.

Very Small System On A Chip

The thing that is fascinating to me is that the ATMega328P is far more powerful than the MOS 6502 that Steve Wozniak built his Apple ][ computer around.

The 6502 could execute about 1.2 million instructions per second (1.2 MIPS).  While the ATMega328P running at 16Mhz can do about 16 million instructions per second (16 MIPS).

Of course the ATMega328P has far more memory at 32K (32 thousand bytes) too.

The ATMega is an entire system on a chip while the 6502 was not, so there was much more work to do (wiring up memory for program storage).  

Everything you need is right on the Nano.   It is amazing that Woz had so many barriers and still succeeded in building a complete and usable computer.  In contrast, we have far fewer barriers and most of the time cannot come close to what Woz did.

The important thing about having all this computing power on such a small device is that it consumes far less energy than you computer does.  That means you can build a small device and run it off of battery power instead of plugging it in. That’s a major key to IoT (Internet of Things) because you can have numerous standalone computers that have provide a specific service.

I think seeing our own circuit run off battery power is very instructive as a progression into understanding how you’ll really use your Arduino-based devices to create final products.

Run On Battery Power

Let’s see how we can run our Nano off of battery power.  It is not difficult at all. You just need to supply 5 Volts and it will run.  Supplying 5 Volts isn’t too difficult because we can get approximately 6 Volts from 4 AA batteries.  

Or, we can use a 9V battery with a very simple connector.  The datasheet on the Nano says that it can take 6V-12V on pin 30 (VIN -- Voltage In).

I’m going to use a 9 Volt battery because it will be easier for you.  You can get a simple connector that you snap on a 9V battery and you are ready.

Snap that onto a 9V battery like so.

Do not allow those two wires to touch each other or it will create a short circuit and your battery will become very hot and could hurt you.

Now we connect the battery to the breadboard to power the Nano.  Make sure you disconnect your Nano from your computer. Do not have both battery and USB connected to the Nano.

I’ve connected the black wire to the ground rail on the breadboard (blue side).  I’ve connected the red (positive) wire to the positive rail on the breadboard. Then I’ve connected a green wire (colors are just to keep things straight) from the positive rail to the VIN (pin 30) on the Nano.  

Finally I connected a black wire to the GND pin on the Nano to create a complete circuit.

I was able to snap the pic right as the LED flashed on.

Here’s a closer look at the wires that are connected to the Nano for ground and voltage in.


Stand-alone Device

Now that we have the ability to build a stand-alone device you can begin to dream up projects that can run on their own powered only by a small battery power supply.

Now, go an do your own great projects. You have the power!  

History

First publication: 2018-06-12

 

Monitor & Store Temperature Stats For Home Zones With Arduino

Introduction

Temperature can be quite subjective since for different reasons each individual may experience it in relation to their own situation (drinking a hot or cold beverage, coming inside after taking a run in hot weather, coming inside after being out in cold weather, etc).

Background

In general, home thermostats are only installed in one location and only measure the temperature in that one location.  However, another room or zone in the home may create a completely different temperature experience for the occupants.  I thought it might be nice to build a simple device which :

  1. Displays the current temperature
  2. Stores time and temperature on an SD card for easy import into a spreadsheet so we can graph temperature over time

Attempt To Turn Subjective Feelings Into Data

All this data could really help us turn the subjective idea that "it feels cold/hot in here" into real data that may allow us to know whether that is a "feeling" or a reality.

Here's a snapshot of everything you need for this project.

Parts List

It's always best to have a list of the parts and approximate prices so you can easily determine where to get the parts and how much the project is going to cost.

  1. Arduino Uno - I use the Elegoo clone (https://amzn.to/2JOoiIp) about $11 USD
  2. I2C LCD - (https://amzn.to/2NBWl8S) I showed you how to use this in my other article (Discovering What Your Code Is Doing Using a 20x4 LCD With Your Nano[^]) about $10 USD
  3. Main Temperature component - I'm using one from a Seeed kit. http://wiki.seeedstudio.com/Grove-Temperature_Sensor_V1.2/^ about $2.80 USD
  4. (Micro) SD Card Reader/Writer : This device also uses I2C (https://amzn.to/2A5nxLd) $8.99 for 5 of them
  5. Breadboard - I use these (https://amzn.to/2uVHteA) about $8.50 USD for 3
  6. (Micro) SD Card of any size, mine's 16GB because they were the smallest/cheapest I could find. (https://amzn.to/2LyLQpp) About $7.60 USD
  7. SD Card adapter for carrying your files to your computer to import them into a spreadsheet for analysis

Do Things In Steps

A couple of guidelines I use when building out a project are:

  1. Do the easiest parts first.
  2. Add layers of functionality

For me, this means getting the I2C LCD working.  There are three reasons for this:

  1. The 12C LCD is easy to set up.
  2. It allows me to test a basic Arduino sketch
  3. I can use the LCD for output as I build the project - as a debugging tool if I need it.

Hook Up & Test the I2C LCD

Here's the circuit wired up on a breadboard.

It's not extremely clear which pins on the I2C LCD are connected to the pins on the Arduino Uno so a schematic view can be far more clear about how things are connected.

Now you can plainly see that the VCC and GND pins are connected from Uno to LCD and the SDA pin on the LCD is connected to pin A4 (Analog 4) and the SCL pin on the LCD is connected to A5.

Here's the first sketch we will use to insure the LCD is working properly and that your circuit is setup properly.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 20, 4);

void setup() {
  
  lcd.begin();
  lcd.setCursor(2,0);
  lcd.print("Hello, LCD!");  
}

void loop() {
  
}

You can see that this first simple sketch doesn't even contain any code in the loop() method. All the sketch does is print "Hello, LCD!" to the screen.  But, this let's us know that we are ready to print any data that we receive.

All you have to do is upload the sketch from the Arduino IDE and you'll get some output on the screen.

Here's a snapshot of it running.

Get the Code and Try It

You can get the code (TempSensor_v001.zip) at the top of this article and try it out yourself. 

Adding the Thermistor

We are ready to add the temperature reading module (thermistor) to our circuit.

It's a very simple component to use.  In the previous picture you can see that about in the middle of the component there are four pins (horizontal) sticking out from the white plastic piece at the bottom.  They are marked (from bottom to top)

  1. SIG (Signal)
  2. NC (Not Connected / unused)
  3. VCC (input Voltage)
  4. GND (Ground)

Connector Bundle

These Seeed modules are set up to be easy to use so they also provide a connector bundle that allows you to snap on all four wires by plugging them into the plastic receptacle shown on the left side of the component in the previous picture.

Once you plug that bundle in it will look like the following:

Seeed also insures the color coding is set nicely so the red is always VCC, Black is GND and the yellow and white are generally data wires of some type.  In this case the thermistor only needs on more wire so the NC (Not Connected) aligns with the white wire and we will not connect anything to that wire.

Connecting The Bundle to The Breadboard

The other end of the bundle has the same connector and each of the wires terminate in a female connector as shown.

I will just strip some of my hobby wire and push the ends into the connector.   Then I will connect those wires to the breadboard.  You can see what the connector looks like after I've pushed wires into it in the following picture.

Now I connect the red to the VCC (breadboard power rail) and the black wire to ground (breadboard ground rail) and the yellow to a column on the breadboard.  After that I connect the breadboard column with the yellow wire connected to the Arduino Uno A0 pin (Analog 0).

Again that isn't exactly clear about how things are connected so here is a schematic of the entire circuit so you can see exactly what is connected.

That's all there is to the circuit.  Now we just need to add some code that will read the value from the powered up temperature sensor.

Code to Read Current Temperature

I got the code from the sample at the product site: http://wiki.seeedstudio.com/Grove-Temperature_Sensor_V1.2/#software^

Two Differences In Code

However, I altered the original code in two ways:

  1. Their code displays on the serial monitor (requires your Arduino to be connected to your computer), but of course ours displays the value on the LCD.
  2. The original displays the value in Celsius, but I've added a line to convert to Fahrenheit.

Get The Code

Here's the entire code listing.  You can get the code by downloading TempSensor_v002.zip.

#include <LiquidCrystal_I2C.h>
#include <math.h>

const int B = 4275;               // B value of the thermistor
const int R0 = 100000;            // R0 = 100k
const int pinTempSensor = A0;     // Grove - Temperature Sensor connect to A0

LiquidCrystal_I2C lcd(0x3F, 20, 4);

void setup() {
  
  lcd.begin();
  lcd.setCursor(2,0);
  lcd.print("Hello, LCD!");  
}

void loop() {
  int a = analogRead(pinTempSensor);

  float R = 1023.0/a-1.0;
  R = R0*R;
  float temperature = 1.0/(log(R/R0)/B+1/298.15)-273.15; // convert to temperature via datasheet
  temperature = (temperature * 1.8) + 32; // convert temp to Fahrenheit
  lcd.setCursor(2,1);
  lcd.print(temperature);
}

Every time the program goes through the loop it will get the current value of the temperature sensor and display it on the LCD.

The Sig (data pin) of the temperature sensor is connected to A0 of the Arduino.  

The Basics Of How the Temperature Sensor Measures Ambient Temperature

The first thing the code does is reads the analog value from pin A0 which is a value in the range of 0-1023.  This value is stored in the a variable.

The Analog pins of the Arduino (and underlying Atmega328 MCU) can read voltages which are split into a range of 1024 values.  As the ambient temperature around the sensor goes down the sensor's resistance will increase.  This in turn will lower the value of the voltage on the A0 pin which lowers the value in the range (0-1024).

The math of the following line allows us to know the temperature (in Celsius) in relation to the resistance that is occurring within the sensor:

float temperature = 1.0/(log(R/R0)/B+1/298.15)-273.15;

Once we have the Celsius temperature it is an easy matter of applying the conversion formula to convert it to Fahrenheit.

After that we simply display the value on the LCD.

But, now we need to add a way to store the temperature values we obtain over time.  SD Card Reader/Writers are inexpensive and allow us to carry the data to computer for more analysis so we'll implement one of those here.

SD Card Reader/Writer

I've added a close up of the SD Card Reader/Writer front side and back side below.  It's very simple to use because it uses I2C also.

 

I've already loaded the 16GB SD card into the spring loaded card holder (on the left side of the reader/writer).  You can see a bit of the card sticking out to the left.

 

You can see that the pins are marked nicely for our use.

SD Card Reader/Writer Uses SPI (Serial Peripheral Interface)

Whenever you see that a component uses MOSI, MISO, SCK, and CS (also sometimes marked SS) then you know that it uses SPI (Serial Peripheral Interface) for communication of data.   

The SCK is the Serial Clock which sets the data pulses (speed) that the master will send the data.  It's basically a way to insure the Master and Slave device understand the timing that the data will be sent.

The CS (Chip Select) or SS (Slave Select) is the pin used to determine which Slave is going to receive the data.

This interface allows multiple devices connected to these four pins to communicate with the master.  This saves data pins on your Arduino but allows you to connect multiple devices.

You can read much more about SPI at : https://www.arduino.cc/en/reference/SPI^

We will connect the four pins to our Arduino pins as follow:

  1. MOSI (Master Out/Slave In) => D11
  2. MISO (Master In/Slave Out) => D12
  3. SCK (Serial Clock) => D13
  4. CS (Chip Select) => D10

Updated Schematic

Here's an updated schematic so you can more easily tell how everything is connected.

I moved things around a bit (from the previous schematic) just so lines wouldn't overlap as much with the newly added component.

 

This component's pins make it easily used with a breadboard.  I just push it into the board so each pin gets its own column on the breadboard.

 

Now, it's just a simple matter of making the connections with our jumper wires.

 

Then we can add some code to test writing to the SD card.

We will add two new includes which will provide us with functions to initialize and use the SD Card reader/writer.

#include <SPI.h>
#include <SD.h>

Next we'll declare a couple of variables we'll use:

File TempData;
const int SD_CS = 10;

The first line declares the File handle to the file that we'll be writing to.

The second line creates a variable for the CS pin of the SD card reader and ties it to the digital pin 10 of the Arduino.  We do that so we can then initialize the SD object that we'll use to write to the file.

We'll add the following code to the setup() function:

if (SD.begin(SD_CS)) {
    lcd.setCursor(2,2);
    lcd.print("SD card init");
  }

This will print "SD card init" to the LCD only if the SD card reader is wired up properly.

Get Code and Try It : TempSensor_v003.zip

Get the TempSensor_v003.zip at the top of this article and try it out.

If everything is good to continue then you'll see something like the following:

If that worked then you know you have things wired up properly and you're ready to continue.

Writing Temperature Data To A File

Let's add the code that writes to a file.

I'm going to add that code to a function and then have the loop() method call the function each time.  I've named the function writeToSD.

void writeToSD(float temperature){
    TempData = SD.open("temps.csv", FILE_WRITE);
    if (TempData) {
      lcd.setCursor(2,2);
      lcd.print("file WRITE success");
      TempData.print(millis());
      TempData.print(",");
      TempData.println(temperature);
      TempData.close();
    }
    else{
      lcd.setCursor(2,3);
      lcd.print("file WRITE fail    ");
    }
}

There's not much code to write the file to the SD card.  It's very simple and the methods are provided by the Arduinio SD library that we included at the top of the source file.

Here's what the data looks like when you open it up in a text editor.  It's just simple comma seperated values:

  1. column 1 is the number of milliseconds since the program started
  2. column 2 is the temperature at that time

This was gathering data every 500ms so the temperature hadn't changed much.  Here are some more details about dealing with files.

Opening / Creating A File For Writing

The first thing we need to do is set the File Handle to point to the actual file we want to write to.  We can do that by calling the SD.open() method.  You can see that I've provided the string name "temps.csv" as the first parameter and the predefined value FILE_WRITE to indicate that I want to open the file for writing.

File Is Created

If the file exists it will be opened for writing (appending to the end).  If the file does not exist then it will create the file and then open it for writing.

File Open Success

If the file is successfully opened (and created, if necessary) the TempData File handle will not be null.  That means we can simply code:

if (TempData)

If the file handle is not null then we can write to it using the print() and println() methods.  The only difference between the two methods is that println() adds a CrLf (Carriage-Return / Line-Feed) to the end of the line after it writes the data to the file.

Importance of Closing File After Writing

Finally, after writing the data to the file it is very important to call the close() method to insure the bytes are flushed from memory and written to the disk file (file on SD).

That's all there is to it.  The rest of the code just gives us some output on the LCD screen in case things fail and to provide us with a status about what is happening.

Importance of FileNames With 8.3

When I first set up the code I had the following line to open the file:

TempData = SD.open("temperature.csv", FILE_WRITE)

I didn't know that line was the problem but when I went to write to the file it always failed.  I couldn't figure it out for a bit but then I guessed that maybe this file system only allows 8.3 file names.  I looked it up and that was the problem. Since I'd provided a longer file name the open() call was failing and TempData was null and then the write was failing.  That's not so easy to determine though because we don't have an Arduino debugger.

The next thing we need to solve is writing the data at a specific interval.  We don't want to write data to the SD card every time through the loop() because the data wouldn't be useful.

Only Write Data At Time Intervals

We only want to write data every X seconds to limit the amount of data we write to the SD card.  The millis() function returns the number of milliseconds since the sketch started running on the Arduino. 

To handle this we could call delay(ms) each time through the loop().  However, that pauses the entire sketch and it really isn't effective.  Instead, I want to make the sketch only call the writeToSD() function every X seconds.

I'm going to have it write the data every minute so at the top I will initialize two variables we will use to do this.

const long SLEEP_TIME = 60000;  // write to card every minute
long multiplier = 0;

The SLEEP_TIME variable is simply a constant so we can easily change the value in one place.  That's the amount of time that will be in between each call to writeToSD().

The next variable which I call multiplier is simply a counter which starts at zero and will help us only make the call to writeToSD() every SLEEP_TIME seconds.  With those two variables in place we will be able to use the following code to insure writeToSD() only occurs every interval.

if (millis() > (multiplier * SLEEP_TIME)){
    writeToSD(temperature);
    multiplier++;
}

The first time through the loop the multiplier will be 0 and millis() will be something greater than zero which means the sketch will immediately write the first temperature it reads to the SD card.  It will then increment the multiplier.

The next time through the loop millis() will be less than multiplier * SLEEP_TIME (1 * 60000) so it will not write again until millis() has been running for at least one minute.  It will continue to do this every minute since the multiplier will be incremented each time.

Final Code : Get TempSensor_v004.zip

Get the code and try it out.  Here it is running on my desk.

Take It Even Further

Now if you want, you can take this even further by making the device more portable.  I won't cover the additional details here -- to keep this project shorter -- but you could do some extra work and make it run from batteries.

You could also add a real-time clock -- which Atmega328 chips do not have available -- so you could write clock times to your file so you can more easily track the temperature against time.  You can buy real-time clocks as a component you hook up on to your Arduino (see amazon link : https://amzn.to/2OqmR6v^)  That component uses SPI just like the SD card so you'll already know how to hook it up.

Topics Touched Upon

Now you know how easy it is to read data from a temperature sensor.  You also learned a bit about:

  • Arduino's File Reading / Writing Library and associated challenges
  • SPI - Serial Peripheral Interface used by the SD card (MOSI, MISO, CS, and SCK).  Whenever you see those four connections used, you'll know the device is using SPI.

Salient Points To Keep In Mind

  • The SD Card reader doesn't have any LEDs to indicate when it is powered or reading or writing and that makes it a bit difficult to determine what is wrong if it isn't writing.  You'll need to use LCD print() statements to debug it if it fails.  Also keep a close eye on how you have it wired up.
  • Make sure your temperature sensor isn't too close to the running Arduino board which puts off some heat and may alter your readings.
  • If you want more data, simply alter the SLEEP_TIME variable so it is a smaller interval.  For example, change it to 5000ms and the sketch will write data every 5 seconds.
  • SD card formatting can have odd effects on your SD card.  If you're getting odd effects of writing to your card, check here : http://forum.arduino.cc/index.php?topic=228201.0^
  • It was also interesting that I needed to make the multiplier and SLEEP_TIME variables longs because I was multiplying them and the product ended up being a number larger than an int and the program would stop when that the int value was exceeded, even though I wasn't actually storing them in an int variable.  Instead, an int size of temp memory was being allocated automatically for the product and when it couldn't hold that value the statement (if (millis() > (multiplier * SLEEP_TIME))) would fail.  It makes sense, but it caught me off guard.

History

2018-07-28 : First publication

Arduino: Just Say No To Shields

Background

I only recently bought an Arduino Uno knock-off board because they finally became inexpensive enough (less than $12 USD).  I'm very cheap.  

Originally when I started with the Arduino (really the AVR ATmega328p-pu) I wanted to be closer to the metal because I thought it would allow me to learn more about what was going on.

I read the book,  AVR Programming: Learning to Write Software for Hardware 1st Edition[^] by Elliott Williams.  That book describes how to program the ATmega328 (and ATmega168) chips directly.  

A Lot of Work

It shows you how to hook up an AVR ISP programmer to a breadboard and how to use a text editor and AVR-GCC.  You write all your programs in straight C.

It's actually a lot of work.  It's a lot more work than you have to do when using the nice Arduino IDE that does everything for you.

You Learn A Lot

However, I also learned a lot about what was going on.  I also learned how to flash a HEX file (AVR machine language file) directly to the ATmega microcontroller using AVRDude.

It was all great information because it put me in a place where I was less dependent upon the Arduino infrastructure.   

Arduino Uno Built-in Headers

Of course the Arduino UNO has those nice built-in headers that make it so easy to wire in your additional components.  For your first Blink program you can literally stick an LED directly into the headers without any other wiring -- yes the 5V is a little high and will overdrive the LED but as an easy first experiment, it is nice.

The Arduino Uno even goes one step further and offers shields you can just plug in directly into it.

What Are Arduino Shields?

If you haven't seen these shields before they are prefabricated extensions you can just plug directly into your Uno that provide functionality.

Here's a good example of one that provides Internet connectivity to your Arduino.

Image from Arduino.cc

Plug It In And Go

You can easily just plug that board into your Arduino Uno's headers and go.  That is really great for prototyping.  However, it is not so great for building out your final product.

Why Shields Aren't Great

Shields aren't great for your final product for a few reasons:

  1. Larger footprint: They make your final product much larger than they would necessarily be.  That's because there is quite a bit more hardware here and it is spread out for ease of use.  Your final product could be far smaller with just the ATmega chip as I showed in my previous article.
  2. Cost: They make your final product cost more.  The ATmega328p-pu only costs about $2. However, the Arduino Uno will cost you anywhere from $12 - $20.  That's a huge difference in price.

Prototype Shields Take This Idea Even Further

Prototyping shields allow you to build your own circuit on a shield that you can easily plug into your Arduino Uno.  

 Image from digikey 

As you can see, you can build your custom circuit on the prototype shield and plug it into your Uno.  However, this means your final project will require that you commit your Uno (which you are really using to provide a programming interface to your ATmega chip) as a part of your project, never to be used in other projects again.  

Break Out Your ATmega Chip

If you'll learn to break out your ATmega chip to the breadboard then you won't have to do this and you'll save money and space.

Here is a great example of a very interesting music synthesizer project that is far larger and far more expensive because it is built around the Arduino Uno and a prototype shield.  Imagine how much smaller and cheaper that project would've been.  

Design Considerations

All of this works into things that we have to think about whenever we design a project.

  1. Footprint - how much space will the final project take up (smaller the better)
  2. Cost - again, the lower the cost, the lower price we can sell the final product
  3. Time - The less time it takes to build, the better.  The shield may save us time up front and if you are simply trying to get to a prototype it may be a great idea. But later you may spend quite a bit of time reverse engineering it into a basic circuit that has a lower cost.

Keep on building, keep on learning.

~ Roger Deutsch

Arduino Uno : Using Your ATMega328p-u As Stand-alone

If you've spent any time at all with an Arduino the you know how to write a program for it.  I uploaded the program (shown below) to simply blink an LED on digital pin 5 on my Arduino Uno (knock-off) board (amazon link).

arduino uno

setup(){
 int LED = 5;
pinMode(LED, OUTPUT); } loop(){
delay(500);
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
}

We use the Arduino Uno to program the ATmega328p chip that is connected to the board on the IC (integrated circuit) socket. 

Once You're Done Programming the Chip

But, after you're done programming the chip, it doesn't make sense that you keep it attached to the Arduino Uno board.  The board takes up a lot of space and is really used to provide you with an easy way to program the chip.

Here's what it looks like when you remove the chip from the Uno.

You can see the socket that I removed the chip from and you can see that the chip itself is far smaller than the board.  That means your final product can be much smaller.

atmega328p

But, how do we get the chip to run our program? 

Build the Circuit to Power the ATmega328p

 Here's a quick snapshot of the initial circuit we are going to build.

bread board circuit

It's very simple. It's one GND (ground) wire connected to pin 8 of the ATmega328p.   It's one 5V wire (coming off bread board rail) to pin 7 of the ATmega328p.  

Then you can see I've connected the anode (positive) pin of the LED to PD5 of the ATmega328 because that is the same pin as digital pin 5 on the Arduino Uno.

That _should_ be all you need.  But as you can see, the LED is not lit up.

The ATmega328p is actually powered in the picture, but for some reason it is not running our sketch.  Why not?

How Is The ATmega328p Set Up On Arduino Uno?

This all has to do with the way the ATmega328p is set up to work on the Uno.  When the manufacturer sets up the chip for use with the UNO they have to set some internal switches on the ATmega328p called fuse bits, so that it works properly with the associated Arduino Uno hardware.

These settings are conventions (arbitrarily chosen but are expected by Arduino users).  

You cannot set the fuses unless you have an AVR(Atmel) ISP (In System Programmer/Programming).  

ATMega328p Can Run At Various Speeds

An ATmega328p can run at various clock speeds.  It can run at 1Mhz (one million cycles per second), 8Mhz and 16Mhz.  However, it can only run at 16Mhz if it has an external crystal attached to it.

16Mhz Crystal On Arduino Uno Board

The Arduino Uno board does have a 16Mhz crystal on board.  

I've highlighted the crystal in the following picture.

16Mhz crystal

 Since thee manufacturer has set these chips to run with the external crystal (oscillator), the chip will not run properly without one.

ATmega328p Datasheet

If you take a look at the datasheet and go down to section 5.1 you'll see a nice pinout diagram for the ATmega328p-u (dip dual inline package).

atmega28p-u pinout

Crystal Pins

You can see that pin 7 is VCC and pin 8 is GND just as I mentioned earlier.  But now we need to find the place where we should install the crystal.  If you look closely you'll see pin 9 is marked xtal1 and pin 10 is marked xtal2.  xtal is the abbreviation for crsytal.  

Two 22pF Capacitors

However, by looking at this diagram you would not know that you also need to add two 22pF ceramic (non-polarized) capacitors to those pins also.

You will connect one pin of one cap to the pin 9 and the other pin to ground.  You will then connect one pin of the other cap to pin 10 and the other pin to ground.  Then you will connect the 16Mhz crystal so that one pin is on pin 9 and one pin is on pin 10.

Here's a quick snapshot of it on the breadboard (and then at the bottom of this article, I'll provide you with a schematic so you can more easily see how things are connected).

atmega28p-u with crystal on pins 9 & 10

Now, when you power this circuit up, it will actually run the sketch.

atmega28p-u running stand-alone

Clears Up A Few Things

 Hopefully this will clear up a few things:

  1. You can actually run the chip stand-alone -- and you should since it is a smaller footprint.
  2. If you haven't been successful getting it to work, it may be because you didn't add the 16Mhz crystal: it won't work without it.
  3. You definitely need 22pF caps.  I tried it what 47pF and it didn't work.  Use 22pF caps.

Keep on building, keep on learning.

~raddevus (roger deutsch)