Friday, January 29, 2016

Even kids can do it!

An overview of building an atmospheric data logger using Arduino for use with myObservatory

Recently, it came to my attention that a particularly bright middle school student was interested in sensing the environment and using data loggers. This is a perfect mesh for myObservatory and its capabilities, and indeed we've built Arduino-based data loggers several times in the past.  I decided to assemble some basic hardware and write a quick blog post about it, in enough detail that someone could hopefully follow along.

Some of our past sensors have used SD-card storage and two-row LCD panels, while others have used GSM cellular connections to upload data in realtime. The former has the advantage of long battery life and being feasible to operate on solar power, with the disadvantage of needing to go retrieve your SD card to get your data (and you don't know when the battery has failed). The latter has the great advantage of seeing your data come through in real time, and knowing if there's a problem (due to the sudden lack of a data stream). The disadvantages are two: needing a data plan from a mobile carrier to use it with, and relatively enormous power requirements.

Thinking about these two approaches, I decided to create a hybrid - merge the idea of an SD card and cellular upload. This would let me record data every 5 minutes and save it to the SD card, then upload via cellular every 12 hours or so, hopefully reducing power requirements. Unfortunately this didn't end up panning out, due to problems with the SIM300 module that I tried to use for cellular connectivity. The final result of this build for the kits I'm sending the student ended up being just SD-card storage, but with an improved user interface leveraging a full-color 1.8" TFT display instead of the original 2-line LCD display.

So, let's get started! The first step is to assemble all the required equipment:

  • Arduino Mega or generic equivalent (Uno is sufficient as well, if you're not doing cellular and TFT together)
  • Optional: GSM modem shield; I tried Geeetech's SIM900 module in this build, and was unimpressed. The official Arduino GSM shield has worked better for me in the past.
  • Optional: 2G-capable unlocked SIM card
  • Adafruit 1.8" 18-bit TFT Shield with MicroSD and Joystick
  • uxcell Sensitivity Control Temperature Humidity Sensor DHT11
  • BUD Industries NBF-32018 Plastic ABS Enclosure with Door
  • Generic 4AA battery holder
  • DS1307 Real-Time Clock
  • Battery holder and connector; DC barrel jack connector
  • Various bits of wire
  • Soldering iron and solder (and desoldering braid, if you're pessimistic about your soldering skills)
  • Digital multimeter

I originally selected the Arduino Mega due to it's increased maximum program space of 256k, a requirement for using both the nice TFT display and the cellular modem libraries together. Without the cellular modem, an Arduino Uno (32k program space) is sufficient.

Some of the components don't always come entirely "assembled". Frequently, the pins of Arduino shields aren't shipped soldered on, so you just need to break off the desired number from the strip that comes with it, and solder those into place. If you're lazy, you can solder only the pins you need to use, but since you never know what pins might end up getting used by other stacked shields, it's wise to solder them all on - shouldn't be more than a 10 minute job. Remember to use a very hot soldering iron so you can minimize the contact time, and reduce risk of melting anything important. The TFT shield, after soldering on the pins, looks like the image at the left. Be sure to also connect the hidden "Lite" pin to D7, which will enable software control of the TFT backlight so we can turn it off when not in use.

Next, we can stack the shields onto the Arduino. In the picture shown below, I still have the (faulty?) Geeetech SIM900 module stacked in place. Be sure to align them properly and have them facing the correct direction - look for the pin numbers along the edge of the boards. Next, since we need to be able to tell what time it is when we save our readings, we'll work in an RTC (Real-Time Clock). This is a digital device that communicates over the I2C interface - so it will attach to the SDA and SCL pins. These vary from device to device; on the Arduino Uno, these are A4 and A5 respectively. On Mega, these are digital pins 20 and 21, respectively. These are connected to the RTC breakout via short wire segments that are removable (a theme you'll see throughout my builds). The power lines are connected by soldering to the TFT shield, and the I2C lines connect over to the Mega directly, since the TFT shield doesn't cover all the Mega inputs.

Next, we need to correct a few pin mapping issues. The Arduino Mega has its SPI interface on pins 50, 51, and 52 instead of the usual 11, 12, and 13 on Uno. So, if you're using an Uno, you can skip this; if using a Mega, we need to connect pins SCK, D1, and D0 to pins 52, 50, and 51 respectively. This is used for digital communication with the SD card portion of the shield; without doing this, the TFT display will work, but not the SD card.

Lastly, we need to attach a few more wires for the simple atmospheric sensor we'll use in this example. We'll attach two more lines for power - to the "5v" and "GND" - and one for sensor data, on pin 3. The completed assembly looks like these two pictures - again ignore the antenna and GSM card, which was unused in the final mailed-out version.



Next, we'll prepare the DHT11 atmospheric sensor, connecting it to a standard 3.5mm headphone-style jack, connecting VCC to tip, ground to the base, and data to the middle. We'll also drill a hole in the enclosure to allow the connector to slide through, and solder some wires to the headphone jack connector. Your multimeter is useful to verify what wires will connect to tip, middle, and base of the headphone jack and its connector. These are shown in the pictures below:



Finally, we can place the assembled components in the box and connect the wires. (The final version has printed labels instead of sticky notes!)  The box size is quite overkill. When ordering the box I neglected to account for centimeters versus inches...but on the plus side, there's plenty of room for documentation, a notebook, a big fat battery, etc. This box is also fully waterproof, and can be screwed to a pole. You'll see I've attached the board to the box via twist ties, and all components are very easily removable using black female wire connectors. I always try to make demonstration or prototype builds easy to change, soldering as little as possible, never using glue, and documenting what wires connect to what with tape labels. This makes tweaking and adjusting much easier.



The next step is to write the Arduino sketch that we'll upload to the board. The original version for this demo factored in the Geeetech cellular shield, but after every conceivable method of trying to communicate with it, I was never able to get the cellular modem to respond to the arduino board, whether I used a Micro, Uno, or Mega, and software or hardware serial, and every baud rate imaginable. The board also failed to connect to AT&T unless I supplied slightly more voltage than the documentation stated was required, which I felt was unsafe. For these reasons, the final version of this build has no GSM modem. In the future I may acquire a few alternate GSM shields to test with. The original Arduino-branded GSM shield works well, but I've found that hard to come by lately.

The logic for Arduino boards are called "sketches" by tradition, and basically tell the Atmel chip on board what to do. The language is based on C, and most standard C library functions are available for use. In particular there are two things to note when getting started with Arduino programming:

  1. Every sketch must have a "void setup()" and a "void loop()". The setup function will run upon initial power on or reset, and after that the loop function will be run over and over endlessly.
  2. Digital control is performed using "pinMode(/* Pin number */, /* OUTPUT or INPUT */)" to set the "direction" of data flow, and "digitalWrite(/* PIN NUMBER */, /* HIGH or LOW */)" to change the voltage of the data pin. digitalRead(pin_number) will read the current state of a digital pin. Also available are analogRead and analogWrite, which work in the same way, but accept float values instead of HIGH or LOW. The analog read/write functions will only work with analog pins, those preceded by "A".

The sketch for this example can be found here - and the software used to send the sketch to the Arduino can be found here. If you're interested in the cellular version of the sketch for uploading directly to myObservatory, get in touch with me or look at the older cellular example for inspiration.

Power in this version is provided via the barrel jack, which is connected to an AA battery holder. Power can be provided to the barrel jack in any voltage from about 5 to 12 volts, though 7 to 12 is recommended. Power can also be provided via the USB port, though the USB port power must be exactly 5 volts. As such, commonly available "cell phone power bricks" make a great power supply, especially the ones with large fold-out solar cells integrated.

This example is fairly bare-bones in having only a single atmospheric sensor, but serves as a good starting point for building your own solution. Additional sensors of a wide variety can be connected and used. One advantage of the Mega board over Uno, in addition to the increased program space, is a much greater number of digital and analog inputs, letting you connect a large number of sensors to a single device.

Have fun, and if you have any questions when building your own sensor devices, get in touch!

No comments:

Post a Comment