Category Archives: DIY Arduino Datalogger

Instructions, circuit diagrams & code links for Arduino based data loggers that you can build on your own.

Arduino Data Logger: 2017 Build Update

This base configuration sleeps at 0.25mA or less depending on your parts, so with a 4xAA battery pack it should run for a year.

If you need a logger with a rugged waterproof housing, it’s still hard to beat the crimped-jumpers build released in 2016. However sometimes I just want a quick bare-bones unit for bookshelf test runs while I shake down a new sensor. I can whip up a breadboard combo in about twenty minutes, but they stop working if I bump one of the wires loose. I’ve lost SD cards from this half way through a long term test, and I’ve also run into issues with noise & resistance from those tiny breadboard contacts.

To address this I’ve come up with a new configuration that uses a screw-terminal expansion shield originally intended for the Nano.  This requires a modest bit of soldering, and after some practice, between 1-1.5 hours to finish depending on how many “extras” you embed into the basic three component core. In return for that time you get all the pins broken out, making this approach almost as flexible as a breadboard, and much more physically robust. Pop them into some pre-made boxes and these little guys qualify as deploy-able for relatively stable environments.


Bill of Materials: $8.40
Pro Mini Style clone 3.3v 8mHz $1.85
Nano V1.O Screw Terminal Expansion Board
Note: To save time, you can spend an extra 60¢ for pre-assembled boards by Deek Robot, Keyes, & Gravitech.  Note that bad vendors show photos of the pre-assembled boards in their listing, but then ship you the no-name assemble-it-yourself part kit. That kind of bait-n-switch tactic is very common with dodgy eBay suppliers.
DS3231 IIC RTC with 4K AT24C32 EEprom (zs-042)
Some ship with CR2032 batteries which will pop if you don’t disable the charging circuit!
SPI Mini SD card Module for Arduino AVR
Be sure to buy the ones with four ‘separate’ pull-up resistors for easy removal.
4xAA 6V Switched Battery Holder
The logger works with battery packs holding 3 to 8 AA batteries (with the default MIC5205 regulator)
CR2032 lithium battery  $0.40
Sandisk Brand Micro SD card 128mb-1gb 
Older Sandisk cards have lower sleep currents. Test used cards well  before putting them in service.
Common Cathode Bright RGB LED 5mm 
( & 30kΩ limit resistor)  A brighter bulb lets you use a larger limit resistor for the same light output.
Double Sided Tape,  2x 10MΩ resistors, 28awg silicone wireheader pins, etc… $0.50
Donation to
If you don’t use a ‘real’ Promini from Sparkfun to build your logger, you should at least consider sending a buck or two back to the mothership to keep the open source hardware movement going…so more cool stuff like this can happen!
Comment:   You might need one of these to get started:                            (not included in the total above)
CP2102 USB-UART Bridge module
These work with Macs & Windows machines after you install the drivers. Or try the FTDI version.   ***Be sure to set the 3.3v jumpers on the module before using it!***


The Main Board:

In this build the six serial UART I/O pins must have 90 degree angled headers to make more room for the RTC board which will sit on top of the main board later.  Solder those header pins onto your Arduino board, and test it with your UART adapter. Generally speaking, about 10% of the cheap modules I buy from eBay are flakey in some way, and it’s quite annoying to discover that after you’ve assembled a logger. Once you know the board is working, remove the power and pin13 LED resistors.  These limit resistors tend to move around from one manufacturer to the next, so you might have to hunting for them on your particular board.  You also need to remove the RESET switch from the board, or that button will be compressed when you put the SD card adapter into place:

{Click any images to see larger versions.}


Solder the side rows of straight header pins so that they project from the bottom of the board.  I usually skip the two reset pins, so that I can re-purpose those screw terminals later as GND and Vcc (photo 3 below) but if your application needs reset functionality then  solder those headers as normal.  Add wires to the top of the board for the A4 (SDA white) & A5 (SCL yellow) lines of the I2C interface.  Add wires to the A6 & A7 vias so that they project from the bottom of the board.

Once all the pins are in place clean any flux residue from the board with 90% isopropyl alcohol and a cotton swab. The final step for the main board preparation is to trim the pin header solder points on the TOP of the board flush with the surface: D4-D9, D10-D13, and A0-A1.  Then affix some double sided tape  in place over those trimmed pins, which will mate with the bottom surface of the SD adapter.

The RTC Module:

The simplest modification to these DS3231 RTC boards is to remove the charging circuit resistor and power LED limit resistor from the circuit board (indicated with the red squares in the first picture).  LIR2032 rechargeable batteries are nominally 3.6v, and will not charge with this module connected to a 3.3v Arduino. Replacing that with a CR2032 will backup the RTC for many years of operation 


Add two layers of double sided foam tape, so that the thickness matches the top surface of the DS3231, and the inside edge aligns with that side of the chip. These two surfaces will mate with tape on the SD adapter board.

Since the RTC board already has 4.7k pullups on the SDA (data) and SCL (clock) lines, you will not need to add them to your I2C sensors.  This board also has a 4.7k pullup on the SQW alarm line.  We will be connecting SDA, SCL, GND and VCC wires to the small cascade port on the module.

The SD Card Adapter:

This SD card adapter comes with small surface mount pullup resistors on the MOSI, MISO & SCK (clock) lines (removed from the dashed red line area photo 2 below).  The Arduino SDfat library uses SPI mode 0 communication, which sets the SCK line low when the logger is sleeping. This would cause a constant drain (~0.33mA) through the 10K SCK pullup on the module if we did not remove it.  I prefer to pull MOSI & MISO high using the internal pullups on the 328P processor, so those physical resistors on the breakout board can also be removed. But be careful to leave the top-most resistor of the four in place to pull up the DAT1 & DAT2 lines.  This keeps those unused pins on the μSD card from floating when the cards are accessed in SPI mode.

sd1 Only remove the bottom three pullup resistors. keep the top one

Add jumper wires to each of the headers pins on the bottom of the SD adapter and trim those solder joints till they have a relatively low profile . Then cut away the vertical header pins from the top of the board. Place a strip of double sided tape on the bottom of the SD card module opposite the soldered wires. This strip acts as a spacer to level the SD board when it is placed in contact with on the double sided tape on the mini style Arduino board.

The SPI connections:
RED:           3.3v regulated
Grey:          Cable select (to D10)
Orange:     MOSI   (to D11)
Brown:      SClocK (to D13)
Purple:      MISO   (to D12)
BLACK:     Ground

The Screw Terminal board:

These screw terminal boards are designed for use with Arduino Nano boards, but if you orient the two correctly when you connect them, labels on one side of the shield will be in alignment with promini pins:


Drilling a pass-through hole lets you bring the jumpers down to those unused pins, and to make other connections to solder points on the underside of the shield without blocking the M3 mounting holes.


Attach SD adapter to the Pro mini:

The first step is to attach the SD adapter to the board, but this must be done with a slight overhang, so that at least the red Vcc wire on the SD adapter extends beyond the top surface of the pro-mini board.  It’s OK to leave more overhang than I’ve shown here, but if you leave less, the wires on the RTC cascade port might interfere with access to the serial I/O pins.

Place a strip of double sided tape across the SD adapter board as shown, taking care not to cover the hole showing the card lock spring.  When that tape is in place, bring the ground and Vcc lines from the SD board forward and make a gap in wire insulation so you can splice-solder them to the GND & Vcc pins on top of the pro mini board. This procedure simultaneously connects the rails to the SD adapter, and brings power to the I2C cascade port on the RTC module.

Connect the RTC board:

I recommend that you take a bit of time holding the RTC board in place over the SD & mini combination while the protective covering is still on the tape, so that you get a feel for the alignment before you actually try to stick these parts together. With the cascade port oriented towards the Arduino’s serial I/O pins, the topography of the SD adapter fits snugly into place against the DS3231 chip on the RTC module.

After you stick the pieces together, trim and solder the I2C bus wires to the RTC’s cascade port. Note that it is possible to unstick the parts afterwards by gently levering them apart with a screw driver, but be careful you don’t rip the metal shield off of the SD card adapter in the process.

Attach everything to the Screw Terminal Shield:

If you’ve gotten this far, then you can now relax, because all the tricky stuff is done.  Trim and tin the four SD lines and bring the down to the D10-13 SPI screw terminals just below. Note that D12(MISO)  & D13(SCLK) lines must crossover.  Bend the pins on the RTC board downward and solder jumpers onto all but the 32K output line.

Pass the SQW alarm line (in blue) through the hole and solder it to the D2 pin projecting from the underside of the terminal adapter board.  If you left out the reset pins when initially soldering the headers, bridge those unconnected terminal screws to the adjacent Vcc & GND lines.  Then patch A6/A7, and the four I2C lines from the RTC board to the unused pins at the end of the screw-terminal shield.  I generally run these loggers on 3xAA battery packs with a 2x10M ohm voltage divider providing 1/2 of that battery voltage to A0.  So the last step is to add that voltage divider, along with some extra tape to serve as foot pads.

The battery voltage calculation for a divider with equal value resistors is:   float batteryVoltage = float((analogRead(A0)/ 511.5)*3.3);  But the MIC5205 regulator found on most promini style boards will accept anything between 3.4 to 12v input, so you will need size your resistors to convert the peak battery pack voltage into something below the 3.3v aref limit. To cover that whole range, you’d need a pair that puts 1/4 of the battery voltage on A0, and a R1(high side) = 3*R2(low side) combination would do that, changing the 511.5 constant in the equation above to 255.75    With 5205’s dropout potentially rising to 300mV during 200mA SD writes, I usually shut down the loggers when the main battery falls below 3.75 volts. With Meg-ohm size resistors, I leave that divider connected all the time, but there is a wonderful self-disconnecting voltage divider idea over at JeeLabs for those who want to use smaller resistance dividers.

As we removed the pin13 LED back at the start,  solder a limit resistor onto the ground of a common cathode RGB and connect that to one of the ground connections, with the other legs going to D4R-D5G-D6B.  I usually add a few labels to keep track of the extra terminal connections, and any re-allocated any pins for a specific build. Unfortunately black sharpie marker doesn’t stick to those green terminal shrouds very well. 

In this example I’ve re-allocated the screw terminals that would normally have been connected to the two reset pins, but you could use under-board wires to re-assign any of the terminals in a similar fashion. For example, if your application will not be using the RX/TX pair, those could be turned into extra Ground or Vcc points. I’ve never understood why the pro-mini design breaks out reset twice but leaves the Aref pin hidden, so adding a wire to the little aref stabilizing cap would let you fix that issue.

Your Logger is ready to go!

As this is simply a different physical arrangement of the same core components, you can follow the logger testing procedures described at the end of  the 2016 build post , which also provides links to a basic data logger script to help you get started on your project.  For the build described above, the pro-mini’s MIC5205 regulator delivers sleep currents less than 0.25mA (Promini~0.05mA,  sleeping SDcard~0.08mA & RTC~0.09mA)
That should should reach a year of operation on 4xAA’s. 

While it took me a day to get the first one of these sorted, the second one took less than three hours, and the third took less than 2 hours. I lost count after that, and now these things seem to be multiplying like tribbles.   If you need unobstructed access to the SPI bus, you can move the SD lines to under-shield solder connections as we did for the I2C bus.  This makes the logger a little prettier, but since I’m usually making these in a hurry, I often leave those wires on the surface.

The photos in this series were made with Adafruits 26AWG silicone wire, but if you are adding more bottom-side connections, switch to smaller diameter 28AWG wire, or make the pass-through hole a bit larger to accommodate the extra lines. Switching the  90° I/O header pins to the bottom of the promini board gives you more room for the RTC wiring.

You can make the component stack more rigid by adding a few strategically placed beads of epoxy putty.  In fact you could hold the whole thing together that way, so long as you take care not to bridge any contacts – especially where the DS3231 legs come near the metal top of the SD adapter. Also keep in mind that the putty sets rock hard in about five minutes, so if you make a mistake with that assembly method then you’ve bricked the unit… literally.

Addendum 2017-06-21:

I’ve been on a steep learning curve since the beginning of this project, and you don’t have to dig very far to find stuff on this blog that seemed like a good idea at the time, but later turned out to be completely wrong.  I should write some sort of disclaimer,  but instead I’ll pass along a recent forum comment that summarizes the kind of criticism we’ve been getting lately:

“In the old days, an embedded enthusiast would have designed the thing (and think AVR) from the outset to meet objectives / specs, not struggle with integrating the various modules and meeting very-so-so sleep currents (while thinking Arduino). Surely, this is a textbook example of how not to do embedded engineering if you are doing it for a salary.”

It’s good to have someone rattle your cage once and a while, and I’ll admit they have a valid point( In addition to the fact that I’m not an engineer, and I don’t get paid…)  People complain like that about the pitfalls of using modules & libraries all the time, but the thing I like about the Arduino platform is that you don’t have to know everything before you can do anything. I’m just figuring it out as I go along.

Still, an affront like that demands some kind of response.  So to defend the honor of my fellow Arduino Kool-Aid drinkers, let’s look at how you might tweak those modules to improve this loggers sleep current performance:

1) Pin Power the RTC:

These DS3231 boards don’t get a lot of love because they have about the worst battery charging circuit ever devised, and an equally useless LED power indicator. But for less than a buck delivered to my door, these boards are considerably cheaper than the components they carry: so I’m going to look under that rock and see what I find.  That charger can be disabled with a simple flick of the soldering iron, and at this point we have years of successful run time using a non rechargeable CR2032 as backup.

More interesting is the fact that on a 3.3v system, you can leave the charger in place, cut the Vbat line, and patch in a 1N5819 Shottky.  After the CR2032 burns down the two circuits should balance out, and the main battery takes over supplying the 3µA timekeeping current.  CR2032s are rated for reverse currents on the scale of Shottky leakage, but I’m sure if you ask an engineer they would tell you this is a bit dodgy.  Since I don’t know any better, I’m just going to do it anyway and see what happens…

The final step is to lift the Vcc leg on the IC and jumper it directly to a digital pin to provide power during I2C communications. During sleep this power-pin is driven low: forcing the RTC into backup powered timekeeping mode and it can still provide wake-up alarms to your logger in this state.  These mods cut your loggers sleep current by about 0.1 mA

2) Buffer your data before saving:

Those DS3231 RTC modules also have a 4K EEprom on the board, and that lets me save data in 32byte page-writes with reasonably simple code. While the I2C bus is dead dog slow by embedded system standards, you can hang oodles of things off those wires without worrying about cable select lines, or some gummy protocol weirdness.  For an extra buck, you can add 32K more memory without any significant changes to your Arduino script. That usually buffers about a week’s worth of data before I need to save to the SD, even though I’m still making the unforgivable programming sin of storing everything in ASCII string variables

Small red-board versions of the AT24C256 tuck nicely into the 12mm gap between the headers, but you could just as easily put an I2C sensor into that space. If you get boards with the address pins broken out (the one above doesn’t), you can connect up to four of these eeproms to the same logger. A side benefit is that the 32K eeproms are rated to 400kHz, while the 4k’s are only 100kHz, so the upgrade also lets you accelerate the I2C bus clock, since the DS3231 is also rated for 400kHz.  Even larger eeproms are available in the code compatible AT series, but I’m not sure if the wire library supports the 64byte page writes they typically use. If I had the chops, the path to an IC-only logger is obvious. Paul Paul Stoffregen’s SerialFlash library is another interesting option, as it allows one to read/write files in a similar way to an SD card.

3) Cut power to the SD card:

The clones I’m using have a tap at the back that is conveniently located for ground side switching on the SD cards. This lets me tuck a 2N2222A under the board with that extra eeprom.  Cards hit the reg pretty hard when they initialize causing significant vdrops, and if you find that your unit is not saving properly with this technique it’s probably because those low-voltage transients are restarting your logger.  I usually add caps to provide at least 30μF on the rails to handle those spikes, and I may bump that even higher for cold climate deployments since cheap ceramic caps have terrible temperature constants.

Code and information about this technique are described in some detail on the
SD power post This is a relatively high risk strategy, but it can cut your sleep current by another 0.1mA. Note that while the BJT works OK, on more recent builds I’ve switched to the Supertex TN0702 mosfet for SD power control.

4) Replace the voltage regulator:

The MIC5205 on those pro-mini clones is not very efficient at low power (~10-20% efficient), so replacing that with an MCP1702-3302E/TO can cut your remaining sleep current in half.  The 10uF caps from the original regulator are still in place on the board, so it’s been working fine with the 1700 just hanging off one side. Also keep an eye on the dropout voltage, which on the MCP1700 series can rise as high as 600mv if you push them to their 250mA maximum: requiring a fairly high 3.9v as your input cutoff. If your not ready for soldering in close quarters, you can always dead-bug the reg & voltage divider onto the battery connector like I did for the 2016 builds.

And the result?

This logger is drawing less than 0.02mA sleep current with a MS5803 sensor in tow. That’s 5x more than you’d see from a raw 328p, but not bad considering that we built a fully functional data logger out of 99¢ eBay modules. (With the default 5205 reg in place, the logger would draw ~0.06mA)

These modifications to the basic build plan probably violate some important electrical engineering rules, and I can almost guarantee that nothing will work properly the first time you try it.  But don’t let the fact that you might destroy a few cheap components along the way prevent you from just going for it.  Although it might be best if you don’t show your project to any engineer friends at the beginning… unless they’re working on a new textbook 🙂

Addendum 2017-10-02:

If you are careful about placement of the batteries, you can fit this new screw-terminal design onto the abs knockout plugs that I’ve been using as mounting platforms. This means that you can still fit the logger into the inexpensive 4″ housings
that I outlined for earlier builds with room under the platform for a second battery bank if needed.  Given how often makers need to put a shell around their projects, I’m surprised that no one has taken the old B-Squares idea into three dimensions to create a re-configurable snap-together housing system.

In addition to the I2C bus, I’ve started breaking out A1-A3, rather than digital lines, since those A ports can do double duty as either analog or digital I/O with some code settings. With screw-terminals on all lines, I only break those out to connectors for quick sensor swaps in the field.

One thing to keep in mind for any project built from eBay parts is that most of those boards use cheap Y5V capacitors; which have terrible temp-coefficients compared to X7R/NPO’s.  So you need to test your project extensively if you want it to operate over a wide temperature range. My home freezer tests to date have been running ok, but I’m not relying on the Arduino’s oscillator/clock for anything that is timing-critical.  I do expect to see things like bus timing drift out of spec eventually.  For loggers built with I2C sensors, stick with 100kHz for your first few builds, then things “just work every time”, 75% of the time. The 1.1v internal bandgap also changes significantly with temperature, so if you use it as Aref, expect to see the readings go up, as the temperature goes down.


Switching off SD cards for Low Power Data Logging

This composite graph compares logger current during identical sd.begin(), File Open & File Close sequences with two different Sandisk brand SD cards on the same datalogger. The 256MB card used less than 3mAs, while the 2GB card burned more than twice as much power during this initialization. Older low cost/size cards often perform better in SPI mode, which is simply an after-thought for high end cards, because it’s required by the SD spec.

The tweaks I discuss in the  power optimization post bring sleep current on a typical build into the 0.1-0.12mA range; leaving the sleeping μSD cards  as the largest remaining power consumer on the Cave Pearl loggers.   And those cards have been a burr under my saddle for quite some time now, as they are probably responsible for most (if not all..) of the power consumption irregularities that were showing up in some of the battery voltage logs.

I already knew the various brands of SD cards could have dramatically different sleep current, but a comment in the forum by William Greiman (the author of the SdFat library for Arduino) made me look a little deeper at what they were doing the rest of the time:

“Performance of microSD cards is not easy to predict on Arduino.  Arduino uses SPI to access the cards and the SD library has a single 512 byte cache. Modern SD cards are designed to be used on the high speed 4-bit SDIO bus with very large (16 KB or larger) multi-block writes and reads so they must emulate the single block access that Arduino libraries use.  This can mean much internal data movement, erasing of flash, and rewriting of data.”

This shows up clearly during data save events:

These screen captures of IDE serial potter output show current drawn during a data writing event with 256mB (left) and 2GB (right) Sandisk SD cards.  4kB of CSV format ASCII data was saved, and the gaps between the writing spikes were caused by i2c coms while SDfat’s cache was filled with data retrieved from the Eeprom on the RTC module. (click to enlarge)

After seeing that I tested a variety of different SD cards, finding that save event power use increased by more than 5x over the range from old 64 & 128mb Nokias to newer 2 & 4Gb Sandisk cards. 

It took me a good while to realize that I had fallen into yet another forest-for-the-trees situation, because even the worst offenders were only using ~30 mAs per save event, but all the cards were delivering similar sleep currents.  A day has 86,400 seconds in it, so the best sleepers, coming in around 70μA, were still burning six thousand milliamp seconds per day overall…

That brought me back to the question of de-powering those SD cards. I had been discouraged from trying this early in the project by some of Grieman’s other forum remarks where he suggested that there was nothing in the default SD library to support multiple shut downs & restarts safely.  But over time I found that Nick Gammon, and several others had card power control working with SdFat, and seeing the folks at OSBSS claim they had power cycled SD cards more than a hundred thousand times, was really the final straw.

As I had no logic level P-channel fets lying around I went with a garden variety 2n2222 BJT, configured as a ground side switch with a 30k pulldown. Driving it to saturation using a 330Ω base resistor (assuming Hfe = 30) should give me enough wiggle room to handle 150mA spikes, though it will burn 10mA to keep the BJT on for full second I needed to wait before pulling the plug.  Write latencies for SD cards can be quite large, and some cards have more than one stage of sleep, drawing around 1.0 ma for maybe a second before entering deep sleep.  But with 6000 mAs/day on the other side of the scale, I could afford the extravagance.

The cross leakage stuff I’d seen on EEVblog convinced me that I needed to actively pull up all of the SPI pins after the ground was disconnected. I cobbled together a set of  ON/OFF functions with pinmode commands, but it did not work reliably until I switched over to port manipulation (like they did at OSBSS), so the lines were all pulled simultaneously.  I was already disabling peripherals like the ADC with the PRR register, but that was just to save a little runtime power. Now it was required because when SPI is active, it controls MISO,MOSI & SCLK.  So you must shutdown the SPI interface before you can set those pins directly.

#include <LowPower.h>
#include <avr/power.h>
#include <SPI.h>
#include <SdFat.h>
SdFat sd;                                   // Create the objects to talk to the SD card
SdFile file;
const byte slaveSelect = 10;   // sd card slave select on pin D10
#define SDpowerPin 9            // pin controlling the BJT on the ground line for the SD card
boolean SDcardOn = true;     // flag for error routines
byte  keep_SPCR;
// spacer comment for blog layout
void setup () {
keep_SPCR=SPCR;                  // save the default SPCR register contents
. . . }

void turnOnSDcard() 

pinMode(SDpowerPin, OUTPUT); digitalWrite(SDpowerPin, HIGH); //turn on the BJT on SD ground line
delay(6);                                            // let the card settle
// some cards will fail on power-up unless SS is pulled up  ( &  D0/MISO as well? )
DDRB = DDRB | (1<<DDB5) | (1<<DDB3) | (1<<DDB2); // set SCLK(D13), MOSI(D11) & SS(D10) as OUTPUT
// Note: | is an OR operation so  the other pins stay as they were.                (MISO stays as INPUT) 
PORTB = PORTB & ~(1<<DDB5);  // disable pin 13 SCLK pull-up – leave pull-up in place on the other 3 lines
power_spi_enable();                      // enable the SPI clock 
SPCR=keep_SPCR;                          // enable SPI peripheral
delay(10);  SDcardOn = true;       // just a flag

void turnOffSDcard() 

SPCR = 0;                                         // disable SPI
power_spi_disable();                     // disable SPI clock
DDRB &= ~((1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2));   // set All SPI pins to INPUT
PORTB |= ((1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2));     // set ALL SPI pins HIGH (~30k pullup)
// Note: you must disconnect the LED on pin 13 or you’ll bleed current through the limit resistor
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); // wait 1 second before pulling the plug!
pinMode(SDpowerPin, OUTPUT); digitalWrite(SDpowerPin, LOW);  //turn off BJT
delay(6); SDcardOn = false;

These two functions book-end any code that needs to write data to the SD cards:

turnOnSDcard();    flushEEpromBuffer();    turnOffSDcard();

All data saving functions start by checking the main battery to make sure there is enough power to save the data without a brown-out, and then re-initialize the cards with sd.begin before opening any files:

vBat = readBattery();   // This function shuts down the logger if the main battery is below 3.65V
if (!sd.begin(chipSelect, SPI_FULL_SPEED)) {
Serial.println(F(“Could NOT initialize SD Card”));Serial.flush();
error();  // note: the flag triggers:  if (SDcardOn) {turnOffSDcard();} in error function
delay(10);, O_WRITE | O_APPEND);  //see this post by Grieman
//…save your stuff…

Looking at the datasheets for the Mic5205, or the Mcp1700,  you see the regulator dropouts can reach 300mV at 100mA+ currents you could see during SD card initialization, so your input cutoff for a 3.3V system needs to be above 3.65V to handle the load.   After the data is saved it is critical that all open files are closed properly before the turnOffSDcard function gets called, otherwise your data will be lost. The graphs tell me that a full one second delay before powering down the card is probably longer than it needs to be,  but in data logger applications it’s pays to err on the side of caution. According to Greiman:

“The standard says reliably removing power is not supported in SPI mode. It does suggest that you can remove power one second after the card goes not busy but does not guarantee this will work. You can’t depend on isBusy() to power down a card. It only means the card can accept a command. It may still be programming flash or moving data for wear-leveling. You really need the one second delay after not busy.”

Lately I’ve been using these 60¢ SD adapters, and removing the bottom three 10k smds that these boards have on the SCLK, MOSI & MISO lines. (the other resistor keeps the ‘RSV’ pins from floating) Having a pullup on the clock line wasted power during mode o sleep as the clock idles low, but now that I’m cutting power rather than just sleeping the SD cards, I could leave those resistors in place…then I wouldn’t need to pull up those lines in the code, (though I’d still have to pull SS…)

Of course, it was pretty flakey the first few times I tried it. Half of the loggers worked, but the other half were restarting every time there was a data save event (killing off SD cards in the process…) This problem affected every logger built around the Rocket Scream Ultra, which has been one of my favorite small form factor boards.  Closer examination of the two-penny clones that were working ok revealed that they had 10μF tantalum capacitors beside the voltage regulator rather than the little 1μFs beside the Ultra’s MCP1700.  So those cards were hitting the rails pretty hard when the SD ground line was re-connected, and this caused brief transients that were low enough to restart the processor on half of my units. Some add a small (33Ω) resistor in series to limit these inrush currents, but I found that adding 2-3 10μF (106) ceramics to buffer that spike got them all working ok, and for field deployment units I’ll probably add more.

I set a several units running on the bookshelf, with a rapid six second sampling interval. A couple of weeks later they were all still going, with some of them seeing more than 30,000 SD card power cycles without error. Given that the loggers normally see less than one save event per day, I’m calling that a successful test. If you run into issues, the first thing to try is extending that delay after sd.begin() and adding a few more delays throughout your functions. If you look at the spec you find that SD cards are allowed to take huge amounts of time for everything from initialization, to file open/close. While I did not see that in cards I used for my tests, these latencies are ‘officially’ allowed to stretch well beyond 100ms.

With both pin-powering on the RTC, and ground line switching on the SD card, the loggers get down to between 0.03-4mA between samples, which should push my operating lifespan into multi-year territory. Or, if I’m really lucky, they’ll make it through one winter-time deployment in Canada 🙂

I was also pleased to discover that the On/Off code seems to work on loggers that do not have the ground side switch installed provided I do not try to re-initialize the cards with sd.begin.  SPI shutdown & line pullup seems to cause the SD cards to enter sleep mode more quickly than they did before, and I have not seen any current leakage. So hopefully I won’t have to maintain vastly different code versions for older non-switched loggers. (Update 2017-06-12: Further tests of SPI shutdown, without the BJT to disconnect power from the SD card have not been reliable. Some worked, some didn’t. When I figure out why that is I will post an update)

Addendum 2017-06-06

A commenter over at Dangerous Prototypes made a point about my use of the 2n2222 which is important enough that I should pass it on:

“I’m surprised he didn’t check the 2N2222. Look at its data sheet, the V(CE) performance is not great. Take 0.3V at 100mA, then the SD card would have been actually running at 3.0V, right at the -10% VCC rating edge. I’m surprised the problems are not worse. Of course it would be extremely sensitive to VCC sag…”

The drop across the collector-emitter was something I had simply missed, and I still struggle to read those datasheet graphs properly.  And I was so used to seeing card operating voltage specified between 2.7-3.6v, that I also missed the fact that in SPI mode, only 3.3v is officially supported. The net result is that I’m probably sailing closer to the wind here than I realized, and I’m going to call this technique “experimental” until I see real-world deployments saving more than a year of data safely. And if I stay with ground-side switching in future, I will start looking for a good logic level N-channel  MOSFET, with low on resistance, to replace that BJT. The Supertex TN0702 looks like a good option with the promini’s with 3.3v logic.

Addendum 2017-06-06

Just thought I should post a reminder to test your SD cards thoroughly before embarking on SD power shut down experiments. I use SD formatter v4.0 & H2testw.  H2t is also a good way to make sure that you are not damaging your cards over time…

DIY Arduino ProMini Data Logger: 2016 Build Update

Cave Pearl data loggers

Click image for larger view. Note that the colors used for this new ‘jumpers’ build don’t match this older diagram. This build should work with any 3.3v, 8mHz 328P board but the pins are in different places on the Sparkfun pro-mini vs the Rocket Scream Mini Ultra, and you will likely have to adjust your connections to match pin locations on the particular board you are using.

Its been almost a year since the last stand-alone logger tutorial, and I continue to receive questions from people adopting the platform in education settings.  That feedback makes it pretty clear that soldering is the biggest stumbling block for beginners, so I have reconfigured the build to use pre-made DuPont style jumper cables wherever possible.  The basic wiring diagram is unchanged, but I use a different SD card adapter and changed the resistor locations to reduce component prep. and make the overall assembly easier.

Cave Pearl data loggersThis comes at the expense of having more wires to deal with on the limited real-estate of the knock-out cap platform, and re-positioning the modules to make room for the overhang of the DuPont connector housings. The overall result is a little uglier, and not as robust to knocking about as a unit where every connection is soldered in place, but the platform takes about a third less time to build (~2.5h) with a part cost under ten bucks before you add sensors.


Parts photo for the 2016 update build of the Cave Pearl Data logger by Edward Mallon

Parts Total: $8.80
Pro Mini Style clone 3.3v 8mHz $2.00
DS3231 IIC RTC with 4K AT24C32 EEprom (zs-042)
Some ship with CR2032 batteries which will pop if you don’t disable the charging circuit!
SPI Mini SD card Module for Arduino AVR
Be sure to buy the ones with four ‘separate’ pull-up resistors.
20cm Dupont Ribbon Cable 40pin F-F 2.54mm
You use ~1/2 of a 20cm cable per logger. Get the ones without the housing caps to save time.
2xAA Battery Holder & 1xAA Battery holder $0.60/both
CR2032 lithium battery  $0.40
4″ Knock-Out Test Cap $0.40
Deans Ultra-T Style Battery Connector Plug $0.30
2x Nylon M2 12mm standoff, Nut & Screw M2 5mm $0.40
Micro SD card 64mb-1gb 
Older Sandisk  cards have lower sleep currents. Test used cards well  before putting them in service.
Dupont Crimp PinsHousings
Most parts  cost about a 1-2 cents each, after you buy the crimping tool.
Common Cathode Bright RGB LED 5mm 
A brighter bulb lets you use a larger limit resistor for the same light output.
Double Sided Tape,  2x 4.7MΩ resistors, 26awg silicone wire, (104) 0.1uF caps, 4″ cable ties, heat shrink tubingheader pins, etc…etc… $0.50
Donation to
It is now possible to build a decent data logger for less than $9 because of the hard work of many people around the world. If you don’t use a ‘real’ Promini from Sparkfun to build your logger, you should at least consider sending a buck or two back to the mothership to keep the open source hardware movement going…so more cool stuff like this can happen!
Comment:  And a few tools you might need to get started:                     (not included in the total above)
CP2102 USB-UART Bridge module
These work with Macs & Windows machines after you install the drivers. Or try the FTDI version.   ***Be sure to set the 3.3v jumpers on the module before using it!***
Yihua 936b soldering station 110v
These have enough power to solder the large battery connectors. Get extra handles & tips.
DT-830D Digital Multimeter $3.00
Heaterizer XL-3000 Heat Gun $14.00
SN-01BM Crimping tool $25.00


CLEANING:  Boards from reputable vendors like Adafruit / Sparkfun are usually clean, but cheap eBay modules are often covered with leftover flux from the manufacturing process and dirty contacts are guaranteed to corrode.  Most of us use 90% isopropyl alcohol to clean this residue, but some prefer Polyclens brush cleaner. A couple of five minute sessions in an ultrasonic bath with Iso90 usually works great, but you can also do it by hand with a cotton swab, etc.   (Never put vibration sensitive components like accelerometers into an ultrasonic bath)

Preparing the Main Board:

Solder the side rows of straight riser pins into place on the pro-mini style board.  This is easier if you use a small breadboard to hold the pins in place, however you should not use that breadboard for anything else afterward because the transferred heat will ruin the contacts.  Be sure to add the two A4 & A5 riser pins after the side rails are on, as they are needed for the I2C interface (and the A6 & A7 risers if your project needs them) One of my pet peeves with  Pro Mini style boards is that those inner pin can not be held in place with the breadboard trick as they at out of alignment.  If you hunt around and you can find clones with A4-A7 broken out to the edges of the board to make the soldering the pin headers a bit easier for beginners.       {Click on any images to see larger versions.}

solderriserpins washfluxfromboard1 Riser Pins on promini arduino. Not the angle for the UART serial.
Cave Pearl data loggers

On the adapter in this picture, the USB to TTL connection pins are in the reverse order of the promini board. This is a fairly common issue with cheap eBay modules and simply requires that you twist the cable between the Arduino and the serial adapter.

It is good to have the six serial UART I/O pins bent slightly away from the other risers to make more room for connecting the UART board. Once the pins are in place clean the flux residue from the board with some 90% isopropyl alcohol and a cotton swab.

Take a few moments and connect the board to your computer via the UART adapter to test it out by uploading the Blink sketch. You need to install drivers to get the serial communications adapter working with your operating system, and this part of the process can be challenging for people who have never done that before. There are well written guides at Sparkfun & Adafruit if you are using boards with the FT232RL chip from FTDI. If you are using the CP2102 from Silicon Labs, or the $1 PL2303 then you need to sort out driver installation on your own, but a quick google search should bring up lots of guides posted around the web. Once you have the drivers installed, the Arduino IDE should display a new com port when the adapter is plugged in to the usb port of your computer. At that point you can upload sketches to your Arduino through the serial adapter after selecting Board: Arduino Pro or Pro Mini   and  ATmega328(3.3v, 8mhz)   in addition to the new com port provided by the drivers. If you are ordering parts from eBay, then buy at least three of everything – it’s not uncommon to see a 10-20% failure rate on these budget parts…that’s why they are so cheap. I also order those backup parts from different vendors, since some will take months to ship, and others get the part to you in a week.

Once you are sure the board is working ok,  remove the power LED limit resistor and the resistor for the LED on pin 13. Simply hold the tip of the iron on one side of the small resistor and apply a gentle sideways pressure. When enough heat has conducted through the resistor, the solder will melt and you should be able to simply ‘flick’ the resistor off the board. Disabling these LEDs conserves battery power. (Note: these limit resistors tend to move around from one board to the next, so you might have to hunting for them.)

pwrledpromini2 pwrledpromini3

Tape on bottom of pinned pro mini

Add two layers of double sided tape to the underside of the Arduino so that it can be affixed to the platform. Due to the riser pins extending from the bottom of the pro-mini, two layers are needed: The first layer should fit “between the pins” and the second layer should extend past the pins to the outer edges of the board.

The RTC Module:

I don’t recommend using LIR2032 rechargeable batteries with this module as the charging circuit wastes a great deal of power, and a CR2032 will backup the RTC for many years.  Remove the charging circuit resistor and power LED limit resistor from the circuit board indicated with the red squares in the first picture below.  Next add four 90-degree header pins to the I2C cascade port on the RTC board. These four pins will become the connection point for any I2C sensors you want to add to the data logger:

rtc1 Cave Pearl data loggers rtc3
Cave Pearl data loggers Note the battery connector leg on the top surface is trimmed a bit Cave Pearl data loggers

Since the RTC board already has 4.7k pullups on the SDA (data) and SCL (clock) lines, you will not need to add them to your I2C sensors. This board also has a 4.7k pullup on the SQW alarm line.  The GND and VCC pins (3.3v) on that cascade port can also be tapped to power other sensors you connect to the data logger.

The SD Card Adapter:

This SD card module comes with small surface mount pullup resistors on the MOSI, MISO & SCK (clock) lines (which have already been removed from the dashed red line area in the diagram).  The Arduino SDfat library uses SPI mode 0 communication, which sets the SCK line low when the logger is sleeping. This would cause a constant drain (~0.33mA) through the 10K SCK pullup on the module if we did not remove it.  I prefer to pull MOSI & MISO high using the internal pullups on the ProMini’s 328P processor, so those physical resistors on the breakout board can also be removed. But be careful to leave the top-most resistor of the four in place to pull up the DAT1 & DAT2 lines. This keeps those unused pins on the μSD card from floating when the cards are accessed in SPI mode.

sd1 Only remove the bottom three pullup resistors. keep the top one sd3

Then add a layer of double sided tape to the bottom of the SD card module and trim it to size.

Dupont Connectors:

trimdupontcableThe RTC & SD card modules will be connected to the Arduino by custom jumpers that you assemble from a 20cm, 40pin F-F Dupont style ribbon cable and 0.1″ (2.54mm) crimp connector housings. Test your cable for end-to-end continuity, then cut the cable into three sections.  Then peel off individual 10cm wires and insert them into the black crimp connector ends to create the cables shown. The longer 20cm wires will be used  later when we assemble the LED indicator cable, and for other sensor attachments.

Cave Pearl data loggers


For the I2C connections:
Blue:          SQW alarm signal.
Yellow:     SCL (clock) (to A4)
White:       SDA (data) (to A5)
RED:          3.3v regulated
BLACK:    Ground
For the SPI cables:
RED:           3.3v regulated
Grey:          Cable select (to D10)
Orange:     MOSI   (to D11)
Brown:      SClocK (to D13)
Purple:      MISO   (to D12)
BLACK:     Ground

I’ve left one of the six RTC connector shroud slots empty for future use with the 32K clock signal but you can change that to a 5-pin housing if you wish.  Single 0.1″ (2.54mm) crimp connector housings are shown on the ends of the red, black and blue wires ,but I find that putting heat shrink over single-wire DuPonts help them hold onto the pins better.


Attach Battery Holders & solder in series

On a 4” PVC knockout cap, arrange your battery holders as close to the edge as possible to maximize room for other parts on the platform, without letting the holders hang off the edge. Mount the battery holders in place with double sided tape.

Join the red wire from the bottom of the single battery holder to the black wire from the double battery holder, so that the three AA batteries are connected in series. Fold the soldered joint and the long RED wire into the gap between the battery holders. Use some heat-shrink to bind them so they stay together inside the gap. Mark and drill 1/8” pair of holes so that you can tie down the wires from the battery pack neatly. Secure the wires to the cap with a zip tie through the holes.

Cave Pearl data loggers Cave Pearl data loggers Cave Pearl data loggers

Risers & Tie Downs

Place the RTC board alongside the batteries with one corner near, but not extending over,  the edge of the cap. You want the back edge (with the four-wire cascade port) as close to the single battery holder and the outer edge of the platform as possible. The larger 6-pin connector side of the RTC module will be at a slight angle inwards to make room for the connector housing that will go on those pins. Mark two places for the nylon standoffs and drill 2mm holes through the knockout cap. Thread the nylon standoffs through the holes and attach them to the platform with the plastic nut on the underside of the cap.

Then add two pairs of ¼ inch holes in the platform to be used later to tie-down the connector cables:

Cave Pearl data loggers Cave Pearl data loggers Cave Pearl data loggers

Battery Pack Connector

Join the two pieces of the Deans battery connector, and add solder to the end tabs of the female side of the square battery connector. For big connectors like this I turn the iron up to ~700°F (370°C). Be sure to heat the part long enough for the solder to “flow” like a liquid, and for the flux to burn off, but not so long that the nylon starts melting. Then trim the battery wires so that they extend to a mid-point over the battery holders on the platform. Strip about 5mm of insulation from the wires and tin the ends. Build up some extra insulation thickness to protect the wires from bending stress by adding two or more layers of heat shrink to the wires just before the tinned ends. Thread two larger pieces of heat shrink over the wires and then solder the wires to the connector and seal the heat shrink over the exposed metal:

Cave Pearl data loggers Cave Pearl data loggers batterycon3

Note: the top of the ‘T’ shape on this connector is the positive (red wire) side. Set your iron back down to ~600°F(315°C) after you get the solder on the big connector tabs. As a general rule: the smaller the component – the less time it can withstand heat. It’s not unusual to see maximum tolerances of 5 sec @ 288C for tiny SMD’s.

Attach modules to the platform

Module mounting for promini data logger by the cave pearl project

With a typical sleep current around 0.25mA you should see around 8-9 months of operation before three AA cells in series reach the regulators 3.5v minimum input cutoff.

Remove the tape backing from the pro-mini and the SD card adapter and affix them to the platform. As you can see the space is pretty tight. The SD card adapter needs to be close to the battery holder, because the SDcard will extend another 5mm from the holder itself, and this must not extend past the edge of the disk.

Then attach the RTC board to the nylon risers. Check to make sure there is good clearance between the RTC pins and the Arduino pins.

Connect the RTC

After the modules are placed on the board begin the interconnections by affixing the I2C cables to the RTC.  Then add the white & yellow two wire connector to risers on A4 (white) and A5 (yellow) of the promini board. Gather the white wires and pull them into the gap between the RTC module and the battery holders. Trim the wires as a group, so that their length just reaches the single battery holder. Then strip, twist & solder the ends of the wires together, and cover the join with heat-shrink.

Cave Pearl data loggers trimjumpers2 Cave Pearl data loggers

Repeat the process with the yellow wires, and thread the joined wire sets through a cable tie that is routed from the bottom of the platform. Do not tighten the cable tie loop too much, as the black and red power lines will go through that later. To finish the RTC connection, plug a single blue wire to pin D2 on the Arduino [int(0)],  and connect it to the blue RTC alarm line as you did for the other lines. Wrap the soldered join with heat shrink and thread it under the cable tie with the I2C bus wires.

Connect the SD card

SPI lines connected on dupont jumper build for Data Logger

Now we will join the SPI lines which connect the SD card adapter to four pins on the Arduino.   Connect the 4-wire SPI cable to pins D10-D13 of the Arduino so that the grey wire is connected to D10 and the brown wire is on pin D13.  Attach the 6-wire SPI cable to the SD card adapter so that the black ground wire is closest to the pro-mini board.

Take each matching color pair of wires and fold them over beside the SD adapter board. Strip, twist & solder the ends together and add heat shrink to the join. Then bind them to the platform with a cable tie.

Join the Power Rails

The final step for the platform interconnect cable is to join the “power rails”. Connect a single red jumper to the VCC pin on the Arduino, and add a single black jumper wire to the GND pin behind the yellow wire on A5. Then gather ALL the black wires together and trim them to length along the same channel used for the RTC wires. Add at least one additional back jumper wire with a pre-crimped end to the bundle, as this extra ground connection will be needed for the LED indicator later. Strip, twist & solder the black wires together.

Repeat the procedure for the red (+3.3v) power wires, and again add at least one extra wire with a pre-crimped end to the bundle. After soldering the ends of these bundles together, cinch them out of the way with the cable tie between the RTC and the battery holders:

Joining the Positive Power rail Extra Power Taps on jumper Interconnects finished on cave pearl datalogger, ready for the main power connection

Extra power and ground connections are quite useful in data logging applications, so I reccomend adding two additional wires to the red & black power rail bundles if you will be connecting many sensors. Tuck theses loose ends under the RTC module to keep them out of the way. (alternatively you can add “sidecar” riser pins to give you more GND and Vcc attachment points on the main board – see the addendum at the bottom of the post on how to do that) 

Battery Connection with Voltage Divider

Note:  The battery connection wires see a lot of handling compared to the other connections on the logger platform.  Since I have crimping pliers to add my own DuPont ends, this is one place on the build where I prefer to use softer silicone wire  that is more flexible than the PVC coated wires. However if you don’t have the pliers, you could just keep using the pre-crimped DuPont wires on the power connector provided you protect them from bending at the connection points with heat shrink.

With the main interconnect wires completed the last part of the logger platform build is the Arduino side power connector. Put the male battery connector in a vise with a spare female side connected to prevent the nylon from sagging due to heat, then add solder to the terminal flaps of the male battery connector. You might need to turn your iron up to 700°F to tin the connections the large connector, but turn it back down to 600°F (315°C) before attaching the voltage divider resistors, or you will cook those smaller components.

Build a voltage divider from two 4.7MΩ resistors, bridging across the low side resistor with a 0.1µF (104) ceramic capacitor. Add a black wire to the capacitor side of the divider, a pink wire to the center, and a red wire to the opposite side. Then solder this divider across the pins on the male battery connector, being sure to connect the black wire side to the ground pin, and the red wire side to the (+) pin.  Blow on the solder to cool it down as soon as the join to the connector pins is complete: there is more than enough residual heat stored in the metal of the connector to scorch the little capacitor, which then usually becomes short.

divider3 divider2 divider4

This voltage divider will cut the battery voltage in half, allowing us to read the status of the 3xAA battery pack on any analog input pin (via the pink wire in the photos above) even though the main battery voltage is above the Arduino’s 3.3v Aref.  The 4.7Meg resistors are large enough to limit losses on the bridge (to about 0.6uA), and because they exceed the input impedance limit of the ADC, the capacitor is needed to provide electrons to fill the ADC’s sample and hold capacitor when a reading is needed. The battery voltage calculation for this combination is:   float batteryVoltage = float((analogRead(A0)/ 511.5)*3.3);  The default MIC5205 regulator found on most promini style boards has ~200-300 mv dropout during SD card writes, so when your AA battery pack gets down 3.65 volts, it’s time to shut down the logger.

Add heat shrink to protect the connections, and then plug the connector into it’s mate on the logger platform. Trim the black wire to length for the ground pin beside D2 (with the blue RTC alarm wire) , and then add a female crimp connector to that wire. Do the same for the pink voltage divider wire which gets attached to A0, and the red wire which gets attached to the RAW pin behind the serial/UART terminal.

Cave Pearl data loggers divider6 Battery connector on main logger platform.

Indicator LED

Since we removed the pin 13 LED from the pro-mini, we will now construct an external indicator. Peel away 2ocm Red, Green, Blue and Black ribbon cable wires and solder them into place on a common cathode RGB LED, matching the wire colors to the correct pin. Then add stiff heat shrink around the connection points to protect them from flexing. Place the ends of the Red, Green and Blue wires into a 3-connector housing.  The R-G-B connector attaches to digital pins 4-5-6 on the Arduino.

Cut the black wire near its mid-point, and insert a 20K resistor to limit the current through the LED. I often replace the bottom half of the wire with a softer flexible length of wire with a MALE crimp connector at its end. The male ground pin connects to one of the ‘extra’ lines we added to the ground power rail bundle.

ledwires2 ledwires3


Cave Pearl data loggersTypical pro-mini loggers built with this design sleep at 0.25mA, before extra sensors are added. At that current draw, the logger should deliver approximately six months of operation on three brand new AA batteries with a 15min duty cycle; depending on sensor load.

Now you can run testing utilities to verify that everything is working. But before you jump into that it’s worth keeping in mind that the entire construction can easily be disassembled for debugging if you suspect a bad connection somewhere, and it is even possible to pop the modules off with a small screwdriver and replace them:

In the build pictured here I added an I2C 32K EEprom to the platform. But since I2C devices all get connected in parallel, the assembly procedure is basically the same – you are just adding one more wire to the bundles connecting the RTC. If your connectors don’t feel like they are securely in place on the pins – then replace that wire.

In the build pictured above, I’ve added an AT24c256 I2C 32K EEprom to the basic platform. But since I2C devices all get connected in parallel, the assembly procedure is basically the same – you are just adding one more wire to the bundles connecting the RTC.  You treat I2C sensors the same way, so that red breakout could just as easily have been a temperature sensing board.

Test continuity on suspect wires with a DVM.  If you carefully lift the little tabs holding the crimps inside the black housings, individual wires can be extracted from the connectors and replaced.  If your crimps don’t feel like they are securely in place when they slide over the riser pins – then you should replace that connector.


platform partsYou can build a robust, inexpensive waterproof housing for your logger from a couple of 4″ plumbing end-caps. I use Loctite E30-CL to pot sensors on the exterior of the housing and you can see a complete walk through of the process in the  Sensors & Housing post from last year. Note that I did not use the 4-pin Deans connectors you see there on this newer build because they are fairly expensive, and a few people have been having a hard time getting their hands on them. If you shell out for crimping pliers, you can make as many custom connectors as you need for pennies each.  Dupont’s are not as robust, but I’ve had loggers running for years with them, so they are not a bad place to start. If the male pins don’t mate tightly, put a thin layer of solder on them to make them a bit thicker. Quality varies quite a bit, and Pololu sells good crimp pins.


1. Test the LED
Connect your indicator LED, to pins 4(R) – 5(B) – 6(G), and the ground line to one of your spare GND connections. Open Blink with the LED connected to the Arduino. Change the LED to Pin 4. Verify and upload. The red LED should start flashing. Repeat with pins 5 and 6 to test green & blue respectively. Note that with the common ground connection, you can not light up two colors of the LED at the same time.

Make polarized (non reversable) connectors by mixing Male & Female connectors

You can make non reversible sensor connectors by mixing male & female pins in the same housing. But never use male pins on wires that supply power to a sensor circuit, or the connector could short out if those pins come into contact with a conductive surface.

2. Test the I2C bus
Use an I2C scanner  to determine if your devices are responding on the I2C bus. With the scanner running, specify P to return to output only the addresses that have devices, and specify S to run a Single Scan. The 4k AT24C32 eeprom on the RTC board is at address 0x57 and the DS3231 will show up at address 0x68. The 32K eeprom should show up at 0x50 and other sensors will show up at different addresses. Note that the 4K AT24C32 is only rated for 100khz operation, but the DS3231 is rated for 400khz bus speeds.

3. Test the RTC
Use the settime & gettime scripts to set and check the time on the RTC. Generally, I set my windows computer to UTC before uploading setTime so that the logger is operating on UTC. This is not possible on a Macintosh, so you will have to check if London time is currently in sync with GMT/UTC, or find some other city that is. Alternatively you could avoid the problem by using the new serial setting script from Mr Alvin’s gitHub.

4. Test μSD Card communication
Insert the microSD in the adapter and test it with the CARDinfo utility at the Arduino  playground.  Remember to change the CSelect variable to 10 to get the CARDino to operate properly, as that is the pin we connected to the μSD card Cable Select line.


The pro-mini’s MIC5205 regulator usually delivers sleep currents in the 0.25mA range (Promini~0.07mA, SDcard~0.09mA, RTC~0.09mA) That should give you at least eight months of operation on 3xAA’s, and with minor modifications you can pull that down into the 0.15mA range to run more than a year.  (Or you could reach the one year mark by powering the logger with 4xAA cells in series. If you do this you will have to change the resistor ratio on the main battery voltage divider to keep it’s output below the 3.3v aref voltage on the analog input pins) Write the build date & your initial sleep current on the bottom of the logger platform – it’s a handy piece of diagnostic information to have later.

5. Test the EEprom(s)
A utility to test I2C eeproms was posted by bHogan at the Arduino playground forum, but that version is now quite old and does not compile in the current IDE without editing. I’ve posted an updated version on gitHub. Setting #define EEPROM_ADDR 0x57 will test the 4k eeprom on the RTC board, and if you install the extra 32k eeprom that shows up on the bus at 0x50. The serial window will return  A through T & 33 through 48 if the eeprom being tested is working OK.

6. Check Sleep Current
#include the LowPower.h library from RocketScream at the beginning of a blank sketch and the put the following line at the beginning of the main loop:



Then enable some internal pull-up resistors in to the setup section of your code:
(be sure to do this before you call sd.begin)

// Always pullup CS:
pinMode(chipSelect, OUTPUT); digitalWrite(chipSelect, HIGH); //pullup the CS pin to tell the SD card go to sleep
//and you may need to pullup MOSI/MISO lines:
//pinMode(MOSIpin, OUTPUT); digitalWrite(MOSIpin, HIGH); 
//pinMode(MISOpin, INPUT); digitalWrite(MISOpin, HIGH);   

Upload that sketch and your logger will be put to sleep as soon as the program runs.  Note: the CS line should have a pullup when using the standard SD libraries, and the MOSI/MISO lines may also need to be enabled to lower the sleep current with some SD cards. But SPI is a complex protocol, and you might have to turn off these pull-ups if you have other SPI sensors attached.

7. Build your datalogger code
A good place to start would be Tom Igoe’s analog pin reading example at  ( be sure  const int chipSelect = 10; for the build described in this tutorial) and there is a nifty little function  for automatically creating log file names over on Adafruit’s site.  For something a little more advanced, I have prepared a basic data logger script that puts the data logger to sleep and wakes it up again based on timed alarms from the real time clock. These are all just starting points for you to add to as you learn more about programming an Arduino.

The first major thing to tackle to achieve a decent operating lifespan is buffering your sensor data to an array, or to the 4k EEprom on the RTC board. Examples of the code I use for this eeprom buffering is embedded the I2C eeprom tester example I’ve placed on gitHub. You don’t want to wake up the card more than once per day, since that operation draws up to 100mA, for 200-400ms, which is more than any other power use on the logger.  Older Sandisk cards (<1Gb) tend to have lower sleep currents around 70µA, but it’s not unusual to see new large capacity cards drawing ~200µA or more.

To fully optimize your code it is helpful monitor current during “logging events”, but this usually requires an oscilloscope.  In this post, I have outlined a method to use an UNO with the serial monitor built into the IDE to capture and display these brief events.

Addendum 2016-11-25:   Adding Sidecar Riser Pins

Depending on the board you are using, you sometimes run out of critical pins for attachment points.  In this tutorial I described adding an extra ground & power wire to the bundles beside the RTC, but another approach is to add extra header pins that extend from the side of the Arduino board:

Sidecar Risers 1 Cave Pearl data loggers Pinned board with sidecar headers

In the photo above I added to ground, Vcc, and a tap on D6 to make PWM output available for that specific unit even though D6 was also being used for the LED indicator. A sacrificial breadboard (the heat kills them) holds everything in alignment while soldering, and a resistor leg lets you bridge to the new headers. This lets you add as many ‘sidecar’ risers as you need, though it gets a bit tricky to solder the resistor lead with more than three sidecar pins. I suggest you add 2-3 more pins to both the Ground and Vcc lines if you intend to re-purpose your logger platform with other sensors later. You can never have too many of those connections.  (…though after seeing these triple-riser promini boards from eBay, I guess you can always have too much of a good thing…)

And this approach can be used beyond the main board:  at, cfastie used a similar method to improvise an inexpensive I2C hub for his nano shield logger.

Addendum 2017-06-22

I wouldn’t bother for just one or two builds, but Dangerous prototypes just introduced a Dirty Cables service to order custom cables. Be interesting if I could build something like this logger interconnect wire with their tool. Might be a good way to throw a few kits up on Tindie…

Using the Arduino UNO for Data Acquisition

Using an UNO and an ADS1115 ADC module to monitor current use by a pro mini logger

Here, I’m using the basic UNO Logger as a tethered Data AcQuisition device, recording the current used by a second data logger. Since the second logger is ‘floating’ with no connection to the UNO’s ground line, the voltage drop across the 5Ω shunt resistor is recorded using a differential channel on the ADS1115. Differential readings are also useful for sensor applications that use a wheatstone bridge arrangement.

I recently picked up a ADS1115 breakout board, and it was fairly easy to use that with the serial data plotting capability of the Arduino IDE. It’s not often that something works this well on the first try, and I thought I would post about using  the combination as a kind of  ‘poor mans oscilloscope’.   The plotter’s vertical axis auto adjusts as the value of your output increases or decreases, while the X axis is fixed at 500 points, with each tick of the axis equal to an executed serial println command.  Having the ability to spool data to the screen with a simple print statement, turns the exercise into a “What happens if I do this?” kind of process, which is perfect for providing feedback to students learning how to program Arduinos.  I posted the code used to generate these graphs on GitHub, but you will have to noodle around with it to figure out what the threshold settings should be for your particular application.

Although I already have a good method to estimate the overall power consumption of my loggers, I was motivated by this Jeelabs post to see if there was a way I could look at individual events. Even if you have a nice Rigol to play with, it can still be tricky to get all the settings and timings right because the loggers can draw anything from 0.15mA while sleeping, all the way to up to 100mA during SD writing events.  Jeelabs elegant solution to this ranging problem uses two shunt resistors and a diode, but with 15bits of differential range on the 1115, the 8x gain setting can do the job with a single resistor. (…provided I don’t exceed the ±0.5 volt limit that PGA setting imposes…) 

After installing Rowbergs I2Cdev library, and running a couple of jumpers, my drip sensors were generating raw count output like this:

Cave Pearl data loggers

Of course that was scrolling by like crazy, and the re-scale feature meant that the y-axis was jumping round like a bullfrog on a hotplate. You can bring the vertical axis under control by adding a few delimiter separated constants before the final data println:

Serial.print(4000); Serial.print(” “);     // sets a stable upper value line
Serial.print(0); Serial.print(” “);             //this constant sets a stable lower value

But to prevent the x axis from scrolling forever, I had to setup a trigger threshold, that would only capture a new set of readings when an actual event was occurring:

void loop(void)
int sensorOneCounts=adc0.getConversion();  //note we already set the mux to differential in setup
if(sensorOneCounts >= LoopThreshold) {      //rapid sampling loop to capture the event
for (int Cycle = 0; Cycle < ADCcycles; Cycle++) {
elapsed=millis()-start;// elapsed gives you the timebase for your samples
//A separate loop to output of the samples to the text monitor or serial plotter
for (int Cycle = 0; Cycle < ADCcycles; Cycle++) {
#ifdef ECHO_TO_SERIAL    //TEXT only output of the time it took for your data acquisition loop
Serial.print(F(“Time for “));Serial.print(ADCcycles);Serial.print(F(” readings: “));Serial.print(elapsed);Serial.println(F(” milliseconds”));


A few runs with text-only output showed the sleeping logger generating around 65 raw counts on the ADC, so I set the LoopThreshold to 75, and the plotter started behaving like an oscilloscope’s triggered sweep: scrolling 500 new readings across the screen each time the drip sensor woke up.  With a known shunt resistance, and the millivolt resolution per bit from the datasheet, I could convert the raw ADC counts to μA in the printing loop. Just for fun I also tried speeding up the I2C bus to see the temporal resolution of that sample loop at 400Khz:

Running ADS1115 with UNO as DAQ - with I2C bus running at 400HZ, the system outraces the ADCSo I was asking for data faster than the 1115’s top speed of 860sps could deliver it.  A few more trials showed that even with the Arduino’s default 100Khz bus, I had to add delayMicroseconds(400);  into the capture loop to keep the UNO from outpacing the ADC module.  I expect that will be different for Arduinos with different clocks like the promini, so one would have to make manual adjustments based on the elapsed times for each system.

These drip logger events are the result of straightforward code that follows the steps:

1) Wake from interrupt & clear the registers, update count variable
2) Turn indicator LED on & sleep for 15ms
3) Wake, turn LED off & sleep for another 32ms (to let impact vibrations die down)
4) Set accelerometer registers & go into deep sleep: wait for next accelerometer interrupt

Since you can drop as many constants on the plotter as you want, it’s easy to determine the current level at a specific point on the plot by intersecting it with a new line:

Cave Pearl data loggers

Though there were no surprises in the pattern per se, it was handy to find out that the “in-event” sleep current was about twice the normal standby state. (which I confirmed at 0.2mA using a DMM)  Now I can go digging through the code to figure out what’s drawing  that extra power.

After resetting I2C bus, I tweaked the delays to exactly match the 860 sps output from the ADC. Then I sat back and waited for one of the real time clock alarms to fire:

Cave Pearl data loggers

This was my first view of that complex logger event, with variable juggling, time stamp creation, eeprom buffering, counter resets, etc. With I2C devices being able to stretch the clock whenever they need to, I had no idea how long these kind of events actually took, and I certainly never managed to capture one so easily on the old clunker scopes I could get my hands on.  The comb pattern you see there is a result of sleeping the processor for 15ms after sending data to I2C device registers; instead of using a 6ms delay while the Arduino waits for the devices to respond.  This lengthens the overall duration of the event, but the time spent running at full power is reduced.

By how much? I reset the logger to use delays after I2C writes rather than sleeps and re-captured the event:

Cave Pearl data loggers

The horizontal axis is at the same scale as before. The start of the event now looks like a solid block and the overall event is about 50ms shorter.  For comparison, I’ve inset the previous graph with the sleep gaps cut out and the spikes moved together, and the two white rectangles at the top represent area equivalent to sleep gaps that were removed.  The grey area shows the power saved by using 15ms sleeps instead of 6ms delays.  To do this properly I would need to take another reading of the 3xAA power supply voltage and calculate the total power used (minus the loss on the shunt resistor), but you can see at least 25% improvement simply by comparing the plots. That kind of feedback is very helpful when you are trying to optimize your code.

Now, I can already hear people scoff that even $3 is too much to pay for a scope that won’t reach 1Khz. Indeed, with a minimum temporal resolution of just over a millisecond, the ADC frequently misses brief current peaks. I know my 8mhz promini based loggers usually draw more than 4mA while running, and you see the longer operations in the RTC/delays event pushing up towards 6 mA.

Cave Pearl data loggers

But even with the upper third lopped off those spikes by timing errors, I can still use this method to make a reasonable estimate of the power being consumed by logger events provided they don’t last more than 580 milliseconds. ( The serial plotter provides a window for only 500 samples and the UNO barely has enough variable memory for a 16bit integer array that size.) If you add the SD card library to your script you are only left with enough memory for about 100 of these samples in your capture loop, although you could try reducing the ADC readings down to 0-256 with a well tuned map function. Then you could use an uint8_t integer array, and store twice as many readings in the limited variable memory of the Arduino.  If you were just doing a classroom demo, that range would probably still give you a decent display on the plotter.

Despite these limitations, the setup is so simple that I think the serial plotter tool will become a go-to for quick looks at sensor data, perhaps even replacing some processing based demos.  The ability to connect four of these ADC modules to a single Arduino makes the platform look quite respectable as a classroom level data acquisition system, especially for environmental data that rarely requires high frequency sampling.  

If you switch to a beefier 1280 based Arduino like the Mega, or the Moteino, those memory limitations disappear and recording much longer events would become possible.  With the delays I had to put in, my gut feeling is that you could juggle a couple of these boards at a time; interleaving the readings to double or triple the effective sampling frequency. (at least until the input impedances start to mess with the shunt resistor…)  And finally, I think adding a couple of well chosen diodes to clamp the input voltage to the ±limits imposed by your PGA setting would be a good idea in the classroom, or you might loose a few of those ADS1115 modules.

It is worth noting that there is a comparator function in the ADS1115 that can be programmed to send a pin change alert when a given threshold is crossed. If I can figure out how to get ADS1115’s built in comparator working with the differential modes, this would even let me put the DAQ to sleep between sampling runs. The ADC module also has a ‘data ready’ alarm that can be enabled to tell you exactly when it has the next reading available.  I did not go that route as the generic approach used here is applicable to sensors without these features, including the ADC built into the Arduino. 

There are plenty of other serial data plotting programs, but using the free IDE version like this is an iterative exercise, forcing you to switch between the serial text monitor & the serial plotter a few times to tweak the delays and constants. If you are using an UNO in a classroom setting, this in itself is a useful activity.  And given how cheap basic DAQ modules are these days, choosing to use an Arduino is always about the showing the process rather than just getting a final result.

Addendum 2016-08-15:     A MUCH faster DAQ with the native UNO ADC

 Here I’m reading the voltage across a 10Ω resistor with the UNO’s built in ADC. To do that I need to join the ground lines because the Arduino can only take single-ended readings. That also forces me to put the shunt on the low side line so I don’t exceed the 1.1 vref. This arrangement causes the drip sensors’s effective ground line to jump around as the current through the resistor changes.

Here I’m reading the voltage across a 10Ω resistor with the UNO’s built in ADC. To do that I need to join the ground lines because the Arduino can only take single-ended readings. That also forces me to put the shunt resistor on the low side line so I don’t exceed the 1.1 vref. This arrangement causes the promini logger’s effective ground line to jump around as the current through the resistor changes.

The folks over at Measuring Stuff  posted a page called The Arduino DAQ Chronicles, which goes into some detail on the process.  It’s a good chunk of background reading even if you are using the ADS1115 ADC described above. The Arduino’s native ADC delivers 10-bit readings, (ie 0-1023) and compared to the relatively pokey ADS1115, a typical UNO can take several thousand analog readings per second; outperforming the ADS1115 by a fair margin. The challenge is balancing the reduced resolution with the other limits imposed by the method itself. Even if you increase the sensitivity of the native 10-bit ADC by changing to the internal 1.1vref, you only reach 1.1v/1024 steps = 1.07 millivolt per bit. Remember that my loggers are sleeping at 0.2 milliamp x 5Ω shunt resistor = 1 millivolt so we are operating right on the lower limit of the ADC resolution. With that 1.1v cap on the ADC input, and a potential 100mA peak current (during SD card data saves), the largest shunt resistor I can use is 1.1v/0.1a= 11Ω. So to get the Arduino to discriminate the low currents we need to use a pretty  large shunt resistor value, and allowing the voltage drop to get that high imposes another challenge in that the drip logger would only be left with 4.5v (the 3xAA battery) 1.1v drop on shunt = 3.4v. That’s right at the minimum input voltage needed by the 3.3v regulator on the Arduino promini board, risking a potential brown-out in the middle of the SD card writing process.

But hey, lets pop in some new batteries, and see what we get:


Not too bad, but that’s a noisy plot with lots of jitter on the base line. Having 1-2 bits toggle like that is typical for ADC’s so there is probably nothing I can do to get rid of it. And the drip sensors resting state reads at zero when it should be registering at least two counts. It is also common for an ADC to under or over read by a few bits, so I added an offset adjustment into the code to bring that sleeping baseline up to the 0.2mA that I have already confirmed with a multimeter.

Then I realized I still had the 400us delay in there from the ADS1115, so I took that out:

Cave Pearl data loggers

Crikey! Even with the code overhead, that thing is taking over 8000 samples a second! That’s far too many readings for the serial plotter to handle if I want to view long events.  And that first spike goes upt to about 5mA – exactly where it should have been on the ADS1115 readings if that module had not missed them at 860sps.  So how do I maintain the Arduino’s ability to spot those rapid sample peaks, but only send 500 readings to the screen?

Instead of delays, I decided to create an “oversampling loop” that creates a running average using a low pass filter, but also checks for peaks throughout the process. You can dig into the code for this over at GitHub, but the basic idea that is if a peak occurs, then the highest reading in an interval becomes the final reading. If a decreasing trend is found, then the output from a leaky integrator becomes the final reading for that interval. So the readings get smoothed on the way down, but not on the way up.

Here is a try with the oversampling interval set to six ADC readings:


That’s the RTC event (with delays) and the drip triggered event at the same scale.

Now here’s another run with a 15:1 ratio:


Squashing more than 7000 raw readings into a 500 line display really starts to distort the curve, but everything is still recognizable, and more importantly, the peaks did not get chopped off like they did with the ADS1115.  Woot!

Now we have a method that lets us adjust the serial plotter’s display to match the event we are trying to see, provided we don’t over-interpret the accuracy of those heavily averaged interval numbers. And rapid sampling can introduce other issues to deal with. For example: Dustyn Roberts has a useful post on creating very precise time stamps with the micros(); function when you are sampling faster than 1 millisecond. 

So within limits, a standard Arduino gives you good temporal resolution but can not detect less than 1 millivolt of change, while the ADS1115 gives you precision down to an impressive 0.0078 millivolts (@16x gain) but is not so great for tracking really brief events.  If you need both resolution & speed, you need opamp circuits designed for the specific situation, as in the Jeelabs example. It’s also worth mentioning that the Arduino ADC also supports a comparator that you could use for the threshold function more elegantly than I’ve done here.  And with such a low impedance input, you can also double or triple the sampling rate by changing the ADC clock prescalers (this is also in the code on GitHub) Both of those things are described in detail over at Nick Gammons excellent page on ADC conversion on the Arduino.

Addendum 2016-08-16

Hopefully they will add export options (like other serial tools) to the plotter in the future, but for now you can manually copy data out of the serial text monitor and paste it into Excel.  Before you start a long run for export to a spreadsheet, comment out the constants that you were printing to stabilize the plotters y – axis, so that only the numbers you are interested in are sent to the serial output.  If you are waiting for an event to happen, it often helps to add a threshold test so that the serial monitor is not just filling up with uninteresting data that you would have to prune away later anyway:thresholdprintline

Then after your DAQ has been capturing events for a while, click inside the serial monitor window,  select all the data & copy it (on a windows machine that would be [CTRL]+[A] followed by [CTRL]+[C] ) then open a new spreadsheet and simply paste the data into an empty column.

This lets you compare the events side by side:

CopySerialdataintoExcelIf you want to graph more than one number, then add a comma between them with Serial.print(“,”);  remembering to use println on the last variable being sent.  Then you need to add the intermediate steps of pasting the data into a text editor like notepad, and saving that text file. Then change the ending from .txt to .csv and Excel will open it directly. If you can’t change the filename, you can still import the text file and specify comma delimiters:


to put the numbers into adjacent columns. If you don’t have excel, there are plenty of other data plotting options out there. And programs like coolterm, can save you from having to do those cutting & pasting steps.

Addendum 2016-10-13

Gokul Shrinivas just posted a neat little bit of code at that reads the Arduino ADC at a cracking 68k samples per second out of a Arduino Due by directly accessing the ADC ports as soon as the DataReady interrupt is triggered. 

He starts with defines:

#define ADC_MR * (volatile unsigned int *) (0x400C0004) /*adc mode word*/
#define ADC_CR * (volatile unsigned int *) (0x400C0000) /*write a 2 to start convertion*/
#define ADC_ISR * (volatile unsigned int *) (0x400C0030) /*status reg -- bit 24 is data ready*/
#define ADC_ISR_DRDY 0x01000000
#define ADC_START 2
#define ADC_LCDR * (volatile unsigned int *) (0x400C0020) /*last converted low 12 bits*/
#define ADC_DATA 0x00000FFF 

And the sampling loop becomes

  for (i=0; i<320; i++){
    // Wait for end of conversion
    while (!(ADC_ISR & ADC_ISR_DRDY));
    // Read the value
    analog_data[i] = ADC_LCDR & ADC_DATA ;
    // start next

He used an LCD screen for the scope, but I am wondering if it would be possible to refine my oversampling trick to squeeze that many data points on the serial plotter somehow…

And I wonder if this trick is even available on the 328p? I guess I will have to go looking at other Arduino Oscilloscope projects. The problem is that most of them seem to be using 8-bit signals from “free-running” modes, and I rarely have an application that needs less resolution. Here’s a project doing Interrupt-Driven Analog Conversion  with an ATMega328p, and Nick Gammon mentions it here, but no one does a speed comparison with the ten analog 10-bit readings you get per millisecond using plain old analogRead();

Even if there is no speed gain, perhaps I could do calculations while I was letting the ADC read continuously to speed up the overall sampling loop.  I could see myself getting out of sync pretty easily though, unless I deactivate the general interrupt flag and activate it again (with  cli() and sei()) or I would randomly miss readings.

Nick posted a code example of reading the Analog-to-Digital converter asynchronously that seems to solve the synchrony problem.  He’s also posted an interesting ‘sleep during ADC conversion’ example buried in there, but that’s only useful if you are not using timers & PWM at the same time, and I often do that…

Update: the project listing magically evaporated… and I just found exactly the same code at Bruce Land’s Hackaday project from 6 months ago. So I think proper attribution for the script above should go to Bruce.

Addendum 2017-01-10

I’ve been playing around with the ADC clock prescalars, and with the asynchronous reading code available over at Nick Gammon’s site to try to get better temporal performance out of my little UNO-scope.  With such a low value shunt resistor the ADC seems to read fine even if you crank it up to about 40k samples/second. Unfortunately you pass a point of diminishing returns due to the processing overhead with the interrupt based asynchronous readings,  so async reading actually reduces the number of readings per millisecond at the higher clock speeds. If you want to play with this approach yourself, I’ve posted the update with the prescalar settings to GitHub.

Addendum 2017-02-27

Anyone interested in using an Arduino as at data acquisition device will probably want to see my recent post: Enhancing ADC resolution with Dithering & Oversampling
For an unmodified UNO,  Qwerty’s triangular dither method is probably the easiest one to use, but for 3.3v boards I’d go for the Toggled pin dither method I outline at the bottom of the post.

Build your own Arduino Starter Kits for the Classroom

A typical student starter kit.

It’s August, and we’re assembling kits for another run of the instrumentation course.  Over time we have come to rely on 328p based microcontroller boards (aka: Arduinos) so I though I would post a list of the parts & materials we use to help others fire up their own classroom. More than a few people have requested this since I posted the UNO based logger tutorial last year.

Before digging in: I should warn you not to reinvent the wheel if you don’t have to: there are lots of premade kits out there. We found that many had parts we simply didn’t need, as the minimal ‘starter kits’ we use are designed to exactly match the lessons in a course focused on environmental monitoring.  We also hand out extra parts for some tutorials as needed through the course, and the students receive a second project box when they start building their stand-alone  projects. Cave Pearl data loggers Even if you want that level customization, it might worth looking at some basic electronic component kits, and building your classroom set on top of those. The DIY approach will save money, but you pay for it with time.  Most of the eBay parts shown here took about two weeks to ship, with some stragglers taking almost a month to arrive.

You will need more than an Arduino and a few components  to set up a classroom, so I am including tools & other miscellaneous bits of hardware that we use in the lab. I would not describe any of these as high quality equipment, but they are ‘good enough’ to get things rolling on a modest budget.  Even if you go with eBay stuff,  you are doing great if you can run a course where students build ‘real world’ deployable prototypes for $100 a seat, once you include the tools and other bits.

Components for the UNO based Datalogger:

UNO Data logger Kit: $25-50 / seat
UNO_100pxw Arduino UNO R3
The real thing, and tough as nails. All of my old UNO R1 boards are still operational despite years of abuse. If you can’t afford the real thing due to budget limitations, then at least donate a few bucks to help them keep the open source project going.
UnoClone_100pxw UNO clone (incl. USB cable)
If you have to go this route, I suggest that you choose exact copy ones with ATmega16U2 or 8U2 UARTs to avoid problems with the IDE. If you can deal with the driver issues, there are clones for as little $3 with alternate UART chips like the CH340.
Transparent Experimental Platform Base-plate
Last year we made our own base plates with M3 risers and Plastruct Styrene sheets. But these acrylic boards save time. Check left/right side orientations before buying..
MiniBreadboard_100pxw Mini Solderless Breadboard 400 Tie-points
Get two per student, in case they need to expand their projects.
JumperWires_100pxw 65pcs Jumper Wire kit
Need at least one of these for every two students.
40p10cmdupont 40wire Dupont 10cm Jumper cable
An alternative to loose jumpers wires, and they keep the kits looking tidy at the beginning of the term. Having students make longer or shorter jumper wires by hand when they need them, gives them practice with the crimping tool.
JumperWire22AWG_100pxw 22AWG Solid Hook up Wire (25 Feet/color)
One box will cover the entire class and they should know how to cut and strip wires properly. Don’t bother with pre-cut jumper wire sets as the longer lengths are never the right size..
SDmodule Micro SD Card Memory Shield Module
And don’t forget to buy μSD cards to go with them. Test any used ones to make sure they are ok.
RTC_100pxw DS3231 & AT24C32 IIC RTC Clock Module
I have a page describing these RTC board in some detail here. You will also need a CR2032 3v Lithium coin cell backup battery, after you remove the charging circuit resistor.
Keyes3ColorRGBLED_100pxw Keyes Ky-009 3-Colour Rgb Smd Led Module
There is nothing special about this common cathode 5050 LED, but it’s easy to remove & re-insert without bending the pins, and the low profile helps it fit in the kit boxes.
Tweezers_100pxw Vetus ESD-15 bent tip tweezers
Make sure they have the rounded shaped ends that come to a sharp tip
ICbox_100pxw 10 Compartment Small Part Storage Case
To keep all the led’s, resistors, etc. from rolling around loose inside the larger clip boxes. Get ones where the section walls can be removed to make room for longer parts.
SteriliteBox Sterilite 1961 – Small Clip Box
Expensive, but they survive in a student back pack. You can find $1 clip box alternatives (like the photos at the top of this post)  at your local dollar store.
CheapMultimeter_100pxw Basic Digitial Multimeter DT-830D
We have better meters in the lab (like the EX330) but at this price you don’t have to worry about students loosing or breaking them. Have replacement 9v batteries on hand, as people frequently forget to turn them off. Expect 1-2% error on readings.
eyeloupe Folding Magnifier (5x)
Useful for inspecting solder connections.
$0.55 ea.
Note: The stuff above this line goes into every UNO logger kit, but I am adding a few optional things to this list that might be appropriate for other courses:
MinimalKit_100pxw Minimal electronic components kit
Even though we don’t use them, I wanted to put this in here as an example of a minimum component package that could be a starting point for your custom kits.
ElecfansKit Slightly less minimal component kit
Another one that’s almost tempting. Search eBay for ‘Electronics starter kit for Arduino’ and you find oodles of these. If you are only making a small number of kits these might be the way to go. But if you are making six or more, check the basic components list below, as most of the parts in these packages are pennies each if you buy them separately.
6xAAbattery_100pxw 6xAA Battery Holder Box for Arduino
These will power an UNO for about 40 hours of continuous stand alone operation. You can stretch that out with processor sleeping & other tricks.
PWradapters_100pxw 9 VDC 1000mA regulated power adapter
5.5mm/2.1mm barrel jack, positive tip. Expect these cheap ones to be noisy as heck compared to the ones from Adafruit. We run most of the UNO based lessons tethered to a USB cable, so these rarely get used.
LongBreadboard_100pxw MB-102 Solderless Breadboard 830 Tie Points
They don’t go into the student kits, it’s a good idea to have a few of these longer breadboards around.
TranspShield_100pxw Arduino UNO R3 Transparent Case
An alternative to the flat platform approach we use  would be to try these in combination with a breadboard shield
BreadboardShield_100pxw Mini Breadboard Prototype Shield
With a little creativity you could squeeze low profile components for the data logger onto this if you find an SD card adapter, and an RTC with perpendicular pins.

Basic Electronic Components:

Most electronic components can be had for pennies if you buy them in quantity. And the difference between low end parts and name brand stuff can be more than an order of magnitude.  That doesn’t mean that off the shelf kits are a bad thing, it just means that what you are really paying for is someone’s time selecting and packaging it.  That still might be the better option for you if you can afford it.

Basic Components:
StanleyBins Stanley Removable 10 Compartment Organizer
Before you buy a bunch of tiny little parts, you need some way to organize them. I usually put the items into 3″x 5″ or 4″x 6″ bags, which then go into these compartments.  Pink 4Mil Anti-static Poly Bags come in all sizes, and work well for this. Being able to remove the section boxes from these organizers to lay out specific parts for a tutorial also comes in handy.  See: Organizer Bin Storage Unit See: Tool Storage
StanleyShallowOrg Stanley Shallow Organizer, 25 Compartment
This organizer is better for really small components & IC’s that you only have a few of, but you still need to bag them or they get jumbled.
AdafruitWire_100pxw 26AWG Silicone Cover Stranded-Core Wire – 2m
This high strand count wire from Adafruit is the nicest stuff you are ever going to work with, and is my favorite after trying just about everything else on the market. Simply fold & cut those pre-cut 2m lengths four times and you end up with 12cm lengths which are perfect for including in kits. [Colors:Red,Black,White,Yellow,Green,Blue,Grey,Orange]
CheapWire_100pxw 100Ft / 30.5M 28AWG Silicone Wire 3KV
As your projects get more advanced you can never have enough different colors of wire so I use this stuff is to add Pink, Brown & Purple to the standard color set . This is thinner seven-strand wire,  so it will not stand up to frequent bending like the highly stranded Adafruit 26awg. If you buy two lots at a time they combine shipping bringing the total to ~$15/60m.  This makes it worth the hour you are going to spend cutting & processing each of those long bundles from Taiwan. Of course, many US vendors are also going send you loose piles of spaghetti like that to deal with. High strand count 28AWG here.
Hshrinkspool_100pxw 1/16″ 2:1 Clear Heat Shrink (MIL-I-23053/2, class 2)
Unlike normal heat shrink, mil-spec is very thick and holds its shape after cooling; making it easier to route cables in a housing. Watch for eBay vendors that advertise mil-spec, and send you the thinner cheap stuff.   I think of 1/16″(=1.5mm) heat shrink as “1-wire sized”, 2mm = “2-wire size” and 1/8″(=3mm) as “3-wire size” when working with 26awg.
I add male DuPont crimps & a bit of heat shrink to thin lead components to make the breadboard friendly

Resistors: Lead diameter makes a resistor breadboard friendly or not. You generally want 0.6 mm not 0.4mm leads, though it is inevitable that you will end up buying a few cheap multipacks with the thin leads. ( Note: You can add male DuPont crimp ends & a bit of heat shrink to components with thin leads to make them breadboard friendly : see inset photo) Brand-names like Vishay, Xicon, KOA Speer are usually very good, but you pay 2-5 cents each for them. Ironically, the cheap old carbon resistors often tend to have thick steel leads while the better brands have softer copper leads which bend more easily. I find 1/4 watt to be the most practical size and 1/2W metfilms are physically about the same size as 1/4W carbons. Beige-background carbon resistors seem to be much easier to read than blue-background metals, but if you need 1% tolerances, you won’t have much choice. 1/8watt metfilms are very tiny, which can be helpful if you need to put a resistor into a small place, like between two pins on a breakout board. Wherever possible, buy 1% tolerance (or better) resistors, rather than 5%, as this affects your sensor accuracy when you use them in voltage dividers – which is a common way to read sensors.

MetfilmResisorSet1 130 values 1-10MΩ 1/4W Metal Film Resistors Assortment
Crappy thin leads, but a huge range of values to have on hand at the beginning of a class – in fact I would order two of these to get started.   Then order 50-200 of the individual resistor values as needed for your labs/exercises. Be prepared for it to take 2-4 weeks for resistors to show up if you order them via eBay.
IndMetfilms MetFilm Resistor 1/4W 0.25W ±1% [Various Sizes]
100 pc of specific sizes with thin leads. We usually put five to ten of 330Ω, 1K, 4.7K & 10K in each kit, but you can tune this to your curriculum and/or hand out other specific sizes at the beginning of each lab.  After you get better at soldering, you will probably switch over to 1/8 watt resistors, as their smaller size lets you put them into tight spaces: like between the pins on a promini board.
HalfwattCarbons 1/2W Carbon Film Assortment (30value x10pc 1-3MΩ)
Sometimes the 1/2 watt size is easier for beginners to handle. It also helps to have “exercise specific” resistor values look physically different from the other resistors in the kits. These still have thin leads though.
carbons Carbon Resistor 1/4W 0.25W 5% [Various Sizes]
Just a typical eBay search link to give you an idea what’s available. Usually these carbons have nicer thicker leads but the quality varies. Check for free shipping.
Components: Most hobby market parts distributors have “Assortment Kits” for commonly used components and its a good idea to just buy a selection those when you are starting out. It might be a while before you actually dig into that mixed bag of capacitors for the odd value you need for that circuit you just found on the internet, but when it happens you will be glad you spend that $1 six months ago. I’m going to list several from Electrodragon as examples, but there is nothing special about them and you can often find a very similar set on eBay for significantly less. A common problem with all the overseas suppliers is that it usually takes 3-4 weeks for stuff to arrive. So if you realize that you need something quickly, go to Sparkfun/Adafruit/Pololu/Amazon etc. My rule of thumb with dodgy flea markets like Dealextreme, AliExpress, etc. is: “If this order never arrives, how unhappy would I be about that?” If the answer to that question is “Quite a bit” then you should order that part from a reputable vendor.  More than 95% of the things I order from eBay do arrive…eventually…though it’s common for things like sensor modules to be significantly different than the photos shown in the listing.
LED's 5mm LED Light Diffused Assorted (5 Kinds*20PCs)
Having the colored plastic makes it easier for students to identify which LED is which. [red, green, yellow, blue, white]
RGBled10mm LED diffused RGB 10MM Common cathode
Having the RGB led a different physical size from the one-color LEDs makes it easier to identify them in the kit. Common cathode means you can use one limit resistor on the ground line. You can use a CR2032 coin cell to identify which leg is which color quickly by putting the common line on the negative side of the battery.
mixedcaps Ceramic Capacitor Assortment (10 Kinds x 50 PCs)
The most important thing to know about ceramic capacitors is that they have the worst thermal coefficients of any component you are ever going to see.  So to build a circuit which will work in real-world environments you need the dielectric to be rated at X7R (±15% from -55 to 125C) or better.  Garden variety Y5V (±82% from -30 to 85C) caps also loose about 30% of their capacitance in their first year of operation (X7R’s loose <10%) and you need to compensate for that too.   And finally you need to buy caps rated for 50v, if you want to use them with 5v because the bizarre rating system means that you could loose up to 80% of the rated value as you approach the rating on the label. 
cCaps 100PCs Ceramic Capacitor [30pF,10nF,100nF]
The four most common sizes of capacitors to keep on hand are 10μF (106), 1μF (105), 0.1μF (104) and 10nF (103). Get 100 of each to start, as they are frequently used for bypass/decoupling. Most of the time you will be using: 104 (100nF) but like resistors it’s handy to have small mixed assortments on hand for one-of builds. 
EcapAssortment Electrolytic Capacitor Assorted (0.22UF-470UF, 12Kinds)
I rarely use these (unlike the little ceramics which get used all the time) Keep an eye on polarity! And there are other kinds of capacitors out there, and for sensor circuits that have to be stable with temperature, or over long periods of time, plastic film capacitors are often a much better choice than either electrolytics or ceramics: I use Polyphenylene Sulphide (PPS +/-1.5%) or Polypropylene (CBB or PP +/-2.5%) when I can since their aging rate (expressed as % change /decade hours operation) is negligible. The only drawback is that they are relatively large, so for a given value, the film cap might be the size of a jellybean, when the equivalent ceramic cap would barely big enough to solder to without a magnifier lens.
GeneralDiodePack General Diode Pack (8 Kinds)
(1N4148 -25PCs, 1N4007 -25PCs, 1N5819 -10PCs, 1N5399 -10PCs, FR107 -10PCs, FR207 -10PCs, 1N5408 -5PCs, 1N5822 -5PCs)
INDdiodes 50PCs Diode [Individual types]
1N4148 is the standard signal diode so it might be worth ordering those.
1N5817 Shottky’s are also useful to isolate battery banks from each other.
DiodePack_100pxw Common Zener Diode Pack, 0.5|1W, 3.3V-30V
(14 kinds, 5pcs each) Each Zenner has a specific breakdown voltage, so it might be a good idea to wait till you know which ones actually need and order only those specific types.
TransistorPack General Transistor Pack (17 Kinds x 10PCS, Low Power)
Like Zenners, there are many different flavors of transistor out there, and you should figure out which one you need before buying too many of them. So perhaps just order this pack as a backup, and wait till you know which specific ones you need. For example: the 2N2222A is one common NPN BJT that most everyone seems to use, and they are about a penny each.  See: Building a Friendstrument. See: Transistor as a Switch  See:TransistorCalculator.       Rule of thumb for using cheap transistors as switches:  Size your base resistor to make the base current twice the calculated value for the smallest hFE you see listed in the data sheet (see calculator here) provided that does not exceed ~20mA digital pin current on an Arduino. Don’t forget to add pull up/downs for stability. Note: E-B-C pinouts are not standardized For most 2N2222s, when the flat side is facing you, the pins are E-B-C but some  are C-B-E.  If  you get C/E reversed the transistor will still sort of work but with a lower β (beta). This is highly annoying to debug…      To test an unknown transistor with a DVM in diode test mode, attach the red positive lead to the base of the transistor, and the black neg. lead to each of the two unknown legs in succession: The slightly lower of the two voltages will correspond to the collector-base junction, and the slightly higher reading will be the emitter-base junction.
2N7000 2N7000 TO-92 N-Channel Mosfet (200mA max)
These mosfets are like “Transistors for Dummies” and work great as digital switches when connected to 5v Arduino digital pins – and you don’t have to do the calculations for the base currents, etc. So they are much easier for beginners to use although they will set you back a whopping four cents each. Note: A 100K resistor between the gate and ground keeps the N-fet off by default, but you can generally operate mosfets without a pin-gate resistor, though many recommend 150 ohms there. N-channel mosfets are usually placed on the ground side of the controlled circuit.

Note for 3.3v systems: The 2n7000 can be used with a 3.3v Arduino to control things like LED’s, but they only pass between 30-60mA because the controlling voltage (Vgs) needs to be at least 4.5v for the 2n7000 to be fully turned on. With only 3.3v control, the resistance across the 2n7000  is ~ 3-4 ohms, so there will also be substantial voltage drop across it.  Although “logic level” is not exactly as standard term, mosfets designed to work with 3.3v mcu’s often have an “L” in the part number, ex: IR540 (non logic level) vs. IRL540 (logic level).  Ideally you want the MAX value for Vgs(threshold) to be lower than 2.4v in the datasheet, or you want to see an RDS(On Resistance) quoted for 2.4v, or lower.  When considering the On Resistance, calculate the voltage drop that will occur when the MOSFET is On and the load is operating. If the load draws 50mA, and the RDS(on) is 3 ohms, the vdrop across the fet is 0.05*3=0.15v. The tricky thing about this calculation, is that the On resistance changes with the level of the controlling Gate Voltage, and as you get closer to the Vgs(th)threshold voltage, the on resistance increases – so you need to dig into the graphs on the datasheet to figure out what the actual vdrop is going to be. Since the whole point of using a MOSFET as a switch, is to achieve lower Vdrops than you would get using a BJT, you want the vdrop  across the FET to stay below 0.25v maximum.   Probably the closest thing to a 3.3v version of the 2n7000 would be one of the Supertex TN0702 or TN0604, which come in the same TO-92 package.

You can solder legs onto SMD parts to make them breadboard friendly.

Most of 3.3v N-channel mosfets come in tiny surface mount SOT-23 packages:  The Philips pmv30, pmv31 and pmv56, and the Vishay Si2302, Vishay Si2356DS  , Si2312BDS (or Si2333DS /DDS for P-channel)  The Fairchild NDS331 / 335 is another good option with very low on resistance and a gate threshold of only 1v.  The problem is that none of them are available in breadboard friendly TO-92 packages  so  you might have to mount them on SOT-23 adapter boards to use them, and if you willing to do that it might be worth going to the Si4562DY which gives you both N & P channel mosfets in the same package. A P-channel mosfet is used on the positive side of the load whereas an N-channel mosfet is used on the negative or ground side of the load. When triggered, a P-fet connects the input on the load to the positive source whereas an N-fet connects the output from the load to ground. Keep in mind that you can’t drive a p-channel directly from an Arduino if the circuit being switched is a different voltage from the control logic, but that can be solved by using an N-fet to invert, then connect it to a P-fet in succession
Also see: P channel FDN338P and N channel FDN337N, STN4NF03L.

Rotary pots 10K Linear Rotary Potentiometer 15mm
Also available in other values like 1K These B1k/10k’s can be put right onto a breadboard, though they are also good for soldering lessons and then you are ready for the ever popular LED Bar graph tutorial at  For some reason, it’s cheaper to buy the plastic knobs separately.
BBorardTrimpot Breadboard trim potentiometer 1 & 10K
These guys are really nice to use on a breadboard as you can turn them with your fingers, however they are more than a buck each. If you can stand using a screwdriver to adjust, the cost of a smaller trimpot goes down to about 20cents each. There are also 3296 Assortment packs of other styles available.
Momentary switches Push Button Momentary Switch (12x12x7.3mm)
15pcs with a selection of different color caps. Cheaper if you get larger quantities. Sometimes there are little bumps on the bottom that you have to snip off to make them breadboard friendly.
LatchingPushButton Latching Push Button Switch DPDT 8x8mm
I prefer these latching push buttons to slide switches because they are less likely to pop out of the breadboard by accident when you are using them.
HeaderPins 2.54mm 40P Break Away Pin Header [Female/Male]
Get both male and female sets. You frequently need to add male header pins to sensor breakout boards.
doubleheader Double Length 2.54mm M-M Header Pins
Extra long header pins are handy at times, as are 90 degree lateral pin headers
DupontRibbon 40 pin Dupont wire jumper cables 20CM
M-M, F-F & M-F. Usually you tear off a strip with the specific number of wires you need for a particular situation, like adding a jumper cable to a UART module that did not come with one. Often it’s convenient to buy these cables without the black plastic end caps so you can make custom cables, but you pay more for that.

Basic Sensors:     

With so many different types of transducers, I can only list a few examples here. And rather than a strict definition, I think of a sensor as ‘basic’ if it’s fairly easy to get the output you are after when you connect it to an Arduino. That can happen for different reasons: (1) Sometimes the raw sensor is electrically simple, such as ‘modulating’ sensors that change their physical properties (like resistance) in the presence of heat, light, etc. and these can easily be turned into a voltage with a simple divider. Some of these sensors are ‘self -generating’, producing a small signal which can be fed directly into the Arduino’s input pins. (2) Others fall into the basic bucket because someone else has put the sensor and some fancy electronics together inside an IC package or onto a cheap breakout board/module, to make connecting to the Arduino easier than it would be with the raw sensor. (3) And other times it’s because someone has released an open source “library” that teaches your Arduino to “talk” to the sensor, which might be more electronically complicated than the Arduino itself. (Although those sensors tend to have so many settings to take care of when you start them up, that even with a library they still end up the “Advanced sensor” category.)

Basic Sensors
reedSwitch Magnetic Reed Switch
Perhaps the most fundamental type of sensor is a switch. You can think of push buttons as crude pressure sensors, and magnetic reeds as proximity sensors. They show up in applications like rain gauges and anemometers because they are robust and draw no current most of the time. Find a good tutorial on pull-up resistors, and de-bouncing is another important issue with switch sensors.
Photocell 5528 Photocell 10KΩ LDR
This light dependent resistor might be the easiest sensor to start your lessons with. Put a fixed 10K resistor in series and read the middle of the voltage divider with a analog pin. That’s it. Add a passive piezo buzzer module and you are ready for the popular Light Theremin exercise.
thermistor NTC Thermistor 10KΩ B=3950 1% tolerance
Thermistors change their resistance with temperature just like LDR’s do with light. So you use the same electrical circuit to read them as the LDRs. The devil though, is in the details. Thermistors are very non linear, so you need to so some fancy calculations to translate the analog readings into an actual temperature. There are lots of great tutorials out there to help with that. Generally, I prefer to use 100K NTC thermistors, since they have less problem with self-heating.
FSresistor Force Sensitive Resistor 0.5″
In this case the resistance changes with applied pressure. In fact there is a whole family of Force / Stretch / Bend sensors like this and they get used for all sorts of things like measuring water level. Unfortunately they are also pretty darned expensive, so sometimes its better for students to make their own FSR sensors instead.
piezo sensors Piezo knock/bump Sensor 27mm
Piezos can generate significant voltages, so they get connected with a shunt resistor to damp things down; protecting the Arduino. Be sure to get the ones with the lead wires already soldered on.
When you move away from raw sensors, there seems to be a bewildering array of ‘breakout boards’ and ‘sensor modules’ for the Arduino and they sell them in mega bundles of twenty, thirty or sixty different pieces. Like the component kits it is probably OK to get one of these when you are starting out; just to play with them and see which ones fit your curriculum. Watch for custom connectors that force you to buy extra cables & interface boards. I actually like the Grove System, and similar systems like the Itead Electronic Bricks, but from a teaching point of view those are better suited to creating ‘snap together’ lessons with younger students. (or no wiring at all if you populate a Multi-sensor Expansion shield) That’s not so good if you want them to become comfortable making their own circuits on a breadboard.
sensor module kit 37 in 1 Sensor Modules Kit
Just an example of one common module set from eBay. So you will have to hunt around for a set that looks interesting to you, and it might be worth an extra buck or two to get one that comes with an organizing case. For some, like the Keyes series, you can find pinout guides and instruction wiki’s There are usually several “How to use it” tutorials for each sensor at and on YouTube.
Once you get a closer look at them, you’ll notice that most of these cheap sensor modules look the same:


That’s because at least 50% of those boards are simply a voltage divider like you would use to read the raw sensor connected to one input of a 5 cent comparator circuit. While a 20 cent trimming pot sets the voltage on the other input:
LM393circuitThese boards take an analog voltage, compare it to a threshold, and then produce a digital on/off output on Dout which you would read on digital input pins on the Arduino. Essentially turning an analog sensor into a kind of switch. This is such a generic circuit, that you could put other resistive sensors on those pins and it would work fine.  Look for boards that give you the 4th analog output pin if you want to read the actual sensor value with the ADC.

LDRmodule Photoresistor Sensor Module for Arduino
Here is that same 5528 LDR I listed at the beginning, being sold as a “sensor module”.
TC5000IRpair TCRT5000 Reflective Infrared Emitter&Sensor Pair (Raw) $1.00/10pc
TCR5000module TCRT5000 Reflective IR Switch (module)
Sometimes used for line following/distance sensing in robots.
HR31resistiveHumidity HR31 Analog Resistive Humidity/Temp Sensor (Raw)
You get one combined Humidity/Temp impedance number out of this sensor, which you have to decode to work out the humidity.
H31module HR31 Analog Resistive Humidity Sensor Module
Be careful which one you order. 3pin=On/Off threshold output only & 4pin modules will let you read the analog output of the divider. By now I hope you see the pattern in these cheap sensor module boards. The list goes on forever…
PIRmotionSensor HC-SR501 PIR (Passive Infrared) Motion Sensor
This module has vastly more complicated supporting electronics than the simple comparator boards above, but you use it in essentially the same way. Adjust some trim pots and then look for High/Low output on a digital pin.
capsensor Capacitive touch sensors
Tons of these on eBay, and dirt cheap, but nowhere near as much fun as making a really big capacitive sensor yourself with some flat sheets of aluminum foil and the Arduino capsense library.
In addition to modules, you also run into integrated circuit sensors where more electronics are embedded inside the sensor itself. These can have either analog, or digital output, but the digital output is no longer limited to simple on/off information . Analog sensors are generally easier for beginners to use, since all you have to do is read an ADC pin to get your numbers. The digital sensors have to “talk” the Arduino, and that usually involves including a library at the start of your sketches to handle the low level details of the serial communication protocol. There are far to many to cover here, so I will just leave you with a comparison of two sensors that have nearly identical sensing capability, with one being analog, and the other as digital. Equivalent pairs like this exist for other environmental parameters like pressure, humidity, etc.
TMP36 TMP36 – Analog Temperature Sensor
Unlike a raw thermistor, these sensors have a bunch of circuitry for amplification and signal conditioning so that the output given to the Arduino’s ADC is beautifully linear.
TMP36 DS18B20 – One-Wire Digital Temp Sensor
This ‘one-wire library dependent’ temperature sensor is often the first one people use when they make that transition, and it is one of my personal favorites. Digital sensors come with various serial communication protocols, but in return for the added code complexity you get the ability to hook many sensors to the same ‘bus’ wires, and in the case of the DS18b20, those can be up to 100 meters long.
Making the transition from simple analog to true digital sensors is like earning your merit badge with the Arduino. There is usually a digital version for every different kind of analog sensor at about the same cost, and in some cases the digital version offers tremendous advantages in terms of resolution. But one of the first things you want to know is: Are there good libraries to make this sensor work with an Arduino? While there are plenty of independent coders posting open source libraries to GitHub, suppliers like Adafruit & Sparkfun often release them in conjunction with a cool new sensor, and it’s one of the reasons why people in the Makers movement like them so much. Though I have listed several low end commodity parts here, I still spend a significant amount at those first tier vendors: both to get sensors I can rely on, and to show them some love for all that hard work.


Before the comments fill up with dire ‘You get what you pay for…’ warnings, I’d like to point out that when I’m buying tools for myself, I check three places: Adafruit, Sparkfun, and EEVBlog. If you want quality tools go there and buy what they recommend because they really know their stuff. However in the real world a teacher is lucky if they get $500-1000 to spend on materials for a 10-12 student class.   See: Collins Lab tool video.

Soldering Stations: ~$130 / station
YiHua936b Yihua 936b soldering station
Unlike thin pencil style irons, These guys have enough thermal mass to handle soldering beefy connectors. Get the ones with the switch on the front and the blue metal stands.
Comment: I love my Hakko FX-888D, in fact I wish I’d bought that before working my way through a bunch of crappy soldering irons. However you can buy four of these cheap knock offs for less money, and that really helps the budget if you need enough for a whole classroom. It also helps that these things are big & ugly if you are working in a place were things tend to grow legs and walk away on their own…
ReplHandle_160pxw Replacement handle for Yihua 936 station
Yes, soldering irons do break if you drop them – especially the cheap ones. This is 5 connector handle is not the same as Hakko 936.  With spare handles this cheap, it’s faster to just change the whole iron when you want to work with a different tip, rather than waiting for everything to cool down, etc.
Tipset_100pxw 12pc Soldering Iron Tip set Hakko 936 (& Yihua)
The ultra thin tip that comes with the 936b is useless.  900M-t-1.2D ‘screwdriver’ and 900M-T-B ‘cone’ are the tips I use  frequently so it might be cheaper buying those individually. Of course these are all fake tips, as real Hakko tips usually cost around $10-15 each, but you will need a good supply of replacements either way.  I’ve been using the  T18-S4 ‘conical sharp’ that came with my Hakko 880 as my default tip two years, and it’s still going strong. Genuine tips usually have laser engraved markings on the sides. Do not buy lead free tips unless you are using lead free solder, as the chemistries do not mix. Remind your students to always re-tin the tips before storage, because once they go dry the tips are ruined.
TipCleaner_160pxw Soldering Iron Tip Cleaning sponge
And you will need some replacement sponges eventually.
400gSolder 400G 0.8mm 60/40 Rosin Core Solder Wire
A large roll like this is for soldering stations that you don’t have to take down at the end of each class. But it should last quite a while.
SolderHolder1_160pxw Solder Wire Holder for large rolls
A holder for the large solder rolls like the one above. There are better looking ones out there a few dollars more..
Solderwire_100pxw 0.6mm 60/40 Rosin Core Solder Wire
I use  0.5-0.6mm wire for things like pin headers and general solder joins. Buy a few per station, as small 50 gram rolls get used up quickly. For really fine work on IC chip legs, it’s also handy to have a roll of 0.3mm around.
SolderWick_100pxw Solder Removing Wick 3mm braided
Get a couple for each soldering station.
NoCleanFluxPaste MG Chemicals 8341-No Clean Flux 10 ml Syringe
Doesn’t make a mess like the $1 options from eBay, easy to pack up & lasts for ages without drying out.
PanaviseJr_160pxw Panavise Jr. – PV-201
This is one of those rare items for which there aren’t any equivalent products on the market – though you could try the attaching a $6 PanaVise 207 Vise Buddy Jr (made of plastic) to a DIY base. Don’t forget the Neoprene Jaw Pads and the Speed Control Handle which add alot to the functionality. As would one of these things.
HelpingHands_64px Third Hand Soldering Stand / Holder
I use these guys to hold wires in place, while a Panavise holds the board I am working on. The alligator clips always fail with time and there are other things that might also do the job. At EMS labs, they make their own with thick wire.
Heaterizer_100pxw Heaterizer XL-3000 Heat Gun
A cheaper option than a full re-work station, but also noisier.
HeatShrinkKit_100pxw Assorted 2:1 Heat Shrink Tubing Kit
You rarely use the larger sizes, but a general assorted size kit like this is good when you are starting out. It is much easier to spot soldering problems if you use CLEAR heat shrink tubing but its not as pretty. Keep a good stock of 1.5 mm, 2mm and 3mm on hand, in fact buying those smaller sizes by the roll might be a good idea.
Glasses_100pxw 3.25 diopter Reading glasses
The cheapest option for close-up soldering work. And get hard shell cases so they can just be tossed into the station kits without scratching.
WireStrippers_100pxw AWG 30-20 Precision Wire Strippers
Hakkos are the gold standard, but these ones from H.Depot are ok. They gave the Ideal T-stripper model 45-121 a good review over at the EMS blog.
CuttingPliers_100pxw #170 Flush Side Shear Cutting Pliers
Again the Hakko CHP-170 would be my first choice, but these work.
Pliers_100pxw Bent Nose Jewelry Pliers
You can find others for a buck if you go hunting, but I like the handles on these.
Baskets_100pxw Plastic Locker Bins with Handles
Reasonably large plastic bins let you pack up the soldering stations after class and put them in storage. Most dollar stores have something like this on hand.
Comment: Even if you teach the course with breadboards, you will need at least one complete solder station for things like adding header pins to your breakout boards. A full set like this will set you back about $130, and but depending on your scheduling, you might get by with one full station for every two or three students. We usually set them up around the perimeter of the classroom.

Other Useful Tools:
CrimpTool_100px SN-01BM Dupont Connector Crimping Tool
If you keep your eyes open, you can find them for less than $20.00. Many prefer the PA-09 crimping tool, but those usually run > $50.00
Make polarized (non reversable) connectors by mixing Male & Female connectors

Make non-reversible  connectors by  combining M&F pins

Comment: Before you get a crimp tool, you have no idea why you would want one. Afterward, you use it almost as often as your soldering iron. Dupont connectors are ubiquitous and lots of electronic components have leads too thin to use on a breadboard, so you end up crimping male DuPont ends onto them just to plug them in. It does take a bit of practice to get the hang of it, but there is no other way to make interconnecting cables this quickly & inexpensively.

DupontMalecrimps_100px Dupont 2.54 Connector Crimp Ends
Be sure to get both Male and Female ends. Buy 2x as many female as male pins.
Terminal Ends Dupont Jumper Plastic Terminal Ends
Get at least 200: 2x, 3x, 4x and 6x plastic covers. I don’t use the 1x ends any more, as I simply put black heat shrink over them. There are and infinite number of other cable variations that you can build.
SolderPot_100pwx 50mm Solder Pot
Once you start building things you end up having to tin allot of wire ends, and a solder pot makes that much faster than using your soldering iron. You only need one of these per lab, and you could probably skip it if you are doing primarily breadboard work.
AligatorCables Alligator to Alligator Prototyping Cables 50cm $3.30/10pc
AtoBcables_100pxw Banana to Alligator Cable Pair Black & Red
A set for every voltmeter, for the times when you need hands-free use.
EpxoyApplicator_100pxw 50ML Epoxy Sealant Applicator Gun 1:1 and 2:1
There are a few different variants on the market and you have to match up all the parts of the system with your brand. This one works with Loctite.
Hysol Loctite Hysol 30-CL, Clr, 50mL, Cartridge
This stuff has proven to be a good potting compound after more than a year of marine water exposure at depth. Takes >24 hours to cure.
Nozzles Static Mixer Nozzle BT MA6.3-21-s
Don’t use the shorter nozzles with less than 20 elements, or the epoxy does not mix &  set properly.
ScotchMountingTape Scotch Permanent Mounting Tape, 1 x 450 Inches 5LB
This stuff is immensely useful when you are putting a prototype together, and you just need to mount your boards inside a housing. Always have a roll on hand.
LableMaker1 Deluxe Label Maker
A label maker is a vital piece of lab equipment. I go through 4-6 ribbons on my old old Brother P-touch setting up for each class. Not sure which one to recommend from the current crop, so you have to do your own homework there. But just get one.
screwdriverSet Multi-tip Precision Screwdriver Set
Get one with at least 30 bits. And it never hurts to have a few of the $1/6pc sets around as well.
conformalcoating MG Silicone Conformal Coating : 422
The best way to protect Arduino boards & RTC modules from moisture in the field. Apply in a fume hood, as this stuff is fairly nasty.
openingpliers_100 5″ Opening Pliers
If you run into a situation where your heat shrink doesn’t quite fit over the item, these fix the situation.
DrillPress_100px WEN 4208 8-Inch 5 Speed Drill Press
You can use a hack saw for most small cuts, but sooner or later someone is going to need holes in something, and this Sears knock off is cheaper than many hand drills. I also use a bench top band saw quite often, but table top scroll saws are probably safer for classroom situations though it’s nearly impossible to get a straight cut out of them. And if you are handy with the soldering iron,  you can often retrofit lithium batteries into portable hand tools after their original cells are shot. It’s also fairly  easy to remove the rust from any cheap tools you come across at a garage sale. 

Addendum 2016-09-15:

Finally have things set up for the next bunch of students, and since it’s unlikely to look this pretty again for a while, I though I would post photos of the classroom set ready to go:

labstorage1    labstorage2

It all fits comfortably into these two cabinets, but we could probably get that down to just one if we had to.

Addendum 2017-10-01:

Just found an interesting circuit visualization idea at instructables.  It’s a pretty time consuming method, but it’s easy to see how this would be applied in a classroom setting. One of the drawbacks of standard breadboard methods is everything on the underside of the boards is hidden once the pins are in place.

Addendum 2017-10-15:

Codebender is an online Arduino IDE alternative that uses a javascript plugin to let your browser access your computers serial ports. The subscription is $10/month, and the .edu version of the service opens the possibility of collaborative projects with your students for an extra $0.50 per seat, perhaps even giving you the ability to grade/guide student work from any location without having to move a bunch of script files around. As an Arduino instructor, Codebender could save you 2-3 hours of computer setup just installing local IDE’s for a workshop. I’m a big fan of the default IDE, but given how much of a pain Github can be for Arduino-scale projects (especially if you work from multiple computers, or if your hard drive fails and you have to rebuild everything), this provides an interesting code-sharing alternative worth looking into. They also have more than 600 sensor libraries in their archive, and since library installation is always a stumbling block for people new to the Arduino platform, this could help beginners.

There are a few issues that are worth considering though: it only works in chrome or firefox, and everything internet related breaks eventually, and will continue to do so in the future, so you need a backup plan for any downtime or loss of the network. If you experiment with weird new Arduino compatible board variants, there’s a good chance those board definitions won’t be available in Codebender, and none of the libraries I use regularly were there because they were one-of variants that I found after digging through GitHub.

Arduino UNO Datalogger for Complete Beginners (ie: no soldering)

Addendum 2017-02-20:

This post is the first in a series of online tutorials that I’ve been working on to help teachers bootstrap their own Arduino based curriculum. The full set are listed at  How to Build an Arduino Data Logger which walks you through the most recent versions  in a more or less logical order.  But if those pages leave you in the dust because you are learning as you go along (like most of us in the makers movement!) then check the list of beginner’s guides & video tutorials in the More Resources for Teachers section at the bottom of this page.

Original Post from 2015:

Since posting the step-by-step build guide in November, I’ve had enquiries from people saying that the equipment & time required for that build still presented a significant barrier in the classroom.  A few asked if I could come up with a plan based on the Uno/Breadboard combination that has become a standard starting point for many people.  So here is a simplified data logger for those high-school teachers who want to add environmental monitoring projects to the curriculum:

An Uno-based basic data logger, with no soldering required.  As the instructor, you can assemble this logger very quickly with pre-made jumpers but we found the connections were too easily knocked loose by clumsy students, so it’s worth taking the time with them to put stiff solid core wires in place. Note: I used an older UNO R1 I had lying around for the photos on this page, and the current R3 has A4&A5 broken out again on the right side above AREF, so follow the pin labels rather than the physical positions to accommodate your particular board revision pinouts


SPI micro SD card adapters like this can be had for less than $1 on eBay, and these can be connected directly to the pins of 5 volt Arduino’s like the UNO or the smaller form factor NANO. (note: the SPI pin labels are on the back).

Similar approaches to assembling a DIY logger can found at other places on the web (including many pre-built data logger combinations), but I thought I would add a quick breadboard logger to my other tutorials for those who Googled their way to this blog looking for something fun to try with an UNO – even if they did not have much experience with electronics.  If you go with no-name clones, the approach I’ve outlined here might also qualify as the cheapest option available (…if you are funding the everything out of your own pocket, like some of the science teachers I know…). The key difference between using an (unmodified) UNO, and the smaller pro-mini style loggers described in my earlier tutorials, is that UNO’s operate at 5v, while smaller form factor boards are generally regulated to 3.3v. This limits the sensors you can connect directly to those capable of operating with 5v logic levels, but most importantly it affects the SD cards, as they can only handle 3.3v. So you would need to use a raw adapter board with a level shifter to accommodate the different voltages. Fortunately, SD modules that already have the regulator & level shifter on the breakout board are very inexpensive, so this issue does not add complexity to the basic connection plan.  These cheap regulators are notorious power wasters, but most people operate UNO based projects on a USB tether for live sensor data in the serial plotter, or power them via a wall ac power adapter.

Parts you will need:

Arduino Uno ($24.95)
 A few students used less expensive clones for their personal projects (~$4.00) and they worked OK, though the soldering looked a bit dodgy, and a couple of the eBay ones used non standard UART chips so we had to go hunting for drivers. I often use the cheap stuff when I am noodling around on the workbench trying to get something working, and then deploy better quality hardware in the field. If you are just starting out, I suggest that you save yourself the driver headaches and use the standard kit. If you do go with the clones, donate something to the Arduino group as a thank you for making such awesome software
DS3231 & AT24C32 RTC module ($1.00)
Mini 400 Contact Solderless Breadboard ($1.50)
CR2032 coin cell battery for the RTC ($0.50)
SanDisk microSD card:  256MB to 1GB ($2.00-4.00)
Stick with cards smaller than 2Gb and format them with SDformater utility (not windows!) to fat16 and test with H2testw.  I generally buy 1Gb MUVE music cards from eBay because they are usually genuine; drawing lower sleep currents. WRT Filenames: use 8.3 format and don’t use spaces or special characters.
SPI microSD breakout ($1.00)
Common Cathode RGB LED 5mm (<$0.50)
+Various tools including needle-nose pliers, wire cutters, strippers, soldering irons, etc.

Total parts cost:  $15 to $35 depending on which Arduino board you use

Optional parts:
USB cable A-B ($1.00)
Jumper wire kit ($2.00)
I usually go with thicker 22 AWG, but 24 works too
Resistor kit ($2.00) 
The limit resistor for the LED can range from : 1,000Ω, to 30,000Ω with 10K being a reasonable option. Note that cheap multi-pack resistors often have thin 0.4mm wire leads which are not “breadboard friendly”, while more expensive resistors from Vishay or Speer usually have 0.6mm leads which stand up much better to handling
6xAA battery holder ($2.00)  or 8xAA battery holder ($6.95) with 5×2.1mm power jack
for longer life a 9v D-cell pack should get you out to a couple of weeks of operation
Scotch Outdoor foam Mounting Tape, 5Lb ($4.00)
Plastruct #91105 .060 White Styrene Sheets 3Pack ($10.00)
We attached the UNOs & breadboards to cut rectangles of styrene with the double sided tape to make stable platforms that the students could just pop into their project boxes when class was over. But premade acrylic mounting plates are also available.

For an extensive list of parts & materials see:  Building your own Arduino Classroom

Arduino software & libraries:

Before you tackle the assembly, install the Arduino IDE and test that it can communicate with your Arduino. Then there are a few libraries to download and install so that they are available when the Arduino IDE compiles & uploads you programs.

a) A library to control the RTC:
(Note: there are many other good libraries out there that you could use and confusingly most of them have the exact same name, but this one allows you to set sub-minute alarms if you need to)

b) An I2C bus scanning utility:
(to make sure your I2C devices are connected & working)

c) A library that puts the Arduino processor to sleep:
(you can’t put the UART to sleep on an UNO, but every little bit still helps save power)

d) A program to make the logger read & save data on the SD card: (this is not a library)

A good place to start would be Tom Igoe’s excellent analog pin reading example at   (but change const int chipSelect = 4; to const int chipSelect = 10; for the build described in this tutorial) 

 For something a little more advanced, I have prepared a basic data logger script that puts the data logger to sleep and wakes it up again based on timed alarms from the real time clock. These are both just starting points for you to add to as you learn more about programming an Arduino

Putting it together:

1)  Prepare the RTC board

Resistor to remove from RTC

I usually begin by removing the resistor highlighted in red to disable the battery charging circuit. There is also a power wasting LED on the RTC board that you can remove as well, but that’s only worth doing if you want to run the logger on batteries. For more details about these cheap DS3231 breakout boards, you can dig into this RTC Post.

I have been using these cheap DS3231 RTC boards for a while now. They have proven to be very robust, although they have one element that is slightly annoying: they come with a charging circuit that assumes you have a rechargeable LIR2032 backup coin cell installed. You can use the RTC board as-is if you have on of those LIR’s in your RTC, but since you are not supposed to ship lithium batteries in the post, you almost always receive these RTC boards with no battery, or even worse they will just stick an non-rechargeable CR2032 in there which will pop if you leave it plugged in for long with the charging circuit connected. I usually end up finding a local supplier for non-rechargeable CR2032 coin cells which work fine as a backup power source for the clock provided you disabled the charging circuit by removing the resistor highlighted in red above.  You can cut that resistor off with a knife, but I find it easier to flick it off the board with the tip of a hot iron ( I know I promised that this was a solder-less build… but I didn’t say anything about de-soldering 🙂 ) Then insert a fresh CR2032 coin cell into the backup battery holder on the other side. If you forget to put in the battery the logger will still run, but the RTC will forget the date/time every time you shut your logger down, so the time stamps will not be correct unless you reset them every time you start the logger.

2)  Power the breadboard rails

1_pwrJumperBring the ground and 5v lines over to the power rails on the breadboard with some solid core 22 gauge wire.  I usually do this at the end of the board that is farthest from the rest of the wires I am patching over. Its worth tucking them in as neatly as possible so that they don’t get bumped around later. Make sure you have stripped enough insulation from then ends that the bare wire penetrates into the riser holes enough for a good connection.

3)  Jumper the RTC module

Connecting the RTC to an Uno

Connecting the DS3231 RTC to an Uno:  This is possible because the DS3231 has a wide voltage range from 3.3v to 5v.  Many other I2C devices would require a 3.3-5v level shifter before they could be connected to the 5v UNO pins. Note: The long red & black wires at the bottom are simply patching power over to the rails on the other side of the mini breadboard.

The RTC board has clearly written silk screened labels for each pin:

Connect VCC & Ground to the appropriate rails on your breadboard.

Since the RTC is an I2C device, it uses the A4 pin on the Arduino as the SDA data line (white) and the A5 pin as the SCL clock signal line (yellow). There are many easy to use I2C sensors (that have pre-written libraries) that you may use with your logger, and they will be connected to these lines in parallel with the RTC. ( …if those sensors can tolerate 5v logic levels like this RTC ) To enable I2C communications, this RTC breakout board already has 4.7K pullup resistors installed on those two lines, so any other sensors you wish to connect to the SDA and SCL communication lines will probably not need pullup resistors to function. Many sensor breakout boards also have pullups on them, which you can usually leave in place, provided that the combined resistance of your parallel pullup resistors does not fall below 2.2k ohms.

Jumper the SQW line (blue) from the RTC board to Arduino pin D2. This wire will carry the “wakup alarm” signal from the RTC to the INT0 line. (note: the angle on the diagram above makes it look like the wire is in D3, but it is D2)

4)  Set the time on the RTC module

Before connecting any other components to the Arduino you should make sure you have the RTC working. Download the library ZIP file, extract the package, and move the library into your Documents/Arduino/Libraries folder.  The moved folder must be re-named ‘RTClib’ for the compiler to find the library and sometimes un-zipping adds extra folder layers that you have to remove to get to the library you want.

Update: 2016-10-12: I just noticed that they have taken the setTime & getTime utilities out of that RTC library that were current when I wrote the original post.  Now you will need to load File/Examples/RTClib/ds3231_v2 and set the time by following the instructions on screen in the serial text monitor. The new method should let you set your RTC more accurately than using the compile time with setTime.

OLD instructions: the greyed out instructions below apply to older versions of the RTClib that were distributed with the gettime & settime utilities.  I’ve posted copies of setTime & getTime utilities to my GitHub and there is an alternate version of the setTime sketch with Paul Stoffregens DS1307RTC library, which sets the RTC to the compile time with the command  RTC.adjust(DateTime(__DATE__, __TIME__)); but I found I also had to install Paul’s Time Library, to use his version of settime.


I set my loggers to UTC to avoid problems with local daylight savings time variations. To do this simply change the time zone on your computer before uploading the settime sketch.

RTClib includes two useful utilities called setTime & getTime that can be found via the IDE pulldown menus after the library is installed at: File / Examples / RTClib / settime   &   File / Examples / RTClib / gettime  Open the settime sketch, verify it, and then  upload it to your Arduino via a USB cable connection. This takes the time signature from the compiled code itself and sets the RTC clock with that time. Do not open the serial window while settime is running or the program restarts – setting the time again incorrectly. Immediately after the settime has been run, LOAD the gettime sketch in the IDE and upload it to the Uno. Now open the serial widow, set the IDE serial window speed to match the script,  and you should see the date & time being read from the RTC.

Technically speaking, if your RTC is showing the correct date and time in the serial window,  you can move on to the next assembly stage. However, I usually run other programs to make sure that both the RTC and the AT25C32 eeprom on the breakout board are working properly.  Rob Tillaart wrote a bus scanning utility which is quite useful for this:
If you run this utility you will usually find that the RTC is on the bus at address 0x68 and the 4K chip is on the bus at address: 0x57 – although the eeprom can move around from one board to the next. In fact the memory address can be changed to avoid conflicts with other devices by connecting the solder pads provided on the breakout board.

On that page you will also find a  link to a “Multispeed I2C Scanner” which I like because it scans the I2C bus with different speeds. This is useful as it identifies when your wires have become so long that capacitance is starting to interfere with the serial communication signals and cause the devices to act flaky and/or “drop off the bus”, but the basic scanner works just fine for most cases, especially when you are adding new sensors to your logger and you don’t know their bus address.

Note: If you see junk characters scrolling across the screen when you run any of these little utility programs, you probably need to check that your serial window is set to the same speed specified in the serial.begin command inside the program:


* I have also found that with some of the cheap UART boards that are needed for Pro-mini style Arduinos, I end up having to set the serial window to 1/2 the speed listed in the arduino code to make them work. But the smaller 3.3v units have their clock prescalars set differently, so this should not affect the Uno based builds.

5)  Connect the indicator LED


I find that its easier to keep the wires tidy by connecting one end of the wire to the Arduino, and then bend / fold it into place before trimming the other end.

Connect a three color common cathode LED to Red=D4, Grn=D5, Blue=D6.  A KEYES KY-009 SMD 5050 breakout board is pictured here, but any common cathode LED would work fine. Use at least a 1 kΩ resistor to connect the common ground line to the ground rail on your breadboard, to limit the current flowing through your LED.  As the limit resistor gets bigger the LED will become dimmer, but most are still visible with limit resistors up in the 20-30 kΩ range so the value is not critical. You do not need a three color indicator LED, but I find it helpful to put different color led flashes in the code so that I can keep track of what the Arduino is doing when I don’t have it connected to the serial window. So I turn on red for SD writing, blue for eeprom buffering, green for sensor reading, etc. 

LED and RTC connected

Two extra I2C jumpers (white and yellow) shown here simply patch those lines to the other side of the breadboard. These are not necessary, but they make it easier to add I2C sensors to your logger later without disturbing the RTC connections. The 220 Ω limit resistor pictured here is an absolute minimum, and probably should be bumped up to between 1-10K Ω.

6)  Connect the SD card Adapter

Place the SD card holder on the breadboard and jumper the following SPI lines from the adapter board ( check and match the labels printed on your particular SD board):
D12=MISO,    D11=MOSI,    D13=SCK,     D10=CS
Then patch the Ground and VCC lines to the rails on your breadboard.

SD card connections1

Before connecting your Arduino to test these connections, you need to insert a micro SD card in the adapter. Check a new card on your computer first, and delete any files that already exist on the card, then save a new blank text format file named “datalog.txt” onto the card (note: name in lowercase letters). Eject the sd card with the blank text file on it from your computer, and insert it into the SDcard adapter on your breadboard. It should slide into the socket. It should register with a nice click when it is in place. I often buy used MUVE music 1-3 GB micro sd cards because they are genuine Sandisk cards so they sleep at low current, and they are cheap because of the DRM on them that only lets you see 1gb of space – which is far more than you need for most data logger applications. (A typical logger recording Date/time and a few sensor readings every 15 minutes might generate about 5mb of text data after running for a year)

7)  TEST the SD card with CardInfo

This handy utility can be downloaded at:

From there  COPY & PASTE the Cardinfo code into a new window in the IDE and make the following changes to the default CARDinfo script:

(a) CHANGE the chipselect from pin 4, to pin 10 with:  const int chipSelect = 10;   at the beginning of the script. We have already used pin 4 to drive our indicator LED’s red channel.

(b) ADD   #include <SPI.h>   to the beginning of the script if it is not there already.

VERIFY & SAVE this file on your computer with the name CardInfo. (you will end up using this utility many times again in the future!)  Then plug in your Arduino and upload the code, and open a serial window. You should see something like the following:

Card found OK
If you do not see a message like this one, it is possible that
-> The SPI line jumper wires are not in the correct place or you have a loose wire somewhere. There is some variation in the different board pin locations so review these on your board first to make sure you have everything connected properly. Note that your particular SD card adapter board pin-outs may not match my diagrams here, so you will have to adjust for that.
-> Your SD card is not formated as fat16 or the card is not inserted properly. I usually use smaller 1-2gb cards, as some of the new larger HDSC cards don’t format as fat16.
-> You have a bad sd card adapter board. I have had plenty of crummy sd card adapters with bad spring contacts, so try to have 2-3 of these on hand in case you get a bad one too.

At this point your jumpered connections should look something like this:

A basic Uno & Breadboard logger

Note that some overhang the SD card adapter board needs to sit “in the groove” at the center of the breadboard so that the pins make proper contact. The RTC and LED boards don’t require that, but it makes the build look a bit neater if you move them to match.

and your pretty much ready to start using your data logger.

8) Upload a basic data logger script

The code for your logger can now be downloaded from github via this LINK

Starting with Tom Igoe’s excellent example at, (which would also work fine with this build if you make sure to change CS to pin 10, but that code does not make use of the RTC, etc)  I added some functionality to create a time stamp and read the temperature register from the DS3231, and then write that information to a file on the SD card. Here is graph of typical temperature output from that RTC:     (@ 15 min interval)


The RTC record only resolves 0.25°C, but I have found these chips to be far more accurate than the ±3C listed in the data sheet – often less than half a degree away from sensors like the MCP9808

The code also puts the UNO’s cpu to sleep between readings, and it wakes up again to take a sensor reading when the RTC alarm goes off. The serial print output is all optional, so you can comment out those statements when the logger is running in stand alone mode. When you start making changes to the code, commenting out the lines you don’t need is generally much safer than deleting them.

This script is only meant to provide you with a basic starting point, and it should be easy to add other I2C sensors, or simple analog sensor readings following the example from . Before you add some new sensor to your logger, spend time searching through the forum at, as someone has probably already answered any question you might have about getting it to work. When you are just starting out, choose sensors that already have good libraries written for them.

It’s worth noting here that this code would also run fine on my pro-mini based logger builds. All you would have to add is a few lines to read analog A0 which tracks the main battery via a resistor voltage divider which is not included in this UNO build. The main Arduino page has a lot of free books and resources as well as explanations for all of the built in code examples.  There are also plenty of good Arduino programming references out there if you google around, which should help you customize the script.

Running the logger:

6xAA battery packs like this are fairly common, and should power an uno based logger for about 4-5 days

Six in series AA battery packs like this are fairly common, and should power this basic Uno logger for a few days of stand alone operation – especially if you use Lithium AA’s which have a flat discharge curve. 8xAA packs are available, but you have to be careful that over-voltage on new batteries does not push the total output above the UNO’s 12v maximum. The optimal solution might be to use 7 batteries in an 8-series battery pack, with a simple wire soldered across the last holder. 18650’s in series would be another option. If you need something that runs longer, rare earth magnets (soldered to the ends of jumper wires) make it easy to connect a number of C or D cell batteries into a custom power supply held together with painters tape. I would not try to power this logger from a 9V battery, as I don’t think it can deliver enough current for safe SD card writing. Rechargeable LiPo shields are also available if your pockets are deep enough.

Always do tethered test runs with sensor output echoed to the serial port so you know the code is working before you run the logger in stand alone mode.  In fact, I assume that most people will use this logger as a data acquisition system so I’ve put together a separate tutorial on using the Arduino as a basic DAQ with the serial plotter tool.  (scroll down to the 2016-08-15 addendum for the UNO only section) Note that to copy data from the serial window and paste it into excel you need commas printed between your numbers, and cartridge returns after, by using println rather than print for the last bit of data. Sometimes students have trouble cutting and pasting from the serial text window, or they accidentally shut the serial window by pressing the wrong button. So it is still a good idea to save to the SD card (if you have enough memory…) because this makes it easy to graph the data later. (with Excel or Google Docs)

One of the weird behaviors to know about with Arduinos is that every time you open the serial window from the IDE, the program that is running on the Arduino will restart, so if you are writing header data to the datalog.txt in the setup section, you will see a new copy of that header in the file each time the serial window is opened.

The easiest way to estimate how long your logger will run on batteries is with one of these USB power meters. Insert one of these $4 adapters between a USB power supply adapter & the datalogger. Reset the timer and let it run for a few hours and then look at the cumulative mAh number. Divide that into the rated mAh of your battery and you have a ballpark run time estimate. For reference, most alkaline AA batteries provide about 2000 mAh. It is even possible to make your own power meters.

Once you are comfortable with the serial plotter tool in the IDE you can look at other methods for  graphing the data in real time. One common method is by using another program called Processing. But be sure you test everything before your classes, as I’ve had some challenges getting processing to work on different windows systems (with the data on the SD card saving the day once again…) There is also an Excel macro called PLX-DAQ that can be used to monitor any serial port and display the data sent through it, but I believe that macro only works with older versions of excel/windows and I’ve never gotten it to work on my versions. Like Processing, it requires a few extra lines of code to be embedded in the Arduino sketch to direct the data to specific cells in the spreadsheet. might also be worth using to share data online in a way that looks professional.  And if you are really get the bug, you could take it all the way to the ‘Internet of Thingslevel if you add a shield or two. Home automation & wireless gardening, are popular applications, with some people using  Google Charts to display live data on their websites.


With the always on UART chip, it’s hard to get an UNO to run for long on batteries, but you should still be able to get few good days out of a set of AA’s with this plan.  If you want a smaller footprint, you could bend the pins 90° and connect the RTC & SD boards with a lower profile to one of the many ‘stack on top’ proto shields available. Probably the best of the lot is the Dead Bug Prototype shield for an Arduino UNO (~$24.00), as this shield also lets you run an UNO for a very long time on batteries, though you would have to wrangle with his code a bit to make things work.  That shield has the RTC, & SD carrier already built in, so my advice is build a jumpered UNO logger as per this tutorial, then when you get all your code & sensors working properly in tethered mode, transpose what you have learned to create a stand alone unit using the Dead Bug shield. Moving on from there: another option that really helped me at the beginning of this project is the compact TinyDuino platform, which is code compatible with all of the larger Arduino boards so you can usually use your existing programs directly. I used Tiny’s in several of my earliest loggers, and some of them were still running after more than two years.  When you are ready to graduate to other small form factor Arduinos like the pro mini, perf-boards & wire wrapping is a quick way to make solder-less prototypes that can be disassembled afterwards. Once you are really comfortable with the different Arduinos, it is even possible to use the raw Atmel processor by itself on the same breadboard as your other parts.  Strip-boards are another popular way to go from circuits on a breadboard to a deployable prototype.

platform parts

In the stand alone logger tutorials, I describe how to build a housing from 4″ PVC fittings, but those parts are all available in larger diameters so the same basic idea could be used with the larger UNO based logger, though the caps get a bit expensive at that size.

With your ‘deployment’ build ready, you can go hunting for a waterproof enclosure for your combination (here is an example using a prebuilt project box and anti vibration mount), or you could try building something more creative with pvc plumbing.  Lego blocks are not waterproof on their own, but they are made from standard ABS, so a little dab of ABS plumbing solvent around the edges lets you quickly assemble very robust internal scaffolds for your prototypes.

Project ideas:

If you are looking for project ideas, it would not hurt to browse through a few commercial data logger websites sites to see how people use them, then search through the Arduino sensors forum and see if someone has already posted helpful information about the application you find interesting.  Although the Cave Pearl Project is focused on environmental monitoring, don’t overlook the other cool things that people do with Arduinos for info on how to integrate sensors when building tools like the TC1 slinky seismometer.  Browsing through the Arduino project hub gives you some sense of the range.  A number of artists create interactive pieces by adding motion, sensing, LEDs & sound. Wear-able projects are also pretty groovy.  Others create simple robots with their Arduinos, and there are plenty of body/wheel/motor kits to get you rolling. Drones get all the media attention, but I think underwater ROV’s are also interesting.

There are lots of great maker resources to search through if can appreciate their sense of humor (though you might want to avoid clock projects…)  Intructables is heaving with Arduino projects which you can find simply by searching for “Arduino” + “subject”.  If you find an Arduino book that sounds interesting, there is a good chance that there are sample projects on the web from the book that you can review.  GPS tracking opens up interesting possibilities and the folks over at the RIFFLE project have been pulling that location data out of digital camera photos, with their data logger hanging from a kite.  So really, the sky is the limit . . .or maybe not even that, commander Sparkles.

Addendum 2016-01-05:

Instrumentation & field methods students building data loggers.

After UNO based labs, the students move on to pro-mini based logger builds with many different sensor combinations.

It’s also worth noting that this UNO logger has been ‘field tested’ many times during Trish’s Instrumentation course. I am happy to report that once the solid core wires are firmly in place, the students were able to reassemble the loggers quickly at the beginning of each class by simply popping the RTC, LED & SD adapter back into place. This saved a great deal of time, and the students used the UNO’s as a code development platform while they built “stand alone” loggers for their final projects.

However there were a few bumps along the way that I would like to share with other instructors:

1) No matter how many times you tell your students to unplug the Arduino from the computer before changing wires around on the breadboard, they will forget, and start changing wires around while the whole system is live. (…making plenty of mistakes in the process) While our Arduinos survived, the USB ports they were connected to sometimes did not. I would recommend that you use a sacrificial powered usb hub between the computer and the Uno to protect the computer’s usb ports from this abuse.

2) The single most common mistake that the students made was forgetting to put the limit resistor on the LED, and a few digital I/O’s were lost from resulting high currents if student failed to notice the the led was unusually bright.  (Again, I am amazed the mcu’s survived these events without needing surgery)  With younger students, I suggest that you pre-solder a 10k limit resistor directly to the ground line of the LED’s before you hand out the parts so that there is no way to make this mistake. They will still hook the thing up wrong, and three color led’s will light up with unusual color combinations if you ground any of the 4 lines, but I don’t think we lost any digital pins that way.

More Resources for Teachers:
(I will add more links here as I find them…)

To begin:
The instructables beginners guide is a good place to start, as is Udemy’s free Learn the Basics Arduino Tutorial. Actually instructables has been busy building a range of free beginners classes on subjects from the internet of things to 3D printingetc.  There are plenty of other “Getting started” videos available with  another free video course offered at the Programming Electronics Academy. Many of these courses require some kind of registration, and given the nature of their business you can expect a fair amount of self promotion messages to be peppered throughout. And finally, don’t overlook the official Arduino example tutorials that come built into the IDE. There are some great learning examples in there like the Tone Pitch follower with tutorials by Massimo Banzi himself.

Special Mention:
Be sure to check out Jeremy Blum’s Arduino Tutorials which are essentially a complete course on the Arduino;  all the more impressive because he did the entire thing as a one-man-band while he was still a student.  In my opinion,  the best quality videos available for Arduino are the ones created by Jeff Feddersen & Tom Igoe for the ITP program at NYU,  though some of those tutorials might be pitched a bit high for beginners. Paul McWhorter also has an extensive tutorial series on youtube.

Going further:
There is also a long set of more detailed videos at Though it’s a bit dry, All About Circuits has a complete textbook online [see: Vol. I – Direct Current (DC) ] And if you really want to dig deep, several universities like Stanford, MIT & Berkeley have made full electronics courses available, though that goes well beyond the Arduino landscape. There is a good walk through the sub-components that make up an UNO at Rheingold Heavy’s build an Arduino From Scratch series.

And don’t forget to search for the many other resources that people have posted individually on youtube!

Arduino in a Nutshell is a free e-book resource worth looking into, as is the Programming Guide from And though I’m not sure if they are still a going concern, the old Earthshine Starter kit manual PDF can still be found floating around the internet. If e-books like that are your thing, and you are willing to shell out a few bucks, there are sometimes good Humblebundle deals, though those are often in weird combinations of topics, and the individual books also available the Make website.

Sparkfun is also a great place to look for teacher resources.

It’s allot to wade through, but the Adafruit tutorial list  is another one of the best resources out there. Just be aware that they have developed their own library “system”, so sometimes their tutorials are tailored to that.

Tronixstuff has a large number of  specific hardware tutorials when you are ready to go further with your Arduino projects, and there are a host of cool Arduino projects to dig through at instructables site. I really believe that you can improve engagement and understanding by providing hands-on experience with real data, but there are plenty of other practical things you can do with the same basic setup.

If you google around, you can find curriculum documents, individual lesson plans, and other resources all over the place, like for example this conductivity lab over at or this beginners set from Arduino 101.  The challenge is that most of the sites were developed for a different curriculum than yours, so first figure out what you want to tackle, then go sifting through the tutorial sites for material that matches your learning outcomes. Otherwise you will just get buried in the shear volume of material.

If you want to abstract away the entire IDE interface for younger students, there are a few visual programming tools out there for the Arduino like Visuino, or MIT’s Scratch, for which there are plenty of tutorials on youtube.

Other inspiring links:

What’s the Maker Movement and Why Should I Care?

The Maker Movement in K-12 Education: A Guide to Emerging Research

Progressive Education and The Maker Movement

TED Talk – Massimo Banzi (the primary founder of Arduino) – How Arduino is Open-Sourcing Imagination

Addendum 2016-03-10

Well looks like someone sent this post to Scrbd. I guess that means you can download it as a PDF from there.  Slightly annoying to see advertising over top of something that is being given away free, but more so that their page comes up higher in search results than the original. Though I guess it’s all good in the end, if it helps more people get started with their logger projects.

A DIY Arduino data logger: Build Instructions – Part 4 (Power Optimization)

The first three tutorials in this series show how to build a promini based data logger that should sleep around 0.25mA, depending on the quiescent current of your sensors and your μSD card. That will usually get you to at least 6 months of operating life before a bank of three AA batteries in series falls below the 3.5v cutoff on your regulator, and most of our field units make to about 11 months on a good quality set of alkaline AA’s. With their flatter discharge curve, lithium AAs would probably have carried those logger past 12 months,  but if you really want the logger to pass one year of operation you need to do a few other things that might be a bit of a stretch for beginners.  So I am posting them here as “additional” things to tackle once you have built a few of the basic loggers and have them working Ok.  Use the cheap parts till you get the hang of soldering and working out how you want your cables & housing to go together physically.  I find that things usually go well the third time I make a new prototype.

A DIY data logger

Usually takes me about 20 minutes to assemble, or less with solderless headers. At any given time I probably have 6-8 of these breadboard loggers running on the bookshelf to test different hardware and code combinations. Be careful not to bump the SD card connections though, as its easy to kill the card with unexpected power interruptions.

Without question the most important thing you can do to extend the life of your data loggers is to build yourself a breadboard “testing platform”.  This lets you determine the sleep current for each component on it’s own, making it easy to spot fake SD cards, or bad sensor breakout boards. And even good SD cards wear out with time , or are  damaged by high temperatures. Checking that cards and boards go to into a low current modes properly (after the main mcu sleeps) is the best diagnostic I have found to determine if the components are Ok. Good SD cards sleep between 0.05-0.07 mA, and these tend to be older Sandisk 128mb cards. Typical cards pull between 0.07-0.09 mA while sleeping. Any more than than that and I simply do not use the card in my data loggers. The difference between a good sensor breakout board and a bad one can be even more extreme, and you should always look for breakout boards that have a native 3.3v input line to avoid regulator losses. I already mentioned pulling up three of the SPI lines, and the breadboard unit lets you easily test how other pin configurations affect the logger. Pin states are generally preserved during sleep, though any timer dependent functions (like PWM) will be shut down when the associated timer stops, unless you use ‘idle’ mode.  Always avoid floating I/O pins.

Retrofit an MCP1700 voltage regulator to an ebay clone

All you have to do to retrofit any 3.3v mini-style board with a more efficient MCP1700 is connect the external regulators output directly to the 3.3v pin, which is the main power rail behind the default voltage regulator. This by-passes the onboard Vreg the same way that your UART board does when you are tethered to USB. When I do this modification I completely remove the original regulator from the Arduino board so there is no leakage current slipping through it while the logger is sleeping.  Also be sure to move the high side of the resistor divider you have monitoring the battery voltage to the new regulators Vin line. Replacing the MIC5205 with a MCP170x will save you ~0.05 mA of sleep current, depending on your particular board. That doesn’t sound like much, but it all adds up over time, and you have 100 mA more current available to power your sensors.

When you test your components individually you notice that there can be significant differences from one pro-mini board to the next (especially with cheep eBay clones) and much of this comes down to the voltage regulator. Sparkfun Pro-mini’s use a Micrel  MIC5205 150mA LDO Regulator, and there are more efficient options out there. I have had success with boards that use MCP1700  & MCP1703 regulators (datasheet) like the Rocket Scream Mini Ultra or the Moteino. Each board has a unique pin-out, so you will have to figure out where to put the jumpers for each particular board.  You can also simply bypass the pro-mini’s on-board regulator and use an external voltage regulator (see the image posted at the bottom of that thread by fat16lib – don’t forget the 1 µF caps.  MCP1700s @ < $0.50 ea here ).

Sleeping your processor & components at every possible opportunity is vital. If there is a power wasting delay statement left in your code anywhere, there ought be a really good reason for it (like waiting for your ADC reading to stabilize, etc)


You can flick the SCL and SDA pullup off the board easily with the tip of a soldering iron.

The next life extending technique is to add a larger I2C eeprom so that you can buffer more data before you write to the SD card. The functions I use to do this buffering is included with the I2C eeprom tester example I posted to gitHub.   Eeprom power consumption limits to how far you can take this strategy, but switching from the 4K AT24C32 on that RTC breakout to a 32K AT24C256  provides a $1 way to extend your operating life by 5-10% depending on the amount of sensor data you are handling. The two eeproms are from the same Atmel family, and the wire.h I2C library limits you to 32 byte page writes, so all you have to do is change the bus address in your code and you are done! Same applies to the AT24C512 all the way up to the 2Mb AT24CM02 if you can find them. You can also lift & jumper the address pins (A0,A1) to enable up to four of these Atmel boards on the same bus. (and it would require some code tweaking, but you might also be able to swap some of the larger Microchip brand I2C eeproms into the cheap press fit DIP boards if you wanted bigger chips to play with. Or you could just roll your own breakout board  for a whopping 1024Kb with the 24LC1025 and the 24AA1025 ) The logical end game if you go down the eeprom road is to abandon simple ASCII and start working with struct’s in C.  Then you could store a years worth of data without any SD cards at all.

Isopropyleeprom1. Remove the two pull-up resistors from the YL-90 breakout (if that’s the one you are using ) as the RTC board pull-ups are sufficient.  Straighten the riser pins and trim them to about 1/2 length.

2. Cut 2” lengths of Black, Red, Yellow, and White wire. Solder them to GND, VCC, SDA, and SCL respectively. Shrink wrap the solder joints.

3. Clean the board with alcohol and let it dry.  Apply conformal coating if desired and put a patch of double sided tape on the bottom.

jumpering the eeprom board

4. The next step is to adhere the eeprom to your logger platform via the tape, so that you can cut the jumpers to length. If you left some excess wire protruding from the board when you added the bus interconnect for the sensor cap, it’s pretty easy to patch the four eeprom wires right onto the cascade port.


Sleeping & buffering are the low-hanging fruit, and after that you get into trickier techniques to improve the power budget. For example that new eeprom also lets you push the bus speed above the 100kHz default if your other I2C devices can handle it. I am still testing prototypes at 400kHz, even though that violates the Tlow spec on 8mHz AVR processors, so I am cautious about recommending that to everyone until I see those units deliver a year of good data. But the results have been promising so far...

Cave Pearl data loggersAnother useful modification is powering the RTC from a digital pin. For some reason I have not been able to dig out of the data sheet, the DS3231 pulls almost 0.1 mA when it is powered by the Vcc pin. Fortunately, you can force the IC into a miserly 3μA timekeeping mode if you draw that Vcc pin down, and if the Battery-Backed Square-Wave Enable register bit is set the RTC will still generate alarms when running off of the backup battery. But the soldering for this is a bit tricky:

Cave Pearl data loggers1. After removing the power LED & charge circuit resistors from the RTC board, wedge a fine tweezer tip behind the power pin and apply an iron to the pad on the board. When the solder melts gently lever the pin away from the board.

2. Then tin the pin, and solder a jumper wire to the lifted power pin, being careful not to bridge any of the other connectors in the process. I usually secure the jumper wire to the board with a zip-tie so that no physical stress can be transferred to that tiny solder connection later.

Cave Pearl data loggersAt that point you can attach the jumper to a free digital pin on your Arduino, and use digital.write(pin#,HIGH/LOW) to power to the chip only when the logger is awake.  My pin-powered builds have eight months under their belt now, and by spring 2016 I will know if the CR2032’s can provide enough power to drive the RTC in timkeeping mode for a full year. (2016 note: they all made it!)  I am trying to track the coin cell status with another voltage divider on the breakout board, but since lithium cells keep their nominal voltage until they are completely dead unless you provide a load, that record might not give me any useful information. I will post updates on those experiments on my RTC page as they become available. (Note: Even with the default MIC5205 reg on the promini, pin-powering the RTC like this should get your logger down to ~0.17mA sleep current)

By testing components, changing regulators, buffering, and pin powering the RTC, I am now seeing power curves like this:


This unit had a TMP102 temperature sensor,  an MS5803-02 pressure sensor, and an HTU21D RH sensor attached, and it still took four months to burn off the over-voltage on 3 AA Duracells. (with a 15 minute sample interval) The logger slept at 0.15 mA because all those sensors all have great low power sleep states.

Though I have reached my original one-year goal, I still keep an eye out for other ways to save power. Several people have explored using a MOSFET to de-power the SD cards but according to the fellow who actually wrote the SdFat library, there are some issues wrt multiple re-starts of the SD library . He also warns that you have to close all files and allow at least one second for the SD card to power down before pulling the plug, just in case you accidentally trigger some internal housekeeping event with the file close command.  The folks over at OSBSS claim they can switch the low side without problems and Nick Gammon seems to be having success with his THL logger switching the high side, though those two examples leave me wondering which way to go.  Some set all the SPI lines HIGH & INPUT before powering down to prevent parasitic leakage after the cut, though the guys at Solarduino imply only the slave select line is vulnerable to the problem, and suggest that line won’t leak if you switch the low side (?)

Another potential factor is low 3.3v I’m using to control the FET, discussed here at  CMicrotek’s Low-power Design Blog:

“When using a P-channel FET to drive a load, a GPIO may not drive the gate high enough to completely turn off the FET so you may be leaking power through the FET. This can often go un-noticed since the amount of power is too low to activate the load. A P-channel FET of similar rated voltage and current as an N-channel FET will typically have 50-100% higher Rds(on) than the N-channel FET. With Rds(on) specs on modern FETs in the double-digit milliohm range even doubling the Rds(on) produces a fairly low value. However, that is simply wasted power that can easily be eliminated if low-side switching is an option for your application.”

Reading that makes me lean towards low side switching; though the 2n7000s in my parts bin probably can’t be fully turned on with only 3.3v on the base?  (Note:  there are beefier N-channels out there  that will work with a 3.3v system if you are also de-powering high current sensors)  Luke_I has proposed using SPI.end() to kill all SPI communications once all files are synced and closed but most people simply set the SPI control register SPCR=0;   When you restore power  after low side switching you have to reset SCLocK(D13), MOSI(D11) & CS back to OUTPUT (MISO stays at input) and set the SCLock line LOW to disable that pullup.  Then you reinitialize the SDcard with sd.begin(chipSelect, SPI_FULL_SPEED);  and reopen your files.   Several sources have suggested that only SdFat allows this re-initialization , while SD.h does not.  

One possibly important thing to note is that the sandisk datasheets states (pg 11) 

“Power must be applied to the VDD pin before any I/O pin is set to logic HIGH. In
other words, CMD, CLK, and DAT0-3 must be at zero (0) volts when power is
applied to the VDD pin. “ 

But perhaps this only applies when accessing the cards in their native SDIO mode? But this does make me wonder if you are supposed to turn on the mcu’s internal SPI peripheral before, or after you restore power to the SD card (?)  I think that datasheet suggest you should be doing it after, but they are switching the high side in that example case.

You can extend that strategy and cut power to the entire logger. As I mentioned in the RTC post, the most elegant way to do this would be using the RTC alarm (outputs low) to control a P-channel Mosfet on the high side of the main battery supply.  When the INT/SQW alarm goes low, this turns the mosfet on and powers everything including the main mcu board which would then goes to work taking samples and storing data. Unfortunately some of my builds use interrupts from both the RTC and the sensors, and there is a good chance that with these frequent startup initializations the resulting delays could miss the phenomenon I was actually trying to capture; like tipping bucket or wind sensor reed switches.

Addendum 2016-02-06

Just thought I would post another shot of a retrofit with an MCP1700 voltage regulator:

Cave Pearl data loggers

Note: I used a 6 volt input MCP1700 here, but the MCP1703-3302E/TO accepts up to 16v

…with the addition of a 2 x 4.7 M‎Ω  voltage divider to put 1/2 of the RAW input voltage on A0. Note that the onboard vreg has been removed (normally you would see it just under the cap in front: you can see some of the empty pads still there) and the two led limit resistors have also been pulled. Other than the mcu there is not much left but the crystal & some caps, and I now think of the board itself as simply a convenient breakout for the 328p. This retrofit with an MCP1700 looses the shutdown enable functionality of the default MIC5205 (marked KBxx or LBxx), and the noise suppression features, but I am hoping the caps are enough to deal with that.  The 1700’s are more efficient at low power than the 5205’s which limp along at about 20% efficiency below at 0.1mA, and loggers typically spend 99.9% of their time sleeping.  The XC6203E332PR is another low-ish standby power option if you need output currents in the 400mA range.

On more recent builds I have started moving the voltage regulator & battery divider from the Arduino board to the battery connectors. Note the ceramic 105's on the MCP1700 as per the proper spec.

On late 2016 builds I started moving the  replacement voltage regulator & battery divider away from the Arduino to the battery connector. Given that this is now separated from the caps on the main board, I’m using ceramic 105’s on the MCP1700 as per the spec. Three wires run from this deadbug back to the pro-mini: 3.3v, GND, and 1/2 battery voltage from that 2x10M divider, which gets read on an analog pin.

Keep track of the capacitors if you change the voltage regulator, as the ones on the outgoing side are still connected after you remove the original reg. Sparkfun promini’s have a pair of black 10µF C106 smd caps on either side of the MIC5205 (& an extra 0.1uF on the output side). Several of the clones I checked match that layout, but others had a pair of 0range & brown tantalum 475C SMD capacitors (4.7µF). The MCP1700’s call for a fairly small 1µF on either side. Since my loggers are powered by a relatively large battery with little chance of brown out and no input noise, I have not been too worried about adding a big cap on the input side (often people add up to 100uF..?). I could probably get by with the output side caps already on the Arduino board, but I have been adding the ceramic 104’s (0.1µF) anyway, as I’ve seen a few forum posts suggesting that you get better noise suppression by using multiple capacitor chemistry-types with different ESR on outputs. And I am still careful to add 0.1µF ceramic bypass capacitor from +V to GND on every sensor IC.

If you combine a pin powered RTC, with the MCP1700 retrofit, and you have a good SD card, it’s not unusual to see the  logger platform sleeping below 0.1 mA, even for units built with cheap eBay clones. The pro-mini style board is only responsible for about a third  of that after the retrofit.

Addendum 2016-04-21

It would be a good idea to re-read Nick Gammons post on Power saving techniques for microprocessors, as much of what I’ve done to optimize these loggers is covered in more detail there.  For folks who want to take it farther, there’s good background info on low power design in Granssle’s article: Issues in Using Ultra-Low Power MCUs. And Hackaday’s post on TI processors shows how far the art in low power operation goes. 

Addendum 2016-06-04

Kevin Darrah has been posting some brilliant you-tube tutorials on lowering the power consumption of an Arduino. This includes a kill power circuit, which has been on my to-do list for quite some time now. Definitely worth a look. The rub of course is that you then have power-up latencies for everything.  That’s probably around 75-100 milliseconds for a typical Arduino, SD card initialization would probably be about the same (ie about 5 milliamp seconds) and a couple of sensor inits could easily double or triple that total.  So you could burn up to 25 milliamp seconds for the restart. Even with a sleeping SD card drawing power, a logger built with the optimizations discussed here usually sleeps at 0.14 mA or less. So a regular startup is probably equivalent to ~3 minutes of sleep time, and it would take several more minutes of sleep time power to match a really bad 1 second startup if you had some pokey sensors. So it all depends on how much time you need to get everything operational.  As best I can tell, I am still getting operating life that compares well to some of the power down approaches people are using.

Addendum 2016-10-17

Another tip for saving power is to always use high output LEDs, and to use the green as a status indicator color whenever possible. Why? If you look at the typical rating for a high output RGB you see Luminosity numbers like: 800R, 4000G & 900B mcd.  That means that you can use a limit resistor that’s three times larger on the green channel for about the same light output. I often get away with 30K on the ground line, and an extra 20-30K on the green line of a common cathode LED, and I’m still able to see the indicators with pulses in the 10-15 ms range.  With that much limiting resistance, the LEDs don’t impact the power budget at all. LEDs tend to stay lit for a relatively long time after they are turned off so switching the LED on/off with a 50/50 duty cycle at a rate faster than 1Khz will cut the power by half with an imperceptible reduction in brightness. While I would never leave an led on all the time for a datalogger application, if your application needs a power on indicator, consider a slow flash of the LED (for ½ second every 3 seconds)  instead of having it on constantly.

Addendum 2016-10-28

With my hardware reaching reasonable sleep currents, I guess its finally time for me to look at reducing the run time power use by turning off unnecessary peripherals with the power reduction register.  Heliosoph posted tests results from his capacitor powered project, with a reminder about grounding unused pins.  There are some 3.3v numbers over at avrProgrammers and Nick Gammon weighs in with some sage advice on his forum. Each peripheral doesn’t use much on it’s own, but together they total up to ~1mA that is just being wasted.  Here’s a few of the things I’m currently experimenting with:

  1. Disable the digital input buffers you aren’t using with DIDR0
  2. Never leave floating pins – always use a pullup or pulldown resistor.
  3. Disable unused module clocks using the PRR register
  4. Especially the ADC with ADCSRA &= ~_BV(ADEN);
  5. Shut off the analog comparator: ACSR |=_BV(ACD);

Here’s how those look in code:

#include <avr/power.h>
//defines for DIDR0 setting
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// create variables to restore the SPI & ADC register values after shutdown
byte keep_ADCSRA;
byte keep_SPCR;
// then be sure to store the default register values during setup:
keep_ADCSRA = ADCSRA;   keep_SPCR=SPCR; 

//  1) where the ADC pins are being used, disable the digital input buffers 
//  from
//sbi(DIDR0,ADC3D);  //A3 not used as analog in
//sbi(DIDR0,ADC4D);  //A4= I2C data
//sbi(DIDR0,ADC5D);  //A5= I2C scl
//not needed for A6&A7 because they have no digital capability
//2) set unused analog pins to digital input & pullup to prevent floating
pinMode(A3, INPUT); digitalWrite(A3, HIGH);
//3) And pull up any unused digital pins:
pinMode(pin#, INPUT_PULLUP);

// Disable internal peripherals that you are not using:
// Note to self: Don’t mess with timer 0!
 power_timer1_disable();              // (0.12mA) controls PWM 9 & 10 , Servo library
 power_timer2_disable();             // (0.12mA) controls PWM 3 & 11
  power_adc_disable();                  // disable the clock to the ADC module 
  ADCSRA = 0;                                 // disable ADC by setting ADCSRA reg. to 0  (0.23mA)
  ACSR = B10000000;                  // disable comparator by setting ACD bit7 of ACSR reg. to one.
  power_spi_disable();                   // disable the clock to the SPI module
  SPCR = 0;                                        //disable SPI by setting SPCR register to 0 (0.15mA)
   #ifndef ECHO_TO_SERIAL
   power_usart0_disable();   //(0.08mA) but only if your are not sending any output to the serial monitor!
// power_twi_disable();    // (0.18mA) I don’t usually turn off I2C because I use the bus frequently

// Shutting down ADC & SPI requires you to wake them up again if you need them:
// Before any SD card data saving:
power_spi_enable(); SPCR=keep_SPCR;  delay(1);
// Before ADC reading:
power_adc_enable(); ADCSRA = keep_ADCSRA;  // & throw away the first reading or two…

Still to explore:   Lower the CPU clock & then using a lower voltage power source.

Slowing down the processor doesn’t help much if you are trying to minimize processor up time,  but if you get into a situation where you are forced to keep the Arduino awake,  you could try to reduce the power consumption by slowing the main system clock.  I’m not brave enough yet to make new board definitionsmess with the CLKPR system prescaler, since I have so many sensor communication events.  Delay and millis I can deal with, but Timer0 PWM, ADC and probably a few other things have to be set in conjunction with CLKPR to keep them running at the right speed.  Slower clocks let you reduce the whole system voltage, but I still need to 3.3v because of the sensors & SD card.   Fuse setting still seems like the dark arts to me, and I’m not sure shutting down the BOD is a great idea for data loggers…

Addendum 2016-12-05

After you apply the optimizations described above the sleeping µSD card becomes the biggest power drain left in the system.  So I should probably add a reminder here that there is a huge difference between SD cards that sleep well, and those that don’t.  Sandisk cards smaller than 1Gb tend to have lower idling/sleeping current modes ~70µA, but it’s not unusual to see new large capacity cards drawing  200µA(I’ve seen spec sheets floating around the web for special  TwinMOS mircoSD cards, listing incredibly low sleep & write currents, but I have never managed to find any for sale.)   Cards between 64-256mb usually give me the lowest sleep currents, but because those older cards have to be purchased from eBay, there is also a significant difference in their speed when I test them with H2testw, with some being slower than 2.0MBytes/s, and others saving at 5MBytes/s or better. I presume that is because used cards get slower due to the onboard wear leveling circuitry working to avoid the accumulated bad spots, and the SD latency spec is worse than all of those, allowing a card to take as long as 250ms per write event. The default SD library in Arduino usually writes data at about 4500-5000 bytes per second, and even if SdFat performs significantly better even the slowest SD cards are much faster than the Arduino.  And my gut feeling is that the relatively slow I2C bus coms to the EEprom I’m currently using are sand-bagging the system so much that whole question of SD speed is moot until I start using SPI EEproms, or faster Fram

The point is, always try several different cards with your logger, so you can reject ones that do not sleep well.  With a good card you can get an optimized build below 0.1 mA between readings, but a bad sleeper will easily bump the logger back up into the 0.2 mA range, cutting your operating life in half.  It’s also worth remembering that there is a world of difference between how often you see problems with consumer grade vs industrial grade SD cards.

With regards to runtime current:  always format SD cards using SD Formatter, as OS level formatting utilities may adversely affect performance with the SdFat library. According to William Greiman (author of the SdFat library) “Performance of microSD cards is not easy to predict on Arduino.  Arduino uses SPI to access the cards and the SD library has a single 512 byte cache. Modern SD cards are designed to be used on the high speed 4-bit SDIO bus with very large (16 KB or larger) multi-block writes and reads so they must emulate the single block access that Arduino libraries use.  This can mean much internal data movement, erasing of flash, and rewriting of data.”  Once again, older, smaller SDcards suffer less from this problem than larger size cards, and it’s probably a good idea to try to match your data saves to that 512 byte block size.

Addendum 2017-01-20

One extension of getting your loggers down to a low sleeping current is that it becomes possible to power your data logger with solar cells, especially with 500F super caps  available for $3 each on eBay (& capacitor balancing boards at $1.50). A commonly seen conversion is 1Farad = 0.277mAh /V, so you can think of that 500F cap roughly equivalent to a 138mAh battery – somewhat similar to the capacity of a CR2032 coin cell.  Ignoring the pulse discharges for sampling, I’m seeing sleep currents in the 0.1-0.2mA range, implying more than a week of operation with that kind of power.   David Pilling has done some interesting experiments using cheap garden solar cells with super caps.   So has Nick Gammon, and the guys over at and 

The real question is how to get the logger to recover gracefully from a brown-out event if the sun goes away for an extended period of time, and then comes back and is able to charge the caps up again…

Addendum 2017-05-21

Well, I finally took the plunge and started cutting power to the SD cards: Switching off SD cards for Low Power Data Logging.   I left that step for last because as I was being cautious about anything that might put my precious data at risk, but so far (and I am still testing the heck out of it) is seems to be working well.